Internal: Refactored Separator into SeparatorEx(), exposed ImGuiSeparatorFlags_SpanAllColumns in imgui_internal.h and support without. (#759) + misc comments
diff --git a/docs/TODO.txt b/docs/TODO.txt
index 4c89c8e..97594ba 100644
--- a/docs/TODO.txt
+++ b/docs/TODO.txt
@@ -133,7 +133,9 @@
- clipper: ability to disable the clipping through a simple flag/bool.
- clipper: ability to run without knowing full count in advance.
- - splitter/separator: formalize the splitter idiom into an official api (we want to handle n-way split) (#319)
+ - separator: expose flags (#759)
+ - separator: width, thickness, centering (#1643)
+ - splitter: formalize the splitter idiom into an official api (we want to handle n-way split) (#319)
- dock: merge docking branch (#2109)
- dock: dock out from a collapsing header? would work nicely but need emitting window to keep submitting the code.
diff --git a/imgui.cpp b/imgui.cpp
index 1045ddd..779ea09 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -5445,7 +5445,8 @@
window->InnerMainRect.Max.x = window->Pos.x + window->Size.x - ImMax(window->ScrollbarSizes.x, window->WindowBorderSize);
window->InnerMainRect.Max.y = window->Pos.y + window->Size.y - ImMax(window->ScrollbarSizes.y, window->WindowBorderSize);
- // Inner clipping rectangle
+ // Inner clipping rectangle will extend a little bit outside the work region.
+ // This is to allow e.g. Selectable or CollapsingHeader or some separators to cover that space.
// Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result.
window->InnerClipRect.Min.x = ImFloor(0.5f + window->InnerMainRect.Min.x + ImMax(0.0f, ImFloor(window->WindowPadding.x * 0.5f - window->WindowBorderSize)));
window->InnerClipRect.Min.y = ImFloor(0.5f + window->InnerMainRect.Min.y);
diff --git a/imgui_internal.h b/imgui_internal.h
index a56471d..01f805b 100644
--- a/imgui_internal.h
+++ b/imgui_internal.h
@@ -354,7 +354,8 @@
{
ImGuiSeparatorFlags_None = 0,
ImGuiSeparatorFlags_Horizontal = 1 << 0, // Axis default to current layout type, so generally Horizontal unless e.g. in a menu bar
- ImGuiSeparatorFlags_Vertical = 1 << 1
+ ImGuiSeparatorFlags_Vertical = 1 << 1,
+ ImGuiSeparatorFlags_SpanAllColumns = 1 << 2
};
// Transient per-window flags, reset at the beginning of the frame. For child window, inherited from parent on first Begin().
@@ -1551,7 +1552,7 @@
IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags);
IMGUI_API void Scrollbar(ImGuiAxis axis);
IMGUI_API ImGuiID GetScrollbarID(ImGuiWindow* window, ImGuiAxis axis);
- IMGUI_API void VerticalSeparator(); // Vertical separator, for menu bars (use current line height). Not exposed because it is misleading and it doesn't have an effect on regular layout.
+ IMGUI_API void SeparatorEx(ImGuiSeparatorFlags flags);
// Widgets low-level behaviors
IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0);
diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp
index df9a7d8..2d505f5 100644
--- a/imgui_widgets.cpp
+++ b/imgui_widgets.cpp
@@ -1146,8 +1146,8 @@
// - Dummy()
// - NewLine()
// - AlignTextToFramePadding()
+// - SeparatorEx() [Internal]
// - Separator()
-// - VerticalSeparator() [Internal]
// - SplitterBehavior() [Internal]
//-------------------------------------------------------------------------
@@ -1198,69 +1198,75 @@
}
// Horizontal/vertical separating line
-void ImGui::Separator()
+void ImGui::SeparatorEx(ImGuiSeparatorFlags flags)
{
ImGuiWindow* window = GetCurrentWindow();
if (window->SkipItems)
return;
- ImGuiContext& g = *GImGui;
- // Those flags should eventually be overrideable by the user
- ImGuiSeparatorFlags flags = (window->DC.LayoutType == ImGuiLayoutType_Horizontal) ? ImGuiSeparatorFlags_Vertical : ImGuiSeparatorFlags_Horizontal;
+ ImGuiContext& g = *GImGui;
IM_ASSERT(ImIsPowerOfTwo(flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical))); // Check that only 1 option is selected
+
if (flags & ImGuiSeparatorFlags_Vertical)
{
- VerticalSeparator();
- return;
+ // Vertical separator, for menu bars (use current line height). Not exposed because it is misleading and it doesn't have an effect on regular layout.
+ 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(1.0f, 0.0f));
+ if (!ItemAdd(bb, 0))
+ return;
+
+ // Draw
+ window->DrawList->AddLine(ImVec2(bb.Min.x, bb.Min.y), ImVec2(bb.Min.x, bb.Max.y), GetColorU32(ImGuiCol_Separator));
+ if (g.LogEnabled)
+ LogText(" |");
}
-
- // Horizontal Separator
- if (window->DC.CurrentColumns)
- PushColumnsBackground();
-
- 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, 1.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit
- if (!ItemAdd(bb, 0))
+ else if (flags & ImGuiSeparatorFlags_Horizontal)
{
- if (window->DC.CurrentColumns)
+ // Horizontal Separator
+ float x1 = window->Pos.x;
+ float x2 = window->Pos.x + window->Size.x;
+ if (!window->DC.GroupStack.empty())
+ x1 += window->DC.Indent.x;
+
+ ImGuiColumns* columns = (flags & ImGuiSeparatorFlags_SpanAllColumns) ? window->DC.CurrentColumns : NULL;
+ if (columns)
+ PushColumnsBackground();
+
+ const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y + 1.0f));
+ ItemSize(ImVec2(0.0f, 1.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit
+ if (!ItemAdd(bb, 0))
+ {
+ if (columns)
+ PopColumnsBackground();
+ return;
+ }
+
+ // Draw
+ window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x, bb.Min.y), GetColorU32(ImGuiCol_Separator));
+ if (g.LogEnabled)
+ LogRenderedText(&bb.Min, "--------------------------------");
+
+ if (columns)
+ {
PopColumnsBackground();
- return;
- }
-
- window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x,bb.Min.y), GetColorU32(ImGuiCol_Separator));
-
- if (g.LogEnabled)
- LogRenderedText(&bb.Min, "--------------------------------");
-
- if (window->DC.CurrentColumns)
- {
- PopColumnsBackground();
- window->DC.CurrentColumns->LineMinY = window->DC.CursorPos.y;
+ columns->LineMinY = window->DC.CursorPos.y;
+ }
}
}
-void ImGui::VerticalSeparator()
+void ImGui::Separator()
{
- ImGuiWindow* window = GetCurrentWindow();
+ ImGuiContext& g = *GImGui;
+ ImGuiWindow* window = g.CurrentWindow;
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(1.0f, 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(" |");
+ // Those flags should eventually be overridable by the user
+ ImGuiSeparatorFlags flags = (window->DC.LayoutType == ImGuiLayoutType_Horizontal) ? ImGuiSeparatorFlags_Vertical : ImGuiSeparatorFlags_Horizontal;
+ flags |= ImGuiSeparatorFlags_SpanAllColumns;
+ SeparatorEx(flags);
}
// 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.