@ -3264,6 +3264,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) : DrawListInst
ViewportAllowPlatformMonitorExtend = - 1 ;
ViewportPos = ImVec2 ( FLT_MAX , FLT_MAX ) ;
MoveId = GetID ( " #MOVE " ) ;
TabId = GetID ( " #TAB " ) ;
ScrollTarget = ImVec2 ( FLT_MAX , FLT_MAX ) ;
ScrollTargetCenterRatio = ImVec2 ( 0.5f , 0.5f ) ;
AutoFitFramesX = AutoFitFramesY = - 1 ;
@ -3541,8 +3542,9 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
// Test if another item is active (e.g. being dragged)
if ( ( flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem ) = = 0 )
if ( g . ActiveId ! = 0 & & g . ActiveId ! = g . LastItemData . ID & & ! g . ActiveIdAllowOverlap & & g . ActiveId ! = window - > MoveId )
return false ;
if ( g . ActiveId ! = 0 & & g . ActiveId ! = g . LastItemData . ID & & ! g . ActiveIdAllowOverlap )
if ( g . ActiveId ! = window - > MoveId & & g . ActiveId ! = window - > TabId )
return false ;
// Test if interactions on this window are blocked by an active popup or modal.
// The ImGuiHoveredFlags_AllowWhenBlockedByPopup flag will be tested here.
@ -3554,7 +3556,8 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
return false ;
// Special handling for calling after Begin() which represent the title bar or tab.
// When the window is collapsed (SkipItems==true) that last item will never be overwritten so we need to detect the case.
// When the window is skipped/collapsed (SkipItems==true) that last item (always ->MoveId submitted by Begin)
// will never be overwritten so we need to detect the case.
if ( g . LastItemData . ID = = window - > MoveId & & window - > WriteAccessed )
return false ;
}
@ -7299,7 +7302,7 @@ void ImGui::FocusWindow(ImGuiWindow* window)
// Select in dock node
if ( dock_node & & dock_node - > TabBar )
dock_node - > TabBar - > SelectedTabId = dock_node - > TabBar - > NextSelectedTabId = window - > ID ;
dock_node - > TabBar - > SelectedTabId = dock_node - > TabBar - > NextSelectedTabId = window - > TabId ;
// Bring to front
BringWindowToFocusFront ( focus_front_window ) ;
@ -12456,6 +12459,7 @@ static void WindowSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandl
buf - > appendf ( " Collapsed=%d \n " , settings - > Collapsed ) ;
if ( settings - > DockId ! = 0 )
{
//buf->appendf("TabId=0x%08X\n", ImHashStr("#TAB", 4, settings->ID)); // window->TabId: this is not read back but writing it makes "debugging" the .ini data easier.
if ( settings - > DockOrder = = - 1 )
buf - > appendf ( " DockId=0x%08X \n " , settings - > DockId ) ;
else
@ -14063,7 +14067,7 @@ void ImGui::DockContextProcessDock(ImGuiContext* ctx, ImGuiDockRequest* req)
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 ;
next_selected_id = payload_window - > TabId ;
}
// FIXME-DOCK: When we are trying to dock an existing single-window node into a loose window, transfer Node ID as well
@ -14340,7 +14344,7 @@ int ImGui::DockNodeGetTabOrder(ImGuiWindow* window)
ImGuiTabBar * tab_bar = window - > DockNode - > TabBar ;
if ( tab_bar = = NULL )
return - 1 ;
ImGuiTabItem * tab = TabBarFindTabByID ( tab_bar , window - > ID ) ;
ImGuiTabItem * tab = TabBarFindTabByID ( tab_bar , window - > TabId ) ;
return tab ? tab_bar - > GetTabOrder ( tab ) : - 1 ;
}
@ -14444,7 +14448,7 @@ static void ImGui::DockNodeRemoveWindow(ImGuiDockNode* node, ImGuiWindow* window
node - > WantHiddenTabBarUpdate = true ;
if ( node - > TabBar )
{
TabBarRemoveTab ( node - > TabBar , window - > ID ) ;
TabBarRemoveTab ( node - > TabBar , window - > TabId ) ;
const int tab_count_threshold_for_tab_bar = node - > IsCentralNode ( ) ? 1 : 2 ;
if ( node - > Windows . Size < tab_count_threshold_for_tab_bar )
DockNodeRemoveTabBar ( node ) ;
@ -14627,7 +14631,7 @@ static void ImGui::DockNodeUpdateFlagsAndCollapse(ImGuiDockNode* node)
bool node_was_active = ( node - > LastFrameActive + 1 = = g . FrameCount ) ;
bool remove = false ;
remove | = node_was_active & & ( window - > LastFrameActive + 1 < g . FrameCount ) ;
remove | = node_was_active & & ( node - > WantCloseAll | | node - > WantCloseTabId = = window - > ID ) & & window - > HasCloseButton & & ! ( window - > Flags & ImGuiWindowFlags_UnsavedDocument ) ; // Submit all _expected_ closure from last frame
remove | = node_was_active & & ( node - > WantCloseAll | | node - > WantCloseTabId = = window - > TabId ) & & window - > HasCloseButton & & ! ( window - > Flags & ImGuiWindowFlags_UnsavedDocument ) ; // Submit all _expected_ closure from last frame
remove | = ( window - > DockTabWantClose ) ;
if ( remove )
{
@ -15159,7 +15163,7 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
if ( is_focused | | root_node - > VisibleWindow = = NULL )
root_node - > VisibleWindow = node - > VisibleWindow ;
if ( node - > TabBar )
node - > TabBar - > VisibleTabId = node - > VisibleWindow - > ID ;
node - > TabBar - > VisibleTabId = node - > VisibleWindow - > TabId ;
}
return ;
}
@ -15210,7 +15214,7 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
for ( int window_n = 0 ; window_n < node - > Windows . Size ; window_n + + )
{
ImGuiWindow * window = node - > Windows [ window_n ] ;
if ( TabBarFindTabByID ( tab_bar , window - > ID ) = = NULL )
if ( TabBarFindTabByID ( tab_bar , window - > TabId ) = = NULL )
TabBarAddTab ( tab_bar , ImGuiTabItemFlags_Unsorted , window ) ;
}
@ -15255,7 +15259,7 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
if ( tab_bar_is_recreated & & TabBarFindTabByID ( tab_bar , node - > SelectedTabId ) ! = NULL )
tab_bar - > SelectedTabId = tab_bar - > NextSelectedTabId = node - > SelectedTabId ;
else if ( tab_bar - > Tabs . Size > tabs_count_old )
tab_bar - > SelectedTabId = tab_bar - > NextSelectedTabId = tab_bar - > Tabs . back ( ) . Window - > ID ;
tab_bar - > SelectedTabId = tab_bar - > NextSelectedTabId = tab_bar - > Tabs . back ( ) . Window - > TabId ;
// Begin tab bar
ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_AutoSelectNewTabs ; // | ImGuiTabBarFlags_NoTabListScrollingButtons);
@ -15275,7 +15279,7 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
for ( int window_n = 0 ; window_n < node - > Windows . Size ; window_n + + )
{
ImGuiWindow * window = node - > Windows [ window_n ] ;
if ( ( closed_all | | closed_one = = window - > ID ) & & window - > HasCloseButton & & ! ( window - > Flags & ImGuiWindowFlags_UnsavedDocument ) )
if ( ( closed_all | | closed_one = = window - > TabId ) & & window - > HasCloseButton & & ! ( window - > Flags & ImGuiWindowFlags_UnsavedDocument ) )
continue ;
if ( window - > LastFrameActive + 1 > = g . FrameCount | | ! node_was_active )
{
@ -15290,11 +15294,12 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
for ( int color_n = 0 ; color_n < ImGuiWindowDockStyleCol_COUNT ; color_n + + )
g . Style . Colors [ GWindowDockStyleColors [ color_n ] ] = ColorConvertU32ToFloat4 ( window - > DockStyle . Colors [ color_n ] ) ;
// Note that TabItemEx() calls TabBarCalcTabID() so our tab item ID will ignore the current ID stack (rightly so)
bool tab_open = true ;
TabItemEx ( tab_bar , window - > Name , window - > HasCloseButton ? & tab_open : NULL , tab_item_flags , window ) ;
if ( ! tab_open )
node - > WantCloseTabId = window - > ID ;
if ( tab_bar - > VisibleTabId = = window - > ID )
node - > WantCloseTabId = window - > TabId ;
if ( tab_bar - > VisibleTabId = = window - > TabId )
node - > VisibleWindow = window ;
// Store last item data so it can be queried with IsItemXXX functions after the user Begin() call
@ -15303,7 +15308,7 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
// Update navigation ID on menu layer
if ( g . NavWindow & & g . NavWindow - > RootWindow = = window & & ( window - > DC . NavLayersActiveMask & ( 1 < < ImGuiNavLayer_Menu ) ) = = 0 )
host_window - > NavLastIds [ 1 ] = window - > ID ;
host_window - > NavLastIds [ 1 ] = window - > TabId ;
}
}
@ -15317,7 +15322,7 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
root_node - > VisibleWindow = node - > VisibleWindow ;
// 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
// Note that VisibleWindow may have been overrided by CTRL+Tabbing, so VisibleWindow-> TabId may be != from tab_bar->SelectedTabId
const bool close_button_is_enabled = node - > HasCloseButton & & node - > VisibleWindow & & node - > VisibleWindow - > HasCloseButton ;
const bool close_button_is_visible = node - > HasCloseButton ;
//const bool close_button_is_visible = close_button_is_enabled; // Most people would expect this behavior of not even showing the button (leaving a hole since we can't claim that space as other windows in the tba bar have one)
@ -16931,7 +16936,7 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
if ( node - > TabBar & & window - > WasActive )
window - > DockOrder = ( short ) DockNodeGetTabOrder ( window ) ;
if ( ( node - > WantCloseAll | | node - > WantCloseTabId = = window - > ID ) & & p_open ! = NULL )
if ( ( node - > WantCloseAll | | node - > WantCloseTabId = = window - > TabId ) & & p_open ! = NULL )
* p_open = false ;
// Update ChildId to allow returning from Child to Parent with Escape