mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-11-04 15:11:05 +01:00 
			
		
		
		
	Docking: Storing HoveredDockNode in context which can be useful for easily detecting e.g. hovering an empty node. (#3398)
This commit is contained in:
		
							
								
								
									
										79
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								imgui.cpp
									
									
									
									
									
								
							@@ -11892,6 +11892,16 @@ void ImGui::DockContextUpdateDocking(ImGuiContext* ctx)
 | 
				
			|||||||
    if (!(g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable))
 | 
					    if (!(g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable))
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Store hovered dock node. We could in theory use DockNodeTreeFindVisibleNodeByPos() on the root host dock node, but using ->DockNode is a good shortcut.
 | 
				
			||||||
 | 
					    g.HoveredDockNode = NULL;
 | 
				
			||||||
 | 
					    if (ImGuiWindow* hovered_window = g.HoveredWindowUnderMovingWindow)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (hovered_window->DockNode)
 | 
				
			||||||
 | 
					            g.HoveredDockNode = hovered_window->DockNode;
 | 
				
			||||||
 | 
					        else if (hovered_window->DockNodeAsHost)
 | 
				
			||||||
 | 
					            g.HoveredDockNode = DockNodeTreeFindVisibleNodeByPos(hovered_window->DockNodeAsHost, g.IO.MousePos);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Process Docking requests
 | 
					    // Process Docking requests
 | 
				
			||||||
    for (int n = 0; n < dc->Requests.Size; n++)
 | 
					    for (int n = 0; n < dc->Requests.Size; n++)
 | 
				
			||||||
        if (dc->Requests[n].Type == ImGuiDockRequestType_Dock)
 | 
					        if (dc->Requests[n].Type == ImGuiDockRequestType_Dock)
 | 
				
			||||||
@@ -14027,8 +14037,7 @@ ImGuiDockNode* ImGui::DockNodeTreeFindVisibleNodeByPos(ImGuiDockNode* node, ImVe
 | 
				
			|||||||
    if (!node->IsVisible)
 | 
					    if (!node->IsVisible)
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ImGuiContext& g = *GImGui;
 | 
					    const float dock_spacing = 0.0f;// g.Style.ItemInnerSpacing.x; // FIXME: Relation to DOCKING_SPLITTER_SIZE?
 | 
				
			||||||
    const float dock_spacing = g.Style.ItemInnerSpacing.x; // FIXME: Relation to DOCKING_SPLITTER_SIZE?
 | 
					 | 
				
			||||||
    ImRect r(node->Pos, node->Pos + node->Size);
 | 
					    ImRect r(node->Pos, node->Pos + node->Size);
 | 
				
			||||||
    r.Expand(dock_spacing * 0.5f);
 | 
					    r.Expand(dock_spacing * 0.5f);
 | 
				
			||||||
    bool inside = r.Contains(pos);
 | 
					    bool inside = r.Contains(pos);
 | 
				
			||||||
@@ -14860,26 +14869,19 @@ void ImGui::BeginDockableDragDropTarget(ImGuiWindow* window)
 | 
				
			|||||||
    if (AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_WINDOW, ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect))
 | 
					    if (AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_WINDOW, ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect))
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // Select target node
 | 
					        // Select target node
 | 
				
			||||||
        ImGuiDockNode* node = NULL;
 | 
					        // (we should not assume that g.HoveredDockNode is != NULL when window is a host dock node: it depends on padding/spacing handled by DockNodeTreeFindVisibleNodeByPos)
 | 
				
			||||||
        bool allow_null_target_node = false;
 | 
					        ImGuiDockNode* node = g.HoveredDockNode;
 | 
				
			||||||
        if (window->DockNodeAsHost)
 | 
					        const bool allow_null_target_node = window->DockNode == NULL && window->DockNodeAsHost == NULL;
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            node = DockNodeTreeFindVisibleNodeByPos(window->DockNodeAsHost, g.IO.MousePos);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // There is an edge case when docking into a dockspace which only has inactive nodes (because none of the windows are active)
 | 
					        // There is an edge case when docking into a dockspace which only has inactive nodes (because none of the windows are active)
 | 
				
			||||||
            // In this case we need to fallback into any leaf mode, possibly the central node.
 | 
					        // In this case we need to fallback into any leaf mode, possibly the central node.
 | 
				
			||||||
            if (node && node->IsDockSpace() && node->IsRootNode())
 | 
					        if (window->DockNodeAsHost && node && node->IsDockSpace() && node->IsRootNode())
 | 
				
			||||||
            {
 | 
					        {
 | 
				
			||||||
                if (node->CentralNode && node->IsLeafNode()) // FIXME-20181220: We should not have to test for IsLeafNode() here but we have another bug to fix first.
 | 
					            if (node->CentralNode && node->IsLeafNode()) // FIXME-20181220: We should not have to test for IsLeafNode() here but we have another bug to fix first.
 | 
				
			||||||
                    node = node->CentralNode;
 | 
					                node = node->CentralNode;
 | 
				
			||||||
                else
 | 
					            else
 | 
				
			||||||
                    node = DockNodeTreeFindFallbackLeafNode(node);
 | 
					                node = DockNodeTreeFindFallbackLeafNode(node);
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (window->DockNode) // && window->DockIsActive)
 | 
					 | 
				
			||||||
            node = window->DockNode;
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
            allow_null_target_node = true; // Dock into a regular window
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const ImRect explicit_target_rect = (node && node->TabBar && !node->IsHiddenTabBar() && !node->IsNoTabBar()) ? node->TabBar->BarRect : ImRect(window->Pos, window->Pos + ImVec2(window->Size.x, GetFrameHeight()));
 | 
					        const ImRect explicit_target_rect = (node && node->TabBar && !node->IsHiddenTabBar() && !node->IsNoTabBar()) ? node->TabBar->BarRect : ImRect(window->Pos, window->Pos + ImVec2(window->Size.x, GetFrameHeight()));
 | 
				
			||||||
        const bool is_explicit_target = g.IO.ConfigDockingWithShift || IsMouseHoveringRect(explicit_target_rect.Min, explicit_target_rect.Max);
 | 
					        const bool is_explicit_target = g.IO.ConfigDockingWithShift || IsMouseHoveringRect(explicit_target_rect.Min, explicit_target_rect.Max);
 | 
				
			||||||
@@ -15824,6 +15826,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
 | 
				
			|||||||
        if (ImGui::SmallButton("Clear nodes")) { DockContextClearNodes(&g, 0, true); }
 | 
					        if (ImGui::SmallButton("Clear nodes")) { DockContextClearNodes(&g, 0, true); }
 | 
				
			||||||
        ImGui::SameLine();
 | 
					        ImGui::SameLine();
 | 
				
			||||||
        if (ImGui::SmallButton("Rebuild all")) { dc->WantFullRebuild = true; }
 | 
					        if (ImGui::SmallButton("Rebuild all")) { dc->WantFullRebuild = true; }
 | 
				
			||||||
 | 
					        ImGui::Text("HoveredDockNode: 0x%08X", g.HoveredDockNode ? g.HoveredDockNode->ID : 0);
 | 
				
			||||||
        for (int n = 0; n < dc->Nodes.Data.Size; n++)
 | 
					        for (int n = 0; n < dc->Nodes.Data.Size; n++)
 | 
				
			||||||
            if (ImGuiDockNode* node = (ImGuiDockNode*)dc->Nodes.Data[n].val_p)
 | 
					            if (ImGuiDockNode* node = (ImGuiDockNode*)dc->Nodes.Data[n].val_p)
 | 
				
			||||||
                if (!root_nodes_only || node->IsRootNode())
 | 
					                if (!root_nodes_only || node->IsRootNode())
 | 
				
			||||||
@@ -15967,29 +15970,21 @@ void ImGui::ShowMetricsWindow(bool* p_open)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#ifdef IMGUI_HAS_DOCK
 | 
					#ifdef IMGUI_HAS_DOCK
 | 
				
			||||||
    // Overlay: Display Docking info
 | 
					    // Overlay: Display Docking info
 | 
				
			||||||
    if (show_docking_nodes && g.IO.KeyCtrl)
 | 
					    if (show_docking_nodes && g.IO.KeyCtrl && g.HoveredDockNode)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        ImGuiDockContext* dc = &g.DockContext;
 | 
					        char buf[64] = "";
 | 
				
			||||||
        for (int n = 0; n < dc->Nodes.Data.Size; n++)
 | 
					        char* p = buf;
 | 
				
			||||||
            if (ImGuiDockNode* node = (ImGuiDockNode*)dc->Nodes.Data[n].val_p)
 | 
					        ImGuiDockNode* node = g.HoveredDockNode;
 | 
				
			||||||
            {
 | 
					        ImDrawList* overlay_draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList((ImGuiViewportP*)GetMainViewport());
 | 
				
			||||||
                ImGuiDockNode* root_node = DockNodeGetRootNode(node);
 | 
					        p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "DockId: %X%s\n", node->ID, node->IsCentralNode() ? " *CentralNode*" : "");
 | 
				
			||||||
                if (ImGuiDockNode* hovered_node = DockNodeTreeFindVisibleNodeByPos(root_node, g.IO.MousePos))
 | 
					        p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "WindowClass: %08X\n", node->WindowClass.ClassId);
 | 
				
			||||||
                    if (hovered_node != node)
 | 
					        p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "Size: (%.0f, %.0f)\n", node->Size.x, node->Size.y);
 | 
				
			||||||
                        continue;
 | 
					        p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "SizeRef: (%.0f, %.0f)\n", node->SizeRef.x, node->SizeRef.y);
 | 
				
			||||||
                char buf[64] = "";
 | 
					        int depth = DockNodeGetDepth(node);
 | 
				
			||||||
                char* p = buf;
 | 
					        overlay_draw_list->AddRect(node->Pos + ImVec2(3, 3) * (float)depth, node->Pos + node->Size - ImVec2(3, 3) * (float)depth, IM_COL32(200, 100, 100, 255));
 | 
				
			||||||
                ImDrawList* overlay_draw_list = node->HostWindow ? GetForegroundDrawList(node->HostWindow) : GetForegroundDrawList((ImGuiViewportP*)GetMainViewport());
 | 
					        ImVec2 pos = node->Pos + ImVec2(3, 3) * (float)depth;
 | 
				
			||||||
                p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "DockId: %X%s\n", node->ID, node->IsCentralNode() ? " *CentralNode*" : "");
 | 
					        overlay_draw_list->AddRectFilled(pos - ImVec2(1, 1), pos + CalcTextSize(buf) + ImVec2(1, 1), IM_COL32(200, 100, 100, 255));
 | 
				
			||||||
                p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "WindowClass: %08X\n", node->WindowClass.ClassId);
 | 
					        overlay_draw_list->AddText(NULL, 0.0f, pos, IM_COL32(255, 255, 255, 255), buf);
 | 
				
			||||||
                p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "Size: (%.0f, %.0f)\n", node->Size.x, node->Size.y);
 | 
					 | 
				
			||||||
                p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "SizeRef: (%.0f, %.0f)\n", node->SizeRef.x, node->SizeRef.y);
 | 
					 | 
				
			||||||
                int depth = DockNodeGetDepth(node);
 | 
					 | 
				
			||||||
                overlay_draw_list->AddRect(node->Pos + ImVec2(3, 3) * (float)depth, node->Pos + node->Size - ImVec2(3, 3) * (float)depth, IM_COL32(200, 100, 100, 255));
 | 
					 | 
				
			||||||
                ImVec2 pos = node->Pos + ImVec2(3, 3) * (float)depth;
 | 
					 | 
				
			||||||
                overlay_draw_list->AddRectFilled(pos - ImVec2(1, 1), pos + CalcTextSize(buf) + ImVec2(1, 1), IM_COL32(200, 100, 100, 255));
 | 
					 | 
				
			||||||
                overlay_draw_list->AddText(NULL, 0.0f, pos, IM_COL32(255, 255, 255, 255), buf);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif // #ifdef IMGUI_HAS_DOCK
 | 
					#endif // #ifdef IMGUI_HAS_DOCK
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1296,6 +1296,7 @@ struct ImGuiContext
 | 
				
			|||||||
    ImGuiWindow*            HoveredWindow;                      // Will catch mouse inputs
 | 
					    ImGuiWindow*            HoveredWindow;                      // Will catch mouse inputs
 | 
				
			||||||
    ImGuiWindow*            HoveredRootWindow;                  // Will catch mouse inputs (for focus/move only)
 | 
					    ImGuiWindow*            HoveredRootWindow;                  // Will catch mouse inputs (for focus/move only)
 | 
				
			||||||
    ImGuiWindow*            HoveredWindowUnderMovingWindow;     // Hovered window ignoring MovingWindow. Only set if MovingWindow is set.
 | 
					    ImGuiWindow*            HoveredWindowUnderMovingWindow;     // Hovered window ignoring MovingWindow. Only set if MovingWindow is set.
 | 
				
			||||||
 | 
					    ImGuiDockNode*          HoveredDockNode;
 | 
				
			||||||
    ImGuiWindow*            MovingWindow;                       // Track the window we clicked on (in order to preserve focus). The actually window that is moved is generally MovingWindow->RootWindow.
 | 
					    ImGuiWindow*            MovingWindow;                       // Track the window we clicked on (in order to preserve focus). The actually window that is moved is generally MovingWindow->RootWindow.
 | 
				
			||||||
    ImGuiWindow*            WheelingWindow;                     // Track the window we started mouse-wheeling on. Until a timer elapse or mouse has moved, generally keep scrolling the same window even if during the course of scrolling the mouse ends up hovering a child window.
 | 
					    ImGuiWindow*            WheelingWindow;                     // Track the window we started mouse-wheeling on. Until a timer elapse or mouse has moved, generally keep scrolling the same window even if during the course of scrolling the mouse ends up hovering a child window.
 | 
				
			||||||
    ImVec2                  WheelingWindowRefMousePos;
 | 
					    ImVec2                  WheelingWindowRefMousePos;
 | 
				
			||||||
@@ -1515,6 +1516,7 @@ struct ImGuiContext
 | 
				
			|||||||
        HoveredWindow = NULL;
 | 
					        HoveredWindow = NULL;
 | 
				
			||||||
        HoveredRootWindow = NULL;
 | 
					        HoveredRootWindow = NULL;
 | 
				
			||||||
        HoveredWindowUnderMovingWindow = NULL;
 | 
					        HoveredWindowUnderMovingWindow = NULL;
 | 
				
			||||||
 | 
					        HoveredDockNode = NULL;
 | 
				
			||||||
        MovingWindow = NULL;
 | 
					        MovingWindow = NULL;
 | 
				
			||||||
        WheelingWindow = NULL;
 | 
					        WheelingWindow = NULL;
 | 
				
			||||||
        WheelingWindowTimer = 0.0f;
 | 
					        WheelingWindowTimer = 0.0f;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user