Docking: Added io.ConfigDockingTabBarOnSingleWindows option (mostly made possible by the previous fixes).
Note that dock node have regressions compared to current floating window: no collapse, no auto-resize, resize grip under the scrollbar, border issues, general overhead. Will tackle those.
This commit is contained in:
parent
8cac70d8af
commit
6644f1ff64
47
imgui.cpp
47
imgui.cpp
@ -4935,6 +4935,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
// Find or create
|
||||
ImGuiWindow* window = FindWindowByName(name);
|
||||
const bool window_just_created = (window == NULL);
|
||||
const bool window_is_fallback = (g.CurrentWindowStack.Size == 0);
|
||||
if (window_just_created)
|
||||
{
|
||||
ImVec2 size_on_first_use = (g.NextWindowData.SizeCond != 0) ? g.NextWindowData.SizeVal : ImVec2(0.0f, 0.0f); // Any condition flag will do since we are creating a new window here.
|
||||
@ -4983,10 +4984,15 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
IM_ASSERT(window->DockNode == NULL || window->DockNodeAsHost == NULL); // Cannot be both
|
||||
if (g.NextWindowData.DockCond)
|
||||
SetWindowDock(window, g.NextWindowData.DockId, g.NextWindowData.DockCond);
|
||||
if (first_begin_of_the_frame && (window->DockId != 0 || window->DockNode != NULL))
|
||||
if (first_begin_of_the_frame)
|
||||
{
|
||||
BeginDocked(window, p_open);
|
||||
flags = window->Flags;
|
||||
bool has_dock_node = (window->DockId != 0 || window->DockNode != NULL);
|
||||
bool new_auto_dock_node = !has_dock_node && g.IO.ConfigDockingTabBarOnSingleWindows && !(flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoDocking)) && !window_is_fallback;
|
||||
if (has_dock_node || new_auto_dock_node)
|
||||
{
|
||||
BeginDocked(window, p_open);
|
||||
flags = window->Flags;
|
||||
}
|
||||
}
|
||||
|
||||
// Parent window is latched only on the first call to Begin() of the frame, so further append-calls can be done from a different window stack
|
||||
@ -10247,7 +10253,7 @@ void ImGui::DockContextProcessDock(ImGuiContext* ctx, ImGuiDockRequest* req)
|
||||
if (target_node)
|
||||
IM_ASSERT(target_node->LastFrameAlive < g.FrameCount);
|
||||
if (target_node && target_window && target_node == target_window->DockNodeAsHost)
|
||||
IM_ASSERT(target_node->Windows.Size > 1 || target_node->IsSplitNode() || target_node->IsCentralNode);
|
||||
IM_ASSERT(target_node->Windows.Size > 0 || target_node->IsSplitNode() || target_node->IsCentralNode);
|
||||
|
||||
// Create new node and add existing window to it
|
||||
if (target_node == NULL)
|
||||
@ -10758,7 +10764,7 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node)
|
||||
}
|
||||
|
||||
// Early out for hidden root dock nodes (when all DockId references are in inactive windows, or there is only 1 floating window holding on the DockId)
|
||||
if (node->IsRootNode() && node->IsLeafNode() && node->Windows.Size <= 1 && !node->IsDockSpace)
|
||||
if (node->Windows.Size <= 1 && node->IsRootNode() && node->IsLeafNode() && !node->IsDockSpace && !g.IO.ConfigDockingTabBarOnSingleWindows)
|
||||
{
|
||||
if (node->Windows.Size == 1)
|
||||
{
|
||||
@ -12288,15 +12294,28 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
|
||||
ImGuiContext* ctx = GImGui;
|
||||
ImGuiContext& g = *ctx;
|
||||
|
||||
// Calling SetNextWindowPos() undock windows by default (by setting PosUndock)
|
||||
bool want_undock = false;
|
||||
want_undock |= (window->Flags & ImGuiWindowFlags_NoDocking) != 0;
|
||||
want_undock |= (g.NextWindowData.PosCond && (window->SetWindowPosAllowFlags & g.NextWindowData.PosCond) && g.NextWindowData.PosUndock);
|
||||
g.NextWindowData.PosUndock = false;
|
||||
if (want_undock)
|
||||
const bool auto_dock_node = (g.IO.ConfigDockingTabBarOnSingleWindows) && !(window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoDocking));
|
||||
|
||||
if (auto_dock_node)
|
||||
{
|
||||
DockContextProcessUndockWindow(ctx, window);
|
||||
return;
|
||||
if (window->DockId == 0)
|
||||
{
|
||||
IM_ASSERT(window->DockNode == NULL);
|
||||
window->DockId = DockContextGenNodeID(ctx);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calling SetNextWindowPos() undock windows by default (by setting PosUndock)
|
||||
bool want_undock = false;
|
||||
want_undock |= (window->Flags & ImGuiWindowFlags_NoDocking) != 0;
|
||||
want_undock |= (g.NextWindowData.PosCond && (window->SetWindowPosAllowFlags & g.NextWindowData.PosCond) && g.NextWindowData.PosUndock);
|
||||
g.NextWindowData.PosUndock = false;
|
||||
if (want_undock)
|
||||
{
|
||||
DockContextProcessUndockWindow(ctx, window);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Bind to our dock node
|
||||
@ -12337,7 +12356,7 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
|
||||
|
||||
// Undock if our dockspace node disappeared
|
||||
// Note how we are testing for LastFrameAlive and NOT LastFrameActive. A DockSpace node can be maintained alive while being inactive with ImGuiDockNodeFlags_KeepAliveOnly.
|
||||
if (dock_node->LastFrameAlive < g.FrameCount)
|
||||
if (dock_node->LastFrameAlive < g.FrameCount && !auto_dock_node)
|
||||
{
|
||||
// If the window has been orphaned, transition the docknode to an implicit node processed in DockContextUpdateDocking()
|
||||
ImGuiDockNode* root_node = DockNodeGetRootNode(dock_node);
|
||||
|
1
imgui.h
1
imgui.h
@ -1278,6 +1278,7 @@ struct ImGuiIO
|
||||
// Miscellaneous configuration options
|
||||
bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by back-end implementations.
|
||||
bool ConfigDockingWithShift; // = false // Enable docking with holding Shift key (reduce visual noise, allows dropping in wider space)
|
||||
bool ConfigDockingTabBarOnSingleWindows;//= false // [BETA] Make every single floating window display within a docking node.
|
||||
bool ConfigDockingTransparentPayload; // = false // [BETA] Make window or viewport transparent when docking and only display docking boxes on the target viewport. Useful if rendering of multiple viewport can be synced. Best used with ImGuiConfigFlags_ViewportsNoMerge.
|
||||
bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl (was called io.OptMacOSXBehaviors prior to 1.63)
|
||||
bool ConfigInputTextCursorBlink; // = true // Set to false to disable blinking cursor, for users who consider it distracting. (was called: io.OptCursorBlink prior to 1.63)
|
||||
|
@ -353,6 +353,8 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
|
||||
ImGui::Checkbox("io.ConfigDockingWithShift", &io.ConfigDockingWithShift);
|
||||
ImGui::SameLine(); ShowHelpMarker("Enable docking when holding Shift only (allows to drop in wider space, reduce visual noise)");
|
||||
ImGui::Checkbox("io.ConfigDockingTabBarOnSingleWindows", &io.ConfigDockingTabBarOnSingleWindows);
|
||||
ImGui::SameLine(); ShowHelpMarker("Associate a docking node and tab-bar to sinle floating windows.");
|
||||
ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink);
|
||||
ImGui::SameLine(); ShowHelpMarker("Set to false to disable blinking cursor, for users who consider it distracting");
|
||||
ImGui::Checkbox("io.ConfigResizeWindowsFromEdges [beta]", &io.ConfigResizeWindowsFromEdges);
|
||||
|
@ -6452,9 +6452,19 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
if (!held)
|
||||
SetItemAllowOverlap();
|
||||
|
||||
// Drag and drop
|
||||
if (held && !tab_appearing && IsMouseDragging())
|
||||
// Drag and drop a single floating window node moves it
|
||||
// FIXME-DOCK: In theory we shouldn't test for the ConfigDockingNodifySingleWindows flag here.
|
||||
// When our single window node and OnlyNodeWithWindows are working properly we may remove this check here.
|
||||
ImGuiDockNode* node = docked_window->DockNode;
|
||||
const bool single_window_node = node->IsRootNode() && node->Windows.Size == 1 && g.IO.ConfigDockingTabBarOnSingleWindows;
|
||||
if (held && single_window_node && IsMouseDragging(0, 0.0f))
|
||||
{
|
||||
// Move
|
||||
StartMouseMovingWindow(docked_window);
|
||||
}
|
||||
else if (held && !tab_appearing && IsMouseDragging(0))
|
||||
{
|
||||
// Drag and drop
|
||||
// Re-order local or dockable tabs
|
||||
float drag_distance_from_edge_x = 0.0f;
|
||||
if (!g.DragDropActive && ((tab_bar->Flags & ImGuiTabBarFlags_Reorderable) || (flags & ImGuiTabItemFlags_DockedWindow)))
|
||||
@ -6478,9 +6488,8 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
if (flags & ImGuiTabItemFlags_DockedWindow)
|
||||
{
|
||||
// We use a variable threshold to distinguish dragging tabs within a tab bar and extracting them out of the tab bar
|
||||
//ImVec2 drag_delta = GetMouseDragDelta();
|
||||
bool undocking_tab = (g.DragDropActive && g.DragDropPayload.SourceId == id);
|
||||
if (!undocking_tab && held)// && (drag_delta.x != 0.0f || drag_delta.y != 0.0f))
|
||||
if (!undocking_tab && held)
|
||||
{
|
||||
//if (!g.IO.ConfigDockingWithShift || g.IO.KeyShift)
|
||||
{
|
||||
@ -6499,9 +6508,9 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
}
|
||||
}
|
||||
|
||||
// Undock
|
||||
if (undocking_tab && g.ActiveId == id && IsMouseDragging())
|
||||
if (undocking_tab)
|
||||
{
|
||||
// Undock
|
||||
DockContextQueueUndockWindow(&g, docked_window);
|
||||
g.MovingWindow = docked_window;
|
||||
g.ActiveId = g.MovingWindow->MoveId;
|
||||
|
Loading…
Reference in New Issue
Block a user