mirror of
https://github.com/ocornut/imgui.git
synced 2026-03-06 09:07:17 +00:00
Docking: Add source dock node parameter DockContextCalcDropPosForDocking() to facilitate test engine (un)docking nodes before they are split out to their own window.
Metrics: Display dock_node->Windows in node metrics.
This commit is contained in:
25
imgui.cpp
25
imgui.cpp
@@ -13841,7 +13841,7 @@ namespace ImGui
|
||||
static void DockNodeUpdateVisibleFlag(ImGuiDockNode* node);
|
||||
static void DockNodeStartMouseMovingWindow(ImGuiDockNode* node, ImGuiWindow* window);
|
||||
static bool DockNodeIsDropAllowed(ImGuiWindow* host_window, ImGuiWindow* payload_window);
|
||||
static void DockNodePreviewDockSetup(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* payload_window, ImGuiDockPreviewData* preview_data, bool is_explicit_target, bool is_outer_docking);
|
||||
static void DockNodePreviewDockSetup(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* payload_window, ImGuiDockNode* payload_node, ImGuiDockPreviewData* preview_data, bool is_explicit_target, bool is_outer_docking);
|
||||
static void DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* payload_window, const ImGuiDockPreviewData* preview_data);
|
||||
static void DockNodeCalcTabBarLayout(const ImGuiDockNode* node, ImRect* out_title_rect, ImRect* out_tab_bar_rect, ImVec2* out_window_menu_button_pos, ImVec2* out_close_button_pos);
|
||||
static void DockNodeCalcSplitRects(ImVec2& pos_old, ImVec2& size_old, ImVec2& pos_new, ImVec2& size_new, ImGuiDir dir, ImVec2 size_new_desired);
|
||||
@@ -14500,14 +14500,14 @@ void ImGui::DockContextProcessUndockNode(ImGuiContext* ctx, ImGuiDockNode* node)
|
||||
}
|
||||
|
||||
// This is mostly used for automation.
|
||||
bool ImGui::DockContextCalcDropPosForDocking(ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, bool split_outer, ImVec2* out_pos)
|
||||
bool ImGui::DockContextCalcDropPosForDocking(ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload_window, ImGuiDockNode* payload_node, ImGuiDir split_dir, bool split_outer, ImVec2* out_pos)
|
||||
{
|
||||
// In DockNodePreviewDockSetup() for a root central node instead of showing both "inner" and "outer" drop rects
|
||||
// (which would be functionally identical) we only show the outer one. Reflect this here.
|
||||
if (target_node && target_node->ParentNode == NULL && target_node->IsCentralNode() && split_dir != ImGuiDir_None)
|
||||
split_outer = true;
|
||||
ImGuiDockPreviewData split_data;
|
||||
DockNodePreviewDockSetup(target, target_node, payload, &split_data, false, split_outer);
|
||||
DockNodePreviewDockSetup(target, target_node, payload_window, payload_node, &split_data, false, split_outer);
|
||||
if (split_data.DropRectsDraw[split_dir+1].IsInverted())
|
||||
return false;
|
||||
*out_pos = split_data.DropRectsDraw[split_dir+1].GetCenter();
|
||||
@@ -15829,20 +15829,21 @@ bool ImGui::DockNodeCalcDropRectsAndTestMousePos(const ImRect& parent, ImGuiDir
|
||||
|
||||
// host_node may be NULL if the window doesn't have a DockNode already.
|
||||
// FIXME-DOCK: This is misnamed since it's also doing the filtering.
|
||||
static void ImGui::DockNodePreviewDockSetup(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* root_payload, ImGuiDockPreviewData* data, bool is_explicit_target, bool is_outer_docking)
|
||||
static void ImGui::DockNodePreviewDockSetup(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* payload_window, ImGuiDockNode* payload_node, ImGuiDockPreviewData* data, bool is_explicit_target, bool is_outer_docking)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
||||
// There is an edge case when docking into a dockspace which only has inactive nodes.
|
||||
// In this case DockNodeTreeFindNodeByPos() will have selected a leaf node which is inactive.
|
||||
// Because the inactive leaf node doesn't have proper pos/size yet, we'll use the root node as reference.
|
||||
ImGuiDockNode* root_payload_as_host = root_payload->DockNodeAsHost;
|
||||
if (payload_node == NULL)
|
||||
payload_node = payload_window->DockNodeAsHost;
|
||||
ImGuiDockNode* ref_node_for_rect = (host_node && !host_node->IsVisible) ? DockNodeGetRootNode(host_node) : host_node;
|
||||
if (ref_node_for_rect)
|
||||
IM_ASSERT(ref_node_for_rect->IsVisible == true);
|
||||
|
||||
// Filter, figure out where we are allowed to dock
|
||||
ImGuiDockNodeFlags src_node_flags = root_payload_as_host ? root_payload_as_host->MergedFlags : root_payload->WindowClass.DockNodeFlagsOverrideSet;
|
||||
ImGuiDockNodeFlags src_node_flags = payload_node ? payload_node->MergedFlags : payload_window->WindowClass.DockNodeFlagsOverrideSet;
|
||||
ImGuiDockNodeFlags dst_node_flags = host_node ? host_node->MergedFlags : host_window->WindowClass.DockNodeFlagsOverrideSet;
|
||||
data->IsCenterAvailable = true;
|
||||
if (is_outer_docking)
|
||||
@@ -15851,7 +15852,7 @@ static void ImGui::DockNodePreviewDockSetup(ImGuiWindow* host_window, ImGuiDockN
|
||||
data->IsCenterAvailable = false;
|
||||
else if (host_node && (dst_node_flags & ImGuiDockNodeFlags_NoDockingInCentralNode) && host_node->IsCentralNode())
|
||||
data->IsCenterAvailable = false;
|
||||
else if ((!host_node || !host_node->IsEmpty()) && root_payload_as_host && root_payload_as_host->IsSplitNode() && (root_payload_as_host->OnlyNodeWithWindows == NULL)) // Is _visibly_ split?
|
||||
else if ((!host_node || !host_node->IsEmpty()) && payload_node && payload_node->IsSplitNode() && (payload_node->OnlyNodeWithWindows == NULL)) // Is _visibly_ split?
|
||||
data->IsCenterAvailable = false;
|
||||
else if (dst_node_flags & ImGuiDockNodeFlags_NoDockingOverMe)
|
||||
data->IsCenterAvailable = false;
|
||||
@@ -15869,7 +15870,7 @@ static void ImGui::DockNodePreviewDockSetup(ImGuiWindow* host_window, ImGuiDockN
|
||||
data->IsSidesAvailable = false;
|
||||
|
||||
// Build a tentative future node (reuse same structure because it is practical. Shape will be readjusted when previewing a split)
|
||||
data->FutureNode.HasCloseButton = (host_node ? host_node->HasCloseButton : host_window->HasCloseButton) || (root_payload->HasCloseButton);
|
||||
data->FutureNode.HasCloseButton = (host_node ? host_node->HasCloseButton : host_window->HasCloseButton) || (payload_window->HasCloseButton);
|
||||
data->FutureNode.HasWindowMenuButton = host_node ? true : ((host_window->Flags & ImGuiWindowFlags_NoCollapse) == 0);
|
||||
data->FutureNode.Pos = ref_node_for_rect ? ref_node_for_rect->Pos : host_window->Pos;
|
||||
data->FutureNode.Size = ref_node_for_rect ? ref_node_for_rect->Size : host_window->Size;
|
||||
@@ -15906,7 +15907,7 @@ static void ImGui::DockNodePreviewDockSetup(ImGuiWindow* host_window, ImGuiDockN
|
||||
ImGuiAxis split_axis = (split_dir == ImGuiDir_Left || split_dir == ImGuiDir_Right) ? ImGuiAxis_X : ImGuiAxis_Y;
|
||||
ImVec2 pos_new, pos_old = data->FutureNode.Pos;
|
||||
ImVec2 size_new, size_old = data->FutureNode.Size;
|
||||
DockNodeCalcSplitRects(pos_old, size_old, pos_new, size_new, split_dir, root_payload->Size);
|
||||
DockNodeCalcSplitRects(pos_old, size_old, pos_new, size_new, split_dir, payload_window->Size);
|
||||
|
||||
// Calculate split ratio so we can pass it down the docking request
|
||||
float split_ratio = ImSaturate(size_new[split_axis] / data->FutureNode.Size[split_axis]);
|
||||
@@ -17274,11 +17275,11 @@ void ImGui::BeginDockableDragDropTarget(ImGuiWindow* window)
|
||||
if (node && (node->ParentNode || node->IsCentralNode()))
|
||||
if (ImGuiDockNode* root_node = DockNodeGetRootNode(node))
|
||||
{
|
||||
DockNodePreviewDockSetup(window, root_node, payload_window, &split_outer, is_explicit_target, true);
|
||||
DockNodePreviewDockSetup(window, root_node, payload_window, NULL, &split_outer, is_explicit_target, true);
|
||||
if (split_outer.IsSplitDirExplicit)
|
||||
split_data = &split_outer;
|
||||
}
|
||||
DockNodePreviewDockSetup(window, node, payload_window, &split_inner, is_explicit_target, false);
|
||||
DockNodePreviewDockSetup(window, node, payload_window, NULL, &split_inner, is_explicit_target, false);
|
||||
if (split_data == &split_outer)
|
||||
split_inner.IsDropAllowed = false;
|
||||
|
||||
@@ -18449,6 +18450,8 @@ void ImGui::DebugNodeDockNode(ImGuiDockNode* node, const char* label)
|
||||
DebugNodeDockNode(node->ChildNodes[1], "Child[1]");
|
||||
if (node->TabBar)
|
||||
DebugNodeTabBar(node->TabBar, "TabBar");
|
||||
DebugNodeWindowsList(&node->Windows, "Windows");
|
||||
|
||||
TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2971,7 +2971,7 @@ namespace ImGui
|
||||
IMGUI_API void DockContextQueueDock(ImGuiContext* ctx, ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, float split_ratio, bool split_outer);
|
||||
IMGUI_API void DockContextQueueUndockWindow(ImGuiContext* ctx, ImGuiWindow* window);
|
||||
IMGUI_API void DockContextQueueUndockNode(ImGuiContext* ctx, ImGuiDockNode* node);
|
||||
IMGUI_API bool DockContextCalcDropPosForDocking(ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, bool split_outer, ImVec2* out_pos);
|
||||
IMGUI_API bool DockContextCalcDropPosForDocking(ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload_window, ImGuiDockNode* payload_node, ImGuiDir split_dir, bool split_outer, ImVec2* out_pos);
|
||||
IMGUI_API ImGuiDockNode*DockContextFindNodeByID(ImGuiContext* ctx, ImGuiID id);
|
||||
IMGUI_API bool DockNodeBeginAmendTabBar(ImGuiDockNode* node);
|
||||
IMGUI_API void DockNodeEndAmendTabBar();
|
||||
|
||||
Reference in New Issue
Block a user