From 71a58261f6d14fdda4eb8c907b6d3aa0c1abcf10 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 27 Nov 2019 18:21:04 +0100 Subject: [PATCH] Docking: Internals: Removed redundancy in code path leading to the BeginAsDockableDragDropSource(), clarified UpdateMouseMovingWindowEndFrame() Note that the ConfigWindowsMoveFromTitleBarOnly path for UpdateMouseMovingWindowEndFrame() would previously test the window->RootWindow title bar instead of window->RootWindowDockStop. This didn't have any side effect afaik because we wouldn't enter that function anyway as clicking on any tab bar would trigger the move before UpdateMouseMovingWindowEndFrame() does it. However for consistency made the UpdateMouseMovingWindowEndFrame()code more correct. + minor renaming --- docs/TODO.txt | 1 + imgui.cpp | 49 +++++++++++++++++++++++++----------------------- imgui_internal.h | 4 ++-- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/docs/TODO.txt b/docs/TODO.txt index e78447b3..cb5a06d6 100644 --- a/docs/TODO.txt +++ b/docs/TODO.txt @@ -169,6 +169,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - docking: B~ tidy up tab list popup buttons features (available with manual tab-bar, see ImGuiTabBarFlags_NoTabListPopupButton code, not used by docking nodes) - docking: B- SetNextWindowDockId(0) with a second Begin() in the frame will asserts - docking: B: resize grip drawn in host window typically appears under scrollbar. + - docking: B: resize grip auto-resize on multiple node hierarchy doesn't make much sense or should be improved? - docking: B- SetNextWindowFocus() doesn't seem to apply if the window is hidden this frame, need repro (#4) - docking: B- resizing a dock tree small currently has glitches (overlapping collapse and close button, etc.) - docking: B- dpi: look at interaction with the hi-dpi and multi-dpi stuff. diff --git a/imgui.cpp b/imgui.cpp index 42e10aef..7f57bba8 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3382,10 +3382,10 @@ void ImGui::UpdateMouseMovingWindowNewFrame() } } -// Initiate moving window, handle left-click and right-click focus +// Initiate moving window when clicking on empty space or title bar. +// Handle left-click and right-click focus. void ImGui::UpdateMouseMovingWindowEndFrame() { - // Initiate moving window ImGuiContext& g = *GImGui; if (g.ActiveId != 0 || g.HoveredId != 0) return; @@ -3394,15 +3394,18 @@ void ImGui::UpdateMouseMovingWindowEndFrame() if (g.NavWindow && g.NavWindow->Appearing) return; - // Click to focus window and start moving (after we're done with all our widgets) + // Click on void to focus window and start moving + // (after we're done with all our widgets, so e.g. clicking on docking tab-bar which have set HoveredId already and not get us here!) if (g.IO.MouseClicked[0]) { - if (g.HoveredRootWindow != NULL) + ImGuiWindow* root_window = g.HoveredWindow->RootWindowDockStop; + if (root_window != NULL) { StartMouseMovingWindow(g.HoveredWindow); - if (g.IO.ConfigWindowsMoveFromTitleBarOnly && (!(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoTitleBar) || g.HoveredWindow->RootWindowDockStop->DockIsActive)) - if (!g.HoveredRootWindow->TitleBarRect().Contains(g.IO.MouseClickedPos[0])) - g.MovingWindow = NULL; + if (g.IO.ConfigWindowsMoveFromTitleBarOnly) + if (!(root_window->Flags & ImGuiWindowFlags_NoTitleBar) || root_window->DockIsActive) + if (!root_window->TitleBarRect().Contains(g.IO.MouseClickedPos[0])) + g.MovingWindow = NULL; } else if (g.NavWindow != NULL && GetTopMostPopupModal() == NULL) { @@ -6406,17 +6409,16 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable) { // Docking: Dragging a dockable window (or any of its child) turns it into a drag and drop source. - // We need to do this _before_ we overwrite window->DC.LastItemId below because BeginAsDockableDragDropSource() also overwrites it. - if ((g.ActiveId == window->MoveId) && (g.IO.ConfigDockingWithShift == g.IO.KeyShift)) - if ((window->Flags & ImGuiWindowFlags_NoMove) == 0) - if ((window->RootWindow->Flags & (ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDocking)) == 0) - BeginAsDockableDragDropSource(window); + // We need to do this _before_ we overwrite window->DC.LastItemId below because BeginDockableDragDropSource() also overwrites it. + if ((g.MovingWindow == window) && (g.IO.ConfigDockingWithShift == g.IO.KeyShift)) + if ((window->RootWindow->Flags & ImGuiWindowFlags_NoDocking) == 0) + BeginDockableDragDropSource(window); - // Docking: Any dockable window can act as a target. For dock node hosts we call BeginAsDockableDragDropTarget() in DockNodeUpdate() instead. + // Docking: Any dockable window can act as a target. For dock node hosts we call BeginDockableDragDropTarget() in DockNodeUpdate() instead. if (g.DragDropActive && !(flags & ImGuiWindowFlags_NoDocking)) if (g.MovingWindow == NULL || g.MovingWindow->RootWindow != window) if ((window == window->RootWindow) && !(window->Flags & ImGuiWindowFlags_DockNodeHost)) - BeginAsDockableDragDropTarget(window); + BeginDockableDragDropTarget(window); } // We fill last item data based on Title Bar/Tab, in order for IsItemHovered() and IsItemActive() to be usable after Begin(). @@ -11817,8 +11819,7 @@ void ImGui::DockContextProcessUndockNode(ImGuiContext* ctx, ImGuiDockNode* node) DockSettingsRenameNodeReferences(node->ID, new_node->ID); for (int n = 0; n < new_node->Windows.Size; n++) UpdateWindowParentAndRootLinks(new_node->Windows[n], new_node->Windows[n]->Flags, NULL); - new_node->AuthorityForPos = new_node->AuthorityForSize = ImGuiDataAuthority_Window; - new_node->WantMouseMove = true; + node = new_node; } else { @@ -11829,9 +11830,9 @@ void ImGui::DockContextProcessUndockNode(ImGuiContext* ctx, ImGuiDockNode* node) DockNodeTreeMerge(ctx, node->ParentNode, node->ParentNode->ChildNodes[index_in_parent ^ 1]); node->ParentNode->AuthorityForViewport = ImGuiDataAuthority_Window; // The node that stays in place keeps the viewport, so our newly dragged out node will create a new viewport node->ParentNode = NULL; - node->AuthorityForPos = node->AuthorityForSize = ImGuiDataAuthority_Window; - node->WantMouseMove = true; } + node->AuthorityForPos = node->AuthorityForSize = ImGuiDataAuthority_Window; + node->WantMouseMove = true; MarkIniSettingsDirty(); } @@ -12525,7 +12526,7 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node) // Draw payload drop target if (host_window && node->IsVisible) if (node->IsRootNode() && (g.MovingWindow == NULL || g.MovingWindow->RootWindow != host_window)) - BeginAsDockableDragDropTarget(host_window); + BeginDockableDragDropTarget(host_window); // We update this after DockNodeUpdateTabBar() node->LastFrameActive = g.FrameCount; @@ -14099,9 +14100,10 @@ void ImGui::DockBuilderFinish(ImGuiID root_id) // Docking: Begin/End Support Functions (called from Begin/End) //----------------------------------------------------------------------------- // - GetWindowAlwaysWantOwnTabBar() +// - DockContextBindNodeToWindow() // - BeginDocked() -// - BeginAsDockableDragDropSource() -// - BeginAsDockableDragDropTarget() +// - BeginDockableDragDropSource() +// - BeginDockableDragDropTarget() //----------------------------------------------------------------------------- bool ImGui::GetWindowAlwaysWantOwnTabBar(ImGuiWindow* window) @@ -14281,10 +14283,11 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open) window->ChildId = parent_window->GetID(window->Name); } -void ImGui::BeginAsDockableDragDropSource(ImGuiWindow* window) +void ImGui::BeginDockableDragDropSource(ImGuiWindow* window) { ImGuiContext& g = *GImGui; IM_ASSERT(g.ActiveId == window->MoveId); + IM_ASSERT(g.MovingWindow == window); window->DC.LastItemId = window->MoveId; window = window->RootWindow; @@ -14297,7 +14300,7 @@ void ImGui::BeginAsDockableDragDropSource(ImGuiWindow* window) } } -void ImGui::BeginAsDockableDragDropTarget(ImGuiWindow* window) +void ImGui::BeginDockableDragDropTarget(ImGuiWindow* window) { ImGuiContext* ctx = GImGui; ImGuiContext& g = *ctx; diff --git a/imgui_internal.h b/imgui_internal.h index 40db1209..40800193 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1914,8 +1914,8 @@ namespace ImGui inline ImGuiDockNode* DockNodeGetRootNode(ImGuiDockNode* node) { while (node->ParentNode) node = node->ParentNode; return node; } IMGUI_API bool GetWindowAlwaysWantOwnTabBar(ImGuiWindow* window); IMGUI_API void BeginDocked(ImGuiWindow* window, bool* p_open); - IMGUI_API void BeginAsDockableDragDropSource(ImGuiWindow* window); - IMGUI_API void BeginAsDockableDragDropTarget(ImGuiWindow* window); + IMGUI_API void BeginDockableDragDropSource(ImGuiWindow* window); + IMGUI_API void BeginDockableDragDropTarget(ImGuiWindow* window); IMGUI_API void SetWindowDock(ImGuiWindow* window, ImGuiID dock_id, ImGuiCond cond); // Docking - Builder function needs to be generally called before the node is used/submitted.