From 3f16a524c894ed556d21856683d56d345855bbd2 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 13 Apr 2021 16:22:30 +0200 Subject: [PATCH] Docking: move NavWindow to SelectedTabId application lower to leave a chance for in-between code to alter focus. + store per-node window menu button id to simplify usage. --- imgui.cpp | 14 +++++++++----- imgui_internal.h | 5 +++-- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 65225622ba05..558c790882ec 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -12761,7 +12761,7 @@ void ImGui::DockContextProcessDock(ImGuiContext* ctx, ImGuiDockRequest* req) ImGuiDir split_dir = req->DockSplitDir; if (split_dir != ImGuiDir_None) { - // Split into one, one side will be our payload node unless we are dropping a loose window + // Split into two, one side will be our payload node unless we are dropping a loose window const ImGuiAxis split_axis = (split_dir == ImGuiDir_Left || split_dir == ImGuiDir_Right) ? ImGuiAxis_X : ImGuiAxis_Y; const int split_inheritor_child_idx = (split_dir == ImGuiDir_Left || split_dir == ImGuiDir_Up) ? 1 : 0; // Current contents will be moved to the opposite side const float split_ratio = req->DockSplitRatio; @@ -12970,6 +12970,7 @@ bool ImGui::DockContextCalcDropPosForDocking(ImGuiWindow* target, ImGuiDockNode* ImGuiDockNode::ImGuiDockNode(ImGuiID id) { ID = id; + WindowMenuButtonId = ImHashStr("#COLLAPSE", 0, ID); SharedFlags = LocalFlags = ImGuiDockNodeFlags_None; ParentNode = ChildNodes[0] = ChildNodes[1] = NULL; TabBar = NULL; @@ -13804,13 +13805,11 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w ImVec2 window_menu_button_pos; DockNodeCalcTabBarLayout(node, &title_bar_rect, &tab_bar_rect, &window_menu_button_pos); - // Submit new tabs and apply NavWindow focus back to the tab bar. They will be added as Unsorted and sorted below based on relative DockOrder value. + // Submit new tabs, they will be added as Unsorted and sorted below based on relative DockOrder value. const int tabs_count_old = tab_bar->Tabs.Size; for (int window_n = 0; window_n < node->Windows.Size; window_n++) { ImGuiWindow* window = node->Windows[window_n]; - if (g.NavWindow && g.NavWindow->RootWindow == window) - tab_bar->SelectedTabId = window->ID; if (TabBarFindTabByID(tab_bar, window->ID) == NULL) TabBarAddTab(tab_bar, ImGuiTabItemFlags_Unsorted, window); } @@ -13824,7 +13823,8 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w // Docking/Collapse button if (has_window_menu_button) { - if (CollapseButton(host_window->GetID("#COLLAPSE"), window_menu_button_pos, node)) + IMGUI_TEST_ENGINE_ID_INFO(node->WindowMenuButtonId, ImGuiDataType_String, "#COLLAPSE"); + if (CollapseButton(node->WindowMenuButtonId, window_menu_button_pos, node)) OpenPopup("#WindowMenu"); if (IsItemActive()) focus_tab_id = tab_bar->SelectedTabId; @@ -13847,6 +13847,10 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w ImQsort(tab_bar->Tabs.Data + tabs_unsorted_start, tab_bar->Tabs.Size - tabs_unsorted_start, sizeof(ImGuiTabItem), TabItemComparerByDockOrder); } + // Apply NavWindow focus back to the tab bar + if (g.NavWindow && g.NavWindow->RootWindow->DockNode == node) + tab_bar->SelectedTabId = g.NavWindow->RootWindow->ID; + // Selected newly added tabs, or persistent tab ID if the tab bar was just recreated if (tab_bar_is_recreated && TabBarFindTabByID(tab_bar, node->SelectedTabId) != NULL) tab_bar->SelectedTabId = tab_bar->NextSelectedTabId = node->SelectedTabId; diff --git a/imgui_internal.h b/imgui_internal.h index 3ad50f8da0ba..cdfc4d9f4cb8 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1227,6 +1227,7 @@ enum ImGuiDockNodeState struct IMGUI_API ImGuiDockNode { ImGuiID ID; + ImGuiID WindowMenuButtonId; // == ImHashStr("#COLLAPSE", ID) ImGuiDockNodeFlags SharedFlags; // Flags shared by all nodes of a same dockspace hierarchy (inherited from the root node) ImGuiDockNodeFlags LocalFlags; // Flags specific to this node ImGuiDockNodeState State; @@ -2860,8 +2861,8 @@ extern void ImGuiTestEngineHook_Log(ImGuiContext* ctx, const char* fmt, #define IMGUI_TEST_ENGINE_ITEM_ADD(_BB,_ID) if (g.TestEngineHookItems) ImGuiTestEngineHook_ItemAdd(&g, _BB, _ID) // Register item bounding box #define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) if (g.TestEngineHookItems) ImGuiTestEngineHook_ItemInfo(&g, _ID, _LABEL, _FLAGS) // Register item label and status flags (optional) #define IMGUI_TEST_ENGINE_LOG(_FMT,...) if (g.TestEngineHookItems) ImGuiTestEngineHook_Log(&g, _FMT, __VA_ARGS__) // Custom log entry from user land into test log -#define IMGUI_TEST_ENGINE_ID_INFO(_ID,_TYPE,_DATA) if (g.TestEngineHookIdInfo == id) ImGuiTestEngineHook_IdInfo(&g, _TYPE, _ID, (const void*)(_DATA)); -#define IMGUI_TEST_ENGINE_ID_INFO2(_ID,_TYPE,_DATA,_DATA2) if (g.TestEngineHookIdInfo == id) ImGuiTestEngineHook_IdInfo(&g, _TYPE, _ID, (const void*)(_DATA), (const void*)(_DATA2)); +#define IMGUI_TEST_ENGINE_ID_INFO(_ID,_TYPE,_DATA) if (g.TestEngineHookIdInfo == _ID) ImGuiTestEngineHook_IdInfo(&g, _TYPE, _ID, (const void*)(_DATA)); +#define IMGUI_TEST_ENGINE_ID_INFO2(_ID,_TYPE,_DATA,_DATA2) if (g.TestEngineHookIdInfo == _ID) ImGuiTestEngineHook_IdInfo(&g, _TYPE, _ID, (const void*)(_DATA), (const void*)(_DATA2)); #else #define IMGUI_TEST_ENGINE_ITEM_ADD(_BB,_ID) do { } while (0) #define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) do { } while (0)