From 7c4be0a000abfc6645f56f654794473d5d358940 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 16 Nov 2017 13:11:16 +0100 Subject: [PATCH 1/3] Internals: Added BringWindowToFront(), BringWindowToBack() helpers. --- imgui.cpp | 43 ++++++++++++++++++++++++++++++++----------- imgui_internal.h | 2 ++ 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 088012bb..6d5b6bc9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4793,7 +4793,35 @@ void ImGui::Scrollbar(ImGuiLayoutType direction) window->DrawList->AddRectFilled(grab_rect.Min, grab_rect.Max, grab_col, style.ScrollbarRounding); } -// Moving window to front of display (which happens to be back of our sorted list) +void ImGui::BringWindowToFront(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + if (g.Windows.back() == window) + return; + for (int i = 0; i < g.Windows.Size; i++) + if (g.Windows[i] == window) + { + g.Windows.erase(g.Windows.begin() + i); + g.Windows.push_back(window); + break; + } +} + +void ImGui::BringWindowToBack(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + if (g.Windows[0] == window) + return; + for (int i = 0; i < g.Windows.Size; i++) + if (g.Windows[i] == window) + { + memmove(&g.Windows[1], &g.Windows[0], (size_t)i * sizeof(ImGuiWindow*)); + g.Windows[0] = window; + break; + } +} + +// Moving window to front of display and set focus (which happens to be back of our sorted list) void ImGui::FocusWindow(ImGuiWindow* window) { ImGuiContext& g = *GImGui; @@ -4805,7 +4833,7 @@ void ImGui::FocusWindow(ImGuiWindow* window) if (!window) return; - // And move its root window to the top of the pile + // Move the root window to the top of the pile if (window->RootWindow) window = window->RootWindow; @@ -4815,15 +4843,8 @@ void ImGui::FocusWindow(ImGuiWindow* window) ClearActiveID(); // Bring to front - if ((window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus) || g.Windows.back() == window) - return; - for (int i = 0; i < g.Windows.Size; i++) - if (g.Windows[i] == window) - { - g.Windows.erase(g.Windows.begin() + i); - break; - } - g.Windows.push_back(window); + if (!(window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) + BringWindowToFront(window); } void ImGui::FocusPreviousWindow() diff --git a/imgui_internal.h b/imgui_internal.h index 85eced9d..be8d84d8 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -779,6 +779,8 @@ namespace ImGui IMGUI_API ImGuiWindow* GetParentWindow(); IMGUI_API ImGuiWindow* FindWindowByName(const char* name); IMGUI_API void FocusWindow(ImGuiWindow* window); + IMGUI_API void BringWindowToFront(ImGuiWindow* window); + IMGUI_API void BringWindowToBack(ImGuiWindow* window); IMGUI_API void Initialize(); IMGUI_API void EndFrame(); // Ends the ImGui frame. Automatically called by Render()! you most likely don't need to ever call that yourself directly. If you don't need to render you can call EndFrame() but you'll have wasted CPU already. If you don't need to render, don't create any windows instead! From 4ad414c8d45493f6282997c7930d1b7737ff9a63 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 13 Nov 2017 23:25:13 +0100 Subject: [PATCH 2/3] Internals: Window: Store whether the windows has a close button (we need that info for window/tabs dropping preview calculation) --- imgui.cpp | 2 ++ imgui_internal.h | 1 + 2 files changed, 3 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 6d5b6bc9..9154c7bf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1800,6 +1800,7 @@ ImGuiWindow::ImGuiWindow(const char* name) Collapsed = false; SkipItems = false; Appearing = false; + CloseButton = false; BeginCount = 0; PopupId = 0; AutoFitFramesX = AutoFitFramesY = -1; @@ -4130,6 +4131,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFrames == 1); window->Appearing = (window_just_activated_by_user || window_just_appearing_after_hidden_for_resize); + window->CloseButton = (p_open != NULL); // Process SetNextWindow***() calls bool window_pos_set_by_api = false, window_size_set_by_api = false; diff --git a/imgui_internal.h b/imgui_internal.h index be8d84d8..6a081dfb 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -700,6 +700,7 @@ struct IMGUI_API ImGuiWindow bool Collapsed; // Set when collapsing window to become only title-bar bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed) bool Appearing; // Set during the frame where the window is appearing (or re-appearing) + bool CloseButton; // Set when the window has a close button (p_open != NULL) int BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs) ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling) int AutoFitFramesX, AutoFitFramesY; From 29d962069d3b90478244a398bb1754195f5b0ece Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 13 Nov 2017 22:15:50 +0100 Subject: [PATCH 3/3] Internals: Updating condition/allow flags with a function. --- imgui.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 9154c7bf..832904ba 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3918,6 +3918,13 @@ static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, return pos; } +static void SetWindowConditionAllowFlags(ImGuiWindow* window, ImGuiCond flags, bool enabled) +{ + window->SetWindowPosAllowFlags = enabled ? (window->SetWindowPosAllowFlags | flags) : (window->SetWindowPosAllowFlags & ~flags); + window->SetWindowSizeAllowFlags = enabled ? (window->SetWindowSizeAllowFlags | flags) : (window->SetWindowSizeAllowFlags & ~flags); + window->SetWindowCollapsedAllowFlags = enabled ? (window->SetWindowCollapsedAllowFlags | flags) : (window->SetWindowCollapsedAllowFlags & ~flags); +} + ImGuiWindow* ImGui::FindWindowByName(const char* name) { ImGuiContext& g = *GImGui; @@ -3949,15 +3956,9 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl ImGuiIniData* settings = FindWindowSettings(name); if (!settings) - { settings = AddWindowSettings(name); - } else - { - window->SetWindowPosAllowFlags &= ~ImGuiCond_FirstUseEver; - window->SetWindowSizeAllowFlags &= ~ImGuiCond_FirstUseEver; - window->SetWindowCollapsedAllowFlags &= ~ImGuiCond_FirstUseEver; - } + SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false); if (settings->Pos.x != FLT_MAX) { @@ -4134,11 +4135,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->CloseButton = (p_open != NULL); // Process SetNextWindow***() calls + if (window->Appearing) + SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true); bool window_pos_set_by_api = false, window_size_set_by_api = false; if (g.SetNextWindowPosCond) { - if (window->Appearing) - window->SetWindowPosAllowFlags |= ImGuiCond_Appearing; window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) != 0; if (window_pos_set_by_api && ImLengthSqr(g.SetNextWindowPosPivot) > 0.00001f) { @@ -4156,8 +4157,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } if (g.SetNextWindowSizeCond) { - if (window->Appearing) - window->SetWindowSizeAllowFlags |= ImGuiCond_Appearing; window_size_set_by_api = (window->SetWindowSizeAllowFlags & g.SetNextWindowSizeCond) != 0; SetWindowSize(window, g.SetNextWindowSizeVal, g.SetNextWindowSizeCond); g.SetNextWindowSizeCond = 0; @@ -4173,8 +4172,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) } if (g.SetNextWindowCollapsedCond) { - if (window->Appearing) - window->SetWindowCollapsedAllowFlags |= ImGuiCond_Appearing; SetWindowCollapsed(window, g.SetNextWindowCollapsedVal, g.SetNextWindowCollapsedCond); g.SetNextWindowCollapsedCond = 0; } @@ -4183,6 +4180,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) SetWindowFocus(); g.SetNextWindowFocus = false; } + if (window->Appearing) + SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, false); // When reusing window again multiple times a frame, just append content (don't need to setup again) if (first_begin_of_the_frame)