From 4c794be41d1833178825306da28b6ce01d919da7 Mon Sep 17 00:00:00 2001 From: Bruce Mitchener Date: Thu, 14 Sep 2017 10:28:18 +0700 Subject: [PATCH 01/14] Improve warning configuration for clang. Clang 4.0 introduced -Wdouble-promotion, so check for and disable that on clang as we do on gcc. The old style casts warning is already disabled globally in this file for clang, so it doesn't need to be re-disabled within this scope. --- imgui_draw.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index b4b7f5648..7f7985b92 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -42,6 +42,9 @@ #if __has_warning("-Wreserved-id-macro") #pragma clang diagnostic ignored "-Wreserved-id-macro" // warning : macro name is a reserved identifier // #endif +#if __has_warning("-Wdouble-promotion") +#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function +#endif #elif defined(__GNUC__) #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used #pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function @@ -69,7 +72,6 @@ namespace IMGUI_STB_NAMESPACE #ifdef __clang__ #pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse. #pragma clang diagnostic ignored "-Wunused-function" #pragma clang diagnostic ignored "-Wmissing-prototypes" #endif From 479e532f184061fee6af9a295a84bc6f5f263852 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 18 Sep 2017 21:41:49 +0200 Subject: [PATCH 02/14] ColorEdit: fixed weird ternary pattern that makes some compiler warning (fair) --- imgui.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index a048e64f2..0b316c1cd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9301,7 +9301,10 @@ static void ColorEditOptionsPopup(ImGuiColorEditFlags flags, float* col) sprintf(buf, "(%d,%d,%d,%d)", cr, cg, cb, ca); if (ImGui::Selectable(buf)) ImGui::SetClipboardText(buf); - sprintf(buf, (flags & ImGuiColorEditFlags_NoAlpha) ? "0x%02X%02X%02X" : "0x%02X%02X%02X%02X", cr, cg, cb, ca); + if (flags & ImGuiColorEditFlags_NoAlpha) + sprintf(buf, "0x%02X%02X%02X", cr, cg, cb); + else + sprintf(buf, "0x%02X%02X%02X%02X", cr, cg, cb, ca); if (ImGui::Selectable(buf)) ImGui::SetClipboardText(buf); ImGui::EndPopup(); From 2fc07c1b7d95c09f5f230ded1b64b662d5943e8e Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 19 Sep 2017 18:32:09 +0200 Subject: [PATCH 03/14] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 31b101567..6fcac1e28 100644 --- a/README.md +++ b/README.md @@ -226,12 +226,14 @@ Double-chocolate sponsors: - Mobigame - Insomniac Games (sponsored the gamepad/keyboard navigation branch) - Aras Pranckevičius +- Lizardcube +- Greggman Salty caramel supporters: -- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko. +- Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko, Mercury Labs, Singularity Demo Group, Mischa Alff, Sebastien Ronsse. Caramel supporters: -- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix. +- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix, Andrew Belt, Codecat, Cort Stratton, Claudio Canepa, Doug McNabb, Emmanuel Julien, Guillaume Chereau, Jeffrey Slutter, Jeremiah Deckard, r-lyeh, Roger Clark, Nekith, Joshua Fisher, Malte Hoffmann, Mustafa Karaalioglu, Merlyn Morgan-Graham, Per Vognsen, Fabian Giesen, Jan Staubach, Matt Hargett, John Shearer, Jesse Chounard, kingcoopa, Miloš Tošić. And other supporters; thanks! From 9b2672a99fa4be849d5f471b988deebf92836965 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 19 Sep 2017 18:33:04 +0200 Subject: [PATCH 04/14] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6fcac1e28..c25d53450 100644 --- a/README.md +++ b/README.md @@ -233,9 +233,10 @@ Salty caramel supporters: - Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Recognition Robotics, Chris Genova, ikrima, Glenn Fiedler, Geoffrey Evans, Dakko Dakko, Mercury Labs, Singularity Demo Group, Mischa Alff, Sebastien Ronsse. Caramel supporters: -- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, [Kit framework](http://svkonsult.se/kit), Josh Faust, Martin Donlon, Quinton, Felix, Andrew Belt, Codecat, Cort Stratton, Claudio Canepa, Doug McNabb, Emmanuel Julien, Guillaume Chereau, Jeffrey Slutter, Jeremiah Deckard, r-lyeh, Roger Clark, Nekith, Joshua Fisher, Malte Hoffmann, Mustafa Karaalioglu, Merlyn Morgan-Graham, Per Vognsen, Fabian Giesen, Jan Staubach, Matt Hargett, John Shearer, Jesse Chounard, kingcoopa, Miloš Tošić. +- Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei, NeiloGD, Justin Paver, FiniteSol, Vincent Pancaldi, James Billot, Robin Hübner, furrtek, Eric, Simon Barratt, Game Atelier, Julian Bosch, Simon Lundmark, Vincent Hamm, Farhan Wali, Jeff Roberts, Matt Reyer, Colin Riley, Victor Martins, Josh Simmons, Garrett Hoofman, Sergio Gonzales, Andrew Berridge, Roy Eltham, Game Preservation Society, Kit framework, Josh Faust, Martin Donlon, Quinton, Felix, Andrew Belt, Codecat, Cort Stratton, Claudio Canepa, Doug McNabb, Emmanuel Julien, Guillaume Chereau, Jeffrey Slutter, Jeremiah Deckard, r-lyeh, Roger Clark, Nekith, Joshua Fisher, Malte Hoffmann, Mustafa Karaalioglu, Merlyn Morgan-Graham, Per Vognsen, Fabian Giesen, Jan Staubach, Matt Hargett, John Shearer, Jesse Chounard, kingcoopa, Miloš Tošić. And other supporters; thanks! +(Please contact me or PR if you would like to be added or removed from this list) License ------- From 229921541b5b10acc41baefe122da924e40562b5 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 20 Sep 2017 18:51:33 +0200 Subject: [PATCH 05/14] TODO list --- TODO.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/TODO.txt b/TODO.txt index 9c7b3a2a4..bddf473c5 100644 --- a/TODO.txt +++ b/TODO.txt @@ -44,6 +44,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - widgets: display mode: widget-label, label-widget (aligned on column or using fixed size), label-newline-tab-widget etc. (#395) - widgets: clean up widgets internal toward exposing everything and stabilizing imgui_internals.h. - widgets: add disabled and read-only modes (#211) + - widgets: add always-allow-overlap mode. - widgets: alignment options in style (e.g. center Selectable, Right-Align within Button, etc.) #1260 - widgets: activate by identifier (trigger button, focus given id) @@ -173,7 +174,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i !- style: better default styles. !- style: move border to style structure, remove _ShowBorder flag. - - style: border types: out-screen, in-screen, etc. + - style: border types: out-screen, in-screen, etc. (#447) - style/optimization: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. - style: add window shadow (fading away from the window. Paint-style calculation of vertices alpha after drawlist would be easier) - style: color-box not always square? @@ -200,6 +201,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - markup: simple markup language for color change? !- font: better CalcTextSizeA() API, at least for simple use cases. current one is horrible (perhaps have simple vs extended versions). + - font: enforce monospace through ImFontConfig (for icons?) + - font: finish CustomRectRegister() to allow mapping unicode codepoint to custom texture data - font: PushFontSize API (#1018) - font/atlas: incremental updates - font/atlas: dynamic font atlas to avoid baking huge ranges into bitmap and make scaling easier. @@ -232,6 +235,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - examples: window minimize, maximize (#583) - examples: provide a zero-framerate/idle example. - examples: document WantCaptureKeyboard, WantCaptureMouse in example apps. (#446) + - examples: glfw: could go idle when minimized? if (glfwGetWindowAttrib(window, GLFW_ICONIFIED)) { glfwWaitEvents(); continue; } // the problem is that DeltaTime will be super high on resume, perhaps provide a way to let impl know (#440) - optimization: replace vsnprintf with stb_printf? or enable the defines/infrastructure to allow it (#1038) - optimization: add clipping for multi-component widgets (SliderFloatX, ColorEditX, etc.). one problem is that nav branch can't easily clip parent group when there is a move request. - optimization: add a flag to disable most of rendering, for the case where the user expect to skip it (#335) From 3dd3d0b2489dcb37601c8b989c5f719f849e0897 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 24 Sep 2017 12:54:49 +0200 Subject: [PATCH 06/14] Examples: DirectX11: allow creating device with feature level 10 sinec we don't really need much for that example. (#1333) --- examples/directx11_example/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index c8d566bfc..76bab9518 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -60,8 +60,8 @@ HRESULT CreateDeviceD3D(HWND hWnd) UINT createDeviceFlags = 0; //createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; D3D_FEATURE_LEVEL featureLevel; - const D3D_FEATURE_LEVEL featureLevelArray[1] = { D3D_FEATURE_LEVEL_11_0, }; - if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK) + const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, }; + if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK) return E_FAIL; CreateRenderTarget(); From 0a5fb24f10caf49ec627a0e1b9ef0cc5e8b1bc93 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Sep 2017 12:52:06 +0200 Subject: [PATCH 07/14] Popups: Exposing a little more of popups internals in imgui_internals.h --- imgui.cpp | 16 +++++++--------- imgui_internal.h | 2 ++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 0b316c1cd..d3a3d2567 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -623,10 +623,8 @@ static void MarkIniSettingsDirty(ImGuiWindow* window); static ImRect GetVisibleRect(); -static bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); static void CloseInactivePopups(); static void ClosePopupToLevel(int remaining); -static void ClosePopup(ImGuiID id); static ImGuiWindow* GetFrontMostModalRootWindow(); static ImVec2 FindBestPopupWindowPos(const ImVec2& base_pos, const ImVec2& size, int* last_dir, const ImRect& rect_to_avoid); @@ -3531,9 +3529,9 @@ static void ClosePopupToLevel(int remaining) g.OpenPopupStack.resize(remaining); } -static void ClosePopup(ImGuiID id) +void ImGui::ClosePopup(ImGuiID id) { - if (!ImGui::IsPopupOpen(id)) + if (!IsPopupOpen(id)) return; ImGuiContext& g = *GImGui; ClosePopupToLevel(g.OpenPopupStack.Size - 1); @@ -3559,17 +3557,17 @@ static inline void ClearSetNextWindowData() g.SetNextWindowSizeConstraint = g.SetNextWindowFocus = false; } -static bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) +bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - if (!ImGui::IsPopupOpen(id)) + if (!IsPopupOpen(id)) { ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; } - ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; char name[20]; @@ -3578,11 +3576,11 @@ static bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) else ImFormatString(name, IM_ARRAYSIZE(name), "##popup_%08x", id); // Not recycling, so we can close/open during the same frame - bool is_open = ImGui::Begin(name, NULL, flags); + bool is_open = Begin(name, NULL, flags); if (!(window->Flags & ImGuiWindowFlags_ShowBorders)) g.CurrentWindow->Flags &= ~ImGuiWindowFlags_ShowBorders; if (!is_open) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display) - ImGui::EndPopup(); + EndPopup(); return is_open; } diff --git a/imgui_internal.h b/imgui_internal.h index fcced1ac9..056dccfa6 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -774,7 +774,9 @@ namespace ImGui IMGUI_API void PopItemFlag(); IMGUI_API void OpenPopupEx(ImGuiID id, bool reopen_existing); + IMGUI_API void ClosePopup(ImGuiID id); IMGUI_API bool IsPopupOpen(ImGuiID id); + IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); IMGUI_API int CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate); From 9f34925b2aa656d1897be50dcd6aed395f401455 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Sep 2017 13:23:25 +0200 Subject: [PATCH 08/14] Window: Tweaked ApplySizeFullWithConstraint() -> CalcSizeFullWithConstraint() so it can be used without side-effect --- imgui.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d3a3d2567..5de150028 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3882,7 +3882,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl return window; } -static void ApplySizeFullWithConstraint(ImGuiWindow* window, ImVec2 new_size) +static ImVec2 CalcSizeFullWithConstraint(ImGuiWindow* window, ImVec2 new_size) { ImGuiContext& g = *GImGui; if (g.SetNextWindowSizeConstraint) @@ -3904,7 +3904,7 @@ static void ApplySizeFullWithConstraint(ImGuiWindow* window, ImVec2 new_size) } if (!(window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysAutoResize))) new_size = ImMax(new_size, g.Style.WindowMinSize); - window->SizeFull = new_size; + return new_size; } static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window) @@ -4161,7 +4161,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us } // Apply minimum/maximum window size constraints and final size - ApplySizeFullWithConstraint(window, window->SizeFull); + window->SizeFull = CalcSizeFullWithConstraint(window, window->SizeFull); window->Size = window->Collapsed ? window->TitleBarRect().GetSize() : window->SizeFull; // POSITION @@ -4286,7 +4286,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (size_target.x != FLT_MAX && size_target.y != FLT_MAX) { - ApplySizeFullWithConstraint(window, size_target); + window->SizeFull = CalcSizeFullWithConstraint(window, size_target); MarkIniSettingsDirty(window); } window->Size = window->SizeFull; From 0a5557328868bb331804ebb8e114d58ec6a28d37 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Sep 2017 15:48:52 +0200 Subject: [PATCH 09/14] Begin(): Minor tidying up of flow --- imgui.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5de150028..310cfe2c0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4143,13 +4143,13 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (window->AutoFitFramesY > 0) window->SizeFull.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; } - else + else if (!window_size_set_by_api) { - if ((flags & ImGuiWindowFlags_AlwaysAutoResize) && !window_size_set_by_api) + if (flags & ImGuiWindowFlags_AlwaysAutoResize) { window->SizeFull = size_auto_fit; } - else if ((window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) && !window_size_set_by_api) + else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) { // Auto-fit only grows during the first few frames if (window->AutoFitFramesX > 0) From 4b82759598e34aed179177ecaa00e774c0d23484 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Sep 2017 18:25:43 +0200 Subject: [PATCH 10/14] SetNextWindowPos: added a ImVec2 pivot parameter for positioning a given a center, bottom-right position, etc. As a generalization of SetNextWindowPosCenter() which is now obsolete. This will be useful for combo-like popups as well. Demo: Simple-overlay window uses the SetWindowPos pivot to select a corner to position itself at. --- imgui.cpp | 37 ++++++++++++++++++++++--------------- imgui.h | 4 ++-- imgui_demo.cpp | 28 +++++++++++++++++++--------- imgui_internal.h | 4 +++- 4 files changed, 46 insertions(+), 27 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 310cfe2c0..f7cda6712 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -204,6 +204,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2017/09/25 (1.52) - removed SetNextWindowPosCenter() because SetNextWindowPos() now has the optional pivot information to do the same and more. Kept redirection function (will obsolete). - 2017/08/25 (1.52) - io.MousePos needs to be set to ImVec2(-FLT_MAX,-FLT_MAX) when mouse is unavailable/missing. Previously ImVec2(-1,-1) was enough but we now accept negative mouse coordinates. In your binding if you need to support unavailable mouse, make sure to replace "io.MousePos = ImVec2(-1,-1)" with "io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX)". - 2017/08/22 (1.51) - renamed IsItemHoveredRect() to IsItemRectHovered(). Kept inline redirection function (will obsolete). - renamed IsMouseHoveringAnyWindow() to IsAnyWindowHovered() for consistency. Kept inline redirection function (will obsolete). @@ -1804,7 +1805,7 @@ ImGuiWindow::ImGuiWindow(const char* name) AutoPosLastDirection = -1; HiddenFrames = 0; SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing; - SetWindowPosCenterWanted = false; + SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX); LastFrameActive = -1; ItemWidthDefault = 0.0f; @@ -3619,11 +3620,15 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags ext return false; } + // Center modal windows by default + if ((window->SetWindowPosAllowFlags & g.SetNextWindowPosCond) == 0) + SetNextWindowPos(g.IO.DisplaySize * 0.5f, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); + ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_Modal|ImGuiWindowFlags_NoCollapse|ImGuiWindowFlags_NoSavedSettings; bool is_open = ImGui::Begin(name, p_open, flags); if (!is_open || (p_open && !*p_open)) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display) { - ImGui::EndPopup(); + EndPopup(); if (is_open) ClosePopup(id); return false; @@ -3994,9 +3999,12 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us 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.SetNextWindowPosVal - ImVec2(-FLT_MAX,-FLT_MAX)) < 0.001f) + if (window_pos_set_by_api && ImLengthSqr(g.SetNextWindowPosPivot) > 0.00001f) { - window->SetWindowPosCenterWanted = true; // May be processed on the next frame if this is our first frame and we are measuring size + // May be processed on the next frame if this is our first frame and we are measuring size + // FIXME: Look into removing the branch so everything can go through this same codepath for consistency. + window->SetWindowPosVal = g.SetNextWindowPosVal; + window->SetWindowPosPivot = g.SetNextWindowPosPivot; window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); } else @@ -4178,13 +4186,11 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us window->Size = window->SizeFull = size_on_first_use; // NB: argument name 'size_on_first_use' misleading here, it's really just 'size' as provided by user passed via BeginChild()->Begin(). } - bool window_pos_center = false; - window_pos_center |= (window->SetWindowPosCenterWanted && window->HiddenFrames == 0); - window_pos_center |= ((flags & ImGuiWindowFlags_Modal) && !window_pos_set_by_api && window_just_appearing_after_hidden_for_resize); - if (window_pos_center) + const bool window_pos_with_pivot = (window->SetWindowPosVal.x != FLT_MAX && window->HiddenFrames == 0); + if (window_pos_with_pivot) { - // Center (any sort of window) - SetWindowPos(window, ImMax(style.DisplaySafeAreaPadding, fullscreen_rect.GetCenter() - window->SizeFull * 0.5f), 0); + // Position given a pivot (e.g. for centering) + SetWindowPos(window, ImMax(style.DisplaySafeAreaPadding, window->SetWindowPosVal - window->SizeFull * window->SetWindowPosPivot), 0); } else if (flags & ImGuiWindowFlags_ChildMenu) { @@ -5010,7 +5016,7 @@ static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond) if (cond && (window->SetWindowPosAllowFlags & cond) == 0) return; window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); - window->SetWindowPosCenterWanted = false; + window->SetWindowPosVal = ImVec2(FLT_MAX, FLT_MAX); // Set const ImVec2 old_pos = window->Pos; @@ -5133,19 +5139,20 @@ void ImGui::SetWindowFocus(const char* name) } } -void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond) +void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pivot) { ImGuiContext& g = *GImGui; g.SetNextWindowPosVal = pos; + g.SetNextWindowPosPivot = pivot; g.SetNextWindowPosCond = cond ? cond : ImGuiCond_Always; } +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS void ImGui::SetNextWindowPosCenter(ImGuiCond cond) { - ImGuiContext& g = *GImGui; - g.SetNextWindowPosVal = ImVec2(-FLT_MAX, -FLT_MAX); - g.SetNextWindowPosCond = cond ? cond : ImGuiCond_Always; + SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, cond, ImVec2(0.5f, 0.5f)); } +#endif void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiCond cond) { diff --git a/imgui.h b/imgui.h index 238ff89d8..4bfa9430d 100644 --- a/imgui.h +++ b/imgui.h @@ -152,8 +152,7 @@ namespace ImGui IMGUI_API bool IsWindowAppearing(); IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows - IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // set next window position. call before Begin() - IMGUI_API void SetNextWindowPosCenter(ImGuiCond cond = 0); // set next window position to be centered on screen. call before Begin() + IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0, const ImVec2& pivot = ImVec2(0,0)); // set next window position. call before Begin(). use pivot=(0.5f,0.5f) to center on given point, etc. IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin() IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeConstraintCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Use callback to apply non-trivial programmatic constraints. IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (enforce the range of scrollbars). set axis to 0.0f to leave it automatic. call before Begin() @@ -489,6 +488,7 @@ namespace ImGui // Obsolete functions (Will be removed! Also see 'API BREAKING CHANGES' section in imgui.cpp) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + static void SetNextWindowPosCenter(ImGuiCond cond = 0); // OBSOLETE 1.52+ static inline bool IsItemHoveredRect() { return IsItemRectHovered(); } // OBSOLETE 1.51+ static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // OBSOLETE 1.51+. This was partly broken. You probably wanted to use ImGui::GetIO().WantCaptureMouse instead. static inline bool IsMouseHoveringAnyWindow() { return IsAnyWindowHovered(); } // OBSOLETE 1.51+ diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 543172b28..9542b8830 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1434,7 +1434,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::OpenPopup("Delete?"); if (ImGui::BeginPopupModal("Delete?", NULL, ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n"); + ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n"); ImGui::Separator(); //static int dummy_i = 0; @@ -2114,20 +2114,30 @@ static void ShowExampleAppConstrainedResize(bool* p_open) ImGui::End(); } -// Demonstrate creating a simple static window with no decoration. +// Demonstrate creating a simple static window with no decoration + a context-menu to choose which corner of the screen to use. static void ShowExampleAppFixedOverlay(bool* p_open) { - ImGui::SetNextWindowPos(ImVec2(10,10)); + const float DISTANCE = 10.0f; + static int corner = 0; + ImVec2 window_pos = ImVec2((corner & 1) ? ImGui::GetIO().DisplaySize.x - DISTANCE : DISTANCE, (corner & 2) ? ImGui::GetIO().DisplaySize.y - DISTANCE : DISTANCE); + ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f); + ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot); ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 0.3f)); - if (!ImGui::Begin("Example: Fixed Overlay", p_open, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) + if (ImGui::Begin("Example: Fixed Overlay", p_open, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) { + ImGui::Text("Simple overlay\nin the corner of the screen.\n(right-click to change position)"); + ImGui::Separator(); + ImGui::Text("Mouse Position: (%.1f,%.1f)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y); + if (ImGui::BeginPopupContextWindow()) + { + if (ImGui::MenuItem("Top-left", NULL, corner == 0)) corner = 0; + if (ImGui::MenuItem("Top-right", NULL, corner == 1)) corner = 1; + if (ImGui::MenuItem("Bottom-left", NULL, corner == 2)) corner = 2; + if (ImGui::MenuItem("Bottom-right", NULL, corner == 3)) corner = 3; + ImGui::EndPopup(); + } ImGui::End(); - return; } - ImGui::Text("Simple overlay\non the top-left side of the screen."); - ImGui::Separator(); - ImGui::Text("Mouse Position: (%.1f,%.1f)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y); - ImGui::End(); ImGui::PopStyleColor(); } diff --git a/imgui_internal.h b/imgui_internal.h index 056dccfa6..8f6762bde 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -437,6 +437,7 @@ struct ImGuiContext // Storage for SetNexWindow** and SetNextTreeNode*** functions ImVec2 SetNextWindowPosVal; + ImVec2 SetNextWindowPosPivot; ImVec2 SetNextWindowSizeVal; ImVec2 SetNextWindowContentSizeVal; bool SetNextWindowCollapsedVal; @@ -696,7 +697,8 @@ struct IMGUI_API ImGuiWindow ImGuiCond SetWindowPosAllowFlags; // store condition flags for next SetWindowPos() call. ImGuiCond SetWindowSizeAllowFlags; // store condition flags for next SetWindowSize() call. ImGuiCond SetWindowCollapsedAllowFlags; // store condition flags for next SetWindowCollapsed() call. - bool SetWindowPosCenterWanted; + ImVec2 SetWindowPosVal; // store window position when using a non-zero Pivot (position set needs to be processed when we know the window size) + ImVec2 SetWindowPosPivot; // store window pivot for positioning. ImVec2(0,0) when positioning from top-left corner; ImVec2(0.5f,0.5f) for centering; ImVec2(1,1) for bottom right. ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame ImVector IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack From a34edb810e8136f46f03dc9fd757fa772660e318 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Sep 2017 21:12:07 +0200 Subject: [PATCH 11/14] Demo: Fixed overlay demo keeps resizing (in case, e.g.: font changes) --- imgui_demo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 9542b8830..6773840f8 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2123,7 +2123,7 @@ static void ShowExampleAppFixedOverlay(bool* p_open) ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f); ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot); ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 0.3f)); - if (ImGui::Begin("Example: Fixed Overlay", p_open, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) + if (ImGui::Begin("Example: Fixed Overlay", p_open, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings)) { ImGui::Text("Simple overlay\nin the corner of the screen.\n(right-click to change position)"); ImGui::Separator(); From 0d56140b4a71f3e68643d1af9139c8d61a8857c1 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Sep 2017 21:45:34 +0200 Subject: [PATCH 12/14] BeginCombo(): rework internals a little to make it easier to provide custom combo-like elements relying in BeginCombo(). BeginPopupEx() doesn't enforce AlwaysAutoResize flag anymore. --- TODO.txt | 3 ++- imgui.cpp | 31 +++++++++++++++++++------------ imgui_internal.h | 2 +- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/TODO.txt b/TODO.txt index bddf473c5..0369c6374 100644 --- a/TODO.txt +++ b/TODO.txt @@ -99,7 +99,8 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - plot: option/feature: draw unit - plot: add a helper e.g. Plot(char* label, float value, float time_span=2.0f) that stores values and Plot them for you - probably another function name. and/or automatically allow to plot ANY displayed value (more reliance on stable ID) - - clipper: ability to force display 1 item in the list would be convenient. + - clipper: ability to force display 1 item in the list would be convenient (for patterns where we need to set active id etc.) + - clipper: ability to disable the clipping through a simple flag/bool. - clipper: ability to run without knowing full count in advance. - splitter/separator: formalize the splitter idiom into an official api (we want to handle n-way split) (#319) diff --git a/imgui.cpp b/imgui.cpp index f7cda6712..88d0fcbbd 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3569,7 +3569,7 @@ bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) } PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); - ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize; + ImGuiWindowFlags flags = extra_flags|ImGuiWindowFlags_Popup|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings; char name[20]; if (flags & ImGuiWindowFlags_ChildMenu) @@ -3594,7 +3594,7 @@ bool ImGui::BeginPopup(const char* str_id) ClearSetNextWindowData(); // We behave like Begin() and need to consume those values return false; } - return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_ShowBorders); + return BeginPopupEx(g.CurrentWindow->GetID(str_id), ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize); } bool ImGui::IsPopupOpen(ImGuiID id) @@ -8602,7 +8602,7 @@ bool ImGui::Combo(const char* label, int* current_item, const char* items_separa return value_changed; } -bool ImGui::BeginCombo(const char* label, const char* preview_value, float popup_opened_height) +bool ImGui::BeginCombo(const char* label, const char* preview_value, ImVec2 popup_size) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) @@ -8662,17 +8662,24 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, float popup if (!popup_open) return false; + if (popup_size.x == 0.0f) + popup_size.x = w; + float popup_y1 = frame_bb.Max.y; - float popup_y2 = ImClamp(popup_y1 + popup_opened_height, popup_y1, g.IO.DisplaySize.y - style.DisplaySafeAreaPadding.y); - if ((popup_y2 - popup_y1) < ImMin(popup_opened_height, frame_bb.Min.y - style.DisplaySafeAreaPadding.y)) + float popup_y2 = ImClamp(popup_y1 + popup_size.y, popup_y1, g.IO.DisplaySize.y - style.DisplaySafeAreaPadding.y); + if ((popup_y2 - popup_y1) < ImMin(popup_size.y, frame_bb.Min.y - style.DisplaySafeAreaPadding.y)) { // Position our combo ABOVE because there's more space to fit! (FIXME: Handle in Begin() or use a shared helper. We have similar code in Begin() for popup placement) - popup_y1 = ImClamp(frame_bb.Min.y - popup_opened_height, style.DisplaySafeAreaPadding.y, frame_bb.Min.y); + popup_y1 = ImClamp(frame_bb.Min.y - popup_size.y, style.DisplaySafeAreaPadding.y, frame_bb.Min.y); popup_y2 = frame_bb.Min.y; + SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Min.y), ImGuiCond_Always, ImVec2(0.0f, 1.0f)); } - ImRect popup_rect(ImVec2(frame_bb.Min.x, popup_y1), ImVec2(frame_bb.Max.x, popup_y2)); - SetNextWindowPos(popup_rect.Min); - SetNextWindowSize(popup_rect.GetSize()); + else + { + // Position our combo below + SetNextWindowPos(ImVec2(frame_bb.Min.x, frame_bb.Max.y), ImGuiCond_Always, ImVec2(0.0f, 0.0f)); + } + SetNextWindowSize(ImVec2(popup_size.x, popup_y2 - popup_y1), ImGuiCond_Appearing); PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); const ImGuiWindowFlags flags = ImGuiWindowFlags_ComboBox | ((window->Flags & ImGuiWindowFlags_ShowBorders) ? ImGuiWindowFlags_ShowBorders : 0); @@ -8705,9 +8712,9 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi // Size default to hold ~7 items if (height_in_items < 0) height_in_items = 7; - float popup_opened_height = (g.FontSize + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + (style.FramePadding.y * 3); + float popup_height = (g.FontSize + style.ItemSpacing.y) * ImMin(items_count, height_in_items) + (style.FramePadding.y * 3); - if (!BeginCombo(label, preview_text, popup_opened_height)) + if (!BeginCombo(label, preview_text, ImVec2(0.0f, popup_height))) return false; // Display items @@ -9119,7 +9126,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) if (menu_is_open) { SetNextWindowPos(popup_pos, ImGuiCond_Always); - ImGuiWindowFlags flags = ImGuiWindowFlags_ShowBorders | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); + ImGuiWindowFlags flags = ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_AlwaysAutoResize | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) } diff --git a/imgui_internal.h b/imgui_internal.h index 8f6762bde..63bbb0437 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -788,7 +788,7 @@ namespace ImGui IMGUI_API void PushColumnClipRect(int column_index = -1); // FIXME-WIP: New Combo API - IMGUI_API bool BeginCombo(const char* label, const char* preview_value, float popup_opened_height); + IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImVec2 popup_size = ImVec2(0.0f,0.0f)); IMGUI_API void EndCombo(); // NB: All position are in absolute pixels coordinates (never using window coordinates internally) From 4b2781fe8761aa63d2f2625263de4560c4b5f00d Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Sep 2017 21:57:42 +0200 Subject: [PATCH 13/14] Begin: Moving some code into a CalcSizeAutoFit() function. --- imgui.cpp | 48 +++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 88d0fcbbd..ae9d74377 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3912,6 +3912,30 @@ static ImVec2 CalcSizeFullWithConstraint(ImGuiWindow* window, ImVec2 new_size) return new_size; } +static ImVec2 CalcSizeAutoFit(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + ImGuiStyle& style = g.Style; + ImGuiWindowFlags flags = window->Flags; + ImVec2 size_auto_fit; + if ((flags & ImGuiWindowFlags_Tooltip) != 0) + { + // Tooltip always resize. We keep the spacing symmetric on both axises for aesthetic purpose. + size_auto_fit = window->SizeContents + window->WindowPadding - ImVec2(0.0f, style.ItemSpacing.y); + } + else + { + // Handling case of auto fit window not fitting in screen on one axis, we are growing auto fit size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding. + size_auto_fit = ImClamp(window->SizeContents + window->WindowPadding, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding)); + if (size_auto_fit.x < window->SizeContents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) + size_auto_fit.y += style.ScrollbarSize; + if (size_auto_fit.y < window->SizeContents.y && !(flags & ImGuiWindowFlags_NoScrollbar)) + size_auto_fit.x += style.ScrollbarSize; + size_auto_fit.y = ImMax(size_auto_fit.y - style.ItemSpacing.y, 0.0f); + } + return size_auto_fit; +} + static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window) { ImVec2 scroll = window->Scroll; @@ -4002,7 +4026,7 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us if (window_pos_set_by_api && ImLengthSqr(g.SetNextWindowPosPivot) > 0.00001f) { // May be processed on the next frame if this is our first frame and we are measuring size - // FIXME: Look into removing the branch so everything can go through this same codepath for consistency. + // FIXME: Look into removing the branch so everything can go through this same code path for consistency. window->SetWindowPosVal = g.SetNextWindowPosVal; window->SetWindowPosPivot = g.SetNextWindowPosPivot; window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); @@ -4122,26 +4146,8 @@ bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_on_first_us // Lock window padding so that altering the ShowBorders flag for children doesn't have side-effects. window->WindowPadding = ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_ShowBorders | ImGuiWindowFlags_ComboBox | ImGuiWindowFlags_Popup))) ? ImVec2(0,0) : style.WindowPadding; - // Calculate auto-fit size - ImVec2 size_auto_fit; - if ((flags & ImGuiWindowFlags_Tooltip) != 0) - { - // Tooltip always resize. We keep the spacing symmetric on both axises for aesthetic purpose. - size_auto_fit = window->SizeContents + window->WindowPadding - ImVec2(0.0f, style.ItemSpacing.y); - } - else - { - size_auto_fit = ImClamp(window->SizeContents + window->WindowPadding, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding)); - - // Handling case of auto fit window not fitting in screen on one axis, we are growing auto fit size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding. - if (size_auto_fit.x < window->SizeContents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) - size_auto_fit.y += style.ScrollbarSize; - if (size_auto_fit.y < window->SizeContents.y && !(flags & ImGuiWindowFlags_NoScrollbar)) - size_auto_fit.x += style.ScrollbarSize; - size_auto_fit.y = ImMax(size_auto_fit.y - style.ItemSpacing.y, 0.0f); - } - - // Handle automatic resize + // Calculate auto-fit size, handle automatic resize + const ImVec2 size_auto_fit = CalcSizeAutoFit(window); if (window->Collapsed) { // We still process initial auto-fit on collapsed windows to get a window width, From c0547d358d746699f8d46a4996e49fdac8c55748 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 25 Sep 2017 22:04:39 +0200 Subject: [PATCH 14/14] Begin: Fixed auto-fit calculation code that predict the presence of ascrollbar so it works in the case size constraints are used. I actually don't need this fix now, but earlier experiment with BeginCombo() required this fix. --- imgui.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ae9d74377..8eb3319ff 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3925,12 +3925,13 @@ static ImVec2 CalcSizeAutoFit(ImGuiWindow* window) } else { - // Handling case of auto fit window not fitting in screen on one axis, we are growing auto fit size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding. + // Handling case of auto fit window not fitting on the screen (on either axis): we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding. size_auto_fit = ImClamp(window->SizeContents + window->WindowPadding, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding)); - if (size_auto_fit.x < window->SizeContents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) + ImVec2 size_auto_fit_after_constraint = CalcSizeFullWithConstraint(window, size_auto_fit); + if (size_auto_fit_after_constraint.x < window->SizeContents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) size_auto_fit.y += style.ScrollbarSize; - if (size_auto_fit.y < window->SizeContents.y && !(flags & ImGuiWindowFlags_NoScrollbar)) - size_auto_fit.x += style.ScrollbarSize; + if (size_auto_fit_after_constraint.y < window->SizeContents.y && !(flags & ImGuiWindowFlags_NoScrollbar)) + size_auto_fit.x += style.ScrollbarSize * 2.0f; size_auto_fit.y = ImMax(size_auto_fit.y - style.ItemSpacing.y, 0.0f); } return size_auto_fit;