Docking: Renamed "DocRoot/DocumentRoot" to "CentralNode", more self explanatory. Moved Splitter update higher up in DockNodeUpdate() + minor misc tweak. (#2109)

This commit is contained in:
omar 2018-10-03 15:48:54 +02:00
parent 1d3862b6b3
commit d348d86df4
5 changed files with 63 additions and 58 deletions

View File

@ -126,8 +126,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- dock: A~ Unreal style document system (requires low-level controls of dockspace serialization fork/copy/delete). this is mostly working but the DockBuilderXXX api are not exposed/finished. - dock: A~ Unreal style document system (requires low-level controls of dockspace serialization fork/copy/delete). this is mostly working but the DockBuilderXXX api are not exposed/finished.
- dock: A- implicit, invisible per-viewport dockspace to dock to. - dock: A- implicit, invisible per-viewport dockspace to dock to.
- dock: B: when docking outer, perform size locking on neighbors nodes the same way we do it with splitters, so other nodes are not resized. - dock: B: when docking outer, perform size locking on neighbors nodes the same way we do it with splitters, so other nodes are not resized.
- dock: B~ document root node resizing behavior incorrect. - dock: B~ central node resizing behavior incorrect.
- dock: B~ document root node retrieval of ID ? - dock: B~ central node ID retrieval API?
- dock: B- debug full rebuild loses viewport of floating dock nodes. - dock: B- debug full rebuild loses viewport of floating dock nodes.
- dock: B- dock node inside its own viewports creates 1 temporary viewport per window on startup before ditching them (doesn't affect the user nor request platform windows to be created, but unnecessary) - dock: B- dock node inside its own viewports creates 1 temporary viewport per window on startup before ditching them (doesn't affect the user nor request platform windows to be created, but unnecessary)
- dock: B- resize sibling locking behavior may be less desirable if we merged same-axis sibling in a same node level? - dock: B- resize sibling locking behavior may be less desirable if we merged same-axis sibling in a same node level?

107
imgui.cpp
View File

@ -9635,11 +9635,11 @@ struct ImGuiDockNodeSettings
char SplitAxis; char SplitAxis;
char Depth; char Depth;
char IsDockSpace; char IsDockSpace;
char IsDocumentRoot; char IsCentralNode;
ImVec2ih Pos; ImVec2ih Pos;
ImVec2ih Size; ImVec2ih Size;
ImVec2ih SizeRef; ImVec2ih SizeRef;
ImGuiDockNodeSettings() { ID = ParentID = SelectedTabID = 0; SplitAxis = ImGuiAxis_None; Depth = 0; IsDockSpace = IsDocumentRoot = 0; } ImGuiDockNodeSettings() { ID = ParentID = SelectedTabID = 0; SplitAxis = ImGuiAxis_None; Depth = 0; IsDockSpace = IsCentralNode = 0; }
}; };
struct ImGuiDockContext struct ImGuiDockContext
@ -9941,7 +9941,7 @@ static void ImGui::DockContextPruneUnusedSettingsNodes(ImGuiContext* ctx)
ImGuiDockContextPruneNodeData* data_root = (data->RootID == settings->ID) ? data : pool.GetByKey(data->RootID); ImGuiDockContextPruneNodeData* data_root = (data->RootID == settings->ID) ? data : pool.GetByKey(data->RootID);
bool remove = false; bool remove = false;
remove |= (data->CountWindows == 1 && settings->ParentID == 0 && data->CountChildNodes == 0 && !settings->IsDocumentRoot); // Floating root node with only 1 window remove |= (data->CountWindows == 1 && settings->ParentID == 0 && data->CountChildNodes == 0 && !settings->IsCentralNode); // Floating root node with only 1 window
remove |= (data->CountWindows == 0 && settings->ParentID == 0 && data->CountChildNodes == 0); // Leaf nodes with 0 window remove |= (data->CountWindows == 0 && settings->ParentID == 0 && data->CountChildNodes == 0); // Leaf nodes with 0 window
remove |= (data_root->CountChildWindows == 0); remove |= (data_root->CountChildWindows == 0);
if (remove) if (remove)
@ -9972,7 +9972,7 @@ static void ImGui::DockContextBuildNodesFromSettings(ImGuiContext* ctx, ImGuiDoc
node->SelectedTabID = node_settings->SelectedTabID; node->SelectedTabID = node_settings->SelectedTabID;
node->SplitAxis = node_settings->SplitAxis; node->SplitAxis = node_settings->SplitAxis;
node->IsDockSpace = node_settings->IsDockSpace != 0; node->IsDockSpace = node_settings->IsDockSpace != 0;
node->IsDocumentRoot = node_settings->IsDocumentRoot != 0; node->IsCentralNode = node_settings->IsCentralNode != 0;
// Bind host window immediately if it already exist (in case of a rebuild) // Bind host window immediately if it already exist (in case of a rebuild)
// This is useful as the RootWindowForTitleBarHighlight links necessary to highlight the currently focused node requires node->HostWindow to be set. // This is useful as the RootWindowForTitleBarHighlight links necessary to highlight the currently focused node requires node->HostWindow to be set.
@ -10070,7 +10070,7 @@ void ImGui::DockContextProcessDock(ImGuiContext* ctx, ImGuiDockRequest* req)
if (target_node) if (target_node)
IM_ASSERT(target_node->LastFrameAlive < g.FrameCount); IM_ASSERT(target_node->LastFrameAlive < g.FrameCount);
if (target_node && target_window && target_node == target_window->DockNodeAsHost) if (target_node && target_window && target_node == target_window->DockNodeAsHost)
IM_ASSERT(target_node->Windows.Size > 1 || target_node->IsSplitNode() || target_node->IsDocumentRoot); IM_ASSERT(target_node->Windows.Size > 1 || target_node->IsSplitNode() || target_node->IsCentralNode);
// Create new node and add existing window to it // Create new node and add existing window to it
if (target_node == NULL) if (target_node == NULL)
@ -10099,8 +10099,8 @@ void ImGui::DockContextProcessDock(ImGuiContext* ctx, ImGuiDockRequest* req)
new_node->HostWindow = target_node->HostWindow; new_node->HostWindow = target_node->HostWindow;
if (target_node) if (target_node)
{ {
inheritor_node->IsDocumentRoot = target_node->IsDocumentRoot; inheritor_node->IsCentralNode = target_node->IsCentralNode;
target_node->IsDocumentRoot = false; target_node->IsCentralNode = false;
} }
target_node = new_node; target_node = new_node;
} }
@ -10180,9 +10180,9 @@ void ImGui::DockContextProcessUndockNode(ImGuiContext* ctx, ImGuiDockNode* node)
IM_ASSERT(node->IsLeafNode()); IM_ASSERT(node->IsLeafNode());
IM_ASSERT(node->Windows.Size >= 1); IM_ASSERT(node->Windows.Size >= 1);
// In the case of a root node or document root, the node will have to stay in place. Create a new node to receive the payload. // In the case of a root node or central node, the node will have to stay in place. Create a new node to receive the payload.
// Otherwise delete the previous node by merging the other sibling back into the parent node. // Otherwise delete the previous node by merging the other sibling back into the parent node.
if (node->IsRootNode() || node->IsDocumentRoot) if (node->IsRootNode() || node->IsCentralNode)
{ {
ImGuiDockNode* new_node = DockContextAddNode(ctx, 0); ImGuiDockNode* new_node = DockContextAddNode(ctx, 0);
DockNodeMoveWindows(new_node, node); DockNodeMoveWindows(new_node, node);
@ -10225,7 +10225,7 @@ ImGuiDockNode::ImGuiDockNode(ImGuiID id)
WantCloseTabID = 0; WantCloseTabID = 0;
InitFromFirstWindowPosSize = InitFromFirstWindowViewport = false; InitFromFirstWindowPosSize = InitFromFirstWindowViewport = false;
IsVisible = true; IsVisible = true;
IsDockSpace = IsDocumentRoot = HasCloseButton = HasCollapseButton = WantCloseAll = WantLockSizeOnce = WantMouseMove = false; IsDockSpace = IsCentralNode = HasCloseButton = HasCollapseButton = WantCloseAll = WantLockSizeOnce = WantMouseMove = false;
} }
ImGuiDockNode::~ImGuiDockNode() ImGuiDockNode::~ImGuiDockNode()
@ -10319,7 +10319,7 @@ static void ImGui::DockNodeRemoveWindow(ImGuiDockNode* node, ImGuiWindow* window
if (node->TabBar) if (node->TabBar)
{ {
TabBarRemoveTab(node->TabBar, window->ID); TabBarRemoveTab(node->TabBar, window->ID);
const int tab_count_threshold_for_tab_bar = node->IsDocumentRoot ? 1 : 2; const int tab_count_threshold_for_tab_bar = node->IsCentralNode ? 1 : 2;
if (node->Windows.Size < tab_count_threshold_for_tab_bar) if (node->Windows.Size < tab_count_threshold_for_tab_bar)
{ {
IM_DELETE(node->TabBar); IM_DELETE(node->TabBar);
@ -10327,14 +10327,14 @@ static void ImGui::DockNodeRemoveWindow(ImGuiDockNode* node, ImGuiWindow* window
} }
} }
if (node->Windows.Size == 0 && !node->IsDocumentRoot && window->DockId != node->ID) if (node->Windows.Size == 0 && !node->IsCentralNode && window->DockId != node->ID)
{ {
// Automatic dock node delete themselves if they are not holding at least one tab // Automatic dock node delete themselves if they are not holding at least one tab
DockContextRemoveNode(&g, node, true); DockContextRemoveNode(&g, node, true);
return; return;
} }
if (node->Windows.Size == 1 && !node->IsDocumentRoot && node->HostWindow) if (node->Windows.Size == 1 && !node->IsCentralNode && node->HostWindow)
{ {
ImGuiWindow* remaining_window = node->Windows[0]; ImGuiWindow* remaining_window = node->Windows[0];
if (node->HostWindow->ViewportOwned && node->IsRootNode()) if (node->HostWindow->ViewportOwned && node->IsRootNode())
@ -10479,7 +10479,7 @@ static void ImGui::DockNodeUpdateVisibleFlagAndInactiveChilds(ImGuiDockNode* nod
if (!remove) if (!remove)
continue; continue;
window->DockTabWantClose = false; window->DockTabWantClose = false;
if (node->Windows.Size == 1 && !node->IsDocumentRoot) if (node->Windows.Size == 1 && !node->IsCentralNode)
{ {
DockNodeHideHostWindow(node); DockNodeHideHostWindow(node);
DockNodeRemoveWindow(node, window, node->ID); // Will delete the node so it'll be invalid on return DockNodeRemoveWindow(node, window, node->ID); // Will delete the node so it'll be invalid on return
@ -10495,7 +10495,7 @@ static void ImGui::DockNodeUpdateVisibleFlagAndInactiveChilds(ImGuiDockNode* nod
static void ImGui::DockNodeUpdateVisibleFlag(ImGuiDockNode* node) static void ImGui::DockNodeUpdateVisibleFlag(ImGuiDockNode* node)
{ {
// Update visibility flag // Update visibility flag
bool is_visible = (node->ParentNode == 0) ? node->IsDockSpace : node->IsDocumentRoot; bool is_visible = (node->ParentNode == 0) ? node->IsDockSpace : node->IsCentralNode;
is_visible |= (node->Windows.Size > 0); is_visible |= (node->Windows.Size > 0);
is_visible |= (node->ChildNodes[0] && node->ChildNodes[0]->IsVisible); is_visible |= (node->ChildNodes[0] && node->ChildNodes[0]->IsVisible);
is_visible |= (node->ChildNodes[1] && node->ChildNodes[1]->IsVisible); is_visible |= (node->ChildNodes[1] && node->ChildNodes[1]->IsVisible);
@ -10523,7 +10523,7 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
{ {
DockNodeUpdateVisibleFlagAndInactiveChilds(node); DockNodeUpdateVisibleFlagAndInactiveChilds(node);
// Find if there's only a single visible window in the hierarchy (in which case we need to display a regular title bar, FIXME-DOCK: Not done yet!) // Find if there's only a single visible window in the hierarchy (in which case we need to display a regular title bar -> FIXME-DOCK: that last part is not done yet!)
if (!node->IsDockSpace) if (!node->IsDockSpace)
{ {
int count = 0; int count = 0;
@ -10657,9 +10657,14 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
if (node->IsSplitNode()) if (node->IsSplitNode())
IM_ASSERT(node->TabBar == NULL); IM_ASSERT(node->TabBar == NULL);
if (node->IsRootNode()) if (node->IsRootNode())
{
if (g.NavWindow && g.NavWindow->RootWindowDockStop->DockNode && g.NavWindow->RootWindowDockStop->ParentWindow == host_window) if (g.NavWindow && g.NavWindow->RootWindowDockStop->DockNode && g.NavWindow->RootWindowDockStop->ParentWindow == host_window)
node->LastFocusedNodeID = g.NavWindow->RootWindowDockStop->DockNode->ID; node->LastFocusedNodeID = g.NavWindow->RootWindowDockStop->DockNode->ID;
// Update position/size, process and draw resizing splitters
if (node->IsRootNode() && host_window)
{
DockNodeTreeUpdatePosSize(node, host_window->Pos, host_window->Size);
DockNodeTreeUpdateSplitter(node);
} }
// Draw and populate Tab Bar // Draw and populate Tab Bar
@ -10682,20 +10687,16 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
if (node->Windows.Size == 0 && !node->IsSplitNode()) if (node->Windows.Size == 0 && !node->IsSplitNode())
host_window->DrawList->AddRectFilled(node->Pos, node->Pos + node->Size, GetColorU32(ImGuiCol_DockingEmptyBg)); host_window->DrawList->AddRectFilled(node->Pos, node->Pos + node->Size, GetColorU32(ImGuiCol_DockingEmptyBg));
// Drop target // Draw drop target
if (node->IsRootNode() && (g.MovingWindow == NULL || g.MovingWindow->RootWindow != host_window)) if (node->IsRootNode() && (g.MovingWindow == NULL || g.MovingWindow->RootWindow != host_window))
BeginAsDockableDragDropTarget(host_window); BeginAsDockableDragDropTarget(host_window);
} }
node->LastFrameActive = g.FrameCount; node->LastFrameActive = g.FrameCount;
// Update pos/size and recurse into children // Recurse into children
if (host_window) if (host_window)
{ {
if (node->IsRootNode())
{
DockNodeTreeUpdatePosSize(node, host_window->Pos, host_window->Size);
DockNodeTreeUpdateSplitter(node);
}
if (node->ChildNodes[0]) if (node->ChildNodes[0])
DockNodeUpdate(node->ChildNodes[0]); DockNodeUpdate(node->ChildNodes[0]);
if (node->ChildNodes[1]) if (node->ChildNodes[1])
@ -11059,13 +11060,13 @@ static bool ImGui::DockNodePreviewDockCalc(ImGuiWindow* host_window, ImGuiDockNo
data->IsCenterAvailable = !is_outer_docking; data->IsCenterAvailable = !is_outer_docking;
if (src_is_visibly_splitted && (!host_node || !host_node->IsEmpty())) if (src_is_visibly_splitted && (!host_node || !host_node->IsEmpty()))
data->IsCenterAvailable = false; data->IsCenterAvailable = false;
if (host_node && (host_node->Flags & ImGuiDockNodeFlags_NoDockingInsideDocRootNode) && host_node->IsDocumentRoot) if (host_node && (host_node->Flags & ImGuiDockNodeFlags_NoDockingInsideCentralNode) && host_node->IsCentralNode)
data->IsCenterAvailable = false; data->IsCenterAvailable = false;
data->IsSidesAvailable = true; data->IsSidesAvailable = true;
if (host_node && (host_node->Flags & ImGuiDockNodeFlags_NoSplit)) if (host_node && (host_node->Flags & ImGuiDockNodeFlags_NoSplit))
data->IsSidesAvailable = false; data->IsSidesAvailable = false;
if (!is_outer_docking && host_node && host_node->ParentNode == NULL && host_node->IsDocumentRoot) if (!is_outer_docking && host_node && host_node->ParentNode == NULL && host_node->IsCentralNode)
data->IsSidesAvailable = false; data->IsSidesAvailable = false;
// Calculate drop shapes geometry for allowed splitting directions // Calculate drop shapes geometry for allowed splitting directions
@ -11268,7 +11269,7 @@ void ImGui::DockNodeTreeMerge(ImGuiContext* ctx, ImGuiDockNode* parent_node, ImG
DockNodeApplyPosSizeToWindows(parent_node); DockNodeApplyPosSizeToWindows(parent_node);
parent_node->InitFromFirstWindowPosSize = parent_node->InitFromFirstWindowViewport = false; parent_node->InitFromFirstWindowPosSize = parent_node->InitFromFirstWindowViewport = false;
parent_node->VisibleWindow = merge_lead_child->VisibleWindow; parent_node->VisibleWindow = merge_lead_child->VisibleWindow;
parent_node->IsDocumentRoot = (child_0 && child_0->IsDocumentRoot) || (child_1 && child_1->IsDocumentRoot); parent_node->IsCentralNode = (child_0 && child_0->IsCentralNode) || (child_1 && child_1->IsCentralNode);
parent_node->SizeRef = backup_last_explicit_size; parent_node->SizeRef = backup_last_explicit_size;
if (child_0) if (child_0)
@ -11322,13 +11323,13 @@ void ImGui::DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 si
child_0_size[axis] = child_0->SizeRef[axis] = (size_avail - child_1_size[axis]); child_0_size[axis] = child_0->SizeRef[axis] = (size_avail - child_1_size[axis]);
} }
// 3) If one window is the document root (~ use remaining space, should be made explicit!), use explicit size from the other, and remainder for the document root // 3) If one window is the central node (~ use remaining space, should be made explicit!), use explicit size from the other, and remainder for the central node
else if (child_1->IsDocumentRoot && child_0->SizeRef[axis] != 0.0f) else if (child_1->IsCentralNode && child_0->SizeRef[axis] != 0.0f)
{ {
child_0_size[axis] = ImMin(size_avail - size_min_each, child_0->SizeRef[axis]); child_0_size[axis] = ImMin(size_avail - size_min_each, child_0->SizeRef[axis]);
child_1_size[axis] = (size_avail - child_0_size[axis]); child_1_size[axis] = (size_avail - child_0_size[axis]);
} }
else if (child_0->IsDocumentRoot && child_1->SizeRef[axis] != 0.0f) else if (child_0->IsCentralNode && child_1->SizeRef[axis] != 0.0f)
{ {
child_1_size[axis] = ImMin(size_avail - size_min_each, child_1->SizeRef[axis]); child_1_size[axis] = ImMin(size_avail - size_min_each, child_1->SizeRef[axis]);
child_0_size[axis] = (size_avail - child_1_size[axis]); child_0_size[axis] = (size_avail - child_1_size[axis]);
@ -11375,6 +11376,7 @@ void ImGui::DockNodeTreeUpdateSplitter(ImGuiDockNode* node)
if (child_0->IsVisible && child_1->IsVisible) if (child_0->IsVisible && child_1->IsVisible)
{ {
// Extend hovering range past the displayed border // Extend hovering range past the displayed border
// FIXME-DOCKING: This is not working as expected.
float HOVER_EXTEND = 4.0f; float HOVER_EXTEND = 4.0f;
// Use a short delay before highlighting the splitter (and changing the mouse cursor) in order for regular mouse movement to not highlight many splitters // Use a short delay before highlighting the splitter (and changing the mouse cursor) in order for regular mouse movement to not highlight many splitters
@ -11514,9 +11516,9 @@ void ImGui::SetWindowDock(ImGuiWindow* window, ImGuiID dock_id, ImGuiCond cond)
window->DockId = dock_id; window->DockId = dock_id;
} }
// Create an explicit dockspace node within an existing window. Also expose dock node flags and creates a DocumentRoot node by default. // Create an explicit dockspace node within an existing window. Also expose dock node flags and creates a CentralNode by default.
// The DocumentRoot node is always displayed even when empty and shrink/extend according to the requested size of its neighbors. // The Central Node is always displayed even when empty and shrink/extend according to the requested size of its neighbors.
void ImGui::DockSpace(ImGuiID id, const ImVec2& size_arg, ImGuiDockNodeFlags dock_space_flags, const ImGuiDockFamily* dock_family) void ImGui::DockSpace(ImGuiID id, const ImVec2& size_arg, ImGuiDockNodeFlags dockspace_flags, const ImGuiDockFamily* dock_family)
{ {
ImGuiContext* ctx = GImGui; ImGuiContext* ctx = GImGui;
ImGuiContext& g = *ctx; ImGuiContext& g = *ctx;
@ -11528,14 +11530,14 @@ void ImGui::DockSpace(ImGuiID id, const ImVec2& size_arg, ImGuiDockNodeFlags doc
if (!node) if (!node)
{ {
node = DockContextAddNode(ctx, id); node = DockContextAddNode(ctx, id);
node->IsDocumentRoot = true; node->IsCentralNode = true;
} }
node->Flags = dock_space_flags; node->Flags = dockspace_flags;
node->DockFamily = dock_family ? *dock_family : ImGuiDockFamily(); node->DockFamily = dock_family ? *dock_family : ImGuiDockFamily();
// When a Dockspace transitioned form implicit to explicit this may be called a second time // When a Dockspace transitioned form implicit to explicit this may be called a second time
// It is possible that the node has already been claimed by a docked window which appeared before the DockSpace() node, so we overwrite IsDockSpace again. // It is possible that the node has already been claimed by a docked window which appeared before the DockSpace() node, so we overwrite IsDockSpace again.
if (node->LastFrameActive == g.FrameCount && !(dock_space_flags & ImGuiDockNodeFlags_KeepAliveOnly)) if (node->LastFrameActive == g.FrameCount && !(dockspace_flags & ImGuiDockNodeFlags_KeepAliveOnly))
{ {
IM_ASSERT(node->IsDockSpace == false && "Cannot call DockSpace() twice a frame with the same ID"); IM_ASSERT(node->IsDockSpace == false && "Cannot call DockSpace() twice a frame with the same ID");
node->IsDockSpace = true; node->IsDockSpace = true;
@ -11544,7 +11546,7 @@ void ImGui::DockSpace(ImGuiID id, const ImVec2& size_arg, ImGuiDockNodeFlags doc
node->IsDockSpace = true; node->IsDockSpace = true;
// Keep alive mode, this is allow windows docked into this node so stay docked even if they are not visible // Keep alive mode, this is allow windows docked into this node so stay docked even if they are not visible
if (dock_space_flags & ImGuiDockNodeFlags_KeepAliveOnly) if (dockspace_flags & ImGuiDockNodeFlags_KeepAliveOnly)
{ {
node->LastFrameAlive = g.FrameCount; node->LastFrameAlive = g.FrameCount;
return; return;
@ -11633,8 +11635,8 @@ void ImGui::DockBuilderRemoveNode(ImGuiContext* ctx, ImGuiID node_id)
return; return;
DockBuilderRemoveNodeDockedWindows(ctx, node_id, true); DockBuilderRemoveNodeDockedWindows(ctx, node_id, true);
DockBuilderRemoveNodeChildNodes(ctx, node_id); DockBuilderRemoveNodeChildNodes(ctx, node_id);
if (node->IsDocumentRoot && node->ParentNode) if (node->IsCentralNode && node->ParentNode)
node->ParentNode->IsDocumentRoot = true; node->ParentNode->IsCentralNode = true;
DockContextRemoveNode(ctx, node, true); DockContextRemoveNode(ctx, node, true);
} }
@ -11655,7 +11657,7 @@ void ImGui::DockBuilderRemoveNodeChildNodes(ImGuiContext* ctx, ImGuiID root_id)
bool want_removal = (root_id == 0) || (node->ID != root_id && DockNodeGetRootNode(node)->ID == root_id); bool want_removal = (root_id == 0) || (node->ID != root_id && DockNodeGetRootNode(node)->ID == root_id);
if (want_removal) if (want_removal)
{ {
if (node->IsDocumentRoot) if (node->IsCentralNode)
has_document_root = true; has_document_root = true;
if (root_id != 0) if (root_id != 0)
DockContextQueueNotifyRemovedNode(ctx, node); DockContextQueueNotifyRemovedNode(ctx, node);
@ -11688,7 +11690,7 @@ void ImGui::DockBuilderRemoveNodeChildNodes(ImGuiContext* ctx, ImGuiID root_id)
} }
else if (has_document_root) else if (has_document_root)
{ {
root_node->IsDocumentRoot = true; root_node->IsCentralNode = true;
} }
} }
@ -11767,7 +11769,7 @@ static ImGuiDockNode* DockBuilderCopyNodeRec(ImGuiContext* ctx, ImGuiDockNode* s
dst_node->SizeRef = src_node->SizeRef; dst_node->SizeRef = src_node->SizeRef;
dst_node->SplitAxis = src_node->SplitAxis; dst_node->SplitAxis = src_node->SplitAxis;
dst_node->IsDockSpace = src_node->IsDockSpace; dst_node->IsDockSpace = src_node->IsDockSpace;
dst_node->IsDocumentRoot = src_node->IsDocumentRoot; dst_node->IsCentralNode = src_node->IsCentralNode;
out_node_remap_pairs->push_back(src_node->ID); out_node_remap_pairs->push_back(src_node->ID);
out_node_remap_pairs->push_back(dst_node->ID); out_node_remap_pairs->push_back(dst_node->ID);
@ -11952,8 +11954,8 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
g.NextWindowData.PosUndock = false; g.NextWindowData.PosUndock = false;
} }
// Undock if the ImGuiDockNodeFlags_NoDockingInDocRootNode got set // Undock if the ImGuiDockNodeFlags_NoDockingInCentralNode got set
if (dock_node->IsDocumentRoot && (dock_node->Flags & ImGuiDockNodeFlags_NoDockingInsideDocRootNode)) if (dock_node->IsCentralNode && (dock_node->Flags & ImGuiDockNodeFlags_NoDockingInsideCentralNode))
{ {
DockContextProcessUndockWindow(ctx, window); DockContextProcessUndockWindow(ctx, window);
return; return;
@ -12091,7 +12093,7 @@ void ImGui::BeginAsDockableDragDropTarget(ImGuiWindow* window)
{ {
ImGuiDockPreviewData split_inner, split_outer; ImGuiDockPreviewData split_inner, split_outer;
ImGuiDockPreviewData* split_data = &split_inner; ImGuiDockPreviewData* split_data = &split_inner;
if (target_node && (target_node->ParentNode || target_node->IsDocumentRoot)) if (target_node && (target_node->ParentNode || target_node->IsCentralNode))
if (ImGuiDockNode* root_node = DockNodeGetRootNode(target_node)) if (ImGuiDockNode* root_node = DockNodeGetRootNode(target_node))
if (DockNodePreviewDockCalc(window, root_node, payload_window, &split_outer, is_explicit_target, true)) if (DockNodePreviewDockCalc(window, root_node, payload_window, &split_outer, is_explicit_target, true))
split_data = &split_outer; split_data = &split_outer;
@ -12193,7 +12195,10 @@ static void ImGui::DockSettingsHandler_ReadLine(ImGuiContext* ctx, ImGuiSettings
if (sscanf(line, " SizeRef=%i,%i%n", &x, &y, &r) == 2) { line += r; node.SizeRef = ImVec2ih((short)x, (short)y); } if (sscanf(line, " SizeRef=%i,%i%n", &x, &y, &r) == 2) { line += r; node.SizeRef = ImVec2ih((short)x, (short)y); }
} }
if (sscanf(line, " Split=%c%n", &c, &r) == 1) { line += r; if (c == 'X') node.SplitAxis = ImGuiAxis_X; else if (c == 'Y') node.SplitAxis = ImGuiAxis_Y; } if (sscanf(line, " Split=%c%n", &c, &r) == 1) { line += r; if (c == 'X') node.SplitAxis = ImGuiAxis_X; else if (c == 'Y') node.SplitAxis = ImGuiAxis_Y; }
if (sscanf(line, " DocRoot=%d%n", &x, &r) == 1) { line += r; node.IsDocumentRoot = (x != 0); } #if 1 // FIXME-DOCK FIXME-LEGACY
if (sscanf(line, " DocRoot=%d%n", &x, &r) == 1) { line += r; node.IsCentralNode = (x != 0); }
#endif
if (sscanf(line, " CentralNode=%d%n", &x, &r) == 1) { line += r; node.IsCentralNode = (x != 0); }
if (sscanf(line, " SelectedTab=0x%08X%n", &node.SelectedTabID,&r) == 1) { line += r; } if (sscanf(line, " SelectedTab=0x%08X%n", &node.SelectedTabID,&r) == 1) { line += r; }
ImGuiDockContext* dc = ctx->DockContext; ImGuiDockContext* dc = ctx->DockContext;
if (node.ParentID != 0) if (node.ParentID != 0)
@ -12212,7 +12217,7 @@ static void DockSettingsHandler_DockNodeToSettings(ImGuiDockContext* dc, ImGuiDo
node_settings.SplitAxis = node->IsSplitNode() ? (char)node->SplitAxis : ImGuiAxis_None; node_settings.SplitAxis = node->IsSplitNode() ? (char)node->SplitAxis : ImGuiAxis_None;
node_settings.Depth = (char)depth; node_settings.Depth = (char)depth;
node_settings.IsDockSpace = (char)node->IsDockSpace; node_settings.IsDockSpace = (char)node->IsDockSpace;
node_settings.IsDocumentRoot = (char)node->IsDocumentRoot; node_settings.IsCentralNode = (char)node->IsCentralNode;
node_settings.Pos = ImVec2ih((short)node->Pos.x, (short)node->Pos.y); node_settings.Pos = ImVec2ih((short)node->Pos.x, (short)node->Pos.y);
node_settings.Size = ImVec2ih((short)node->Size.x, (short)node->Size.y); node_settings.Size = ImVec2ih((short)node->Size.x, (short)node->Size.y);
node_settings.SizeRef = ImVec2ih((short)node->SizeRef.x, (short)node->SizeRef.y); node_settings.SizeRef = ImVec2ih((short)node->SizeRef.x, (short)node->SizeRef.y);
@ -12255,8 +12260,8 @@ static void ImGui::DockSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettings
buf->appendf(" Pos=%d,%d Size=%d,%d", node_settings->Pos.x, node_settings->Pos.y, node_settings->Size.x, node_settings->Size.y); buf->appendf(" Pos=%d,%d Size=%d,%d", node_settings->Pos.x, node_settings->Pos.y, node_settings->Size.x, node_settings->Size.y);
if (node_settings->SplitAxis != ImGuiAxis_None) if (node_settings->SplitAxis != ImGuiAxis_None)
buf->appendf(" Split=%c", (node_settings->SplitAxis == ImGuiAxis_X) ? 'X' : 'Y'); buf->appendf(" Split=%c", (node_settings->SplitAxis == ImGuiAxis_X) ? 'X' : 'Y');
if (node_settings->IsDocumentRoot) if (node_settings->IsCentralNode)
buf->appendf(" DocRoot=%d", node_settings->IsDocumentRoot); buf->appendf(" CentralNode=%d", node_settings->IsCentralNode);
if (node_settings->SelectedTabID) if (node_settings->SelectedTabID)
buf->appendf(" SelectedTab=0x%08X", node_settings->SelectedTabID); buf->appendf(" SelectedTab=0x%08X", node_settings->SelectedTabID);
@ -13131,7 +13136,7 @@ void ImGui::ShowDockingDebug()
node->Pos.x, node->Pos.y, node->Size.x, node->Size.y, node->Pos.x, node->Pos.y, node->Size.x, node->Size.y,
node->SizeRef.x, node->SizeRef.y); node->SizeRef.x, node->SizeRef.y);
ImGui::BulletText("Flags %02X%s%s%s%s", ImGui::BulletText("Flags %02X%s%s%s%s",
node->Flags, node->IsDockSpace ? ", IsDockSpace" : "", node->IsDocumentRoot ? ", IsDocumentRoot" : "", node->Flags, node->IsDockSpace ? ", IsDockSpace" : "", node->IsCentralNode ? ", IsCentralNode" : "",
(GImGui->FrameCount - node->LastFrameAlive < 2) ? ", IsAlive" : "", (GImGui->FrameCount - node->LastFrameActive < 2) ? ", IsActive" : ""); (GImGui->FrameCount - node->LastFrameAlive < 2) ? ", IsAlive" : "", (GImGui->FrameCount - node->LastFrameActive < 2) ? ", IsActive" : "");
if (node->ChildNodes[0]) if (node->ChildNodes[0])
NodeDockNode(node->ChildNodes[0], "Child[0]"); NodeDockNode(node->ChildNodes[0], "Child[0]");
@ -13237,7 +13242,7 @@ void ImGui::ShowDockingDebug()
char buf[64] = ""; char buf[64] = "";
char* p = buf; char* p = buf;
ImDrawList* overlay_draw_list = node->HostWindow ? GetOverlayDrawList(node->HostWindow) : GetOverlayDrawList((ImGuiViewportP*)GetMainViewport()); ImDrawList* overlay_draw_list = node->HostWindow ? GetOverlayDrawList(node->HostWindow) : GetOverlayDrawList((ImGuiViewportP*)GetMainViewport());
p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "DockId: %X%s\n", node->ID, node->IsDocumentRoot ? " *DocRoot*" : ""); p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "DockId: %X%s\n", node->ID, node->IsCentralNode ? " *CentralNode*" : "");
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, "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); p += ImFormatString(p, buf + IM_ARRAYSIZE(buf) - p, "SizeRef: (%.0f, %.0f)\n", node->SizeRef.x, node->SizeRef.y);
int depth = DockNodeGetDepth(node); int depth = DockNodeGetDepth(node);

View File

@ -798,7 +798,7 @@ enum ImGuiDockNodeFlags_
ImGuiDockNodeFlags_None = 0, ImGuiDockNodeFlags_None = 0,
ImGuiDockNodeFlags_KeepAliveOnly = 1 << 0, // Don't display the dockspace node but keep it alive. Windows docked into this dockspace node won't be undocked. ImGuiDockNodeFlags_KeepAliveOnly = 1 << 0, // Don't display the dockspace node but keep it alive. Windows docked into this dockspace node won't be undocked.
ImGuiDockNodeFlags_NoSplit = 1 << 1, // Disable splitting the node into smaller nodes. Useful e.g. when embedding dockspaces into a main root one (the root one may have splitting disabled to reduce confusion) ImGuiDockNodeFlags_NoSplit = 1 << 1, // Disable splitting the node into smaller nodes. Useful e.g. when embedding dockspaces into a main root one (the root one may have splitting disabled to reduce confusion)
ImGuiDockNodeFlags_NoDockingInsideDocRootNode = 1 << 2 // Disable docking inside the DocumentRoot node. Useful if it is kept empty and invisible. ImGuiDockNodeFlags_NoDockingInsideCentralNode = 1 << 2 // Disable docking inside the central node (which can stay empty). Useful if it is kept empty and invisible.
}; };
// Flags for ImGui::IsWindowFocused() // Flags for ImGui::IsWindowFocused()
@ -1016,7 +1016,7 @@ enum ImGuiCol_
ImGuiCol_TabUnfocused, ImGuiCol_TabUnfocused,
ImGuiCol_TabUnfocusedActive, ImGuiCol_TabUnfocusedActive,
ImGuiCol_DockingPreview, ImGuiCol_DockingPreview,
ImGuiCol_DockingEmptyBg, // Background color for empty node (e.g. DocRoot node with no window docked into it) ImGuiCol_DockingEmptyBg, // Background color for empty node (e.g. CentralNode with no window docked into it)
ImGuiCol_PlotLines, ImGuiCol_PlotLines,
ImGuiCol_PlotLinesHovered, ImGuiCol_PlotLinesHovered,
ImGuiCol_PlotHistogram, ImGuiCol_PlotHistogram,

View File

@ -3760,8 +3760,8 @@ void ShowExampleAppDockSpace(bool* p_open)
if (ImGui::MenuItem("Flag: NoSplit", "", (dockspace_flags & ImGuiDockNodeFlags_NoSplit) != 0)) if (ImGui::MenuItem("Flag: NoSplit", "", (dockspace_flags & ImGuiDockNodeFlags_NoSplit) != 0))
dockspace_flags ^= ImGuiDockNodeFlags_NoSplit; dockspace_flags ^= ImGuiDockNodeFlags_NoSplit;
if (ImGui::MenuItem("Flag: NoDockingInsideDocRootNode", "", (dockspace_flags & ImGuiDockNodeFlags_NoDockingInsideDocRootNode) != 0)) if (ImGui::MenuItem("Flag: NoDockingInsideCentralNode", "", (dockspace_flags & ImGuiDockNodeFlags_NoDockingInsideCentralNode) != 0))
dockspace_flags ^= ImGuiDockNodeFlags_NoDockingInsideDocRootNode; dockspace_flags ^= ImGuiDockNodeFlags_NoDockingInsideCentralNode;
// Disabling fullscreen would allow the window to be moved to the front of other windows, // Disabling fullscreen would allow the window to be moved to the front of other windows,
// which we can't undo at the moment without finer window depth/z control. // which we can't undo at the moment without finer window depth/z control.

View File

@ -767,7 +767,7 @@ struct ImGuiDockNode
bool InitFromFirstWindowViewport :1; bool InitFromFirstWindowViewport :1;
bool IsVisible :1; // Set to false when the node is hidden (usually disabled as it has no active window) bool IsVisible :1; // Set to false when the node is hidden (usually disabled as it has no active window)
bool IsDockSpace :1; // Root node was created by a DockSpace() call. bool IsDockSpace :1; // Root node was created by a DockSpace() call.
bool IsDocumentRoot :1; bool IsCentralNode :1;
bool HasCloseButton :1; bool HasCloseButton :1;
bool HasCollapseButton :1; bool HasCollapseButton :1;
bool WantCloseAll :1; // Set when closing all tabs at once. bool WantCloseAll :1; // Set when closing all tabs at once.