Update Pos/Size for a node hierarchy (don't affect child Windows yet) (Depth-first, Pre-Order)
| 20191 | // Update Pos/Size for a node hierarchy (don't affect child Windows yet) |
| 20192 | // (Depth-first, Pre-Order) |
| 20193 | void ImGui::DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 size, ImGuiDockNode* only_write_to_single_node) |
| 20194 | { |
| 20195 | // During the regular dock node update we write to all nodes. |
| 20196 | // 'only_write_to_single_node' is only set when turning a node visible mid-frame and we need its size right-away. |
| 20197 | ImGuiContext& g = *GImGui; |
| 20198 | const bool write_to_node = only_write_to_single_node == NULL || only_write_to_single_node == node; |
| 20199 | if (write_to_node) |
| 20200 | { |
| 20201 | node->Pos = pos; |
| 20202 | node->Size = size; |
| 20203 | } |
| 20204 | |
| 20205 | if (node->IsLeafNode()) |
| 20206 | return; |
| 20207 | |
| 20208 | ImGuiDockNode* child_0 = node->ChildNodes[0]; |
| 20209 | ImGuiDockNode* child_1 = node->ChildNodes[1]; |
| 20210 | ImVec2 child_0_pos = pos, child_1_pos = pos; |
| 20211 | ImVec2 child_0_size = size, child_1_size = size; |
| 20212 | |
| 20213 | const bool child_0_is_toward_single_node = (only_write_to_single_node != NULL && DockNodeIsInHierarchyOf(only_write_to_single_node, child_0)); |
| 20214 | const bool child_1_is_toward_single_node = (only_write_to_single_node != NULL && DockNodeIsInHierarchyOf(only_write_to_single_node, child_1)); |
| 20215 | const bool child_0_is_or_will_be_visible = child_0->IsVisible || child_0_is_toward_single_node; |
| 20216 | const bool child_1_is_or_will_be_visible = child_1->IsVisible || child_1_is_toward_single_node; |
| 20217 | |
| 20218 | if (child_0_is_or_will_be_visible && child_1_is_or_will_be_visible) |
| 20219 | { |
| 20220 | const float spacing = g.Style.DockingSeparatorSize; |
| 20221 | const ImGuiAxis axis = (ImGuiAxis)node->SplitAxis; |
| 20222 | const float size_avail = ImMax(size[axis] - spacing, 0.0f); |
| 20223 | |
| 20224 | // Size allocation policy |
| 20225 | // 1) The first 0..WindowMinSize[axis]*2 are allocated evenly to both windows. |
| 20226 | const float size_min_each = ImTrunc(ImMin(size_avail, g.Style.WindowMinSize[axis] * 2.0f) * 0.5f); |
| 20227 | |
| 20228 | // FIXME: Blocks 2) and 3) are essentially doing nearly the same thing. |
| 20229 | // Difference are: write-back to SizeRef; application of a minimum size; rounding before ImTrunc() |
| 20230 | // Clarify and rework differences between Size & SizeRef and purpose of WantLockSizeOnce |
| 20231 | |
| 20232 | // 2) Process locked absolute size (during a splitter resize we preserve the child of nodes not touching the splitter edge) |
| 20233 | if (child_0->WantLockSizeOnce && !child_1->WantLockSizeOnce) |
| 20234 | { |
| 20235 | child_0_size[axis] = child_0->SizeRef[axis] = ImMin(size_avail - 1.0f, child_0->Size[axis]); |
| 20236 | child_1_size[axis] = child_1->SizeRef[axis] = (size_avail - child_0_size[axis]); |
| 20237 | IM_ASSERT(child_0->SizeRef[axis] > 0.0f && child_1->SizeRef[axis] > 0.0f); |
| 20238 | } |
| 20239 | else if (child_1->WantLockSizeOnce && !child_0->WantLockSizeOnce) |
| 20240 | { |
| 20241 | child_1_size[axis] = child_1->SizeRef[axis] = ImMin(size_avail - 1.0f, child_1->Size[axis]); |
| 20242 | child_0_size[axis] = child_0->SizeRef[axis] = (size_avail - child_1_size[axis]); |
| 20243 | IM_ASSERT(child_0->SizeRef[axis] > 0.0f && child_1->SizeRef[axis] > 0.0f); |
| 20244 | } |
| 20245 | else if (child_0->WantLockSizeOnce && child_1->WantLockSizeOnce) |
| 20246 | { |
| 20247 | // FIXME-DOCK: We cannot honor the requested size, so apply ratio. |
| 20248 | // Currently this path will only be taken if code programmatically sets WantLockSizeOnce |
| 20249 | float split_ratio = child_0_size[axis] / (child_0_size[axis] + child_1_size[axis]); |
| 20250 | child_0_size[axis] = child_0->SizeRef[axis] = ImTrunc(size_avail * split_ratio); |
nothing calls this directly
no test coverage detected