mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-30 20:51:06 +01:00 
			
		
		
		
	Docking: Clarified terminology of docking/tablist/collapse button into Window Menu button matching master. Added private ImGuiDockNodeFlags_NoWindowMenuButton, ImGuiDockNodeFlags_NoCloseButton flags. (#2583, #2109)
This commit is contained in:
		
							
								
								
									
										86
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										86
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -5438,6 +5438,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar | ||||
| } | ||||
|  | ||||
| // Render title text, collapse button, close button | ||||
| // When inside a dock node, this is handled in DockNodeUpdateTabBar() instead. | ||||
| void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
| @@ -5447,7 +5448,7 @@ void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& titl | ||||
|     const bool has_close_button = (p_open != NULL); | ||||
|     const bool has_collapse_button = !(flags & ImGuiWindowFlags_NoCollapse); | ||||
|  | ||||
|     // Close & collapse button are on the Menu NavLayer and don't default focus (unless there's nothing else on that layer) | ||||
|     // Close & Collapse button are on the Menu NavLayer and don't default focus (unless there's nothing else on that layer) | ||||
|     const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags; | ||||
|     window->DC.ItemFlags |= ImGuiItemFlags_NoNavDefaultFocus; | ||||
|     window->DC.NavLayerCurrent = ImGuiNavLayer_Menu; | ||||
| @@ -11119,13 +11120,13 @@ namespace ImGui | ||||
|     static void             DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_window); | ||||
|     static void             DockNodeAddTabBar(ImGuiDockNode* node); | ||||
|     static void             DockNodeRemoveTabBar(ImGuiDockNode* node); | ||||
|     static ImGuiID          DockNodeUpdateTabListMenu(ImGuiDockNode* node, ImGuiTabBar* tab_bar); | ||||
|     static ImGuiID          DockNodeUpdateWindowMenu(ImGuiDockNode* node, ImGuiTabBar* tab_bar); | ||||
|     static void             DockNodeUpdateVisibleFlag(ImGuiDockNode* node); | ||||
|     static void             DockNodeStartMouseMovingWindow(ImGuiDockNode* node, ImGuiWindow* window); | ||||
|     static bool             DockNodeIsDropAllowed(ImGuiWindow* host_window, ImGuiWindow* payload_window); | ||||
|     static void             DockNodePreviewDockCalc(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* payload_window, ImGuiDockPreviewData* preview_data, bool is_explicit_target, bool is_outer_docking); | ||||
|     static void             DockNodePreviewDockRender(ImGuiWindow* host_window, ImGuiDockNode* host_node, ImGuiWindow* payload_window, const ImGuiDockPreviewData* preview_data); | ||||
|     static void             DockNodeCalcTabBarLayout(const ImGuiDockNode* node, ImRect* out_title_rect, ImRect* out_tab_bar_rect, ImVec2* out_collapse_button_pos); | ||||
|     static void             DockNodeCalcTabBarLayout(const ImGuiDockNode* node, ImRect* out_title_rect, ImRect* out_tab_bar_rect, ImVec2* out_window_menu_button_pos); | ||||
|     static void             DockNodeCalcSplitRects(ImVec2& pos_old, ImVec2& size_old, ImVec2& pos_new, ImVec2& size_new, ImGuiDir dir, ImVec2 size_new_desired); | ||||
|     static bool             DockNodeCalcDropRectsAndTestMousePos(const ImRect& parent, ImGuiDir dir, ImRect& out_draw, bool outer_docking, ImVec2* test_mouse_pos); | ||||
|     static const char*      DockNodeGetHostWindowTitle(ImGuiDockNode* node, char* buf, int buf_size) { ImFormatString(buf, buf_size, "##DockNode_%02X", node->ID); return buf; } | ||||
| @@ -11713,7 +11714,7 @@ ImGuiDockNode::ImGuiDockNode(ImGuiID id) | ||||
|     AuthorityForPos = AuthorityForSize = ImGuiDataAuthority_DockNode; | ||||
|     AuthorityForViewport = ImGuiDataAuthority_Auto; | ||||
|     IsVisible = true; | ||||
|     IsFocused = HasCloseButton = HasCollapseButton = false; | ||||
|     IsFocused = HasCloseButton = HasWindowMenuButton = EnableCloseButton = false; | ||||
|     WantCloseAll = WantLockSizeOnce = WantMouseMove = WantHiddenTabBarUpdate = WantHiddenTabBarToggle = false; | ||||
| } | ||||
|  | ||||
| @@ -12112,7 +12113,7 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node) | ||||
|         DockNodeHideHostWindow(node); | ||||
|         node->WantCloseAll = false; | ||||
|         node->WantCloseTabID = 0; | ||||
|         node->HasCloseButton = node->HasCollapseButton = false; | ||||
|         node->HasCloseButton = node->HasWindowMenuButton = node->EnableCloseButton = false; | ||||
|         node->LastFrameActive = g.FrameCount; | ||||
|  | ||||
|         if (node->WantMouseMove && node->Windows.Size == 1) | ||||
| @@ -12120,27 +12121,31 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node) | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     const ImGuiDockNodeFlags node_flags = node->GetMergedFlags(); | ||||
|  | ||||
|     ImGuiWindow* host_window = NULL; | ||||
|     bool beginned_into_host_window = false; | ||||
|     if (node->IsDockSpace()) | ||||
|     { | ||||
|         // [Explicit root dockspace node] | ||||
|         IM_ASSERT(node->HostWindow); | ||||
|         node->HasCloseButton = false; | ||||
|         node->HasCollapseButton = true; | ||||
|         node->EnableCloseButton = false; | ||||
|         node->HasCloseButton = (node_flags & ImGuiDockNodeFlags_NoCloseButton) == 0; | ||||
|         node->HasWindowMenuButton = (node_flags & ImGuiDockNodeFlags_NoWindowMenuButton) == 0; | ||||
|         host_window = node->HostWindow; | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         // [Automatic root or child nodes] | ||||
|         node->HasCloseButton = false; | ||||
|         node->HasCollapseButton = (node->Windows.Size > 0); | ||||
|         node->EnableCloseButton = false; | ||||
|         node->HasCloseButton = (node->Windows.Size > 0) && (node_flags & ImGuiDockNodeFlags_NoWindowMenuButton) == 0; | ||||
|         node->HasWindowMenuButton = (node->Windows.Size > 0) && (node_flags & ImGuiDockNodeFlags_NoWindowMenuButton) == 0; | ||||
|         for (int window_n = 0; window_n < node->Windows.Size; window_n++) | ||||
|         { | ||||
|             // FIXME-DOCK: Setting DockIsActive here means that for single active window in a leaf node, DockIsActive will be cleared until the next Begin() call. | ||||
|             ImGuiWindow* window = node->Windows[window_n]; | ||||
|             window->DockIsActive = (node->Windows.Size > 1); | ||||
|             node->HasCloseButton |= window->HasCloseButton; | ||||
|             node->EnableCloseButton |= window->HasCloseButton; | ||||
|         } | ||||
|  | ||||
|         if (node->IsRootNode() && node->IsVisible) | ||||
| @@ -12217,7 +12222,6 @@ static void ImGui::DockNodeUpdate(ImGuiDockNode* node) | ||||
|  | ||||
|     // We need to draw a background at the root level if requested by ImGuiDockNodeFlags_PassthruCentralNode, but we will only know the correct pos/size after | ||||
|     // processing the resizing splitters. So we are using the DrawList channel splitting facility to submit drawing primitives out of order! | ||||
|     const ImGuiDockNodeFlags node_flags = node->GetMergedFlags(); | ||||
|     const bool render_dockspace_bg = node->IsRootNode() && host_window && (node_flags & ImGuiDockNodeFlags_PassthruCentralNode) != 0; | ||||
|     if (render_dockspace_bg) | ||||
|     { | ||||
| @@ -12319,7 +12323,7 @@ static int IMGUI_CDECL TabItemComparerByDockOrder(const void* lhs, const void* r | ||||
|     return (a->BeginOrderWithinContext - b->BeginOrderWithinContext); | ||||
| } | ||||
|  | ||||
| static ImGuiID ImGui::DockNodeUpdateTabListMenu(ImGuiDockNode* node, ImGuiTabBar* tab_bar) | ||||
| static ImGuiID ImGui::DockNodeUpdateWindowMenu(ImGuiDockNode* node, ImGuiTabBar* tab_bar) | ||||
| { | ||||
|     // Try to position the menu so it is more likely to stays within the same viewport | ||||
|     ImGuiContext& g = *GImGui; | ||||
| @@ -12328,7 +12332,7 @@ static ImGuiID ImGui::DockNodeUpdateTabListMenu(ImGuiDockNode* node, ImGuiTabBar | ||||
|         SetNextWindowPos(ImVec2(node->Pos.x, node->Pos.y + GetFrameHeight()), ImGuiCond_Always, ImVec2(0.0f, 0.0f)); | ||||
|     else | ||||
|         SetNextWindowPos(ImVec2(node->Pos.x + node->Size.x, node->Pos.y + GetFrameHeight()), ImGuiCond_Always, ImVec2(1.0f, 0.0f)); | ||||
|     if (BeginPopup("#TabListMenu")) | ||||
|     if (BeginPopup("#WindowMenu")) | ||||
|     { | ||||
|         node->IsFocused = true; | ||||
|         if (tab_bar->Tabs.Size == 1) | ||||
| @@ -12414,19 +12418,23 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w | ||||
|     ImGuiID focus_tab_id = 0; | ||||
|     node->IsFocused = is_focused; | ||||
|  | ||||
|     // Collapse button changes shape and display a list | ||||
|     // FIXME-DOCK: Could we recycle popups id? | ||||
|     if (IsPopupOpen("#TabListMenu")) | ||||
|     const ImGuiDockNodeFlags node_flags = node->GetMergedFlags(); | ||||
|     const bool has_window_menu_button = (node_flags & ImGuiDockNodeFlags_NoWindowMenuButton) == 0; | ||||
|     const bool has_close_button = (node_flags & ImGuiDockNodeFlags_NoCloseButton) == 0; | ||||
|  | ||||
|     // In a dock node, the Collapse Button turns into the Window Menu button. | ||||
|     // FIXME-DOCK FIXME-OPT: Could we recycle popups id accross multiple dock nodes? | ||||
|     if (has_window_menu_button && IsPopupOpen("#WindowMenu")) | ||||
|     { | ||||
|         if (ImGuiID tab_id = DockNodeUpdateTabListMenu(node, tab_bar)) | ||||
|         if (ImGuiID tab_id = DockNodeUpdateWindowMenu(node, tab_bar)) | ||||
|             focus_tab_id = tab_bar->NextSelectedTabId = tab_id; | ||||
|         is_focused |= node->IsFocused; | ||||
|     } | ||||
|  | ||||
|     // Layout | ||||
|     ImRect title_bar_rect, tab_bar_rect; | ||||
|     ImVec2 collapse_button_pos; | ||||
|     DockNodeCalcTabBarLayout(node, &title_bar_rect, &tab_bar_rect, &collapse_button_pos); | ||||
|     ImVec2 window_menu_button_pos; | ||||
|     DockNodeCalcTabBarLayout(node, &title_bar_rect, &tab_bar_rect, &window_menu_button_pos); | ||||
|  | ||||
|     // Title bar | ||||
|     if (is_focused) | ||||
| @@ -12434,11 +12442,14 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w | ||||
|     ImU32 title_bar_col = GetColorU32(host_window->Collapsed ? ImGuiCol_TitleBgCollapsed : is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg); | ||||
|     host_window->DrawList->AddRectFilled(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, host_window->WindowRounding, ImDrawCornerFlags_Top); | ||||
|  | ||||
|     // Collapse button | ||||
|     if (CollapseButton(host_window->GetID("#COLLAPSE"), collapse_button_pos, node)) | ||||
|         OpenPopup("#TabListMenu"); | ||||
|     if (IsItemActive()) | ||||
|         focus_tab_id = tab_bar->SelectedTabId; | ||||
|     // Docking/Collapse button | ||||
|     if (has_window_menu_button) | ||||
|     { | ||||
|         if (CollapseButton(host_window->GetID("#COLLAPSE"), window_menu_button_pos, node)) | ||||
|             OpenPopup("#WindowMenu"); | ||||
|         if (IsItemActive()) | ||||
|             focus_tab_id = tab_bar->SelectedTabId; | ||||
|     } | ||||
|  | ||||
|     // Submit new tabs and apply NavWindow focus back to the tab bar. They will be added as Unsorted and sorted below based on relative DockOrder value. | ||||
|     const int tabs_count_old = tab_bar->Tabs.Size; | ||||
| @@ -12515,7 +12526,7 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w | ||||
|  | ||||
|     // Close button (after VisibleWindow was updated) | ||||
|     // Note that VisibleWindow may have been overrided by CTRL+Tabbing, so VisibleWindow->ID may be != from tab_bar->SelectedTabId | ||||
|     if (node->VisibleWindow) | ||||
|     if (has_close_button && node->VisibleWindow) | ||||
|     { | ||||
|         if (!node->VisibleWindow->HasCloseButton) | ||||
|         { | ||||
| @@ -12628,27 +12639,32 @@ static bool ImGui::DockNodeIsDropAllowed(ImGuiWindow* host_window, ImGuiWindow* | ||||
|     return false; | ||||
| } | ||||
|  | ||||
| // window menu button == collapse button when not in a dock node. | ||||
| // FIXME: This is similar to RenderWindowTitleBarContents, may want to share code. | ||||
| static void ImGui::DockNodeCalcTabBarLayout(const ImGuiDockNode* node, ImRect* out_title_rect, ImRect* out_tab_bar_rect, ImVec2* out_collapse_button_pos) | ||||
| static void ImGui::DockNodeCalcTabBarLayout(const ImGuiDockNode* node, ImRect* out_title_rect, ImRect* out_tab_bar_rect, ImVec2* out_window_menu_button_pos) | ||||
| { | ||||
|     ImGuiContext& g = *GImGui; | ||||
|     ImRect r = ImRect(node->Pos.x, node->Pos.y, node->Pos.x + node->Size.x, node->Pos.y + g.FontSize + g.Style.FramePadding.y * 2.0f); | ||||
|     if (out_title_rect) { *out_title_rect = r; } | ||||
|  | ||||
|     ImVec2 collapse_button_pos = r.Min; | ||||
|     r.Max.x -= g.Style.FramePadding.x + g.FontSize;// +1.0f; // In DockNodeUpdateTabBar() we currently display a disabled close button even if there is none. | ||||
|     if (node->HasCollapseButton && g.Style.WindowMenuButtonPosition == ImGuiDir_Left) | ||||
|     ImVec2 window_menu_button_pos = r.Min; | ||||
|     r.Min.x += g.Style.FramePadding.x; | ||||
|     r.Max.x -= g.Style.FramePadding.x; | ||||
|     if (node->HasCloseButton) | ||||
|     { | ||||
|         r.Min.x += g.Style.FramePadding.x + g.FontSize; // + g.Style.ItemInnerSpacing.x; // <-- Adding ItemInnerSpacing makes the title text moves slightly when in a docking tab bar. Instead we adjusted RenderArrowDockMenu() | ||||
|         r.Max.x -= g.FontSize;// +1.0f; // In DockNodeUpdateTabBar() we currently display a disabled close button even if there is none. | ||||
|     } | ||||
|     else if (node->HasCollapseButton && g.Style.WindowMenuButtonPosition == ImGuiDir_Right) | ||||
|     if (node->HasWindowMenuButton && g.Style.WindowMenuButtonPosition == ImGuiDir_Left) | ||||
|     { | ||||
|         r.Min.x += g.FontSize; // + g.Style.ItemInnerSpacing.x; // <-- Adding ItemInnerSpacing makes the title text moves slightly when in a docking tab bar. Instead we adjusted RenderArrowDockMenu() | ||||
|     } | ||||
|     else if (node->HasWindowMenuButton && g.Style.WindowMenuButtonPosition == ImGuiDir_Right) | ||||
|     { | ||||
|         r.Min.x += g.Style.FramePadding.x; | ||||
|         r.Max.x -= g.FontSize + g.Style.FramePadding.x; | ||||
|         collapse_button_pos = ImVec2(r.Max.x, r.Min.y); | ||||
|         window_menu_button_pos = ImVec2(r.Max.x, r.Min.y); | ||||
|     } | ||||
|     if (out_tab_bar_rect) { *out_tab_bar_rect = r; } | ||||
|     if (out_collapse_button_pos) { *out_collapse_button_pos = collapse_button_pos; } | ||||
|     if (out_window_menu_button_pos) { *out_window_menu_button_pos = window_menu_button_pos; } | ||||
| } | ||||
|  | ||||
| void ImGui::DockNodeCalcSplitRects(ImVec2& pos_old, ImVec2& size_old, ImVec2& pos_new, ImVec2& size_new, ImGuiDir dir, ImVec2 size_new_desired) | ||||
| @@ -12751,7 +12767,7 @@ static void ImGui::DockNodePreviewDockCalc(ImGuiWindow* host_window, ImGuiDockNo | ||||
|  | ||||
|     // Build a tentative future node (reuse same structure because it is practical) | ||||
|     data->FutureNode.HasCloseButton = (host_node ? host_node->HasCloseButton : host_window->HasCloseButton) || (root_payload->HasCloseButton); | ||||
|     data->FutureNode.HasCollapseButton = host_node ? true : ((host_window->Flags & ImGuiWindowFlags_NoCollapse) == 0); | ||||
|     data->FutureNode.HasWindowMenuButton = host_node ? true : ((host_window->Flags & ImGuiWindowFlags_NoCollapse) == 0); | ||||
|     data->FutureNode.Pos = host_node ? ref_node_for_rect->Pos : host_window->Pos; | ||||
|     data->FutureNode.Size = host_node ? ref_node_for_rect->Size : host_window->Size; | ||||
|  | ||||
|   | ||||
							
								
								
									
										3
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								imgui.h
									
									
									
									
									
								
							| @@ -745,7 +745,7 @@ enum ImGuiWindowFlags_ | ||||
|     ImGuiWindowFlags_NoMove                 = 1 << 2,   // Disable user moving the window | ||||
|     ImGuiWindowFlags_NoScrollbar            = 1 << 3,   // Disable scrollbars (window can still scroll with mouse or programmatically) | ||||
|     ImGuiWindowFlags_NoScrollWithMouse      = 1 << 4,   // Disable user vertically scrolling with mouse wheel. On child window, mouse wheel will be forwarded to the parent unless NoScrollbar is also set. | ||||
|     ImGuiWindowFlags_NoCollapse             = 1 << 5,   // Disable user collapsing window by double-clicking on it | ||||
|     ImGuiWindowFlags_NoCollapse             = 1 << 5,   // Disable user collapsing window by double-clicking on it. Also referred to as "window menu button" within a docking node. | ||||
|     ImGuiWindowFlags_AlwaysAutoResize       = 1 << 6,   // Resize every window to its content every frame | ||||
|     ImGuiWindowFlags_NoBackground           = 1 << 7,   // Disable drawing background color (WindowBg, etc.) and outside border. Similar as using SetNextWindowBgAlpha(0.0f). | ||||
|     ImGuiWindowFlags_NoSavedSettings        = 1 << 8,   // Never load/save settings in .ini file | ||||
| @@ -886,6 +886,7 @@ enum ImGuiTabItemFlags_ | ||||
|  | ||||
| // Flags for ImGui::DockSpace(), shared/inherited by child nodes. | ||||
| // (Some flags can be applied to individual nodes directly) | ||||
| // FIXME-DOCK: Also see ImGuiDockNodeFlagsPrivate_ which may involve using the WIP and internal DockBuilder api. | ||||
| enum ImGuiDockNodeFlags_ | ||||
| { | ||||
|     ImGuiDockNodeFlags_None                         = 0, | ||||
|   | ||||
| @@ -891,8 +891,10 @@ enum ImGuiDockNodeFlagsPrivate_ | ||||
|     ImGuiDockNodeFlags_CentralNode              = 1 << 11,  // Local | ||||
|     ImGuiDockNodeFlags_NoTabBar                 = 1 << 12,  // Local  // Tab bar is completely unavailable. No triangle in the corner to enable it back. | ||||
|     ImGuiDockNodeFlags_HiddenTabBar             = 1 << 13,  // Local  // Tab bar is hidden, with a triangle in the corner to show it again (NB: actual tab-bar instance may be destroyed as this is only used for single-window tab bar) | ||||
|     ImGuiDockNodeFlags_NoWindowMenuButton       = 1 << 14,  // Local  // Disable window/docking menu (that one that appears instead of the collapse button) | ||||
|     ImGuiDockNodeFlags_NoCloseButton            = 1 << 15,  // Local | ||||
|     ImGuiDockNodeFlags_SharedFlagsInheritMask_  = ~0, | ||||
|     ImGuiDockNodeFlags_LocalFlagsMask_          = ImGuiDockNodeFlags_NoSplit | ImGuiDockNodeFlags_NoResize | ImGuiDockNodeFlags_AutoHideTabBar | ImGuiDockNodeFlags_DockSpace | ImGuiDockNodeFlags_CentralNode | ImGuiDockNodeFlags_NoTabBar | ImGuiDockNodeFlags_HiddenTabBar, | ||||
|     ImGuiDockNodeFlags_LocalFlagsMask_          = ImGuiDockNodeFlags_NoSplit | ImGuiDockNodeFlags_NoResize | ImGuiDockNodeFlags_AutoHideTabBar | ImGuiDockNodeFlags_DockSpace | ImGuiDockNodeFlags_CentralNode | ImGuiDockNodeFlags_NoTabBar | ImGuiDockNodeFlags_HiddenTabBar | ImGuiDockNodeFlags_NoWindowMenuButton | ImGuiDockNodeFlags_NoCloseButton, | ||||
|     ImGuiDockNodeFlags_LocalFlagsTransferMask_  = ImGuiDockNodeFlags_LocalFlagsMask_ & ~ImGuiDockNodeFlags_DockSpace  // When splitting those flags are moved to the inheriting child, never duplicated | ||||
| }; | ||||
|  | ||||
| @@ -936,7 +938,8 @@ struct ImGuiDockNode | ||||
|     bool                    IsVisible               :1; // Set to false when the node is hidden (usually disabled as it has no active window) | ||||
|     bool                    IsFocused               :1; | ||||
|     bool                    HasCloseButton          :1; | ||||
|     bool                    HasCollapseButton       :1; | ||||
|     bool                    HasWindowMenuButton     :1; | ||||
|     bool                    EnableCloseButton       :1; | ||||
|     bool                    WantCloseAll            :1; // Set when closing all tabs at once. | ||||
|     bool                    WantLockSizeOnce        :1; | ||||
|     bool                    WantMouseMove           :1; // After a node extraction we need to transition toward moving the newly created host window | ||||
|   | ||||
		Reference in New Issue
	
	Block a user