From ef8ff1b5d8dda5d37ac34b63277db5df314cf39e Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 18 Sep 2023 15:22:10 +0200 Subject: [PATCH 1/4] TabBar, Style: added style.TabBarBorderSize and associated ImGuiStyleVar_TabBarBorderSize. (#6820, #4859, #5022, #5239) Cherry-picked from docking's 64b1e44 --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 2 ++ imgui.h | 2 ++ imgui_demo.cpp | 1 + imgui_internal.h | 2 ++ imgui_widgets.cpp | 13 ++++++++----- 6 files changed, 17 insertions(+), 5 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index ef5de7b69..b43ab60eb 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -122,6 +122,8 @@ Other changes: - Windows: Layout of Close/Collapse buttons uses style.ItemInnerSpacing.x between items, stopped incorrectly using FramePadding in a way where hit-boxes could overlap when setting large values. (#6749) +- TabBar, Style: added style.TabBarBorderSize and associated ImGuiStyleVar_TabBarBorderSize. + Tweaked rendering of that separator to allow thicker values. (#6820, #4859, #5022, #5239) - InputFloat, SliderFloat, DragFloat: always turn both '.' and ',' into the current decimal point character when using Decimal/Scientific character filter. (#6719, #2278) [@adamsepp] - ColorEdit, ColorPicker: Manipulating options popup don't mark item as edited. (#6722) diff --git a/imgui.cpp b/imgui.cpp index 73c3904a3..5ac64edf1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1185,6 +1185,7 @@ ImGuiStyle::ImGuiStyle() TabRounding = 4.0f; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs. TabBorderSize = 0.0f; // Thickness of border around tabs. TabMinWidthForCloseButton = 0.0f; // Minimum width for close button to appear on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected. + TabBarBorderSize = 1.0f; // Thickness of tab-bar separator, which takes on the tab active color to denote focus. ColorButtonPosition = ImGuiDir_Right; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right. ButtonTextAlign = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text. SelectableTextAlign = ImVec2(0.0f,0.0f);// Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line. @@ -3140,6 +3141,7 @@ static const ImGuiDataVarInfo GStyleVarInfo[] = { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, TabRounding) }, // ImGuiStyleVar_TabRounding + { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, TabBarBorderSize) }, // ImGuiStyleVar_TabBarBorderSize { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, SeparatorTextBorderSize) },// ImGuiStyleVar_SeparatorTextBorderSize diff --git a/imgui.h b/imgui.h index c2bca7334..0d11f545b 100644 --- a/imgui.h +++ b/imgui.h @@ -1645,6 +1645,7 @@ enum ImGuiStyleVar_ ImGuiStyleVar_GrabMinSize, // float GrabMinSize ImGuiStyleVar_GrabRounding, // float GrabRounding ImGuiStyleVar_TabRounding, // float TabRounding + ImGuiStyleVar_TabBarBorderSize, // float TabBarBorderSize ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign ImGuiStyleVar_SelectableTextAlign, // ImVec2 SelectableTextAlign ImGuiStyleVar_SeparatorTextBorderSize,// float SeparatorTextBorderSize @@ -1912,6 +1913,7 @@ struct ImGuiStyle float TabRounding; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs. float TabBorderSize; // Thickness of border around tabs. float TabMinWidthForCloseButton; // Minimum width for close button to appear on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected. + float TabBarBorderSize; // Thickness of tab-bar separator, which takes on the tab active color to denote focus. ImGuiDir ColorButtonPosition; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right. ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f, 0.5f) (centered). ImVec2 SelectableTextAlign; // Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line. diff --git a/imgui_demo.cpp b/imgui_demo.cpp index f60338e78..66329afb2 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -6369,6 +6369,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::SliderFloat("PopupBorderSize", &style.PopupBorderSize, 0.0f, 1.0f, "%.0f"); ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f, "%.0f"); ImGui::SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("TabBarBorderSize", &style.TabBarBorderSize, 0.0f, 2.0f, "%.0f"); ImGui::SeparatorText("Rounding"); ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 12.0f, "%.0f"); diff --git a/imgui_internal.h b/imgui_internal.h index 61fc4ba66..4dcdf97fc 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2551,6 +2551,8 @@ struct IMGUI_API ImGuiTabBar float ScrollingSpeed; float ScrollingRectMinX; float ScrollingRectMaxX; + float SeparatorMinX; + float SeparatorMaxX; ImGuiID ReorderRequestTabId; ImS16 ReorderRequestOffset; ImS8 BeginCount; diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 8d66da113..3aa905c89 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7788,6 +7788,8 @@ bool ImGui::BeginTabBar(const char* str_id, ImGuiTabBarFlags flags) ImGuiTabBar* tab_bar = g.TabBars.GetOrAddByKey(id); ImRect tab_bar_bb = ImRect(window->DC.CursorPos.x, window->DC.CursorPos.y, window->WorkRect.Max.x, window->DC.CursorPos.y + g.FontSize + g.Style.FramePadding.y * 2); tab_bar->ID = id; + tab_bar->SeparatorMinX = tab_bar->BarRect.Min.x - IM_FLOOR(window->WindowPadding.x * 0.5f); + tab_bar->SeparatorMaxX = tab_bar->BarRect.Max.x + IM_FLOOR(window->WindowPadding.x * 0.5f); return BeginTabBarEx(tab_bar, tab_bar_bb, flags | ImGuiTabBarFlags_IsFocused); } @@ -7798,6 +7800,7 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG if (window->SkipItems) return false; + IM_ASSERT(tab_bar->ID != 0); if ((flags & ImGuiTabBarFlags_DockNode) == 0) PushOverrideID(tab_bar->ID); @@ -7840,12 +7843,12 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG window->DC.CursorPos = ImVec2(tab_bar->BarRect.Min.x, tab_bar->BarRect.Max.y + tab_bar->ItemSpacingY); // Draw separator + // (it would be misleading to draw this in EndTabBar() suggesting that it may be drawn over tabs, as tab bar are appendable) const ImU32 col = GetColorU32((flags & ImGuiTabBarFlags_IsFocused) ? ImGuiCol_TabActive : ImGuiCol_TabUnfocusedActive); - const float y = tab_bar->BarRect.Max.y - 1.0f; + if (g.Style.TabBarBorderSize > 0.0f) { - const float separator_min_x = tab_bar->BarRect.Min.x - IM_FLOOR(window->WindowPadding.x * 0.5f); - const float separator_max_x = tab_bar->BarRect.Max.x + IM_FLOOR(window->WindowPadding.x * 0.5f); - window->DrawList->AddLine(ImVec2(separator_min_x, y), ImVec2(separator_max_x, y), col, 1.0f); + const float y = tab_bar->BarRect.Max.y; + window->DrawList->AddRectFilled(ImVec2(tab_bar->SeparatorMinX, y - g.Style.TabBarBorderSize), ImVec2(tab_bar->SeparatorMaxX, y), col); } return true; } @@ -8787,7 +8790,7 @@ void ImGui::TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabI IM_ASSERT(width > 0.0f); const float rounding = ImMax(0.0f, ImMin((flags & ImGuiTabItemFlags_Button) ? g.Style.FrameRounding : g.Style.TabRounding, width * 0.5f - 1.0f)); const float y1 = bb.Min.y + 1.0f; - const float y2 = bb.Max.y - 1.0f; + const float y2 = bb.Max.y - g.Style.TabBarBorderSize; draw_list->PathLineTo(ImVec2(bb.Min.x, y2)); draw_list->PathArcToFast(ImVec2(bb.Min.x + rounding, y1 + rounding), rounding, 6, 9); draw_list->PathArcToFast(ImVec2(bb.Max.x - rounding, y1 + rounding), rounding, 9, 12); From ff36fe365e042a6b72b9a20767fcb4b2c0571d42 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 18 Sep 2023 17:07:35 +0200 Subject: [PATCH 2/4] IO, Inputs: setting io.WantSetMousePos ignores incoming MousePos events. (#6837, #228) Allow easily implementing wrapping behaviors. --- docs/CHANGELOG.txt | 1 + imgui.cpp | 18 +++++++++++++----- imgui_internal.h | 1 + 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index b43ab60eb..4d769176c 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -92,6 +92,7 @@ Other changes: - MenuBar: Fixed an issue where layouting an item in the menu-bar would erroneously register contents size in a way that would affect the scrolling layer. Was most often noticable when using an horizontal scrollbar. (#6789) +- IO: Setting io.WantSetMousePos ignores incoming MousePos events. (#6837, #228) - ImDrawList: Added AddEllipse(), AddEllipseFilled(), PathEllipticalArcTo(). (#2743) [@Doohl] - ImVector: Added find_index() helper. - Backends: GLFW: Clear emscripten's MouseWheel callback before shutdown. (#6790, #6096, #4019) [@halx99] diff --git a/imgui.cpp b/imgui.cpp index 5ac64edf1..3f730e7a1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7888,6 +7888,7 @@ bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max) // - IsMouseDragPastThreshold() [Internal] // - IsMouseDragging() // - GetMousePos() +// - SetMousePos() [Internal] // - GetMousePosOnOpeningCurrentPopup() // - IsMousePosValid() // - IsAnyMouseDown() @@ -8415,6 +8416,15 @@ ImVec2 ImGui::GetMousePos() return g.IO.MousePos; } +// It is expected you only call this if (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos) is set and supported by backend. +void ImGui::SetMousePos(const ImVec2& pos) +{ + ImGuiContext& g = *GImGui; + g.IO.MousePos = g.IO.MousePosPrev = pos; + g.IO.WantSetMousePos = true; + //IMGUI_DEBUG_LOG_IO("SetMousePos: (%.1f,%.1f)\n", io.MousePos.x, io.MousePos.y); +} + // NB: prefer to call right after BeginPopup(). At the time Selectable/MenuItem is activated, the popup is already closed! ImVec2 ImGui::GetMousePosOnOpeningCurrentPopup() { @@ -8903,6 +8913,8 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs) ImGuiInputEvent* e = &g.InputEventsQueue[event_n]; if (e->Type == ImGuiInputEventType_MousePos) { + if (g.IO.WantSetMousePos) + continue; // Trickling Rule: Stop processing queued events if we already handled a mouse button change ImVec2 event_pos(e->MousePos.PosX, e->MousePos.PosY); if (trickle_fast_inputs && (mouse_button_changed != 0 || mouse_wheeled || key_changed || text_inputted)) @@ -11550,11 +11562,7 @@ static void ImGui::NavUpdate() // Update mouse position if requested // (This will take into account the possibility that a Scroll was queued in the window to offset our absolute mouse position before scroll has been applied) if (set_mouse_pos && (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) && (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos)) - { - io.MousePos = io.MousePosPrev = NavCalcPreferredRefPos(); - io.WantSetMousePos = true; - //IMGUI_DEBUG_LOG_IO("SetMousePos: (%.1f,%.1f)\n", io.MousePos.x, io.MousePos.y); - } + SetMousePos(NavCalcPreferredRefPos()); // [DEBUG] g.NavScoringDebugCount = 0; diff --git a/imgui_internal.h b/imgui_internal.h index 4dcdf97fc..6596a67ef 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -3059,6 +3059,7 @@ namespace ImGui IMGUI_API float GetNavTweakPressedAmount(ImGuiAxis axis); IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate); IMGUI_API void GetTypematicRepeatRate(ImGuiInputFlags flags, float* repeat_delay, float* repeat_rate); + IMGUI_API void SetMousePos(const ImVec2& pos); IMGUI_API void SetActiveIdUsingAllKeyboardKeys(); inline bool IsActiveIdUsingNavDir(ImGuiDir dir) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavDirMask & (1 << dir)) != 0; } From 6c022f9bf12a39c2dffc8ff0015273ce6737e1a0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 18 Sep 2023 17:11:10 +0200 Subject: [PATCH 3/4] IO, Inputs: rename SetMousePos() to TeleportMousePos(). (#6837, #228) --- imgui.cpp | 8 +++++--- imgui_internal.h | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 3f730e7a1..9edd1aa23 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8416,13 +8416,15 @@ ImVec2 ImGui::GetMousePos() return g.IO.MousePos; } +// This is called TeleportMousePos() and not SetMousePos() to emphasis that setting MousePosPrev will effectively clear mouse delta as well. // It is expected you only call this if (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos) is set and supported by backend. -void ImGui::SetMousePos(const ImVec2& pos) +void ImGui::TeleportMousePos(const ImVec2& pos) { ImGuiContext& g = *GImGui; g.IO.MousePos = g.IO.MousePosPrev = pos; + g.IO.MouseDelta = ImVec2(0.0f, 0.0f); g.IO.WantSetMousePos = true; - //IMGUI_DEBUG_LOG_IO("SetMousePos: (%.1f,%.1f)\n", io.MousePos.x, io.MousePos.y); + //IMGUI_DEBUG_LOG_IO("TeleportMousePos: (%.1f,%.1f)\n", io.MousePos.x, io.MousePos.y); } // NB: prefer to call right after BeginPopup(). At the time Selectable/MenuItem is activated, the popup is already closed! @@ -11562,7 +11564,7 @@ static void ImGui::NavUpdate() // Update mouse position if requested // (This will take into account the possibility that a Scroll was queued in the window to offset our absolute mouse position before scroll has been applied) if (set_mouse_pos && (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) && (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos)) - SetMousePos(NavCalcPreferredRefPos()); + TeleportMousePos(NavCalcPreferredRefPos()); // [DEBUG] g.NavScoringDebugCount = 0; diff --git a/imgui_internal.h b/imgui_internal.h index 6596a67ef..672f7ebb4 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -3059,7 +3059,7 @@ namespace ImGui IMGUI_API float GetNavTweakPressedAmount(ImGuiAxis axis); IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate); IMGUI_API void GetTypematicRepeatRate(ImGuiInputFlags flags, float* repeat_delay, float* repeat_rate); - IMGUI_API void SetMousePos(const ImVec2& pos); + IMGUI_API void TeleportMousePos(const ImVec2& pos); IMGUI_API void SetActiveIdUsingAllKeyboardKeys(); inline bool IsActiveIdUsingNavDir(ImGuiDir dir) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavDirMask & (1 << dir)) != 0; } From d6360c1ba9934e18ea46913a9e6f3f888a2521b8 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 20 Sep 2023 11:31:28 +0200 Subject: [PATCH 4/4] Fonts, imgui_freetype: Fixed a warning and leak in IMGUI_ENABLE_FREETYPE_LUNASVG support. (#6842, #6591) --- docs/CHANGELOG.txt | 3 ++- misc/freetype/imgui_freetype.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 4d769176c..535e40d85 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -84,6 +84,7 @@ Other changes: - Fonts: Better assert during load when passing truncated font data or wrong data size. (#6822) - Fonts: Ensure calling AddFontXXX function doesn't invalidates ImFont's ConfigData pointers prior to building again. (#6825) +- Fonts, imgui_freetype: Fixed a warning and leak in IMGUI_ENABLE_FREETYPE_LUNASVG support. (#6842, #6591) - InputTextMultiline: Fixed a crash pressing Down on last empty line of a multiline buffer. (regression from 1.89.2, only happened in some states). (#6783, #6000) - InputTextMultiline: Fixed Tabbing cycle leading to a situation where Enter key wouldn't @@ -92,7 +93,7 @@ Other changes: - MenuBar: Fixed an issue where layouting an item in the menu-bar would erroneously register contents size in a way that would affect the scrolling layer. Was most often noticable when using an horizontal scrollbar. (#6789) -- IO: Setting io.WantSetMousePos ignores incoming MousePos events. (#6837, #228) +- IO: Setting io.WantSetMousePos ignores incoming MousePos events. (#6837, #228) [@bertaye] - ImDrawList: Added AddEllipse(), AddEllipseFilled(), PathEllipticalArcTo(). (#2743) [@Doohl] - ImVector: Added find_index() helper. - Backends: GLFW: Clear emscripten's MouseWheel callback before shutdown. (#6790, #6096, #4019) [@halx99] diff --git a/misc/freetype/imgui_freetype.cpp b/misc/freetype/imgui_freetype.cpp index a11e58255..facb9c9ee 100644 --- a/misc/freetype/imgui_freetype.cpp +++ b/misc/freetype/imgui_freetype.cpp @@ -840,7 +840,7 @@ static FT_Error ImGuiLunasvgPortInit(FT_Pointer* _state) static void ImGuiLunasvgPortFree(FT_Pointer* _state) { - IM_DELETE(*_state); + IM_DELETE(*(LunasvgPortState*)_state); } static FT_Error ImGuiLunasvgPortRender(FT_GlyphSlot slot, FT_Pointer* _state)