mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-22 20:07:01 +00:00
Internals: maintaining focus order inside windows + only storing root windows in WindowsFocusOrder[] array. (toward #2304)
This commit is contained in:
parent
770f9daab3
commit
936f53229d
44
imgui.cpp
44
imgui.cpp
@ -4034,7 +4034,7 @@ void ImGui::NewFrame()
|
|||||||
UpdateTabFocus();
|
UpdateTabFocus();
|
||||||
|
|
||||||
// Mark all windows as not visible and compact unused memory.
|
// Mark all windows as not visible and compact unused memory.
|
||||||
IM_ASSERT(g.WindowsFocusOrder.Size == g.Windows.Size);
|
IM_ASSERT(g.WindowsFocusOrder.Size <= g.Windows.Size);
|
||||||
const float memory_compact_start_time = (g.GcCompactAll || g.IO.ConfigMemoryCompactTimer < 0.0f) ? FLT_MAX : (float)g.Time - g.IO.ConfigMemoryCompactTimer;
|
const float memory_compact_start_time = (g.GcCompactAll || g.IO.ConfigMemoryCompactTimer < 0.0f) ? FLT_MAX : (float)g.Time - g.IO.ConfigMemoryCompactTimer;
|
||||||
for (int i = 0; i != g.Windows.Size; i++)
|
for (int i = 0; i != g.Windows.Size; i++)
|
||||||
{
|
{
|
||||||
@ -5143,7 +5143,12 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags)
|
|||||||
window->AutoFitOnlyGrows = (window->AutoFitFramesX > 0) || (window->AutoFitFramesY > 0);
|
window->AutoFitOnlyGrows = (window->AutoFitFramesX > 0) || (window->AutoFitFramesY > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(flags & ImGuiWindowFlags_ChildWindow))
|
||||||
|
{
|
||||||
g.WindowsFocusOrder.push_back(window);
|
g.WindowsFocusOrder.push_back(window);
|
||||||
|
window->FocusOrder = (short)(g.WindowsFocusOrder.Size - 1);
|
||||||
|
}
|
||||||
|
|
||||||
if (flags & ImGuiWindowFlags_NoBringToFrontOnFocus)
|
if (flags & ImGuiWindowFlags_NoBringToFrontOnFocus)
|
||||||
g.Windows.push_front(window); // Quite slow but rare and only once
|
g.Windows.push_front(window); // Quite slow but rare and only once
|
||||||
else
|
else
|
||||||
@ -6378,15 +6383,22 @@ void ImGui::End()
|
|||||||
void ImGui::BringWindowToFocusFront(ImGuiWindow* window)
|
void ImGui::BringWindowToFocusFront(ImGuiWindow* window)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
IM_ASSERT(window == window->RootWindow);
|
||||||
|
|
||||||
|
const int cur_order = window->FocusOrder;
|
||||||
|
IM_ASSERT(g.WindowsFocusOrder[cur_order] == window);
|
||||||
if (g.WindowsFocusOrder.back() == window)
|
if (g.WindowsFocusOrder.back() == window)
|
||||||
return;
|
return;
|
||||||
for (int i = g.WindowsFocusOrder.Size - 2; i >= 0; i--) // We can ignore the top-most window
|
|
||||||
if (g.WindowsFocusOrder[i] == window)
|
const int new_order = g.WindowsFocusOrder.Size - 1;
|
||||||
|
for (int n = cur_order; n < new_order; n++)
|
||||||
{
|
{
|
||||||
memmove(&g.WindowsFocusOrder[i], &g.WindowsFocusOrder[i + 1], (size_t)(g.WindowsFocusOrder.Size - i - 1) * sizeof(ImGuiWindow*));
|
g.WindowsFocusOrder[n] = g.WindowsFocusOrder[n + 1];
|
||||||
g.WindowsFocusOrder[g.WindowsFocusOrder.Size - 1] = window;
|
g.WindowsFocusOrder[n]->FocusOrder--;
|
||||||
break;
|
IM_ASSERT(g.WindowsFocusOrder[n]->FocusOrder == n);
|
||||||
}
|
}
|
||||||
|
g.WindowsFocusOrder[new_order] = window;
|
||||||
|
window->FocusOrder = (short)new_order;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui::BringWindowToDisplayFront(ImGuiWindow* window)
|
void ImGui::BringWindowToDisplayFront(ImGuiWindow* window)
|
||||||
@ -6466,18 +6478,13 @@ void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWind
|
|||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
|
||||||
int start_idx = g.WindowsFocusOrder.Size - 1;
|
const int start_idx = ((under_this_window != NULL) ? FindWindowFocusIndex(under_this_window) : g.WindowsFocusOrder.Size) - 1;
|
||||||
if (under_this_window != NULL)
|
|
||||||
{
|
|
||||||
int under_this_window_idx = FindWindowFocusIndex(under_this_window);
|
|
||||||
if (under_this_window_idx != -1)
|
|
||||||
start_idx = under_this_window_idx - 1;
|
|
||||||
}
|
|
||||||
for (int i = start_idx; i >= 0; i--)
|
for (int i = start_idx; i >= 0; i--)
|
||||||
{
|
{
|
||||||
// We may later decide to test for different NoXXXInputs based on the active navigation input (mouse vs nav) but that may feel more confusing to the user.
|
// We may later decide to test for different NoXXXInputs based on the active navigation input (mouse vs nav) but that may feel more confusing to the user.
|
||||||
ImGuiWindow* window = g.WindowsFocusOrder[i];
|
ImGuiWindow* window = g.WindowsFocusOrder[i];
|
||||||
if (window != ignore_window && window->WasActive && !(window->Flags & ImGuiWindowFlags_ChildWindow))
|
IM_ASSERT(window == window->RootWindow);
|
||||||
|
if (window != ignore_window && window->WasActive)
|
||||||
if ((window->Flags & (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) != (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs))
|
if ((window->Flags & (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs)) != (ImGuiWindowFlags_NoMouseInputs | ImGuiWindowFlags_NoNavInputs))
|
||||||
{
|
{
|
||||||
ImGuiWindow* focus_window = NavRestoreLastChildNavWindow(window);
|
ImGuiWindow* focus_window = NavRestoreLastChildNavWindow(window);
|
||||||
@ -9479,13 +9486,12 @@ static void ImGui::NavEndFrame()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ImGui::FindWindowFocusIndex(ImGuiWindow* window) // FIXME-OPT O(N)
|
static int ImGui::FindWindowFocusIndex(ImGuiWindow* window)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
for (int i = g.WindowsFocusOrder.Size - 1; i >= 0; i--)
|
int order = window->FocusOrder;
|
||||||
if (g.WindowsFocusOrder[i] == window)
|
IM_ASSERT(g.WindowsFocusOrder[order] == window);
|
||||||
return i;
|
return order;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ImGuiWindow* FindWindowNavFocusable(int i_start, int i_stop, int dir) // FIXME-OPT O(N)
|
static ImGuiWindow* FindWindowNavFocusable(int i_start, int i_stop, int dir) // FIXME-OPT O(N)
|
||||||
|
@ -1322,7 +1322,7 @@ struct ImGuiContext
|
|||||||
|
|
||||||
// Windows state
|
// Windows state
|
||||||
ImVector<ImGuiWindow*> Windows; // Windows, sorted in display order, back to front
|
ImVector<ImGuiWindow*> Windows; // Windows, sorted in display order, back to front
|
||||||
ImVector<ImGuiWindow*> WindowsFocusOrder; // Windows, sorted in focus order, back to front. (FIXME: We could only store root windows here! Need to sort out the Docking equivalent which is RootWindowDockStop and is unfortunately a little more dynamic)
|
ImVector<ImGuiWindow*> WindowsFocusOrder; // Root windows, sorted in focus order, back to front.
|
||||||
ImVector<ImGuiWindow*> WindowsTempSortBuffer; // Temporary buffer used in EndFrame() to reorder windows so parents are kept before their child
|
ImVector<ImGuiWindow*> WindowsTempSortBuffer; // Temporary buffer used in EndFrame() to reorder windows so parents are kept before their child
|
||||||
ImVector<ImGuiWindow*> CurrentWindowStack;
|
ImVector<ImGuiWindow*> CurrentWindowStack;
|
||||||
ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow*
|
ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow*
|
||||||
@ -1786,8 +1786,9 @@ struct IMGUI_API ImGuiWindow
|
|||||||
bool HasCloseButton; // Set when the window has a close button (p_open != NULL)
|
bool HasCloseButton; // Set when the window has a close button (p_open != NULL)
|
||||||
signed char ResizeBorderHeld; // Current border being held for resize (-1: none, otherwise 0-3)
|
signed char ResizeBorderHeld; // Current border being held for resize (-1: none, otherwise 0-3)
|
||||||
short BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs)
|
short BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs)
|
||||||
short BeginOrderWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0.
|
short BeginOrderWithinParent; // Begin() order within immediate parent window, if we are a child window. Otherwise 0.
|
||||||
short BeginOrderWithinContext; // Order within entire imgui context. This is mostly used for debugging submission order related issues.
|
short BeginOrderWithinContext; // Begin() order within entire imgui context. This is mostly used for debugging submission order related issues.
|
||||||
|
short FocusOrder; // Order within WindowsFocusOrder[], altered when windows are focused.
|
||||||
ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling)
|
ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling)
|
||||||
ImS8 AutoFitFramesX, AutoFitFramesY;
|
ImS8 AutoFitFramesX, AutoFitFramesY;
|
||||||
ImS8 AutoFitChildAxises;
|
ImS8 AutoFitChildAxises;
|
||||||
|
Loading…
Reference in New Issue
Block a user