Refactor: moved low-layout helpers to imgui_widgets.cpp (Spacing, Dummy, NewLine, Separator, etc.) (#2036)
diff --git a/imgui.cpp b/imgui.cpp
index 061f9a3..6638f33 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -6030,17 +6030,6 @@
return window->DC.StateStorage;
}
-void ImGui::AlignTextToFramePadding()
-{
- ImGuiWindow* window = GetCurrentWindow();
- if (window->SkipItems)
- return;
-
- ImGuiContext& g = *GImGui;
- window->DC.CurrentLineSize.y = ImMax(window->DC.CurrentLineSize.y, g.FontSize + g.Style.FramePadding.y * 2);
- window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y);
-}
-
void ImGui::PushID(const char* str_id)
{
ImGuiWindow* window = GetCurrentWindowRead();
@@ -6087,148 +6076,6 @@
return GImGui->CurrentWindow->GetID(ptr_id);
}
-// Horizontal/vertical separating line
-void ImGui::Separator()
-{
- ImGuiWindow* window = GetCurrentWindow();
- if (window->SkipItems)
- return;
- ImGuiContext& g = *GImGui;
-
- // Those flags should eventually be overridable by the user
- ImGuiSeparatorFlags flags = (window->DC.LayoutType == ImGuiLayoutType_Horizontal) ? ImGuiSeparatorFlags_Vertical : ImGuiSeparatorFlags_Horizontal;
- IM_ASSERT(ImIsPowerOfTwo((int)(flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical)))); // Check that only 1 option is selected
- if (flags & ImGuiSeparatorFlags_Vertical)
- {
- VerticalSeparator();
- return;
- }
-
- // Horizontal Separator
- if (window->DC.ColumnsSet)
- PopClipRect();
-
- float x1 = window->Pos.x;
- float x2 = window->Pos.x + window->Size.x;
- if (!window->DC.GroupStack.empty())
- x1 += window->DC.Indent.x;
-
- const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y+1.0f));
- ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout.
- if (!ItemAdd(bb, 0))
- {
- if (window->DC.ColumnsSet)
- PushColumnClipRect();
- return;
- }
-
- window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x,bb.Min.y), GetColorU32(ImGuiCol_Separator));
-
- if (g.LogEnabled)
- LogRenderedText(NULL, IM_NEWLINE "--------------------------------");
-
- if (window->DC.ColumnsSet)
- {
- PushColumnClipRect();
- window->DC.ColumnsSet->LineMinY = window->DC.CursorPos.y;
- }
-}
-
-void ImGui::VerticalSeparator()
-{
- ImGuiWindow* window = GetCurrentWindow();
- if (window->SkipItems)
- return;
- ImGuiContext& g = *GImGui;
-
- float y1 = window->DC.CursorPos.y;
- float y2 = window->DC.CursorPos.y + window->DC.CurrentLineSize.y;
- const ImRect bb(ImVec2(window->DC.CursorPos.x, y1), ImVec2(window->DC.CursorPos.x + 1.0f, y2));
- ItemSize(ImVec2(bb.GetWidth(), 0.0f));
- if (!ItemAdd(bb, 0))
- return;
-
- window->DrawList->AddLine(ImVec2(bb.Min.x, bb.Min.y), ImVec2(bb.Min.x, bb.Max.y), GetColorU32(ImGuiCol_Separator));
- if (g.LogEnabled)
- LogText(" |");
-}
-
-// Using 'hover_visibility_delay' allows us to hide the highlight and mouse cursor for a short time, which can be convenient to reduce visual noise.
-bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend, float hover_visibility_delay)
-{
- ImGuiContext& g = *GImGui;
- ImGuiWindow* window = g.CurrentWindow;
-
- const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags;
- window->DC.ItemFlags |= ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus;
- bool item_add = ItemAdd(bb, id);
- window->DC.ItemFlags = item_flags_backup;
- if (!item_add)
- return false;
-
- bool hovered, held;
- ImRect bb_interact = bb;
- bb_interact.Expand(axis == ImGuiAxis_Y ? ImVec2(0.0f, hover_extend) : ImVec2(hover_extend, 0.0f));
- ButtonBehavior(bb_interact, id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap);
- if (g.ActiveId != id)
- SetItemAllowOverlap();
-
- if (held || (g.HoveredId == id && g.HoveredIdPreviousFrame == id && g.HoveredIdTimer >= hover_visibility_delay))
- SetMouseCursor(axis == ImGuiAxis_Y ? ImGuiMouseCursor_ResizeNS : ImGuiMouseCursor_ResizeEW);
-
- ImRect bb_render = bb;
- if (held)
- {
- ImVec2 mouse_delta_2d = g.IO.MousePos - g.ActiveIdClickOffset - bb_interact.Min;
- float mouse_delta = (axis == ImGuiAxis_Y) ? mouse_delta_2d.y : mouse_delta_2d.x;
-
- // Minimum pane size
- float size_1_maximum_delta = ImMax(0.0f, *size1 - min_size1);
- float size_2_maximum_delta = ImMax(0.0f, *size2 - min_size2);
- if (mouse_delta < -size_1_maximum_delta)
- mouse_delta = -size_1_maximum_delta;
- if (mouse_delta > size_2_maximum_delta)
- mouse_delta = size_2_maximum_delta;
-
- // Apply resize
- if (mouse_delta != 0.0f)
- {
- if (mouse_delta < 0.0f)
- IM_ASSERT(*size1 + mouse_delta >= min_size1);
- if (mouse_delta > 0.0f)
- IM_ASSERT(*size2 - mouse_delta >= min_size2);
- *size1 += mouse_delta;
- *size2 -= mouse_delta;
- bb_render.Translate((axis == ImGuiAxis_X) ? ImVec2(mouse_delta, 0.0f) : ImVec2(0.0f, mouse_delta));
- MarkItemEdited(id);
- }
- }
-
- // Render
- const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : (hovered && g.HoveredIdTimer >= hover_visibility_delay) ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator);
- window->DrawList->AddRectFilled(bb_render.Min, bb_render.Max, col, g.Style.FrameRounding);
-
- return held;
-}
-
-void ImGui::Spacing()
-{
- ImGuiWindow* window = GetCurrentWindow();
- if (window->SkipItems)
- return;
- ItemSize(ImVec2(0,0));
-}
-
-void ImGui::Dummy(const ImVec2& size)
-{
- ImGuiWindow* window = GetCurrentWindow();
- if (window->SkipItems)
- return;
-
- const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size);
- ItemSize(bb);
- ItemAdd(bb, 0);
-}
bool ImGui::IsRectVisible(const ImVec2& size)
{
@@ -6336,22 +6183,6 @@
window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset;
}
-void ImGui::NewLine()
-{
- ImGuiWindow* window = GetCurrentWindow();
- if (window->SkipItems)
- return;
-
- ImGuiContext& g = *GImGui;
- const ImGuiLayoutType backup_layout_type = window->DC.LayoutType;
- window->DC.LayoutType = ImGuiLayoutType_Vertical;
- if (window->DC.CurrentLineSize.y > 0.0f) // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height.
- ItemSize(ImVec2(0,0));
- else
- ItemSize(ImVec2(0.0f, g.FontSize));
- window->DC.LayoutType = backup_layout_type;
-}
-
void ImGui::Indent(float indent_w)
{
ImGuiContext& g = *GImGui;
diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp
index 82fde1e..6e0428d 100644
--- a/imgui_widgets.cpp
+++ b/imgui_widgets.cpp
@@ -6,6 +6,7 @@
Index of this file:
- Widgets: Text, etc.
- Widgets: Button, Image, Checkbox, RadioButton, ProgressBar, Bullet, etc.
+- Widgets: Low-level Layout helpers: Spacing, Dummy, NewLine, Separator, etc.
- Widgets: ComboBox
- Data Type and Data Formatting Helpers
- Widgets: DragScalar, DragFloat, DragInt, etc.
@@ -1052,6 +1053,188 @@
}
//-------------------------------------------------------------------------
+// WIDGETS: Low-level Layout helpers
+// - Spacing()
+// - Dummy()
+// - NewLine()
+// - AlignTextToFramePadding()
+// - Separator()
+// - VerticalSeparator() [Internal]
+// - SplitterBehavior() [Internal]
+//-------------------------------------------------------------------------
+
+void ImGui::Spacing()
+{
+ ImGuiWindow* window = GetCurrentWindow();
+ if (window->SkipItems)
+ return;
+ ItemSize(ImVec2(0,0));
+}
+
+void ImGui::Dummy(const ImVec2& size)
+{
+ ImGuiWindow* window = GetCurrentWindow();
+ if (window->SkipItems)
+ return;
+
+ const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size);
+ ItemSize(bb);
+ ItemAdd(bb, 0);
+}
+
+void ImGui::NewLine()
+{
+ ImGuiWindow* window = GetCurrentWindow();
+ if (window->SkipItems)
+ return;
+
+ ImGuiContext& g = *GImGui;
+ const ImGuiLayoutType backup_layout_type = window->DC.LayoutType;
+ window->DC.LayoutType = ImGuiLayoutType_Vertical;
+ if (window->DC.CurrentLineSize.y > 0.0f) // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height.
+ ItemSize(ImVec2(0,0));
+ else
+ ItemSize(ImVec2(0.0f, g.FontSize));
+ window->DC.LayoutType = backup_layout_type;
+}
+
+void ImGui::AlignTextToFramePadding()
+{
+ ImGuiWindow* window = GetCurrentWindow();
+ if (window->SkipItems)
+ return;
+
+ ImGuiContext& g = *GImGui;
+ window->DC.CurrentLineSize.y = ImMax(window->DC.CurrentLineSize.y, g.FontSize + g.Style.FramePadding.y * 2);
+ window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y);
+}
+
+// Horizontal/vertical separating line
+void ImGui::Separator()
+{
+ ImGuiWindow* window = GetCurrentWindow();
+ if (window->SkipItems)
+ return;
+ ImGuiContext& g = *GImGui;
+
+ // Those flags should eventually be overridable by the user
+ ImGuiSeparatorFlags flags = (window->DC.LayoutType == ImGuiLayoutType_Horizontal) ? ImGuiSeparatorFlags_Vertical : ImGuiSeparatorFlags_Horizontal;
+ IM_ASSERT(ImIsPowerOfTwo((int)(flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical)))); // Check that only 1 option is selected
+ if (flags & ImGuiSeparatorFlags_Vertical)
+ {
+ VerticalSeparator();
+ return;
+ }
+
+ // Horizontal Separator
+ if (window->DC.ColumnsSet)
+ PopClipRect();
+
+ float x1 = window->Pos.x;
+ float x2 = window->Pos.x + window->Size.x;
+ if (!window->DC.GroupStack.empty())
+ x1 += window->DC.Indent.x;
+
+ const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y+1.0f));
+ ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout.
+ if (!ItemAdd(bb, 0))
+ {
+ if (window->DC.ColumnsSet)
+ PushColumnClipRect();
+ return;
+ }
+
+ window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x,bb.Min.y), GetColorU32(ImGuiCol_Separator));
+
+ if (g.LogEnabled)
+ LogRenderedText(NULL, IM_NEWLINE "--------------------------------");
+
+ if (window->DC.ColumnsSet)
+ {
+ PushColumnClipRect();
+ window->DC.ColumnsSet->LineMinY = window->DC.CursorPos.y;
+ }
+}
+
+void ImGui::VerticalSeparator()
+{
+ ImGuiWindow* window = GetCurrentWindow();
+ if (window->SkipItems)
+ return;
+ ImGuiContext& g = *GImGui;
+
+ float y1 = window->DC.CursorPos.y;
+ float y2 = window->DC.CursorPos.y + window->DC.CurrentLineSize.y;
+ const ImRect bb(ImVec2(window->DC.CursorPos.x, y1), ImVec2(window->DC.CursorPos.x + 1.0f, y2));
+ ItemSize(ImVec2(bb.GetWidth(), 0.0f));
+ if (!ItemAdd(bb, 0))
+ return;
+
+ window->DrawList->AddLine(ImVec2(bb.Min.x, bb.Min.y), ImVec2(bb.Min.x, bb.Max.y), GetColorU32(ImGuiCol_Separator));
+ if (g.LogEnabled)
+ LogText(" |");
+}
+
+// Using 'hover_visibility_delay' allows us to hide the highlight and mouse cursor for a short time, which can be convenient to reduce visual noise.
+bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend, float hover_visibility_delay)
+{
+ ImGuiContext& g = *GImGui;
+ ImGuiWindow* window = g.CurrentWindow;
+
+ const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags;
+ window->DC.ItemFlags |= ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus;
+ bool item_add = ItemAdd(bb, id);
+ window->DC.ItemFlags = item_flags_backup;
+ if (!item_add)
+ return false;
+
+ bool hovered, held;
+ ImRect bb_interact = bb;
+ bb_interact.Expand(axis == ImGuiAxis_Y ? ImVec2(0.0f, hover_extend) : ImVec2(hover_extend, 0.0f));
+ ButtonBehavior(bb_interact, id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap);
+ if (g.ActiveId != id)
+ SetItemAllowOverlap();
+
+ if (held || (g.HoveredId == id && g.HoveredIdPreviousFrame == id && g.HoveredIdTimer >= hover_visibility_delay))
+ SetMouseCursor(axis == ImGuiAxis_Y ? ImGuiMouseCursor_ResizeNS : ImGuiMouseCursor_ResizeEW);
+
+ ImRect bb_render = bb;
+ if (held)
+ {
+ ImVec2 mouse_delta_2d = g.IO.MousePos - g.ActiveIdClickOffset - bb_interact.Min;
+ float mouse_delta = (axis == ImGuiAxis_Y) ? mouse_delta_2d.y : mouse_delta_2d.x;
+
+ // Minimum pane size
+ float size_1_maximum_delta = ImMax(0.0f, *size1 - min_size1);
+ float size_2_maximum_delta = ImMax(0.0f, *size2 - min_size2);
+ if (mouse_delta < -size_1_maximum_delta)
+ mouse_delta = -size_1_maximum_delta;
+ if (mouse_delta > size_2_maximum_delta)
+ mouse_delta = size_2_maximum_delta;
+
+ // Apply resize
+ if (mouse_delta != 0.0f)
+ {
+ if (mouse_delta < 0.0f)
+ IM_ASSERT(*size1 + mouse_delta >= min_size1);
+ if (mouse_delta > 0.0f)
+ IM_ASSERT(*size2 - mouse_delta >= min_size2);
+ *size1 += mouse_delta;
+ *size2 -= mouse_delta;
+ bb_render.Translate((axis == ImGuiAxis_X) ? ImVec2(mouse_delta, 0.0f) : ImVec2(0.0f, mouse_delta));
+ MarkItemEdited(id);
+ }
+ }
+
+ // Render
+ const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : (hovered && g.HoveredIdTimer >= hover_visibility_delay) ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator);
+ window->DrawList->AddRectFilled(bb_render.Min, bb_render.Max, col, g.Style.FrameRounding);
+
+ return held;
+}
+
+
+//-------------------------------------------------------------------------
// WIDGETS: Combo Box
// - BeginCombo()
// - EndCombo()