1
0
mirror of https://github.com/ocornut/imgui.git synced 2025-01-18 17:24:09 +01:00

Docking: storing window menu handler in a function pointer to allow customizing menu (undocumented)

This commit is contained in:
ocornut 2023-03-06 16:59:57 +01:00
parent e25e4526cd
commit 702626dd8a
2 changed files with 42 additions and 24 deletions

View File

@ -14646,7 +14646,8 @@ namespace ImGui
static void DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_window);
static void DockNodeAddTabBar(ImGuiDockNode* node);
static void DockNodeRemoveTabBar(ImGuiDockNode* node);
static ImGuiID DockNodeUpdateWindowMenu(ImGuiDockNode* node, ImGuiTabBar* tab_bar);
static void DockNodeWindowMenuUpdate(ImGuiDockNode* node, ImGuiTabBar* tab_bar);
static void DockNodeWindowMenuHandler_Default(ImGuiContext* ctx, 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);
@ -14720,6 +14721,8 @@ void ImGui::DockContextInitialize(ImGuiContext* ctx)
ini_handler.ApplyAllFn = DockSettingsHandler_ApplyAll;
ini_handler.WriteAllFn = DockSettingsHandler_WriteAll;
g.SettingsHandlers.push_back(ini_handler);
g.DockNodeWindowMenuHandler = &DockNodeWindowMenuHandler_Default;
}
void ImGui::DockContextShutdown(ImGuiContext* ctx)
@ -16122,11 +16125,39 @@ static int IMGUI_CDECL TabItemComparerByDockOrder(const void* lhs, const void* r
return (a->BeginOrderWithinContext - b->BeginOrderWithinContext);
}
static ImGuiID ImGui::DockNodeUpdateWindowMenu(ImGuiDockNode* node, ImGuiTabBar* tab_bar)
// Default handler for g.DockNodeWindowMenuHandler(): display the list of windows for a given dock-node.
// This is exceptionally stored in a function pointer to also user applications to tweak this menu (undocumented)
// Custom overrides may want to decorate, group, sort entries.
// Please note those are internal structures: if you copy this expect occasional breakage.
static void ImGui::DockNodeWindowMenuHandler_Default(ImGuiContext* ctx, ImGuiDockNode* node, ImGuiTabBar* tab_bar)
{
IM_UNUSED(ctx);
if (tab_bar->Tabs.Size == 1)
{
// "Hide tab bar" option. Being one of our rare user-facing string we pull it from a table.
if (MenuItem(LocalizeGetMsg(ImGuiLocKey_DockingHideTabBar), NULL, node->IsHiddenTabBar()))
node->WantHiddenTabBarToggle = true;
}
else
{
// Display a selectable list of windows in this docking node
for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++)
{
ImGuiTabItem* tab = &tab_bar->Tabs[tab_n];
if (tab->Flags & ImGuiTabItemFlags_Button)
continue;
if (Selectable(TabBarGetTabName(tab_bar, tab), tab->ID == tab_bar->SelectedTabId))
TabBarQueueFocus(tab_bar, tab);
SameLine();
Text(" ");
}
}
}
static void ImGui::DockNodeWindowMenuUpdate(ImGuiDockNode* node, ImGuiTabBar* tab_bar)
{
// Try to position the menu so it is more likely to stays within the same viewport
ImGuiContext& g = *GImGui;
ImGuiID ret_tab_id = 0;
if (g.Style.WindowMenuButtonPosition == ImGuiDir_Left)
SetNextWindowPos(ImVec2(node->Pos.x, node->Pos.y + GetFrameHeight()), ImGuiCond_Always, ImVec2(0.0f, 0.0f));
else
@ -16134,27 +16165,9 @@ static ImGuiID ImGui::DockNodeUpdateWindowMenu(ImGuiDockNode* node, ImGuiTabBar*
if (BeginPopup("#WindowMenu"))
{
node->IsFocused = true;
if (tab_bar->Tabs.Size == 1)
{
if (MenuItem(LocalizeGetMsg(ImGuiLocKey_DockingHideTabBar), NULL, node->IsHiddenTabBar()))
node->WantHiddenTabBarToggle = true;
}
else
{
for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++)
{
ImGuiTabItem* tab = &tab_bar->Tabs[tab_n];
if (tab->Flags & ImGuiTabItemFlags_Button)
continue;
if (Selectable(TabBarGetTabName(tab_bar, tab), tab->ID == tab_bar->SelectedTabId))
ret_tab_id = tab->ID;
SameLine();
Text(" ");
}
}
g.DockNodeWindowMenuHandler(&g, node, tab_bar);
EndPopup();
}
return ret_tab_id;
}
// User helper to append/amend into a dock node tab bar. Most commonly used to add e.g. a "+" button.
@ -16267,8 +16280,10 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
// FIXME-DOCK FIXME-OPT: Could we recycle popups id across multiple dock nodes?
if (has_window_menu_button && IsPopupOpen("#WindowMenu"))
{
if (ImGuiID tab_id = DockNodeUpdateWindowMenu(node, tab_bar))
focus_tab_id = tab_bar->NextSelectedTabId = tab_id;
ImGuiID next_selected_tab_id = tab_bar->NextSelectedTabId;
DockNodeWindowMenuUpdate(node, tab_bar);
if (tab_bar->NextSelectedTabId != 0 && tab_bar->NextSelectedTabId != next_selected_tab_id)
focus_tab_id = tab_bar->NextSelectedTabId;
is_focused |= node->IsFocused;
}

View File

@ -2163,6 +2163,7 @@ struct ImGuiContext
// Extensions
// FIXME: We could provide an API to register one slot in an array held in ImGuiContext?
ImGuiDockContext DockContext;
void (*DockNodeWindowMenuHandler)(ImGuiContext* ctx, ImGuiDockNode* node, ImGuiTabBar* tab_bar);
// Settings
bool SettingsLoaded;
@ -2356,6 +2357,8 @@ struct ImGuiContext
PlatformImeViewport = 0;
PlatformLocaleDecimalPoint = '.';
DockNodeWindowMenuHandler = NULL;
SettingsLoaded = false;
SettingsDirtyTimer = 0.0f;
HookIdNext = 0;