From bd82539ad595fcf3b0c2c28058f1a74b585a2415 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 3 Oct 2018 11:24:52 +0200 Subject: [PATCH] Docking: Fixed DockSpace() child window displaying a scrollbar behind the node backgrounds. Rename ImGuiCol_DockingBg to ImGuiCol_DockingEmptyBg. Added ImGuiDockNode::IsLeaftNode(). (#2109) --- docs/CHANGELOG.txt | 2 +- imgui.cpp | 28 +++++++++++++--------------- imgui.h | 2 +- imgui_demo.cpp | 2 -- imgui_draw.cpp | 6 +++--- imgui_internal.h | 1 + 6 files changed, 19 insertions(+), 22 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 53bb92d82..21a7ae8b5 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -47,7 +47,7 @@ HOW TO UPDATE? - Added ImGuiWindowFlags_UnsavedDocument window flag to append '*' to title without altering the ID, as a convenience to avoid using the ### operator. - Added io.ConfigDockingWithShift option to configure docking mode. -- Style: Added ImGuiCol_DockingPreview, ImGuiCol_DockingBg colors. (#351) +- Style: Added ImGuiCol_DockingPreview, ImGuiCol_DockingEmptyBg colors. (#351) - Style: Added ImGuiCol_Tab, ImGuiCol_TabHovered, ImGuiCol_TabActive, ImGuiCol_TabUnfocused, ImGuiCol_TabUnfocusedActive colors. (#261, #351) - Demo: Added Layout->Tabs demo code. (#261, #351) - Demo: Added "Documents" example app showcasing possible use for tabs. (#261, #351) diff --git a/imgui.cpp b/imgui.cpp index c17e0b0df..4ae4cec72 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6040,7 +6040,7 @@ const char* ImGui::GetStyleColorName(ImGuiCol idx) case ImGuiCol_TabUnfocused: return "TabUnfocused"; case ImGuiCol_TabUnfocusedActive: return "TabUnfocusedActive"; case ImGuiCol_DockingPreview: return "DockingPreview"; - case ImGuiCol_DockingBg: return "DockingBg"; + case ImGuiCol_DockingEmptyBg: return "DockingEmptyBg"; case ImGuiCol_PlotLines: return "PlotLines"; case ImGuiCol_PlotLinesHovered: return "PlotLinesHovered"; case ImGuiCol_PlotHistogram: return "PlotHistogram"; @@ -10059,7 +10059,7 @@ void ImGui::DockContextProcessDock(ImGuiContext* ctx, ImGuiDockRequest* req) { payload_node = payload_window->DockNodeAsHost; payload_window->DockNodeAsHost = NULL; // Important to clear this as the node will have its life as a child which might be merged/deleted later. - if (payload_node && !payload_node->IsSplitNode()) + if (payload_node && payload_node->IsLeafNode()) next_selected_id = payload_node->TabBar->NextSelectedTabId ? payload_node->TabBar->NextSelectedTabId : payload_node->TabBar->SelectedTabId; if (payload_node == NULL) next_selected_id = payload_window->ID; @@ -10177,7 +10177,7 @@ void ImGui::DockContextProcessUndockWindow(ImGuiContext* ctx, ImGuiWindow* windo void ImGui::DockContextProcessUndockNode(ImGuiContext* ctx, ImGuiDockNode* node) { (void)ctx; - IM_ASSERT(!node->IsSplitNode()); + IM_ASSERT(node->IsLeafNode()); IM_ASSERT(node->Windows.Size >= 1); // In the case of a root node or document root, the node will have to stay in place. Create a new node to receive the payload. @@ -10545,7 +10545,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->IsSplitNode() && node->Windows.Size <= 1 && !node->IsDockSpace) + if (node->IsRootNode() && node->IsLeafNode() && node->Windows.Size <= 1 && !node->IsDockSpace) { if (node->Windows.Size == 1) { @@ -10649,14 +10649,11 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node) DockNodeStartMouseMovingWindow(node, node->HostWindow); } - // Update active node (the one whose title bar is highlight) within a node tree + // Update focused node (the one whose title bar is highlight) within a node tree if (node->IsSplitNode()) IM_ASSERT(node->TabBar == NULL); if (node->IsRootNode()) { - //if (!node->IsSplitNode()) - // node->LastFocusedNodeID = node->ID; // This also ensure on our creation frame we will receive the title screen highlight - //else if (g.NavWindow && g.NavWindow->RootWindowDockStop->DockNode && g.NavWindow->RootWindowDockStop->ParentWindow == host_window) node->LastFocusedNodeID = g.NavWindow->RootWindowDockStop->DockNode->ID; } @@ -10679,7 +10676,7 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node) { // Background for empty nodes if (node->Windows.Size == 0 && !node->IsSplitNode()) - host_window->DrawList->AddRectFilled(node->Pos, node->Pos + node->Size, GetColorU32(ImGuiCol_DockingBg)); + host_window->DrawList->AddRectFilled(node->Pos, node->Pos + node->Size, GetColorU32(ImGuiCol_DockingEmptyBg)); // Drop target if (node->IsRootNode() && (g.MovingWindow == NULL || g.MovingWindow->RootWindow != host_window)) @@ -11285,7 +11282,7 @@ void ImGui::DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 si { node->Pos = pos; node->Size = size; - if (!node->IsSplitNode()) + if (node->IsLeafNode()) return; ImGuiDockNode* child_0 = node->ChildNodes[0]; @@ -11347,7 +11344,7 @@ void ImGui::DockNodeTreeUpdatePosSize(ImGuiDockNode* node, ImVec2 pos, ImVec2 si static void DockNodeTreeUpdateSplitterFindTouchingNode(ImGuiDockNode* node, ImGuiAxis axis, int side, ImVector* touching_nodes) { - if (!node->IsSplitNode()) + if (node->IsLeafNode()) { touching_nodes->push_back(node); return; @@ -11362,7 +11359,7 @@ static void DockNodeTreeUpdateSplitterFindTouchingNode(ImGuiDockNode* node, ImGu void ImGui::DockNodeTreeUpdateSplitter(ImGuiDockNode* node) { - if (!node->IsSplitNode()) + if (node->IsLeafNode()) return; ImGuiContext& g = *GImGui; @@ -11483,7 +11480,7 @@ ImGuiDockNode* ImGui::DockNodeTreeFindNodeByPos(ImGuiDockNode* node, ImVec2 pos) if (!inside) return NULL; - if (!node->IsSplitNode()) + if (node->IsLeafNode()) return node; if (ImGuiDockNode* hovered_node = DockNodeTreeFindNodeByPos(node->ChildNodes[0], pos)) return hovered_node; @@ -11562,6 +11559,7 @@ void ImGui::DockSpace(ImGuiID id, const ImVec2& size_arg, ImGuiDockNodeFlags doc ImGuiWindowFlags window_flags = ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_DockNodeHost; window_flags |= ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoTitleBar; + window_flags |= ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse; char title[256]; ImFormatString(title, IM_ARRAYSIZE(title), "%s/DockSpace_%08X", window->Name, id); @@ -11733,7 +11731,7 @@ ImGuiID ImGui::DockBuilderSplitNode(ImGuiContext* ctx, ImGuiID id, ImGuiDir spli return 0; } - IM_ASSERT(!node->IsSplitNode()); // Already Split + IM_ASSERT(!node->IsSplitNode()); // Assert if already Split ImGuiDockRequest req; req.Type = ImGuiDockRequestType_Split; @@ -11981,7 +11979,7 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open) } IM_ASSERT(dock_node->HostWindow); - IM_ASSERT(!dock_node->IsSplitNode()); + IM_ASSERT(dock_node->IsLeafNode()); // Position window SetNextWindowPos(dock_node->Pos); diff --git a/imgui.h b/imgui.h index b8b563f3a..6527623c0 100644 --- a/imgui.h +++ b/imgui.h @@ -1015,7 +1015,7 @@ enum ImGuiCol_ ImGuiCol_TabUnfocused, ImGuiCol_TabUnfocusedActive, ImGuiCol_DockingPreview, - ImGuiCol_DockingBg, // Empty node + ImGuiCol_DockingEmptyBg, // Background color for empty node (e.g. DocRoot node with no window docked into it) ImGuiCol_PlotLines, ImGuiCol_PlotLinesHovered, ImGuiCol_PlotHistogram, diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 27c87c07d..ef9d680e4 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -3765,10 +3765,8 @@ void ShowExampleAppDockSpace(bool* p_open) ImGuiIO& io = ImGui::GetIO(); if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable) { - //ImGui::PushStyleColor(ImGuiCol_DockingBg, ImVec4(0.2f, 0.2f, 0.2f, 1.0f)); ImGuiID dockspace_id = ImGui::GetID("MyDockspace"); ImGui::DockSpace(dockspace_id); - //ImGui::PopStyleColor(); } else { diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 2a45b2e60..8a48bd4f9 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -211,7 +211,7 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst) colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f); colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered]; colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_HeaderActive] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f); - colors[ImGuiCol_DockingBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);; + colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);; colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); @@ -268,7 +268,7 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst) colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f); colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered]; colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_Header] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f); - colors[ImGuiCol_DockingBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);; + colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);; colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); @@ -326,7 +326,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst) colors[ImGuiCol_TabUnfocusedActive] = ImLerp(colors[ImGuiCol_TabActive], colors[ImGuiCol_TitleBg], 0.40f); colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered]; colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_Header] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f); - colors[ImGuiCol_DockingBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);; + colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);; colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); diff --git a/imgui_internal.h b/imgui_internal.h index 42a6564ae..76ec1b351 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -778,6 +778,7 @@ struct ImGuiDockNode ~ImGuiDockNode(); bool IsRootNode() const { return ParentNode == NULL; } bool IsSplitNode() const { return ChildNodes[0] != NULL; } + bool IsLeafNode() const { return ChildNodes[0] == NULL; } bool IsEmpty() const { return ChildNodes[0] == NULL && Windows.Size == 0; } ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); } };