From e5dfa0855f8de98664dfc9502068a3e42da67bb6 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 24 May 2019 21:59:00 +0200 Subject: [PATCH] Docking: Honor style.WindowMenuButtonPosition setting in docking node. --- imgui.cpp | 46 +++++++++++++++++++++++++++++++++------------- imgui_widgets.cpp | 2 +- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1333bc290..cde3c4ab1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -11125,7 +11125,7 @@ namespace ImGui static bool DockNodeIsDropAllowed(ImGuiWindow* host_window, ImGuiWindow* payload_window); static void DockNodePreviewDockCalc(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* payload_window, ImGuiDockPreviewData* preview_data, bool is_explicit_target, bool is_outer_docking); static void DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* payload_window, const ImGuiDockPreviewData* preview_data); - static ImRect DockNodeCalcTabBarRect(const ImGuiDockNode* node); + static void DockNodeCalcTabBarLayout(const ImGuiDockNode* node, ImRect* out_title_rect, ImRect* out_tab_bar_rect, ImVec2* out_collapse_button_pos); static void DockNodeCalcSplitRects(ImVec2& pos_old, ImVec2& size_old, ImVec2& pos_new, ImVec2& size_new, ImGuiDir dir, ImVec2 size_new_desired); static bool DockNodeCalcDropRectsAndTestMousePos(const ImRect& parent, ImGuiDir dir, ImRect& out_draw, bool outer_docking, ImVec2* test_mouse_pos); static const char* DockNodeGetHostWindowTitle(ImGuiDockNode* node, char* buf, int buf_size) { ImFormatString(buf, buf_size, "##DockNode_%02X", node->ID); return buf; } @@ -12322,8 +12322,12 @@ static int IMGUI_CDECL TabItemComparerByDockOrder(const void* lhs, const void* r static ImGuiID ImGui::DockNodeUpdateTabListMenu(ImGuiDockNode* node, ImGuiTabBar* tab_bar) { // Try to position the menu so it is more likely to stays within the same viewport + ImGuiContext& g = *GImGui; ImGuiID ret_tab_id = 0; - SetNextWindowPos(ImVec2(node->Pos.x, node->Pos.y + GetFrameHeight())); + if (g.Style.WindowMenuButtonPosition == ImGuiDir_Left) + SetNextWindowPos(ImVec2(node->Pos.x, node->Pos.y + GetFrameHeight()), ImGuiCond_Always, ImVec2(0.0f, 0.0f)); + else + SetNextWindowPos(ImVec2(node->Pos.x + node->Size.x, node->Pos.y + GetFrameHeight()), ImGuiCond_Always, ImVec2(1.0f, 0.0f)); if (BeginPopup("#TabListMenu")) { node->IsFocused = true; @@ -12419,15 +12423,19 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w is_focused |= node->IsFocused; } + // Layout + ImRect title_bar_rect, tab_bar_rect; + ImVec2 collapse_button_pos; + DockNodeCalcTabBarLayout(node, &title_bar_rect, &tab_bar_rect, &collapse_button_pos); + // Title bar if (is_focused) node->LastFrameFocused = g.FrameCount; - ImRect title_bar_rect = ImRect(node->Pos, node->Pos + ImVec2(node->Size.x, g.FontSize + style.FramePadding.y * 2.0f)); ImU32 title_bar_col = GetColorU32(host_window->Collapsed ? ImGuiCol_TitleBgCollapsed : is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg); host_window->DrawList->AddRectFilled(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, host_window->WindowRounding, ImDrawCornerFlags_Top); // Collapse button - if (CollapseButton(host_window->GetID("#COLLAPSE"), title_bar_rect.Min, node)) + if (CollapseButton(host_window->GetID("#COLLAPSE"), collapse_button_pos, node)) OpenPopup("#TabListMenu"); if (IsItemActive()) focus_tab_id = tab_bar->SelectedTabId; @@ -12461,7 +12469,6 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w tab_bar->SelectedTabId = tab_bar->NextSelectedTabId = tab_bar->Tabs.back().Window->ID; // Begin tab bar - const ImRect tab_bar_rect = DockNodeCalcTabBarRect(node); ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_AutoSelectNewTabs; // | ImGuiTabBarFlags_NoTabListScrollingButtons); tab_bar_flags |= ImGuiTabBarFlags_SaveSettings | ImGuiTabBarFlags_DockNode; if (!host_window->Collapsed && is_focused) @@ -12621,15 +12628,27 @@ static bool ImGui::DockNodeIsDropAllowed(ImGuiWindow* host_window, ImGuiWindow* return false; } -static ImRect ImGui::DockNodeCalcTabBarRect(const ImGuiDockNode* node) +// FIXME: This is similar to RenderWindowTitleBarContents, may want to share code. +static void ImGui::DockNodeCalcTabBarLayout(const ImGuiDockNode* node, ImRect* out_title_rect, ImRect* out_tab_bar_rect, ImVec2* out_collapse_button_pos) { ImGuiContext& g = *GImGui; - ImRect r = ImRect(node->Pos.x, node->Pos.y, node->Pos.x + node->Size.x, node->Pos.y + (g.FontSize + g.Style.FramePadding.y * 2.0f)); - if (node->HasCollapseButton) - r.Min.x += g.Style.FramePadding.x + g.FontSize; // + g.Style.ItemInnerSpacing.x; // <-- Adding ItemInnerSpacing makes the title text moves slightly when in a tab bar. Instead we adjusted RenderArrowDockMenu() - // In DockNodeUpdateTabBar() we currently display a disabled close button even if there is none. - r.Max.x -= g.Style.FramePadding.x + g.FontSize + 1.0f; - return r; + ImRect r = ImRect(node->Pos.x, node->Pos.y, node->Pos.x + node->Size.x, node->Pos.y + g.FontSize + g.Style.FramePadding.y * 2.0f); + if (out_title_rect) { *out_title_rect = r; } + + ImVec2 collapse_button_pos = r.Min; + r.Max.x -= g.Style.FramePadding.x + g.FontSize;// +1.0f; // In DockNodeUpdateTabBar() we currently display a disabled close button even if there is none. + if (node->HasCollapseButton && g.Style.WindowMenuButtonPosition == ImGuiDir_Left) + { + r.Min.x += g.Style.FramePadding.x + g.FontSize; // + g.Style.ItemInnerSpacing.x; // <-- Adding ItemInnerSpacing makes the title text moves slightly when in a docking tab bar. Instead we adjusted RenderArrowDockMenu() + } + else if (node->HasCollapseButton && g.Style.WindowMenuButtonPosition == ImGuiDir_Right) + { + r.Min.x += g.Style.FramePadding.x; + r.Max.x -= g.FontSize + g.Style.FramePadding.x; + collapse_button_pos = ImVec2(r.Max.x, r.Min.y); + } + if (out_tab_bar_rect) { *out_tab_bar_rect = r; } + if (out_collapse_button_pos) { *out_collapse_button_pos = collapse_button_pos; } } void ImGui::DockNodeCalcSplitRects(ImVec2& pos_old, ImVec2& size_old, ImVec2& pos_new, ImVec2& size_new, ImGuiDir dir, ImVec2 size_new_desired) @@ -12832,7 +12851,8 @@ static void ImGui::DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDock if (data->IsDropAllowed && can_preview_tabs && data->SplitDir == ImGuiDir_None && data->IsCenterAvailable) { // Compute target tab bar geometry so we can locate our preview tabs - ImRect tab_bar_rect = DockNodeCalcTabBarRect(&data->FutureNode); + ImRect tab_bar_rect; + DockNodeCalcTabBarLayout(&data->FutureNode, NULL, &tab_bar_rect, NULL); ImVec2 tab_pos = tab_bar_rect.Min; if (host_node && host_node->TabBar) { diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 5e2acb13f..22af64917 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -793,7 +793,7 @@ bool ImGui::CollapseButton(ImGuiID id, const ImVec2& pos, ImGuiDockNode* dock_no } else { - ImVec2 backup_active_click_offset = g.ActiveIdClickOffset; + ImVec2 backup_active_click_offset = g.ActiveIdClickOffset + (pos - window->Pos); StartMouseMovingWindow(window); g.ActiveIdClickOffset = backup_active_click_offset; }