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:
omar 2018-12-04 13:36:36 +01:00
parent 8cac70d8af
commit 6644f1ff64
4 changed files with 51 additions and 20 deletions

View File

@ -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,11 +4984,16 @@ 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)
{
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
ImGuiWindow* parent_window_in_stack = window->DockIsActive ? window->DockNode->HostWindow : g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back();
@ -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,6 +12294,18 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
ImGuiContext* ctx = GImGui;
ImGuiContext& g = *ctx;
const bool auto_dock_node = (g.IO.ConfigDockingTabBarOnSingleWindows) && !(window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoDocking));
if (auto_dock_node)
{
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;
@ -12298,6 +12316,7 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
DockContextProcessUndockWindow(ctx, window);
return;
}
}
// Bind to our dock node
ImGuiDockNode* dock_node = window->DockNode;
@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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;