From 914200212187d9d2e30b56420af256642ee63e07 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Sep 2017 16:40:28 +0200 Subject: [PATCH 1/4] Separator(): Tweak Logging so that the separator text is aligned according to tree padding. --- imgui.cpp | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4a1f49fc..496b677b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -590,8 +590,6 @@ // Forward Declarations //------------------------------------------------------------------------- -static void LogRenderedText(const ImVec2& ref_pos, const char* text, const char* text_end = NULL); - static float GetDraggedColumnOffset(int column_index); static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true); @@ -2870,7 +2868,7 @@ void ImGui::LogText(const char* fmt, ...) // Internal version that takes a position to decide on newline placement and pad items according to their depth. // We split text into individual lines to add current tree level padding -static void LogRenderedText(const ImVec2& ref_pos, const char* text, const char* text_end) +static void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL) { ImGuiContext& g = *GImGui; ImGuiWindow* window = ImGui::GetCurrentWindowRead(); @@ -2878,8 +2876,9 @@ static void LogRenderedText(const ImVec2& ref_pos, const char* text, const char* if (!text_end) text_end = ImGui::FindRenderedTextEnd(text, text_end); - const bool log_new_line = ref_pos.y > window->DC.LogLinePosY+1; - window->DC.LogLinePosY = ref_pos.y; + const bool log_new_line = ref_pos && (ref_pos->y > window->DC.LogLinePosY + 1); + if (ref_pos) + window->DC.LogLinePosY = ref_pos->y; const char* text_remaining = text; if (g.LogStartDepth > window->DC.TreeDepth) // Re-adjust padding if we have popped out of our starting depth @@ -2944,7 +2943,7 @@ void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool { window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end); if (g.LogEnabled) - LogRenderedText(pos, text, text_display_end); + LogRenderedText(&pos, text, text_display_end); } } @@ -2961,7 +2960,7 @@ void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end { window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width); if (g.LogEnabled) - LogRenderedText(pos, text, text_end); + LogRenderedText(&pos, text, text_end); } } @@ -3003,7 +3002,7 @@ void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, cons window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, NULL); } if (g.LogEnabled) - LogRenderedText(pos, text, text_display_end); + LogRenderedText(&pos, text, text_display_end); } // Render a rectangle shaped with optional rounding and borders @@ -4288,7 +4287,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (window->Collapsed) { // Title bar only - RenderFrame(title_bar_rect.GetTL(), title_bar_rect.GetBR(), GetColorU32(ImGuiCol_TitleBgCollapsed), true, window_rounding); + RenderFrame(title_bar_rect.Min, title_bar_rect.Max, GetColorU32(ImGuiCol_TitleBgCollapsed), true, window_rounding); } else { @@ -6148,9 +6147,9 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l // NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here. const char log_prefix[] = "\n##"; const char log_suffix[] = "##"; - LogRenderedText(text_pos, log_prefix, log_prefix+3); + LogRenderedText(&text_pos, log_prefix, log_prefix+3); RenderTextClipped(text_pos, bb.Max, label, label_end, &label_size); - LogRenderedText(text_pos, log_suffix+1, log_suffix+3); + LogRenderedText(&text_pos, log_suffix+1, log_suffix+3); } else { @@ -6168,7 +6167,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l else if (!(flags & ImGuiTreeNodeFlags_Leaf)) RenderCollapseTriangle(bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), is_open, 0.70f); if (g.LogEnabled) - LogRenderedText(text_pos, ">"); + LogRenderedText(&text_pos, ">"); RenderText(text_pos, label, label_end, false); } @@ -7461,9 +7460,9 @@ bool ImGui::Checkbox(const char* label, bool* v) } if (g.LogEnabled) - LogRenderedText(text_bb.GetTL(), *v ? "[x]" : "[ ]"); + LogRenderedText(&text_bb.Min, *v ? "[x]" : "[ ]"); if (label_size.x > 0.0f) - RenderText(text_bb.GetTL(), label); + RenderText(text_bb.Min, label); return pressed; } @@ -7533,9 +7532,9 @@ bool ImGui::RadioButton(const char* label, bool active) } if (g.LogEnabled) - LogRenderedText(text_bb.GetTL(), active ? "(x)" : "( )"); + LogRenderedText(&text_bb.Min, active ? "(x)" : "( )"); if (label_size.x > 0.0f) - RenderText(text_bb.GetTL(), label); + RenderText(text_bb.Min, label); return pressed; } @@ -8378,7 +8377,7 @@ bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2 // Log as text if (g.LogEnabled && !is_password) - LogRenderedText(render_pos, buf_display, NULL); + LogRenderedText(&render_pos, buf_display, NULL); if (label_size.x > 0) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); @@ -9917,7 +9916,7 @@ void ImGui::Separator() window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x,bb.Min.y), GetColorU32(ImGuiCol_Separator)); if (g.LogEnabled) - LogText(IM_NEWLINE "--------------------------------"); + LogRenderedText(NULL, IM_NEWLINE "--------------------------------"); if (window->DC.ColumnsCount > 1) { From f99348711bb85047ebd3fce743090af3f5df2e9a Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Sep 2017 16:41:01 +0200 Subject: [PATCH 2/4] Added VerticalSeparator() entry point in imgui_internal. Seperator() in an horizontal layout context still does that. --- imgui.cpp | 87 +++++++++++++++++++++++++----------------------- imgui.h | 2 +- imgui_internal.h | 2 ++ 3 files changed, 49 insertions(+), 42 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 496b677b..c791da66 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9879,65 +9879,70 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl // Horizontal separating line. void ImGui::Separator() { - ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return; + ImGuiContext& g = *GImGui; ImGuiWindowFlags flags = 0; if ((flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical)) == 0) - { - if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) - flags |= ImGuiSeparatorFlags_Vertical; - else - flags |= ImGuiSeparatorFlags_Horizontal; - } + 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; + } - if (flags & ImGuiSeparatorFlags_Horizontal) + // Horizontal Separator + if (window->DC.ColumnsCount > 1) + PopClipRect(); + + float x1 = window->Pos.x; + float x2 = window->Pos.x + window->Size.x; + if (!window->DC.GroupStack.empty()) + x1 += window->DC.IndentX; + + 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, NULL)) { if (window->DC.ColumnsCount > 1) - PopClipRect(); + PushColumnClipRect(); + return; + } - float x1 = window->Pos.x; - float x2 = window->Pos.x + window->Size.x; - if (!window->DC.GroupStack.empty()) - x1 += window->DC.IndentX; + window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x,bb.Min.y), GetColorU32(ImGuiCol_Separator)); - 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, NULL)) - { - if (window->DC.ColumnsCount > 1) - PushColumnClipRect(); - return; - } - - window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x,bb.Min.y), GetColorU32(ImGuiCol_Separator)); - - if (g.LogEnabled) + if (g.LogEnabled) LogRenderedText(NULL, IM_NEWLINE "--------------------------------"); - if (window->DC.ColumnsCount > 1) - { - PushColumnClipRect(); - window->DC.ColumnsCellMinY = window->DC.CursorPos.y; - } - } - else if (flags & ImGuiSeparatorFlags_Vertical) + if (window->DC.ColumnsCount > 1) { - const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(1.0f, window->DC.CurrentLineHeight)); - ItemSize(ImVec2(bb.GetWidth(), 0.0f)); - if (!ItemAdd(bb, NULL)) - 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("|"); + PushColumnClipRect(); + window->DC.ColumnsCellMinY = 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.CurrentLineHeight; + 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, NULL)) + 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(" |"); +} + void ImGui::Spacing() { ImGuiWindow* window = GetCurrentWindow(); diff --git a/imgui.h b/imgui.h index 48eda19c..0740592f 100644 --- a/imgui.h +++ b/imgui.h @@ -209,7 +209,7 @@ namespace ImGui IMGUI_API void PopButtonRepeat(); // Cursor / Layout - IMGUI_API void Separator(); // horizontal line + IMGUI_API void Separator(); // separator, generally horizontal. inside a menu bar or in horizontal layout mode, this becomes a vertical separator. IMGUI_API void SameLine(float pos_x = 0.0f, float spacing_w = -1.0f); // call between widgets or groups to layout them horizontally IMGUI_API void NewLine(); // undo a SameLine() IMGUI_API void Spacing(); // add vertical spacing diff --git a/imgui_internal.h b/imgui_internal.h index 29d8ca7c..7687c393 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -789,6 +789,8 @@ namespace ImGui IMGUI_API int CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate); + IMGUI_API void VerticalSeparator(); // Vertical separator, for menu bars (use current line height). not exposed because it is misleading what it doesn't have an effect on regular layout. + // FIXME-WIP: New Columns API IMGUI_API void BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). IMGUI_API void EndColumns(); // close columns From 926c1cf9a43f739d3a6ab7c9144d15917dfac2be Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Sep 2017 17:02:28 +0200 Subject: [PATCH 3/4] Merged from Navigation branch: ImGuiItemFlags_SelectableDontClosePopup flag --- imgui.cpp | 2 +- imgui_internal.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c791da66..49282a40 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8813,7 +8813,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl if (flags & ImGuiSelectableFlags_Disabled) PopStyleColor(); // Automatically close popups - if (pressed && !(flags & ImGuiSelectableFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup)) + if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !(window->DC.ItemFlags & ImGuiItemFlags_SelectableDontClosePopup)) CloseCurrentPopup(); return pressed; } diff --git a/imgui_internal.h b/imgui_internal.h index 7687c393..84eec71d 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -580,8 +580,8 @@ enum ImGuiItemFlags_ ImGuiItemFlags_ButtonRepeat = 1 << 1, // false // Button() will return true multiple times based on io.KeyRepeatDelay and io.KeyRepeatRate settings. //ImGuiItemFlags_Disabled = 1 << 2, // false // All widgets appears are disabled //ImGuiItemFlags_AllowNavDefaultFocus = 1 << 3, // true - //ImGuiItemFlags_SelectableDontClosePopup = 1 << 4, // false // MenuItem/Selectable() automatically closes current Popup window - ImGuiItemFlags_Default_ = ImGuiItemFlags_AllowKeyboardFocus + ImGuiItemFlags_SelectableDontClosePopup = 1 << 4, // false // MenuItem/Selectable() automatically closes current Popup window + ImGuiItemFlags_Default_ = ImGuiItemFlags_AllowKeyboardFocus }; // Transient per-window data, reset at the beginning of the frame From e8f7c83138bfcd5f4bab6d15ed9fc8eeded7b063 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Sep 2017 17:37:55 +0200 Subject: [PATCH 4/4] Begin: Shallow tweak to minimize diff with nav branch --- imgui.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 49282a40..85840bfb 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4448,6 +4448,12 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us // Title bar if (!(flags & ImGuiWindowFlags_NoTitleBar)) { + // Collapse button + if (!(flags & ImGuiWindowFlags_NoCollapse)) + { + RenderCollapseTriangle(window->Pos + style.FramePadding, !window->Collapsed, 1.0f); + } + // Close button if (p_open != NULL) { @@ -4457,10 +4463,8 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us *p_open = false; } + // Title text (FIXME: refactor text alignment facilities along with RenderText helpers) const ImVec2 text_size = CalcTextSize(name, NULL, true); - if (!(flags & ImGuiWindowFlags_NoCollapse)) - RenderCollapseTriangle(window->Pos + style.FramePadding, !window->Collapsed, 1.0f); - ImVec2 text_min = window->Pos; ImVec2 text_max = window->Pos + ImVec2(window->Size.x, style.FramePadding.y*2 + text_size.y); ImRect clip_rect; @@ -6979,6 +6983,7 @@ bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_s if (v_speed == 0.0f && (v_max - v_min) != 0.0f && (v_max - v_min) < FLT_MAX) v_speed = (v_max - v_min) * g.DragSpeedDefaultRatio; + float v_cur = g.DragCurrentValue; const ImVec2 mouse_drag_delta = GetMouseDragDelta(0, 1.0f); float adjust_delta = 0.0f;