mirror of
https://github.com/Drezil/imgui.git
synced 2024-12-18 22:26:34 +00: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:
parent
e5dfa0855f
commit
511e32e8ca
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
|
||||
|
Loading…
Reference in New Issue
Block a user