mirror of
https://github.com/Drezil/imgui.git
synced 2024-12-18 22:26:34 +00:00
Docking: Added SetNextWindowUserType() + user type filtering in dockspace and window merging. Added DockSpace() flag ImGuiDockFlags_NoSplit. Renaming. Reworked the DockNodeUpdateFindOnlyNodeWithWindows code so DockNodeUpdate can access the first window.
This commit is contained in:
parent
b872aa5c8e
commit
a68c98bb67
69
imgui.cpp
69
imgui.cpp
@ -2371,6 +2371,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
|
||||
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;
|
||||
@ -3350,7 +3351,7 @@ void ImGui::NewFrame()
|
||||
|
||||
// Undocking
|
||||
// (needs to be before UpdateMovingWindow so the window is already offset and following the mouse on the detaching frame)
|
||||
DockContextUpdateUndocking(g.DockContext);
|
||||
DockContextNewFrameUpdateUndocking(g.DockContext);
|
||||
|
||||
// Find hovered window
|
||||
// (needs to be before UpdateMovingWindow so we fill HoveredWindowUnderMovingWindow on the mouse release frame)
|
||||
@ -3404,7 +3405,7 @@ void ImGui::NewFrame()
|
||||
ClosePopupsOverWindow(g.NavWindow);
|
||||
|
||||
// Docking
|
||||
DockContextUpdateDocking(g.DockContext);
|
||||
DockContextNewFrameUpdateDocking(g.DockContext);
|
||||
|
||||
// Create implicit window - we will only render it if the user has added something to it.
|
||||
// We don't use "Debug" to avoid colliding with user trying to create a "Debug" window with custom flags.
|
||||
@ -4954,6 +4955,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
{
|
||||
window->SizeContentsExplicit = ImVec2(0.0f, 0.0f);
|
||||
}
|
||||
window->UserTypeId = g.NextWindowData.UserTypeId;
|
||||
if (g.NextWindowData.CollapsedCond)
|
||||
SetWindowCollapsed(window, g.NextWindowData.CollapsedVal, g.NextWindowData.CollapsedCond);
|
||||
if (g.NextWindowData.FocusCond)
|
||||
@ -6320,6 +6322,12 @@ void ImGui::SetNextWindowDock(ImGuiID id, ImGuiCond cond)
|
||||
g.NextWindowData.DockId = id;
|
||||
}
|
||||
|
||||
void ImGui::SetNextWindowUserType(ImGuiID user_type)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.NextWindowData.UserTypeId = user_type;
|
||||
}
|
||||
|
||||
// In window space (not screen space!)
|
||||
ImVec2 ImGui::GetContentRegionMax()
|
||||
{
|
||||
@ -9580,7 +9588,6 @@ namespace ImGui
|
||||
static void DockNodeRemoveWindow(ImGuiDockNode* node, ImGuiWindow* window, ImGuiID save_dock_id);
|
||||
static void DockNodeHideHostWindow(ImGuiDockNode* node);
|
||||
static void DockNodeUpdate(ImGuiDockNode* node);
|
||||
static ImGuiDockNode* DockNodeUpdateFindOnlyNodeWithWindows(ImGuiDockNode* node);
|
||||
static void DockNodeUpdateVisibleFlagAndInactiveChilds(ImGuiDockNode* node);
|
||||
static void DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_window);
|
||||
static void DockNodeUpdateVisibleFlag(ImGuiDockNode* node);
|
||||
@ -9656,7 +9663,7 @@ void ImGui::DockContextRebuild(ImGuiDockContext* ctx)
|
||||
DockContextBuildAddWindowsToNodes(ctx);
|
||||
}
|
||||
|
||||
void ImGui::DockContextUpdateUndocking(ImGuiDockContext* ctx)
|
||||
void ImGui::DockContextNewFrameUpdateUndocking(ImGuiDockContext* ctx)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (!(g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable))
|
||||
@ -9682,7 +9689,7 @@ void ImGui::DockContextUpdateUndocking(ImGuiDockContext* ctx)
|
||||
DockContextProcessUndock(ctx, ctx->Requests[n].WindowUndock);
|
||||
}
|
||||
|
||||
void ImGui::DockContextUpdateDocking(ImGuiDockContext* ctx)
|
||||
void ImGui::DockContextNewFrameUpdateDocking(ImGuiDockContext* ctx)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (!(g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable))
|
||||
@ -10000,6 +10007,8 @@ void ImGui::DockContextProcessUndock(ImGuiDockContext* ctx, ImGuiWindow* window)
|
||||
ImGuiDockNode::ImGuiDockNode(ImGuiID id)
|
||||
{
|
||||
ID = id;
|
||||
UserTypeIdFilter = 0;
|
||||
Flags = 0;
|
||||
ParentNode = ChildNodes[0] = ChildNodes[1] = NULL;
|
||||
TabBar = NULL;
|
||||
SplitAxis = ImGuiAxis_None;
|
||||
@ -10197,28 +10206,20 @@ static void ImGui::DockNodeHideHostWindow(ImGuiDockNode* node)
|
||||
}
|
||||
}
|
||||
|
||||
static void DockNodeUpdateFindOnlyNodeWithWindowsRec(ImGuiDockNode* node, int* p_count, ImGuiDockNode** p_only_node_with_windows)
|
||||
static void DockNodeUpdateFindOnlyNodeWithWindowsRec(ImGuiDockNode* node, int* p_count, ImGuiDockNode** p_first_node_with_windows)
|
||||
{
|
||||
if (node->Windows.Size > 0)
|
||||
{
|
||||
if (*p_only_node_with_windows == NULL)
|
||||
*p_only_node_with_windows = node;
|
||||
if (*p_first_node_with_windows == NULL)
|
||||
*p_first_node_with_windows = node;
|
||||
(*p_count)++;
|
||||
}
|
||||
if (*p_count > 1)
|
||||
return;
|
||||
if (node->ChildNodes[0])
|
||||
DockNodeUpdateFindOnlyNodeWithWindowsRec(node->ChildNodes[0], p_count, p_only_node_with_windows);
|
||||
DockNodeUpdateFindOnlyNodeWithWindowsRec(node->ChildNodes[0], p_count, p_first_node_with_windows);
|
||||
if (node->ChildNodes[1])
|
||||
DockNodeUpdateFindOnlyNodeWithWindowsRec(node->ChildNodes[1], p_count, p_only_node_with_windows);
|
||||
}
|
||||
|
||||
static ImGuiDockNode* ImGui::DockNodeUpdateFindOnlyNodeWithWindows(ImGuiDockNode* node)
|
||||
{
|
||||
int count = 0;
|
||||
ImGuiDockNode* only_node_with_windows = NULL;
|
||||
DockNodeUpdateFindOnlyNodeWithWindowsRec(node, &count, &only_node_with_windows);
|
||||
return (count == 1 ? only_node_with_windows : NULL);
|
||||
DockNodeUpdateFindOnlyNodeWithWindowsRec(node->ChildNodes[1], p_count, p_first_node_with_windows);
|
||||
}
|
||||
|
||||
static void ImGui::DockNodeUpdateVisibleFlagAndInactiveChilds(ImGuiDockNode* node)
|
||||
@ -10280,8 +10281,19 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
|
||||
if (node->IsRootNode())
|
||||
{
|
||||
DockNodeUpdateVisibleFlagAndInactiveChilds(node);
|
||||
ImGuiDockNode* only_node_with_windows = node->IsExplicitRoot ? NULL : DockNodeUpdateFindOnlyNodeWithWindows(node);
|
||||
node->OnlyNodeWithWindows = only_node_with_windows;
|
||||
|
||||
// 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!)
|
||||
if (!node->IsExplicitRoot)
|
||||
{
|
||||
int count = 0;
|
||||
ImGuiDockNode* first_node_with_windows = NULL;
|
||||
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.
|
||||
if (first_node_with_windows)
|
||||
node->UserTypeIdFilter = first_node_with_windows->Windows[0]->UserTypeId;
|
||||
}
|
||||
}
|
||||
|
||||
// Early out for standalone floating window that are holding on a DockId (with an invisible dock node)
|
||||
@ -10640,6 +10652,11 @@ static bool ImGui::DockNodeIsDropAllowed(ImGuiWindow* host_window, ImGuiWindow*
|
||||
ImGuiWindow* payload = root_payload->DockNodeAsHost ? root_payload->DockNodeAsHost->Windows[payload_n] : root_payload;
|
||||
if ((host_window->Flags & ImGuiWindowFlags_DockNodeHost) && payload->BeginOrderWithinContext < host_window->BeginOrderWithinContext)
|
||||
continue;
|
||||
|
||||
ImGuiID host_user_type_id = host_window->DockNodeAsHost ? host_window->DockNodeAsHost->UserTypeIdFilter : host_window->UserTypeId;
|
||||
if (payload->UserTypeId != host_user_type_id)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -10756,6 +10773,8 @@ static bool ImGui::DockNodePreviewDockCalc(ImGuiWindow* host_window, ImGuiDockNo
|
||||
data->IsCenterAvailable = false;
|
||||
|
||||
data->IsSidesAvailable = true;
|
||||
if (host_node && (host_node->Flags & ImGuiDockFlags_NoSplit))
|
||||
data->IsSidesAvailable = false;
|
||||
if (!is_outer_docking && host_node && host_node->ParentNode == NULL && host_node->IsDocumentRoot)
|
||||
data->IsSidesAvailable = false;
|
||||
|
||||
@ -10871,6 +10890,9 @@ static void ImGui::DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDock
|
||||
}
|
||||
}
|
||||
|
||||
if (host_node && (host_node->Flags & ImGuiDockFlags_NoSplit))
|
||||
return;
|
||||
|
||||
// Display drop boxes
|
||||
const float overlay_rounding = ImMax(3.0f, g.Style.FrameRounding);
|
||||
for (int dir = ImGuiDir_None; dir < ImGuiDir_COUNT; dir++)
|
||||
@ -11189,7 +11211,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)
|
||||
void ImGui::DockSpace(const char* str_id, const ImVec2& size_arg, ImGuiDockFlags dock_flags, ImGuiID user_type_filter)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiDockContext* ctx = g.DockContext;
|
||||
@ -11204,6 +11226,8 @@ void ImGui::DockSpace(const char* str_id, const ImVec2& size_arg)
|
||||
node = DockContextAddNode(ctx, id);
|
||||
node->IsDocumentRoot = true;
|
||||
}
|
||||
node->Flags = dock_flags;
|
||||
node->UserTypeIdFilter = user_type_filter;
|
||||
node->IsExplicitRoot = true;
|
||||
|
||||
const ImVec2 content_avail = GetContentRegionAvail();
|
||||
@ -11235,6 +11259,7 @@ void ImGui::DockSpace(const char* str_id, const ImVec2& size_arg)
|
||||
host_window->DockNodeAsHost = node;
|
||||
host_window->ChildId = window->GetID(title);
|
||||
node->HostWindow = host_window;
|
||||
node->OnlyNodeWithWindows = NULL;
|
||||
|
||||
IM_ASSERT(node->IsRootNode());
|
||||
DockNodeUpdate(node);
|
||||
@ -11320,7 +11345,7 @@ 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
|
||||
// Position window
|
||||
SetNextWindowPos(dock_node->Pos);
|
||||
SetNextWindowSize(dock_node->Size);
|
||||
g.NextWindowData.PosUndock = false;
|
||||
|
11
imgui.h
11
imgui.h
@ -111,6 +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 ImGuiDragDropFlags; // -> enum ImGuiDragDropFlags_ // Flags: for *DragDrop*()
|
||||
typedef int ImGuiFocusedFlags; // -> enum ImGuiFocusedFlags_ // Flags: for IsWindowFocused()
|
||||
typedef int ImGuiHoveredFlags; // -> enum ImGuiHoveredFlags_ // Flags: for IsItemHovered(), IsWindowHovered() etc.
|
||||
@ -519,7 +520,8 @@ 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));
|
||||
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 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.
|
||||
IMGUI_API void LogToTTY(int max_depth = -1); // start logging to tty
|
||||
@ -779,6 +781,13 @@ enum ImGuiTabItemFlags_
|
||||
ImGuiTabItemFlags_NoPushId = 1 << 3 // Don't call PushID(tab->ID)/PopID() on BeginTabItem()/EndTabItem()
|
||||
};
|
||||
|
||||
// Flags for ImGui::DockSpace()
|
||||
enum ImGuiDockFlags_
|
||||
{
|
||||
ImGuiDockFlags_None = 0,
|
||||
ImGuiDockFlags_NoSplit = 1 << 0
|
||||
};
|
||||
|
||||
// Flags for ImGui::IsWindowFocused()
|
||||
enum ImGuiFocusedFlags_
|
||||
{
|
||||
|
@ -704,6 +704,7 @@ struct ImGuiNextWindowData
|
||||
float BgAlphaVal;
|
||||
ImGuiID ViewportId;
|
||||
ImGuiID DockId;
|
||||
ImGuiID UserTypeId;
|
||||
ImVec2 MenuBarOffsetMinVal; // This is not exposed publicly, so we don't clear it.
|
||||
|
||||
ImGuiNextWindowData()
|
||||
@ -716,13 +717,14 @@ struct ImGuiNextWindowData
|
||||
SizeCallback = NULL;
|
||||
SizeCallbackUserData = NULL;
|
||||
BgAlphaVal = FLT_MAX;
|
||||
ViewportId = DockId = 0;
|
||||
ViewportId = DockId = UserTypeId = 0;
|
||||
MenuBarOffsetMinVal = ImVec2(0.0f, 0.0f);
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
PosCond = SizeCond = ContentSizeCond = CollapsedCond = SizeConstraintCond = FocusCond = BgAlphaCond = ViewportCond = DockCond = 0;
|
||||
UserTypeId = 0;
|
||||
}
|
||||
};
|
||||
|
||||
@ -740,6 +742,8 @@ struct ImGuiTabBarSortItem
|
||||
struct ImGuiDockNode
|
||||
{
|
||||
ImGuiID ID;
|
||||
ImGuiID UserTypeIdFilter;
|
||||
ImGuiDockFlags Flags;
|
||||
ImGuiDockNode* ParentNode;
|
||||
ImGuiDockNode* ChildNodes[2];
|
||||
ImVector<ImGuiWindow*> Windows; // Note: unordered list! Iterate TabBar->Tabs for user-order.
|
||||
@ -1200,6 +1204,7 @@ struct IMGUI_API ImGuiWindow
|
||||
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*)
|
||||
|
||||
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<ImGuiID> IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack
|
||||
@ -1457,8 +1462,8 @@ namespace ImGui
|
||||
IMGUI_API void DockContextShutdown(ImGuiContext* imgui_context);
|
||||
IMGUI_API void DockContextOnLoadSettings();
|
||||
IMGUI_API void DockContextRebuild(ImGuiDockContext* ctx);
|
||||
IMGUI_API void DockContextUpdateUndocking(ImGuiDockContext* ctx);
|
||||
IMGUI_API void DockContextUpdateDocking(ImGuiDockContext* ctx);
|
||||
IMGUI_API void DockContextNewFrameUpdateUndocking(ImGuiDockContext* ctx);
|
||||
IMGUI_API void DockContextNewFrameUpdateDocking(ImGuiDockContext* ctx);
|
||||
IMGUI_API void DockContextQueueUndock(ImGuiDockContext* ctx, ImGuiWindow* window);
|
||||
IMGUI_API void BeginDocked(ImGuiWindow* window, bool* p_open);
|
||||
IMGUI_API void BeginAsDockableDragDropSource(ImGuiWindow* window);
|
||||
|
Loading…
Reference in New Issue
Block a user