mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 05:01:05 +01:00 
			
		
		
		
	Docking: Fixed single-frame node pos/size inconsistencies when window stop or start being submitted.
Fix 718e15c7d while preserving its intended property. Tested by "docking_window_appearing_layout". (#2109)
			
			
This commit is contained in:
		| @@ -159,6 +159,7 @@ Docking+Viewports Branch: | ||||
| - Docking: Fixed a bug undocking windows docked into a non-visible or _KeepAliveOnly dockspace | ||||
|   when unrelated windows submitted before the dockspace have dynamic visibility. (#4757) | ||||
| - Docking: Fixed incorrectly rounded tab bars for dock node that are not at the top of their dock tree. | ||||
| - Docking: Fixed single-frame node pos/size inconsistencies when window stop or start being submitted. | ||||
| - Viewports: Made it possible to explicitly assign ImGuiWindowClass::ParentViewportId to 0 in order | ||||
|   to ensure a window is not parented. Previously this would use the global default (which might be 0, | ||||
|   but not always as it would depend on io.ConfigViewportsNoDefaultParent). (#3152, #2871) | ||||
|   | ||||
							
								
								
									
										41
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										41
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -12908,7 +12908,7 @@ namespace ImGui | ||||
|     // ImGuiDockNode tree manipulations | ||||
|     static void             DockNodeTreeSplit(ImGuiContext* ctx, ImGuiDockNode* parent_node, ImGuiAxis split_axis, int split_first_child, float split_ratio, ImGuiDockNode* new_node); | ||||
|     static void             DockNodeTreeMerge(ImGuiContext* ctx, ImGuiDockNode* parent_node, ImGuiDockNode* merge_lead_child); | ||||
|     static void             DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 size, bool only_write_to_marked_nodes = false); | ||||
|     static void             DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 size, ImGuiDockNode* only_write_to_single_node = NULL); | ||||
|     static void             DockNodeTreeUpdateSplitter(ImGuiDockNode* node); | ||||
|     static ImGuiDockNode*   DockNodeTreeFindVisibleNodeByPos(ImGuiDockNode* node, ImVec2 pos); | ||||
|     static ImGuiDockNode*   DockNodeTreeFindFallbackLeafNode(ImGuiDockNode* node); | ||||
| @@ -13604,7 +13604,6 @@ ImGuiDockNode::ImGuiDockNode(ImGuiID id) | ||||
|     IsVisible = true; | ||||
|     IsFocused = HasCloseButton = HasWindowMenuButton = HasCentralNodeChild = false; | ||||
|     WantCloseAll = WantLockSizeOnce = WantMouseMove = WantHiddenTabBarUpdate = WantHiddenTabBarToggle = false; | ||||
|     MarkedForPosSizeWrite = false; | ||||
| } | ||||
|  | ||||
| ImGuiDockNode::~ImGuiDockNode() | ||||
| @@ -14045,7 +14044,6 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node) | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     IM_ASSERT(node->LastFrameActive != g.FrameCount); | ||||
|     node->LastFrameAlive = g.FrameCount; | ||||
|     node->MarkedForPosSizeWrite = false; | ||||
|  | ||||
|     node->CentralNode = node->OnlyNodeWithWindows = NULL; | ||||
|     if (node->IsRootNode()) | ||||
| @@ -15153,11 +15151,11 @@ void ImGui::DockNodeTreeMerge(ImGuiContext* ctx, ImGuiDockNode* parent_node, ImG | ||||
|  | ||||
| // Update Pos/Size for a node hierarchy (don't affect child Windows yet) | ||||
| // (Depth-first, Pre-Order) | ||||
| void ImGui::DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 size, bool only_write_to_marked_nodes) | ||||
| void ImGui::DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 size, ImGuiDockNode* only_write_to_single_node) | ||||
| { | ||||
|     // During the regular dock node update we write to all nodes. | ||||
|     // 'only_write_to_marked_nodes' is only set when turning a node visible mid-frame and we need its size right-away. | ||||
|     const bool write_to_node = (only_write_to_marked_nodes == false) || (node->MarkedForPosSizeWrite); | ||||
|     // 'only_write_to_single_node' is only set when turning a node visible mid-frame and we need its size right-away. | ||||
|     const bool write_to_node = only_write_to_single_node == NULL || only_write_to_single_node == node; | ||||
|     if (write_to_node) | ||||
|     { | ||||
|         node->Pos = pos; | ||||
| @@ -15171,15 +15169,21 @@ void ImGui::DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 si | ||||
|     ImGuiDockNode* child_1 = node->ChildNodes[1]; | ||||
|     ImVec2 child_0_pos = pos, child_1_pos = pos; | ||||
|     ImVec2 child_0_size = size, child_1_size = size; | ||||
|     if (child_0->IsVisible && child_1->IsVisible) | ||||
|  | ||||
|     const bool child_0_is_toward_single_node = (only_write_to_single_node != NULL && DockNodeIsInHierarchyOf(only_write_to_single_node, child_0)); | ||||
|     const bool child_1_is_toward_single_node = (only_write_to_single_node != NULL && DockNodeIsInHierarchyOf(only_write_to_single_node, child_1)); | ||||
|     const bool child_0_is_or_will_be_visible = child_0->IsVisible || child_0_is_toward_single_node; | ||||
|     const bool child_1_is_or_will_be_visible = child_1->IsVisible || child_1_is_toward_single_node; | ||||
|  | ||||
|     if (child_0_is_or_will_be_visible && child_1_is_or_will_be_visible) | ||||
|     { | ||||
|         ImGuiContext& g = *GImGui; | ||||
|         const float spacing = DOCKING_SPLITTER_SIZE; | ||||
|         const ImGuiAxis axis = (ImGuiAxis)node->SplitAxis; | ||||
|         const float size_avail = ImMax(size[axis] - spacing, 0.0f); | ||||
|  | ||||
|         // Size allocation policy | ||||
|         // 1) The first 0..WindowMinSize[axis]*2 are allocated evenly to both windows. | ||||
|         ImGuiContext& g = *GImGui; | ||||
|         const float size_min_each = ImFloor(ImMin(size_avail, g.Style.WindowMinSize[axis] * 2.0f) * 0.5f); | ||||
|  | ||||
|         // FIXME: Blocks 2) and 3) are essentially doing nearly the same thing. | ||||
| @@ -15230,11 +15234,15 @@ void ImGui::DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 si | ||||
|  | ||||
|         child_1_pos[axis] += spacing + child_0_size[axis]; | ||||
|     } | ||||
|     child_0->WantLockSizeOnce = child_1->WantLockSizeOnce = false; | ||||
|  | ||||
|     if (child_0->IsVisible) | ||||
|     if (only_write_to_single_node == NULL) | ||||
|         child_0->WantLockSizeOnce = child_1->WantLockSizeOnce = false; | ||||
|  | ||||
|     const bool child_0_recurse = only_write_to_single_node ? child_0_is_toward_single_node : child_0->IsVisible; | ||||
|     const bool child_1_recurse = only_write_to_single_node ? child_1_is_toward_single_node : child_1->IsVisible; | ||||
|     if (child_0_recurse) | ||||
|         DockNodeTreeUpdatePosSize(child_0, child_0_pos, child_0_size); | ||||
|     if (child_1->IsVisible) | ||||
|     if (child_1_recurse) | ||||
|         DockNodeTreeUpdatePosSize(child_1, child_1_pos, child_1_size); | ||||
| } | ||||
|  | ||||
| @@ -16048,16 +16056,11 @@ static ImGuiDockNode* ImGui::DockContextBindNodeToWindow(ImGuiContext* ctx, ImGu | ||||
|     if (!node->IsVisible) | ||||
|     { | ||||
|         ImGuiDockNode* ancestor_node = node; | ||||
|         while (!ancestor_node->IsVisible) | ||||
|         { | ||||
|             ancestor_node->IsVisible = true; | ||||
|             ancestor_node->MarkedForPosSizeWrite = true; | ||||
|             if (ancestor_node->ParentNode) | ||||
|                 ancestor_node = ancestor_node->ParentNode; | ||||
|         } | ||||
|         while (!ancestor_node->IsVisible && ancestor_node->ParentNode) | ||||
|             ancestor_node = ancestor_node->ParentNode; | ||||
|         IM_ASSERT(ancestor_node->Size.x > 0.0f && ancestor_node->Size.y > 0.0f); | ||||
|         DockNodeUpdateHasCentralNodeChild(DockNodeGetRootNode(ancestor_node)); | ||||
|         DockNodeTreeUpdatePosSize(ancestor_node, ancestor_node->Pos, ancestor_node->Size, true); | ||||
|         DockNodeTreeUpdatePosSize(ancestor_node, ancestor_node->Pos, ancestor_node->Size, node); | ||||
|     } | ||||
|  | ||||
|     // Add window to node | ||||
|   | ||||
| @@ -1457,7 +1457,6 @@ struct IMGUI_API ImGuiDockNode | ||||
|     bool                    WantMouseMove           :1; // After a node extraction we need to transition toward moving the newly created host window | ||||
|     bool                    WantHiddenTabBarUpdate  :1; | ||||
|     bool                    WantHiddenTabBarToggle  :1; | ||||
|     bool                    MarkedForPosSizeWrite   :1; // Update by DockNodeTreeUpdatePosSize() write-filtering | ||||
|  | ||||
|     ImGuiDockNode(ImGuiID id); | ||||
|     ~ImGuiDockNode(); | ||||
| @@ -2837,6 +2836,7 @@ namespace ImGui | ||||
|     IMGUI_API bool          DockNodeBeginAmendTabBar(ImGuiDockNode* node); | ||||
|     IMGUI_API void          DockNodeEndAmendTabBar(); | ||||
|     inline ImGuiDockNode*   DockNodeGetRootNode(ImGuiDockNode* node)                 { while (node->ParentNode) node = node->ParentNode; return node; } | ||||
|     inline bool             DockNodeIsInHierarchyOf(ImGuiDockNode* node, ImGuiDockNode* parent) { while (node) { if (node == parent) return true; node = node->ParentNode; } return false; } | ||||
|     inline int              DockNodeGetDepth(const ImGuiDockNode* node)              { int depth = 0; while (node->ParentNode) { node = node->ParentNode; depth++; } return depth; } | ||||
|     inline ImGuiID          DockNodeGetWindowMenuButtonId(const ImGuiDockNode* node) { return ImHashStr("#COLLAPSE", 0, node->ID); } | ||||
|     inline ImGuiDockNode*   GetWindowDockNode()                                      { ImGuiContext& g = *GImGui; return g.CurrentWindow->DockNode; } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user