mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-10-26 12:27:30 +00:00 
			
		
		
		
	Docking: Fixed focus restore lagging by a frame when a tab stops being submitted. (#2109) Building on a little build of technical debt there, should transition toward a more general docking-agnostic system (#2304)
This commit is contained in:
		| @@ -9,6 +9,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i | |||||||
|  - doc/test: checklist app to verify binding/integration of imgui (test inputs, rendering, callback, etc.). |  - doc/test: checklist app to verify binding/integration of imgui (test inputs, rendering, callback, etc.). | ||||||
|  - doc/tips: tips of the day: website? applet in imgui_club? |  - doc/tips: tips of the day: website? applet in imgui_club? | ||||||
|  |  | ||||||
|  |  - window: preserve/restore relative focus ordering (persistent or not) (#2304) -> also see docking reference to same #. | ||||||
|  - window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). (#690) |  - window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). (#690) | ||||||
|  - window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass. |  - window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass. | ||||||
|  - window: auto-fit feedback loop when user relies on any dynamic layout (window width multiplier, column) appears weird to end-user. clarify. |  - window: auto-fit feedback loop when user relies on any dynamic layout (window width multiplier, column) appears weird to end-user. clarify. | ||||||
| @@ -130,6 +131,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i | |||||||
|  - splitter/separator: formalize the splitter idiom into an official api (we want to handle n-way split) (#319) |  - splitter/separator: formalize the splitter idiom into an official api (we want to handle n-way split) (#319) | ||||||
|  |  | ||||||
|  - dock: merge docking branch (#2109) |  - dock: merge docking branch (#2109) | ||||||
|  |  - dock: B: ordering currently held in tab bar should be implicitly held by windows themselves (also see #2304) | ||||||
|  |  - dock: B- tab bar: the order/focus restoring code could be part of TabBar and not DockNode? (#8) | ||||||
|  - dock: B~ rework code to be able to lazily create tab bar instance in a single place. The _Unsorted tab flag could be replacing a trailing-counter in DockNode? |  - dock: B~ rework code to be able to lazily create tab bar instance in a single place. The _Unsorted tab flag could be replacing a trailing-counter in DockNode? | ||||||
|  - dock: B~ fully track windows/settings reference in dock nodes. perhaps find a representation that allows facilitate use of dock builder functions. |  - dock: B~ fully track windows/settings reference in dock nodes. perhaps find a representation that allows facilitate use of dock builder functions. | ||||||
|  - dock: B~ Unreal style document system (requires low-level controls of dockspace serialization fork/copy/delete). this is mostly working but the DockBuilderXXX api are not exposed/finished. |  - dock: B~ Unreal style document system (requires low-level controls of dockspace serialization fork/copy/delete). this is mostly working but the DockBuilderXXX api are not exposed/finished. | ||||||
| @@ -148,7 +151,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i | |||||||
|  - dock: B- dpi: look at interaction with the hi-dpi and multi-dpi stuff. |  - dock: B- dpi: look at interaction with the hi-dpi and multi-dpi stuff. | ||||||
|  - dock: B- tab bar: appearing on first frame with a dumb layout would do less harm that not appearing? (when behind dynamic branch) or store titles + render in EndTabBar() |  - dock: B- tab bar: appearing on first frame with a dumb layout would do less harm that not appearing? (when behind dynamic branch) or store titles + render in EndTabBar() | ||||||
|  - dock: B- tab bar: make selected tab always shows its full title? |  - dock: B- tab bar: make selected tab always shows its full title? | ||||||
|  - dock: B- tab bar: the order/focus restoring code could be part of TabBar and not DockNode? (#8) |  | ||||||
|  - dock: B- nav: design interactions so nav controls can dock/undock |  - dock: B- nav: design interactions so nav controls can dock/undock | ||||||
|  - dock: B- dockspace: flag to lock the dock tree and/or sizes (ImGuiDockNodeFlags_Locked?) |  - dock: B- dockspace: flag to lock the dock tree and/or sizes (ImGuiDockNodeFlags_Locked?) | ||||||
|  - dock: B- reintroduce collapsing a floating dock node. also collapsing a docked dock node! |  - dock: B- reintroduce collapsing a floating dock node. also collapsing a docked dock node! | ||||||
|   | |||||||
							
								
								
									
										20
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -1040,7 +1040,7 @@ static float            NavUpdatePageUpPageDown(int allowed_dir_flags); | |||||||
| static inline void      NavUpdateAnyRequestFlag(); | static inline void      NavUpdateAnyRequestFlag(); | ||||||
| static void             NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, ImGuiID id); | static void             NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, ImGuiID id); | ||||||
| static ImVec2           NavCalcPreferredRefPos(); | static ImVec2           NavCalcPreferredRefPos(); | ||||||
| static void             NavSaveLastChildNavWindow(ImGuiWindow* nav_window); | static void             NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window); | ||||||
| static ImGuiWindow*     NavRestoreLastChildNavWindow(ImGuiWindow* window); | static ImGuiWindow*     NavRestoreLastChildNavWindow(ImGuiWindow* window); | ||||||
|  |  | ||||||
| // Misc | // Misc | ||||||
| @@ -8143,7 +8143,9 @@ void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags mov | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| static void ImGui::NavSaveLastChildNavWindow(ImGuiWindow* nav_window) | // FIXME: This could be replaced by updating a frame number in each window when (window == NavWindow) and (NavLayer == 0). | ||||||
|  | // This way we could find the last focused window among our children. It would be much less confusing this way? | ||||||
|  | static void ImGui::NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window) | ||||||
| { | { | ||||||
|     ImGuiWindow* parent_window = nav_window; |     ImGuiWindow* parent_window = nav_window; | ||||||
|     while (parent_window && (parent_window->Flags & ImGuiWindowFlags_ChildWindow) != 0 && (parent_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0) |     while (parent_window && (parent_window->Flags & ImGuiWindowFlags_ChildWindow) != 0 && (parent_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0) | ||||||
| @@ -8152,10 +8154,16 @@ static void ImGui::NavSaveLastChildNavWindow(ImGuiWindow* nav_window) | |||||||
|         parent_window->NavLastChildNavWindow = nav_window; |         parent_window->NavLastChildNavWindow = nav_window; | ||||||
| } | } | ||||||
|  |  | ||||||
| // Call when we are expected to land on Layer 0 after FocusWindow() | // Restore the last focused child. | ||||||
|  | // Call when we are expected to land on the Main Layer (0) after FocusWindow() | ||||||
| static ImGuiWindow* ImGui::NavRestoreLastChildNavWindow(ImGuiWindow* window) | static ImGuiWindow* ImGui::NavRestoreLastChildNavWindow(ImGuiWindow* window) | ||||||
| { | { | ||||||
|     return window->NavLastChildNavWindow ? window->NavLastChildNavWindow : window; |     if (window->NavLastChildNavWindow && window->NavLastChildNavWindow->WasActive) | ||||||
|  |         return window->NavLastChildNavWindow; | ||||||
|  |     if (window->DockNodeAsHost && window->DockNodeAsHost->TabBar) | ||||||
|  |         if (ImGuiTabItem* tab = TabBarFindMostRecentlySelectedTabForActiveWindow(window->DockNodeAsHost->TabBar)) | ||||||
|  |             return tab->Window; | ||||||
|  |     return window; | ||||||
| } | } | ||||||
|  |  | ||||||
| static void NavRestoreLayer(ImGuiNavLayer layer) | static void NavRestoreLayer(ImGuiNavLayer layer) | ||||||
| @@ -8380,7 +8388,7 @@ static void ImGui::NavUpdate() | |||||||
|  |  | ||||||
|     // Store our return window (for returning from Layer 1 to Layer 0) and clear it as soon as we step back in our own Layer 0 |     // Store our return window (for returning from Layer 1 to Layer 0) and clear it as soon as we step back in our own Layer 0 | ||||||
|     if (g.NavWindow) |     if (g.NavWindow) | ||||||
|         NavSaveLastChildNavWindow(g.NavWindow); |         NavSaveLastChildNavWindowIntoParent(g.NavWindow); | ||||||
|     if (g.NavWindow && g.NavWindow->NavLastChildNavWindow != NULL && g.NavLayer == 0) |     if (g.NavWindow && g.NavWindow->NavLastChildNavWindow != NULL && g.NavLayer == 0) | ||||||
|         g.NavWindow->NavLastChildNavWindow = NULL; |         g.NavWindow->NavLastChildNavWindow = NULL; | ||||||
|  |  | ||||||
| @@ -8833,7 +8841,7 @@ static void ImGui::NavUpdateWindowing() | |||||||
|         // Move to parent menu if necessary |         // Move to parent menu if necessary | ||||||
|         ImGuiWindow* new_nav_window = g.NavWindow; |         ImGuiWindow* new_nav_window = g.NavWindow; | ||||||
|         while (new_nav_window->ParentWindow |         while (new_nav_window->ParentWindow | ||||||
|             && (new_nav_window->DC.NavLayerActiveMask & (1 << 1)) == 0 |             && (new_nav_window->DC.NavLayerActiveMask & (1 << ImGuiNavLayer_Menu)) == 0 | ||||||
|             && (new_nav_window->Flags & ImGuiWindowFlags_ChildWindow) != 0 |             && (new_nav_window->Flags & ImGuiWindowFlags_ChildWindow) != 0 | ||||||
|             && (new_nav_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0) |             && (new_nav_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0) | ||||||
|             new_nav_window = new_nav_window->ParentWindow; |             new_nav_window = new_nav_window->ParentWindow; | ||||||
|   | |||||||
| @@ -1707,6 +1707,7 @@ namespace ImGui | |||||||
|     // Tab Bars |     // Tab Bars | ||||||
|     IMGUI_API bool          BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags, ImGuiDockNode* dock_node); |     IMGUI_API bool          BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags, ImGuiDockNode* dock_node); | ||||||
|     IMGUI_API ImGuiTabItem* TabBarFindTabByID(ImGuiTabBar* tab_bar, ImGuiID tab_id); |     IMGUI_API ImGuiTabItem* TabBarFindTabByID(ImGuiTabBar* tab_bar, ImGuiID tab_id); | ||||||
|  |     IMGUI_API ImGuiTabItem* TabBarFindMostRecentlySelectedTabForActiveWindow(ImGuiTabBar* tab_bar); | ||||||
|     IMGUI_API void          TabBarAddTab(ImGuiTabBar* tab_bar, ImGuiTabItemFlags tab_flags, ImGuiWindow* window); |     IMGUI_API void          TabBarAddTab(ImGuiTabBar* tab_bar, ImGuiTabItemFlags tab_flags, ImGuiWindow* window); | ||||||
|     IMGUI_API void          TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id); |     IMGUI_API void          TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id); | ||||||
|     IMGUI_API void          TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab); |     IMGUI_API void          TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab); | ||||||
|   | |||||||
| @@ -6455,6 +6455,20 @@ ImGuiTabItem* ImGui::TabBarFindTabByID(ImGuiTabBar* tab_bar, ImGuiID tab_id) | |||||||
|     return NULL; |     return NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // FIXME: See references to #2304 in TODO.txt | ||||||
|  | ImGuiTabItem* ImGui::TabBarFindMostRecentlySelectedTabForActiveWindow(ImGuiTabBar* tab_bar) | ||||||
|  | { | ||||||
|  |     ImGuiTabItem* most_recently_selected_tab = NULL; | ||||||
|  |     for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++) | ||||||
|  |     { | ||||||
|  |         ImGuiTabItem* tab = &tab_bar->Tabs[tab_n]; | ||||||
|  |         if (most_recently_selected_tab == NULL || most_recently_selected_tab->LastFrameSelected < tab->LastFrameSelected) | ||||||
|  |             if (tab->Window && tab->Window->WasActive) | ||||||
|  |                 most_recently_selected_tab = tab; | ||||||
|  |     } | ||||||
|  |     return most_recently_selected_tab; | ||||||
|  | } | ||||||
|  |  | ||||||
| // The purpose of this call is to register tab in advance so we can control their order at the time they appear.  | // The purpose of this call is to register tab in advance so we can control their order at the time they appear.  | ||||||
| // Otherwise calling this is unnecessary as tabs are appending as needed by the BeginTabItem() function. | // Otherwise calling this is unnecessary as tabs are appending as needed by the BeginTabItem() function. | ||||||
| void ImGui::TabBarAddTab(ImGuiTabBar* tab_bar, ImGuiTabItemFlags tab_flags, ImGuiWindow* window) | void ImGui::TabBarAddTab(ImGuiTabBar* tab_bar, ImGuiTabItemFlags tab_flags, ImGuiWindow* window) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 omar
					omar