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;
SelectedTabID = 0;
LastFocusedNodeID = 0;
LastFrameActive = -1;
LastFrameAlive = LastFrameActive = -1;
WantCloseOne = 0;
IsVisible = true;
InitFromFirstWindow = IsExplicitRoot = IsDocumentRoot = HasCloseButton = HasCollapseButton = WantCloseAll = WantLockSizeOnce = false;
@ -10327,6 +10327,7 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
{
ImGuiContext& g = *GImGui;
IM_ASSERT(node->LastFrameActive != g.FrameCount);
node->LastFrameAlive = g.FrameCount;
if (node->IsRootNode())
{
@ -10829,7 +10830,7 @@ static bool ImGui::DockNodePreviewDockCalc(ImGuiWindow* host_window, ImGuiDockNo
data->IsCenterAvailable = false;
data->IsSidesAvailable = true;
if (host_node && (host_node->Flags & ImGuiDockFlags_NoSplit))
if (host_node && (host_node->Flags & ImGuiDockSpaceFlags_NoSplit))
data->IsSidesAvailable = false;
if (!is_outer_docking && host_node && host_node->ParentNode == NULL && host_node->IsDocumentRoot)
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;
// Display drop boxes
@ -11267,7 +11268,7 @@ void ImGui::SetWindowDock(ImGuiWindow* window, ImGuiID dock_id, ImGuiCond cond)
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;
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->IsDocumentRoot = true;
}
node->Flags = dock_flags;
node->Flags = dock_space_flags;
node->UserTypeIdFilter = user_type_filter;
node->IsExplicitRoot = true;
// When a Dockspace transitioned form implicit to explicit this may be called a second time
if (node->LastFrameActive == g.FrameCount)
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();
ImVec2 size = ImFloor(size_arg);
if (size.x <= 0.0f)
@ -11370,13 +11379,16 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
}
// 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()
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;
window->DockIsActive = false;
}
return;
}
@ -11396,7 +11408,19 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
IM_ASSERT(dock_node->HostWindow);
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;
if (dock_node->Flags & ImGuiDockSpaceFlags_KeepAliveOnly)
{
window->DockTabIsVisible = false;
return;
}
window->DockTabIsVisible = (dock_node->TabBar && dock_node->TabBar->VisibleTabId == window->ID);
// 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_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
if (dock_node->TabBar)
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 ImGuiConfigFlags; // -> enum ImGuiConfigFlags_ // Flags: for io.ConfigFlags
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 ImGuiFocusedFlags; // -> enum ImGuiFocusedFlags_ // Flags: for IsWindowFocused()
typedef int ImGuiHoveredFlags; // -> enum ImGuiHoveredFlags_ // Flags: for IsItemHovered(), IsWindowHovered() etc.
@ -520,7 +520,7 @@ namespace ImGui
// Docking
// [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)
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)
// 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()
enum ImGuiDockFlags_
enum ImGuiDockSpaceFlags_
{
ImGuiDockFlags_None = 0,
ImGuiDockFlags_NoSplit = 1 << 0
ImGuiDockSpaceFlags_None = 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()

View File

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