diff --git a/imgui.cpp b/imgui.cpp index 706edfa..a73b38c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2371,7 +2371,6 @@ HiddenFramesRegular = HiddenFramesForResize = 0; SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = SetWindowDockAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing; SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX); - UserTypeId = 0; LastFrameActive = -1; ItemWidthDefault = 0.0f; @@ -4969,7 +4968,7 @@ { window->SizeContentsExplicit = ImVec2(0.0f, 0.0f); } - window->UserTypeId = g.NextWindowData.UserTypeId; + window->DockFamily = g.NextWindowData.DockFamily; if (g.NextWindowData.CollapsedCond) SetWindowCollapsed(window, g.NextWindowData.CollapsedVal, g.NextWindowData.CollapsedCond); if (g.NextWindowData.FocusCond) @@ -6357,10 +6356,10 @@ g.NextWindowData.DockId = id; } -void ImGui::SetNextWindowUserType(ImGuiID user_type) +void ImGui::SetNextWindowDockFamily(const ImGuiDockFamily* family) { ImGuiContext& g = *GImGui; - g.NextWindowData.UserTypeId = user_type; + g.NextWindowData.DockFamily = *family; } // In window space (not screen space!) @@ -10178,19 +10177,19 @@ ImGuiDockNode::ImGuiDockNode(ImGuiID id) { ID = id; - UserTypeIdFilter = 0; Flags = 0; ParentNode = ChildNodes[0] = ChildNodes[1] = NULL; TabBar = NULL; SplitAxis = ImGuiAxis_None; + HostWindow = VisibleWindow = NULL; OnlyNodeWithWindows = NULL; LastFrameAlive = LastFrameActive = -1; LastFocusedNodeID = 0; SelectedTabID = 0; WantCloseTabID = 0; - IsVisible = true; InitFromFirstWindowPosSize = InitFromFirstWindowViewport = false; + IsVisible = true; IsDockSpace = IsDocumentRoot = HasCloseButton = HasCollapseButton = WantCloseAll = WantLockSizeOnce = WantMouseMove = false; } @@ -10493,9 +10492,18 @@ DockNodeUpdateFindOnlyNodeWithWindowsRec(node, &count, &first_node_with_windows); node->OnlyNodeWithWindows = (count == 1 ? first_node_with_windows : NULL); - // Copy the user type from _any_ of our window so it can be used for proper dock filtering. + // Copy the dock family from of our window so it can be used for proper dock filtering. + // When node has mixed windows, prioritize the family with the most constraint (CompatibleWithNeutral = false) as the reference to copy. if (first_node_with_windows) - node->UserTypeIdFilter = first_node_with_windows->Windows[0]->UserTypeId; + { + node->DockFamily = first_node_with_windows->Windows[0]->DockFamily; + for (int n = 1; n < first_node_with_windows->Windows.Size; n++) + if (first_node_with_windows->Windows[n]->DockFamily.CompatibleWithFamilyZero == false) + { + node->DockFamily = first_node_with_windows->Windows[n]->DockFamily; + break; + } + } } } @@ -10863,9 +10871,16 @@ if ((host_window->Flags & ImGuiWindowFlags_DockNodeHost) && host_window->DockNodeAsHost->IsDockSpace && payload->BeginOrderWithinContext < host_window->BeginOrderWithinContext) return false; - ImGuiID host_user_type_id = host_window->DockNodeAsHost ? host_window->DockNodeAsHost->UserTypeIdFilter : host_window->UserTypeId; - if (payload->UserTypeId != host_user_type_id) + ImGuiDockFamily* host_family = host_window->DockNodeAsHost ? &host_window->DockNodeAsHost->DockFamily : &host_window->DockFamily; + ImGuiDockFamily* payload_family = &payload->DockFamily; + if (host_family->FamilyId != payload_family->FamilyId) + { + if (host_family->FamilyId != 0 && host_family->CompatibleWithFamilyZero && payload_family->FamilyId == 0) + return true; + if (payload_family->FamilyId != 0 && payload_family->CompatibleWithFamilyZero && host_family->FamilyId == 0) + return true; return false; + } return true; } @@ -11443,7 +11458,7 @@ // Create an explicit dockspace node within an existing window. Also expose dock node flags and creates a DocumentRoot node by default. // The DocumentRoot 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, ImGuiID user_type_filter) +void ImGui::DockSpace(ImGuiID id, const ImVec2& size_arg, ImGuiDockNodeFlags dock_space_flags, const ImGuiDockFamily* dock_family) { ImGuiContext* ctx = GImGui; ImGuiContext& g = *ctx; @@ -11456,7 +11471,7 @@ node->IsDocumentRoot = true; } node->Flags = dock_space_flags; - node->UserTypeIdFilter = user_type_filter; + node->DockFamily = dock_family ? *dock_family : ImGuiDockFamily(); // 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. @@ -12391,6 +12406,7 @@ else if (sscanf(line, "Collapsed=%d", &i) == 1) { settings->Collapsed = (i != 0); } else if (sscanf(line, "DockId=0x%X,%d", &u1, &i) == 2) { settings->DockId = u1; settings->DockOrder = (short)i; } else if (sscanf(line, "DockId=0x%X", &u1) == 1) { settings->DockId = u1; settings->DockOrder = -1; } + else if (sscanf(line, "DockFamilyId=0x%X", &u1) == 1) { settings->DockFamilyId = u1; } } static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf) @@ -12419,6 +12435,7 @@ settings->ViewportPos = window->ViewportPos; IM_ASSERT(window->DockNode == NULL || window->DockNode->ID == window->DockId); settings->DockId = window->DockId; + settings->DockFamilyId = window->DockFamily.FamilyId; settings->DockOrder = window->DockOrder; settings->Collapsed = window->Collapsed; } @@ -12449,6 +12466,8 @@ buf->appendf("DockId=0x%08X\n", settings->DockId); else buf->appendf("DockId=0x%08X,%d\n", settings->DockId, settings->DockOrder); + if (settings->DockFamilyId != 0) + buf->appendf("DockFamilyId=0x%08X\n", settings->DockFamilyId); } buf->appendf("\n"); } diff --git a/imgui.cpp b/imgui.cpp index 706edfa..a73b38c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2371,7 +2371,6 @@ HiddenFramesRegular = HiddenFramesForResize = 0; SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = SetWindowDockAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing; SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX); - UserTypeId = 0; LastFrameActive = -1; ItemWidthDefault = 0.0f; @@ -4969,7 +4968,7 @@ { window->SizeContentsExplicit = ImVec2(0.0f, 0.0f); } - window->UserTypeId = g.NextWindowData.UserTypeId; + window->DockFamily = g.NextWindowData.DockFamily; if (g.NextWindowData.CollapsedCond) SetWindowCollapsed(window, g.NextWindowData.CollapsedVal, g.NextWindowData.CollapsedCond); if (g.NextWindowData.FocusCond) @@ -6357,10 +6356,10 @@ g.NextWindowData.DockId = id; } -void ImGui::SetNextWindowUserType(ImGuiID user_type) +void ImGui::SetNextWindowDockFamily(const ImGuiDockFamily* family) { ImGuiContext& g = *GImGui; - g.NextWindowData.UserTypeId = user_type; + g.NextWindowData.DockFamily = *family; } // In window space (not screen space!) @@ -10178,19 +10177,19 @@ ImGuiDockNode::ImGuiDockNode(ImGuiID id) { ID = id; - UserTypeIdFilter = 0; Flags = 0; ParentNode = ChildNodes[0] = ChildNodes[1] = NULL; TabBar = NULL; SplitAxis = ImGuiAxis_None; + HostWindow = VisibleWindow = NULL; OnlyNodeWithWindows = NULL; LastFrameAlive = LastFrameActive = -1; LastFocusedNodeID = 0; SelectedTabID = 0; WantCloseTabID = 0; - IsVisible = true; InitFromFirstWindowPosSize = InitFromFirstWindowViewport = false; + IsVisible = true; IsDockSpace = IsDocumentRoot = HasCloseButton = HasCollapseButton = WantCloseAll = WantLockSizeOnce = WantMouseMove = false; } @@ -10493,9 +10492,18 @@ DockNodeUpdateFindOnlyNodeWithWindowsRec(node, &count, &first_node_with_windows); node->OnlyNodeWithWindows = (count == 1 ? first_node_with_windows : NULL); - // Copy the user type from _any_ of our window so it can be used for proper dock filtering. + // Copy the dock family from of our window so it can be used for proper dock filtering. + // When node has mixed windows, prioritize the family with the most constraint (CompatibleWithNeutral = false) as the reference to copy. if (first_node_with_windows) - node->UserTypeIdFilter = first_node_with_windows->Windows[0]->UserTypeId; + { + node->DockFamily = first_node_with_windows->Windows[0]->DockFamily; + for (int n = 1; n < first_node_with_windows->Windows.Size; n++) + if (first_node_with_windows->Windows[n]->DockFamily.CompatibleWithFamilyZero == false) + { + node->DockFamily = first_node_with_windows->Windows[n]->DockFamily; + break; + } + } } } @@ -10863,9 +10871,16 @@ if ((host_window->Flags & ImGuiWindowFlags_DockNodeHost) && host_window->DockNodeAsHost->IsDockSpace && payload->BeginOrderWithinContext < host_window->BeginOrderWithinContext) return false; - ImGuiID host_user_type_id = host_window->DockNodeAsHost ? host_window->DockNodeAsHost->UserTypeIdFilter : host_window->UserTypeId; - if (payload->UserTypeId != host_user_type_id) + ImGuiDockFamily* host_family = host_window->DockNodeAsHost ? &host_window->DockNodeAsHost->DockFamily : &host_window->DockFamily; + ImGuiDockFamily* payload_family = &payload->DockFamily; + if (host_family->FamilyId != payload_family->FamilyId) + { + if (host_family->FamilyId != 0 && host_family->CompatibleWithFamilyZero && payload_family->FamilyId == 0) + return true; + if (payload_family->FamilyId != 0 && payload_family->CompatibleWithFamilyZero && host_family->FamilyId == 0) + return true; return false; + } return true; } @@ -11443,7 +11458,7 @@ // Create an explicit dockspace node within an existing window. Also expose dock node flags and creates a DocumentRoot node by default. // The DocumentRoot 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, ImGuiID user_type_filter) +void ImGui::DockSpace(ImGuiID id, const ImVec2& size_arg, ImGuiDockNodeFlags dock_space_flags, const ImGuiDockFamily* dock_family) { ImGuiContext* ctx = GImGui; ImGuiContext& g = *ctx; @@ -11456,7 +11471,7 @@ node->IsDocumentRoot = true; } node->Flags = dock_space_flags; - node->UserTypeIdFilter = user_type_filter; + node->DockFamily = dock_family ? *dock_family : ImGuiDockFamily(); // 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. @@ -12391,6 +12406,7 @@ else if (sscanf(line, "Collapsed=%d", &i) == 1) { settings->Collapsed = (i != 0); } else if (sscanf(line, "DockId=0x%X,%d", &u1, &i) == 2) { settings->DockId = u1; settings->DockOrder = (short)i; } else if (sscanf(line, "DockId=0x%X", &u1) == 1) { settings->DockId = u1; settings->DockOrder = -1; } + else if (sscanf(line, "DockFamilyId=0x%X", &u1) == 1) { settings->DockFamilyId = u1; } } static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf) @@ -12419,6 +12435,7 @@ settings->ViewportPos = window->ViewportPos; IM_ASSERT(window->DockNode == NULL || window->DockNode->ID == window->DockId); settings->DockId = window->DockId; + settings->DockFamilyId = window->DockFamily.FamilyId; settings->DockOrder = window->DockOrder; settings->Collapsed = window->Collapsed; } @@ -12449,6 +12466,8 @@ buf->appendf("DockId=0x%08X\n", settings->DockId); else buf->appendf("DockId=0x%08X,%d\n", settings->DockId, settings->DockOrder); + if (settings->DockFamilyId != 0) + buf->appendf("DockFamilyId=0x%08X\n", settings->DockFamilyId); } buf->appendf("\n"); } diff --git a/imgui.h b/imgui.h index 0c13859..c91e29d 100644 --- a/imgui.h +++ b/imgui.h @@ -77,6 +77,7 @@ typedef void* ImTextureID; // User data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp) #endif struct ImGuiContext; // ImGui context (opaque) +struct ImGuiDockFamily; // Docking family for dock filtering struct ImGuiIO; // Main configuration and I/O between your application and ImGui struct ImGuiInputTextCallbackData; // Shared state of InputText() when using custom ImGuiInputTextCallback (rare/advanced use) struct ImGuiListClipper; // Helper to manually clip large list of items @@ -519,9 +520,9 @@ // [BETA API] Enable with io.ConfigFlags |= ImGuiConfigFlags_DockingEnable. // Note: you DO NOT need to call DockSpace() to use most Docking facilities! You can hold SHIFT anywhere while moving windows. // Use DockSpace() to create an explicit dock node _within_ an existing window. See Docking demo for details. - IMGUI_API void DockSpace(ImGuiID id, const ImVec2& size = ImVec2(0, 0), ImGuiDockNodeFlags flags = 0, ImGuiID user_type_filter = 0); + IMGUI_API void DockSpace(ImGuiID id, const ImVec2& size = ImVec2(0, 0), ImGuiDockNodeFlags flags = 0, const ImGuiDockFamily* dock_family = NULL); IMGUI_API void SetNextWindowDock(ImGuiID dock_id, ImGuiCond cond = 0); // set next window dock id (FIXME-DOCK) - IMGUI_API void SetNextWindowUserType(ImGuiID user_type); // FIXME-DOCK: set next window user type (docking filters by same user_type) + IMGUI_API void SetNextWindowDockFamily(const ImGuiDockFamily* dock_family); // FIXME-DOCK: set next window user type (docking filters by same user_type) IMGUI_API bool IsWindowDocked(); // is current window docked into another window? // Logging/Capture: all text output from interface is captured to tty/file/clipboard. By default, tree nodes are automatically opened during logging. @@ -1563,6 +1564,15 @@ ImVec2 DesiredSize; // Read-write. Desired size, based on user's mouse position. Write to this field to restrain resizing. }; +// For SetNextWindowDockFamily() and DockSpace() function +struct ImGuiDockFamily +{ + ImGuiID FamilyId; // 0 = unaffiliated + bool CompatibleWithFamilyZero; // true = can be docked/merged with an unaffiliated window + + ImGuiDockFamily() { FamilyId = 0; CompatibleWithFamilyZero = true; } +}; + // Data payload for Drag and Drop operations struct ImGuiPayload { diff --git a/imgui.cpp b/imgui.cpp index 706edfa..a73b38c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2371,7 +2371,6 @@ HiddenFramesRegular = HiddenFramesForResize = 0; SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = SetWindowDockAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing; SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX); - UserTypeId = 0; LastFrameActive = -1; ItemWidthDefault = 0.0f; @@ -4969,7 +4968,7 @@ { window->SizeContentsExplicit = ImVec2(0.0f, 0.0f); } - window->UserTypeId = g.NextWindowData.UserTypeId; + window->DockFamily = g.NextWindowData.DockFamily; if (g.NextWindowData.CollapsedCond) SetWindowCollapsed(window, g.NextWindowData.CollapsedVal, g.NextWindowData.CollapsedCond); if (g.NextWindowData.FocusCond) @@ -6357,10 +6356,10 @@ g.NextWindowData.DockId = id; } -void ImGui::SetNextWindowUserType(ImGuiID user_type) +void ImGui::SetNextWindowDockFamily(const ImGuiDockFamily* family) { ImGuiContext& g = *GImGui; - g.NextWindowData.UserTypeId = user_type; + g.NextWindowData.DockFamily = *family; } // In window space (not screen space!) @@ -10178,19 +10177,19 @@ ImGuiDockNode::ImGuiDockNode(ImGuiID id) { ID = id; - UserTypeIdFilter = 0; Flags = 0; ParentNode = ChildNodes[0] = ChildNodes[1] = NULL; TabBar = NULL; SplitAxis = ImGuiAxis_None; + HostWindow = VisibleWindow = NULL; OnlyNodeWithWindows = NULL; LastFrameAlive = LastFrameActive = -1; LastFocusedNodeID = 0; SelectedTabID = 0; WantCloseTabID = 0; - IsVisible = true; InitFromFirstWindowPosSize = InitFromFirstWindowViewport = false; + IsVisible = true; IsDockSpace = IsDocumentRoot = HasCloseButton = HasCollapseButton = WantCloseAll = WantLockSizeOnce = WantMouseMove = false; } @@ -10493,9 +10492,18 @@ DockNodeUpdateFindOnlyNodeWithWindowsRec(node, &count, &first_node_with_windows); node->OnlyNodeWithWindows = (count == 1 ? first_node_with_windows : NULL); - // Copy the user type from _any_ of our window so it can be used for proper dock filtering. + // Copy the dock family from of our window so it can be used for proper dock filtering. + // When node has mixed windows, prioritize the family with the most constraint (CompatibleWithNeutral = false) as the reference to copy. if (first_node_with_windows) - node->UserTypeIdFilter = first_node_with_windows->Windows[0]->UserTypeId; + { + node->DockFamily = first_node_with_windows->Windows[0]->DockFamily; + for (int n = 1; n < first_node_with_windows->Windows.Size; n++) + if (first_node_with_windows->Windows[n]->DockFamily.CompatibleWithFamilyZero == false) + { + node->DockFamily = first_node_with_windows->Windows[n]->DockFamily; + break; + } + } } } @@ -10863,9 +10871,16 @@ if ((host_window->Flags & ImGuiWindowFlags_DockNodeHost) && host_window->DockNodeAsHost->IsDockSpace && payload->BeginOrderWithinContext < host_window->BeginOrderWithinContext) return false; - ImGuiID host_user_type_id = host_window->DockNodeAsHost ? host_window->DockNodeAsHost->UserTypeIdFilter : host_window->UserTypeId; - if (payload->UserTypeId != host_user_type_id) + ImGuiDockFamily* host_family = host_window->DockNodeAsHost ? &host_window->DockNodeAsHost->DockFamily : &host_window->DockFamily; + ImGuiDockFamily* payload_family = &payload->DockFamily; + if (host_family->FamilyId != payload_family->FamilyId) + { + if (host_family->FamilyId != 0 && host_family->CompatibleWithFamilyZero && payload_family->FamilyId == 0) + return true; + if (payload_family->FamilyId != 0 && payload_family->CompatibleWithFamilyZero && host_family->FamilyId == 0) + return true; return false; + } return true; } @@ -11443,7 +11458,7 @@ // Create an explicit dockspace node within an existing window. Also expose dock node flags and creates a DocumentRoot node by default. // The DocumentRoot 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, ImGuiID user_type_filter) +void ImGui::DockSpace(ImGuiID id, const ImVec2& size_arg, ImGuiDockNodeFlags dock_space_flags, const ImGuiDockFamily* dock_family) { ImGuiContext* ctx = GImGui; ImGuiContext& g = *ctx; @@ -11456,7 +11471,7 @@ node->IsDocumentRoot = true; } node->Flags = dock_space_flags; - node->UserTypeIdFilter = user_type_filter; + node->DockFamily = dock_family ? *dock_family : ImGuiDockFamily(); // 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. @@ -12391,6 +12406,7 @@ else if (sscanf(line, "Collapsed=%d", &i) == 1) { settings->Collapsed = (i != 0); } else if (sscanf(line, "DockId=0x%X,%d", &u1, &i) == 2) { settings->DockId = u1; settings->DockOrder = (short)i; } else if (sscanf(line, "DockId=0x%X", &u1) == 1) { settings->DockId = u1; settings->DockOrder = -1; } + else if (sscanf(line, "DockFamilyId=0x%X", &u1) == 1) { settings->DockFamilyId = u1; } } static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf) @@ -12419,6 +12435,7 @@ settings->ViewportPos = window->ViewportPos; IM_ASSERT(window->DockNode == NULL || window->DockNode->ID == window->DockId); settings->DockId = window->DockId; + settings->DockFamilyId = window->DockFamily.FamilyId; settings->DockOrder = window->DockOrder; settings->Collapsed = window->Collapsed; } @@ -12449,6 +12466,8 @@ buf->appendf("DockId=0x%08X\n", settings->DockId); else buf->appendf("DockId=0x%08X,%d\n", settings->DockId, settings->DockOrder); + if (settings->DockFamilyId != 0) + buf->appendf("DockFamilyId=0x%08X\n", settings->DockFamilyId); } buf->appendf("\n"); } diff --git a/imgui.h b/imgui.h index 0c13859..c91e29d 100644 --- a/imgui.h +++ b/imgui.h @@ -77,6 +77,7 @@ typedef void* ImTextureID; // User data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp) #endif struct ImGuiContext; // ImGui context (opaque) +struct ImGuiDockFamily; // Docking family for dock filtering struct ImGuiIO; // Main configuration and I/O between your application and ImGui struct ImGuiInputTextCallbackData; // Shared state of InputText() when using custom ImGuiInputTextCallback (rare/advanced use) struct ImGuiListClipper; // Helper to manually clip large list of items @@ -519,9 +520,9 @@ // [BETA API] Enable with io.ConfigFlags |= ImGuiConfigFlags_DockingEnable. // Note: you DO NOT need to call DockSpace() to use most Docking facilities! You can hold SHIFT anywhere while moving windows. // Use DockSpace() to create an explicit dock node _within_ an existing window. See Docking demo for details. - IMGUI_API void DockSpace(ImGuiID id, const ImVec2& size = ImVec2(0, 0), ImGuiDockNodeFlags flags = 0, ImGuiID user_type_filter = 0); + IMGUI_API void DockSpace(ImGuiID id, const ImVec2& size = ImVec2(0, 0), ImGuiDockNodeFlags flags = 0, const ImGuiDockFamily* dock_family = NULL); IMGUI_API void SetNextWindowDock(ImGuiID dock_id, ImGuiCond cond = 0); // set next window dock id (FIXME-DOCK) - IMGUI_API void SetNextWindowUserType(ImGuiID user_type); // FIXME-DOCK: set next window user type (docking filters by same user_type) + IMGUI_API void SetNextWindowDockFamily(const ImGuiDockFamily* dock_family); // FIXME-DOCK: set next window user type (docking filters by same user_type) IMGUI_API bool IsWindowDocked(); // is current window docked into another window? // Logging/Capture: all text output from interface is captured to tty/file/clipboard. By default, tree nodes are automatically opened during logging. @@ -1563,6 +1564,15 @@ ImVec2 DesiredSize; // Read-write. Desired size, based on user's mouse position. Write to this field to restrain resizing. }; +// For SetNextWindowDockFamily() and DockSpace() function +struct ImGuiDockFamily +{ + ImGuiID FamilyId; // 0 = unaffiliated + bool CompatibleWithFamilyZero; // true = can be docked/merged with an unaffiliated window + + ImGuiDockFamily() { FamilyId = 0; CompatibleWithFamilyZero = true; } +}; + // Data payload for Drag and Drop operations struct ImGuiPayload { diff --git a/imgui_internal.h b/imgui_internal.h index aeabbdb..0d8f2d1 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -541,10 +541,11 @@ ImVec2 ViewportPos; ImGuiID ViewportId; ImGuiID DockId; // ID of last known DockNode (even if the DockNode is invisible because it has only 1 active window), or 0 if none. + ImGuiID DockFamilyId; // ID of dock family if specified short DockOrder; // Order of the last time the window was visible within its DockNode. This is used to reorder windows that are reappearing on the same frame. Same value between windows that were active and windows that were none are possible. bool Collapsed; - ImGuiWindowSettings() { Name = NULL; ID = 0; Pos = Size = ViewportPos = ImVec2(0, 0); ViewportId = DockId = 0; DockOrder = -1; Collapsed = false; } + ImGuiWindowSettings() { Name = NULL; ID = 0; Pos = Size = ViewportPos = ImVec2(0, 0); ViewportId = DockId = DockFamilyId = 0; DockOrder = -1; Collapsed = false; } }; struct ImGuiSettingsHandler @@ -704,7 +705,7 @@ float BgAlphaVal; ImGuiID ViewportId; ImGuiID DockId; - ImGuiID UserTypeId; + ImGuiDockFamily DockFamily; ImVec2 MenuBarOffsetMinVal; // This is not exposed publicly, so we don't clear it. ImGuiNextWindowData() @@ -717,14 +718,14 @@ SizeCallback = NULL; SizeCallbackUserData = NULL; BgAlphaVal = FLT_MAX; - ViewportId = DockId = UserTypeId = 0; + ViewportId = DockId = 0; MenuBarOffsetMinVal = ImVec2(0.0f, 0.0f); } void Clear() { PosCond = SizeCond = ContentSizeCond = CollapsedCond = SizeConstraintCond = FocusCond = BgAlphaCond = ViewportCond = DockCond = 0; - UserTypeId = 0; + DockFamily = ImGuiDockFamily(); } }; @@ -742,7 +743,6 @@ struct ImGuiDockNode { ImGuiID ID; - ImGuiID UserTypeIdFilter; ImGuiDockNodeFlags Flags; ImGuiDockNode* ParentNode; ImGuiDockNode* ChildNodes[2]; // [Split node only] Child nodes (left/right or top/bottom). Consider switching to an array. @@ -752,6 +752,7 @@ ImVec2 Size; // Current size ImVec2 SizeRef; // [Split node only] Last explicitly written-to size (overridden when using a splitter affecting the node), used to calculate Size. int SplitAxis; // [Split node only] Split axis (X or Y) + ImGuiDockFamily DockFamily; ImGuiWindow* HostWindow; ImGuiWindow* VisibleWindow; @@ -1208,7 +1209,7 @@ ImGuiCond SetWindowDockAllowFlags; // store acceptable condition flags for SetNextWindowDock() use. ImVec2 SetWindowPosVal; // store window position when using a non-zero Pivot (position set needs to be processed when we know the window size) ImVec2 SetWindowPosPivot; // store window pivot for positioning. ImVec2(0,0) when positioning from top-left corner; ImVec2(0.5f,0.5f) for centering; ImVec2(1,1) for bottom right. - ImGuiID UserTypeId; // user value set with SetNextWindowUserType(const char*) + ImGuiDockFamily DockFamily; // set with SetNextWindowDockFamily() ImGuiWindowTempData DC; // Temporary per-window data, reset at the beginning of the frame. This used to be called ImGuiDrawContext, hence the "DC" variable name. ImVector IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack