Docking: Added ImGuiDockSpaceFlags_KeepAliveOnly, important for multiple level of tabs. (also renamed ImGuiDockFlags to ImGuiDockSpaceFlags.)

This commit is contained in:
omar 2018-09-11 16:04:02 +02:00
parent c4e26f4b92
commit 211a9c8fd2
3 changed files with 41 additions and 20 deletions

View File

@ -10065,7 +10065,7 @@ ImGuiDockNode::ImGuiDockNode(ImGuiID id)
OnlyNodeWithWindows = NULL; OnlyNodeWithWindows = NULL;
SelectedTabID = 0; SelectedTabID = 0;
LastFocusedNodeID = 0; LastFocusedNodeID = 0;
LastFrameActive = -1; LastFrameAlive = LastFrameActive = -1;
WantCloseOne = 0; WantCloseOne = 0;
IsVisible = true; IsVisible = true;
InitFromFirstWindow = IsExplicitRoot = IsDocumentRoot = HasCloseButton = HasCollapseButton = WantCloseAll = WantLockSizeOnce = false; InitFromFirstWindow = IsExplicitRoot = IsDocumentRoot = HasCloseButton = HasCollapseButton = WantCloseAll = WantLockSizeOnce = false;
@ -10327,6 +10327,7 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_ASSERT(node->LastFrameActive != g.FrameCount); IM_ASSERT(node->LastFrameActive != g.FrameCount);
node->LastFrameAlive = g.FrameCount;
if (node->IsRootNode()) if (node->IsRootNode())
{ {
@ -10829,7 +10830,7 @@ static bool ImGui::DockNodePreviewDockCalc(ImGuiWindow* host_window, ImGuiDockNo
data->IsCenterAvailable = false; data->IsCenterAvailable = false;
data->IsSidesAvailable = true; data->IsSidesAvailable = true;
if (host_node && (host_node->Flags & ImGuiDockFlags_NoSplit)) if (host_node && (host_node->Flags & ImGuiDockSpaceFlags_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->IsDocumentRoot)
data->IsSidesAvailable = false; data->IsSidesAvailable = false;
@ -10946,7 +10947,7 @@ static void ImGui::DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDock
} }
} }
if (host_node && (host_node->Flags & ImGuiDockFlags_NoSplit)) if (host_node && (host_node->Flags & ImGuiDockSpaceFlags_NoSplit))
return; return;
// Display drop boxes // Display drop boxes
@ -11267,7 +11268,7 @@ void ImGui::SetWindowDock(ImGuiWindow* window, ImGuiID dock_id, ImGuiCond cond)
window->DockId = dock_id; window->DockId = dock_id;
} }
void ImGui::DockSpace(const char* str_id, const ImVec2& size_arg, ImGuiDockFlags dock_flags, ImGuiID user_type_filter) void ImGui::DockSpace(const char* str_id, const ImVec2& size_arg, ImGuiDockSpaceFlags dock_space_flags, ImGuiID user_type_filter)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
ImGuiDockContext* ctx = g.DockContext; ImGuiDockContext* ctx = g.DockContext;
@ -11282,13 +11283,21 @@ void ImGui::DockSpace(const char* str_id, const ImVec2& size_arg, ImGuiDockFlags
node = DockContextAddNode(ctx, id); node = DockContextAddNode(ctx, id);
node->IsDocumentRoot = true; node->IsDocumentRoot = true;
} }
node->Flags = dock_flags; node->Flags = dock_space_flags;
node->UserTypeIdFilter = user_type_filter; node->UserTypeIdFilter = user_type_filter;
node->IsExplicitRoot = true; node->IsExplicitRoot = true;
// When a Dockspace transitioned form implicit to explicit this may be called a second time
if (node->LastFrameActive == g.FrameCount) if (node->LastFrameActive == g.FrameCount)
return; return;
// Keep alive mode, this is allow windows docked into this node so stay docked even if they are not visible
if (dock_space_flags & ImGuiDockSpaceFlags_KeepAliveOnly)
{
node->LastFrameAlive = g.FrameCount;
return;
}
const ImVec2 content_avail = GetContentRegionAvail(); const ImVec2 content_avail = GetContentRegionAvail();
ImVec2 size = ImFloor(size_arg); ImVec2 size = ImFloor(size_arg);
if (size.x <= 0.0f) if (size.x <= 0.0f)
@ -11370,13 +11379,16 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
} }
// Undock if our dockspace disappeared // Undock if our dockspace disappeared
if (dock_node->LastFrameActive < g.FrameCount) // Note how we are testing for LastFrameAlive and NOT LastFrameActive. A DockSpace can be maintained alive while being inactive with ImGuiDockSpaceFlags_KeepAliveOnly.
if (dock_node->LastFrameAlive < g.FrameCount)
{ {
// If the window has been orphaned (lost its dockspace), transition the docknode to an implicit node processed in DockContextUpdateDocking() // If the window has been orphaned (lost its dockspace), transition the docknode to an implicit node processed in DockContextUpdateDocking()
ImGuiDockNode* root_node = DockNodeGetRootNode(dock_node); ImGuiDockNode* root_node = DockNodeGetRootNode(dock_node);
if (root_node->IsExplicitRoot && root_node->LastFrameActive < g.FrameCount) if (root_node->LastFrameAlive < g.FrameCount)
{
root_node->IsExplicitRoot = false; root_node->IsExplicitRoot = false;
window->DockIsActive = false; window->DockIsActive = false;
}
return; return;
} }
@ -11396,7 +11408,19 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
IM_ASSERT(dock_node->HostWindow); IM_ASSERT(dock_node->HostWindow);
IM_ASSERT(!dock_node->IsParent()); IM_ASSERT(!dock_node->IsParent());
// Position window
SetNextWindowPos(dock_node->Pos);
SetNextWindowSize(dock_node->Size);
g.NextWindowData.PosUndock = false; // Cancel implicit undocking of SetNextWindowPos()
window->DockIsActive = true; window->DockIsActive = true;
if (dock_node->Flags & ImGuiDockSpaceFlags_KeepAliveOnly)
{
window->DockTabIsVisible = false;
return;
}
window->DockTabIsVisible = (dock_node->TabBar && dock_node->TabBar->VisibleTabId == window->ID); window->DockTabIsVisible = (dock_node->TabBar && dock_node->TabBar->VisibleTabId == window->ID);
// Update window flag // Update window flag
@ -11404,11 +11428,6 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
window->Flags |= ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoResize; window->Flags |= ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_NoResize;
window->Flags &= ~ImGuiWindowFlags_NoTitleBar; // Clear the NoTitleBar flag in case the user set it: confusingly enough we need a title bar height so we are correctly offset, but it won't be displayed! window->Flags &= ~ImGuiWindowFlags_NoTitleBar; // Clear the NoTitleBar flag in case the user set it: confusingly enough we need a title bar height so we are correctly offset, but it won't be displayed!
// Position window
SetNextWindowPos(dock_node->Pos);
SetNextWindowSize(dock_node->Size);
g.NextWindowData.PosUndock = false;
// Save new dock order only if the tab bar is active // Save new dock order only if the tab bar is active
if (dock_node->TabBar) if (dock_node->TabBar)
window->DockOrder = (short)DockNodeGetTabOrder(window); window->DockOrder = (short)DockNodeGetTabOrder(window);

11
imgui.h
View File

@ -111,7 +111,7 @@ typedef int ImGuiColorEditFlags; // -> enum ImGuiColorEditFlags_ // Flags: f
typedef int ImGuiColumnsFlags; // -> enum ImGuiColumnsFlags_ // Flags: for Columns(), BeginColumns() typedef int ImGuiColumnsFlags; // -> enum ImGuiColumnsFlags_ // Flags: for Columns(), BeginColumns()
typedef int ImGuiConfigFlags; // -> enum ImGuiConfigFlags_ // Flags: for io.ConfigFlags typedef int ImGuiConfigFlags; // -> enum ImGuiConfigFlags_ // Flags: for io.ConfigFlags
typedef int ImGuiComboFlags; // -> enum ImGuiComboFlags_ // Flags: for BeginCombo() typedef int ImGuiComboFlags; // -> enum ImGuiComboFlags_ // Flags: for BeginCombo()
typedef int ImGuiDockFlags; // -> enum ImGuiDockFlags_ // Flags: for DockSpace() typedef int ImGuiDockSpaceFlags; // -> enum ImGuiDockSpaceFlags_ // Flags: for DockSpace()
typedef int ImGuiDragDropFlags; // -> enum ImGuiDragDropFlags_ // Flags: for *DragDrop*() typedef int ImGuiDragDropFlags; // -> enum ImGuiDragDropFlags_ // Flags: for *DragDrop*()
typedef int ImGuiFocusedFlags; // -> enum ImGuiFocusedFlags_ // Flags: for IsWindowFocused() typedef int ImGuiFocusedFlags; // -> enum ImGuiFocusedFlags_ // Flags: for IsWindowFocused()
typedef int ImGuiHoveredFlags; // -> enum ImGuiHoveredFlags_ // Flags: for IsItemHovered(), IsWindowHovered() etc. typedef int ImGuiHoveredFlags; // -> enum ImGuiHoveredFlags_ // Flags: for IsItemHovered(), IsWindowHovered() etc.
@ -520,7 +520,7 @@ namespace ImGui
// Docking // Docking
// [BETA API] Enable with io.ConfigFlags |= ImGuiConfigFlags_DockingEnable. // [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() if you need to create an explicit docking space _within_ an existing window. See Docking demo for details) // Note: you DO NOT need to call DockSpace() to use most Docking facilities! You can hold SHIFT anywhere while moving windows. Use DockSpace() if you need to create an explicit docking space _within_ an existing window. See Docking demo for details)
IMGUI_API void DockSpace(const char* str_id, const ImVec2& size = ImVec2(0, 0), ImGuiDockFlags flags = 0, ImGuiID user_type_filter = 0); IMGUI_API void DockSpace(const char* str_id, const ImVec2& size = ImVec2(0, 0), ImGuiDockSpaceFlags flags = 0, ImGuiID user_type_filter = 0);
IMGUI_API void SetNextWindowUserType(ImGuiID user_type); // FIXME-DOCK: set next window user type (docking filters by same user_type) IMGUI_API void SetNextWindowUserType(ImGuiID user_type); // FIXME-DOCK: set next window user type (docking filters by same user_type)
// Logging/Capture: all text output from interface is captured to tty/file/clipboard. By default, tree nodes are automatically opened during logging. // Logging/Capture: all text output from interface is captured to tty/file/clipboard. By default, tree nodes are automatically opened during logging.
@ -782,10 +782,11 @@ enum ImGuiTabItemFlags_
}; };
// Flags for ImGui::DockSpace() // Flags for ImGui::DockSpace()
enum ImGuiDockFlags_ enum ImGuiDockSpaceFlags_
{ {
ImGuiDockFlags_None = 0, ImGuiDockSpaceFlags_None = 0,
ImGuiDockFlags_NoSplit = 1 << 0 ImGuiDockSpaceFlags_KeepAliveOnly = 1 << 0, // Don't create/display the dockspace but keep it alive. Windows docked into this dockspace won't be undocked.
ImGuiDockSpaceFlags_NoSplit = 1 << 1 // Disable splitting the dockspace into smaller nodes. Useful e.g. when embedding dockspaces into a main root one.
}; };
// Flags for ImGui::IsWindowFocused() // Flags for ImGui::IsWindowFocused()

View File

@ -738,12 +738,12 @@ struct ImGuiTabBarSortItem
float Width; float Width;
}; };
// sizeof() 88~124 // sizeof() 92~128
struct ImGuiDockNode struct ImGuiDockNode
{ {
ImGuiID ID; ImGuiID ID;
ImGuiID UserTypeIdFilter; ImGuiID UserTypeIdFilter;
ImGuiDockFlags Flags; ImGuiDockSpaceFlags Flags;
ImGuiDockNode* ParentNode; ImGuiDockNode* ParentNode;
ImGuiDockNode* ChildNodes[2]; ImGuiDockNode* ChildNodes[2];
ImVector<ImGuiWindow*> Windows; // Note: unordered list! Iterate TabBar->Tabs for user-order. ImVector<ImGuiWindow*> Windows; // Note: unordered list! Iterate TabBar->Tabs for user-order.
@ -757,6 +757,7 @@ struct ImGuiDockNode
ImGuiWindow* VisibleWindow; ImGuiWindow* VisibleWindow;
ImGuiDockNode* OnlyNodeWithWindows; // Root node only, set when there is a single visible node within the hierarchy ImGuiDockNode* OnlyNodeWithWindows; // Root node only, set when there is a single visible node within the hierarchy
ImGuiID SelectedTabID; ImGuiID SelectedTabID;
int LastFrameAlive;
int LastFrameActive; int LastFrameActive;
ImGuiID LastFocusedNodeID; ImGuiID LastFocusedNodeID;
ImGuiID WantCloseOne; ImGuiID WantCloseOne;