From 10fdc03a46921c71356d1e5c932a6f2ea1250f38 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 17 Dec 2019 13:19:36 +0100 Subject: [PATCH 1/7] Clarification about Im helpers + moving GetColorXXX functions outside of that block. --- imgui.cpp | 66 ++++++++++++++++++++++++------------------------ imgui_internal.h | 2 ++ 2 files changed, 35 insertions(+), 33 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c32b64c1..30957849 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1726,38 +1726,6 @@ void ImGui::ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& } } -ImU32 ImGui::GetColorU32(ImGuiCol idx, float alpha_mul) -{ - ImGuiStyle& style = GImGui->Style; - ImVec4 c = style.Colors[idx]; - c.w *= style.Alpha * alpha_mul; - return ColorConvertFloat4ToU32(c); -} - -ImU32 ImGui::GetColorU32(const ImVec4& col) -{ - ImGuiStyle& style = GImGui->Style; - ImVec4 c = col; - c.w *= style.Alpha; - return ColorConvertFloat4ToU32(c); -} - -const ImVec4& ImGui::GetStyleColorVec4(ImGuiCol idx) -{ - ImGuiStyle& style = GImGui->Style; - return style.Colors[idx]; -} - -ImU32 ImGui::GetColorU32(ImU32 col) -{ - float style_alpha = GImGui->Style.Alpha; - if (style_alpha >= 1.0f) - return col; - ImU32 a = (col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT; - a = (ImU32)(a * style_alpha); // We don't need to clamp 0..255 because Style.Alpha is in 0..1 range. - return (col & ~IM_COL32_A_MASK) | (a << IM_COL32_A_SHIFT); -} - //----------------------------------------------------------------------------- // [SECTION] ImGuiStorage // Helper: Key->value storage @@ -2215,10 +2183,42 @@ bool ImGuiListClipper::Step() //----------------------------------------------------------------------------- // [SECTION] RENDER HELPERS -// Those (internal) functions are currently quite a legacy mess - their signature and behavior will change. +// Some of those (internal) functions are currently quite a legacy mess - their signature and behavior will change. // Also see imgui_draw.cpp for some more which have been reworked to not rely on ImGui:: state. //----------------------------------------------------------------------------- +ImU32 ImGui::GetColorU32(ImGuiCol idx, float alpha_mul) +{ + ImGuiStyle& style = GImGui->Style; + ImVec4 c = style.Colors[idx]; + c.w *= style.Alpha * alpha_mul; + return ColorConvertFloat4ToU32(c); +} + +ImU32 ImGui::GetColorU32(const ImVec4& col) +{ + ImGuiStyle& style = GImGui->Style; + ImVec4 c = col; + c.w *= style.Alpha; + return ColorConvertFloat4ToU32(c); +} + +const ImVec4& ImGui::GetStyleColorVec4(ImGuiCol idx) +{ + ImGuiStyle& style = GImGui->Style; + return style.Colors[idx]; +} + +ImU32 ImGui::GetColorU32(ImU32 col) +{ + ImGuiStyle& style = GImGui->Style; + if (style.Alpha >= 1.0f) + return col; + ImU32 a = (col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT; + a = (ImU32)(a * style.Alpha); // We don't need to clamp 0..255 because Style.Alpha is in 0..1 range. + return (col & ~IM_COL32_A_MASK) | (a << IM_COL32_A_SHIFT); +} + const char* ImGui::FindRenderedTextEnd(const char* text, const char* text_end) { const char* text_display_end = text; diff --git a/imgui_internal.h b/imgui_internal.h index ec35468f..07fb2882 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -192,6 +192,8 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer //----------------------------------------------------------------------------- // Generic helpers +// Note that the ImXXX helpers functions are lower-level than ImGui functions. +// ImGui functions or the ImGui context are never called/used from other ImXXX functions. //----------------------------------------------------------------------------- // - Helpers: Misc // - Helpers: Bit manipulation From 9d444062f974b21f1fc09b7e85479fff3e0789c2 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 17 Dec 2019 13:25:46 +0100 Subject: [PATCH 2/7] Limiting Columns()/BeginColumns() api to 64 columns (#125) While the current code technically supports it, future code may not so we're putting the restriction ahead. --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 1 + imgui.h | 1 + imgui_widgets.cpp | 4 ++-- 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 13e3cec7..c9ff9b2d 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -55,6 +55,8 @@ Breaking Changes: documented (can only unreserve from the last reserve call). If you suspect you ever used that feature before, #define IMGUI_DEBUG_PARANOID in imconfig.h to catch existing calls. [@ShironekoBen] +- Limiting Columns()/BeginColumns() api to 64 columns with an assert. While the current code + technically supports it, future code may not so we're putting the restriction ahead. - imgui_internal.h: changed ImRect() default constructor initializes all fields to 0.0f instead of (FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX). If you used ImRect::Add() to create bounding boxes by adding multiple points into it, you may need to fix your initial value. diff --git a/imgui.cpp b/imgui.cpp index 30957849..dff12b62 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -353,6 +353,7 @@ CODE When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. You can read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2019/12/17 (1.75) - made Columns() limited to 64 columns by asserting above that limit. While the current code technically supports it, future code may not so we're putting the restriction ahead. - 2019/12/13 (1.75) - [imgui_internal.h] changed ImRect() default constructor initializes all fields to 0.0f instead of (FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX). If you used ImRect::Add() to create bounding boxes by adding multiple points into it, you may need to fix your initial value. - 2019/12/08 (1.75) - removed redirecting functions/enums that were marked obsolete in 1.53 (December 2017): - ShowTestWindow() -> use ShowDemoWindow() diff --git a/imgui.h b/imgui.h index 13150f14..704a7211 100644 --- a/imgui.h +++ b/imgui.h @@ -584,6 +584,7 @@ namespace ImGui // Columns // - You can also use SameLine(pos_x) to mimic simplified columns. // - The columns API is work-in-progress and rather lacking (columns are arguably the worst part of dear imgui at the moment!) + // - There is a maximum of 64 columns. // - By end of the 2019 we will expose a new 'Table' api which will replace columns. IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true); IMGUI_API void NextColumn(); // next column, defaults to current row or next row if the current row is finished diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index d605e2d7..684dbe55 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7411,8 +7411,8 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); - IM_ASSERT(columns_count >= 1); - IM_ASSERT(window->DC.CurrentColumns == NULL); // Nested columns are currently not supported + IM_ASSERT(columns_count >= 1 && columns_count <= 64); // Maximum 64 columns + IM_ASSERT(window->DC.CurrentColumns == NULL); // Nested columns are currently not supported // Acquire storage for the columns set ImGuiID id = GetColumnsID(str_id, columns_count); From 78ff147181919f3f3595d90b571bd0863c0c4aa4 Mon Sep 17 00:00:00 2001 From: NeroBurner-tux Date: Tue, 24 Sep 2019 19:44:29 +0200 Subject: [PATCH 3/7] SDL: On wayland use SDL_GetMouseState (#2802) When the SDL Video backend is set to wayland the function `SDL_GetGlobalMouseState` does not work. Most probably a security measure for programs to not grab everything the user does https://wiki.libsdl.org/SDL_GetGlobalMouseState using SDL_GetMouseState https://wiki.libsdl.org/SDL_GetMouseState works on wayland --- examples/imgui_impl_sdl.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/examples/imgui_impl_sdl.cpp b/examples/imgui_impl_sdl.cpp index 05498c09..ac4f55fc 100644 --- a/examples/imgui_impl_sdl.cpp +++ b/examples/imgui_impl_sdl.cpp @@ -17,6 +17,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2019-12-17: Inputs: Use SDL_GetMouseState, because there is no global mouse state on Wayland. // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. // 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter. // 2019-04-23: Inputs: Added support for SDL_GameController (if ImGuiConfigFlags_NavEnableGamepad is set by user application). @@ -60,6 +61,7 @@ static Uint64 g_Time = 0; static bool g_MousePressed[3] = { false, false, false }; static SDL_Cursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; static char* g_ClipboardTextData = NULL; +static bool g_VideoDriverIsWayland = false; static const char* ImGui_ImplSDL2_GetClipboardText(void*) { @@ -124,6 +126,9 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window) { g_Window = window; + // Check and store if we are on Wayland to not check on every frame. + g_VideoDriverIsWayland = strncmp(SDL_GetCurrentVideoDriver(), "wayland", 7) == 0; + // Setup back-end capabilities flags ImGuiIO& io = ImGui::GetIO(); io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) @@ -238,13 +243,17 @@ static void ImGui_ImplSDL2_UpdateMousePosAndButtons() SDL_Window* focused_window = SDL_GetKeyboardFocus(); if (g_Window == focused_window) { - // SDL_GetMouseState() gives mouse position seemingly based on the last window entered/focused(?) - // The creation of a new windows at runtime and SDL_CaptureMouse both seems to severely mess up with that, so we retrieve that position globally. - int wx, wy; - SDL_GetWindowPosition(focused_window, &wx, &wy); - SDL_GetGlobalMouseState(&mx, &my); - mx -= wx; - my -= wy; + if (!g_VideoDriverIsWayland) + { + // SDL_GetMouseState() gives mouse position seemingly based on the last window entered/focused(?) + // The creation of a new windows at runtime and SDL_CaptureMouse both seems to severely mess up with that, so we retrieve that position globally. + // Won't use this workaround when on Wayland, as there is no global mouse position. + int wx, wy; + SDL_GetWindowPosition(focused_window, &wx, &wy); + SDL_GetGlobalMouseState(&mx, &my); + mx -= wx; + my -= wy; + } io.MousePos = ImVec2((float)mx, (float)my); } From 0f7105e15608b7198980864c1a92b07c124c7c0d Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 17 Dec 2019 14:34:18 +0100 Subject: [PATCH 4/7] Backends: SDL: Wayland: Use SDL_GetMouseState (amend 78ff147) (#2800, 2802) --- docs/CHANGELOG.txt | 2 ++ examples/imgui_impl_sdl.cpp | 13 +++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index c9ff9b2d..0eecd414 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -71,6 +71,8 @@ Other Changes: selection, those new api can fill a gap. [@ShironekoBen] - Backends: GLFW, SDL, Win32, OSX, Allegro: Added support for ImGuiMouseCursor_NotAllowed. [@rokups] - Backends: GLFW: Added support for the missing mouse cursors newly added in GLFW 3.4+. [@rokups] +- Backends: SDL: Wayland: use SDL_GetMouseState (because there is no global mouse state available + on Wayland). (#2800, #2802) [@NeroBurner] - Examples: Explicitly adding -DIMGUI_IMPL_OPENGL_LOADER_GL3W to Makefile to match linking settings (otherwise if another loader such as Glew is accessible, the opengl3 backend might automatically use it). [#2919, #2798] diff --git a/examples/imgui_impl_sdl.cpp b/examples/imgui_impl_sdl.cpp index ac4f55fc..8a295aaa 100644 --- a/examples/imgui_impl_sdl.cpp +++ b/examples/imgui_impl_sdl.cpp @@ -17,7 +17,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) -// 2019-12-17: Inputs: Use SDL_GetMouseState, because there is no global mouse state on Wayland. +// 2019-12-17: Inputs: On Wayland, use SDL_GetMouseState (because there is no global mouse state). // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. // 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter. // 2019-04-23: Inputs: Added support for SDL_GameController (if ImGuiConfigFlags_NavEnableGamepad is set by user application). @@ -61,7 +61,7 @@ static Uint64 g_Time = 0; static bool g_MousePressed[3] = { false, false, false }; static SDL_Cursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; static char* g_ClipboardTextData = NULL; -static bool g_VideoDriverIsWayland = false; +static bool g_MouseCanUseGlobalState = true; static const char* ImGui_ImplSDL2_GetClipboardText(void*) { @@ -126,9 +126,6 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window) { g_Window = window; - // Check and store if we are on Wayland to not check on every frame. - g_VideoDriverIsWayland = strncmp(SDL_GetCurrentVideoDriver(), "wayland", 7) == 0; - // Setup back-end capabilities flags ImGuiIO& io = ImGui::GetIO(); io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) @@ -163,6 +160,7 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window) io.GetClipboardTextFn = ImGui_ImplSDL2_GetClipboardText; io.ClipboardUserData = NULL; + // Load mouse cursors g_MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); g_MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); g_MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); @@ -173,6 +171,9 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window) g_MouseCursors[ImGuiMouseCursor_Hand] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); g_MouseCursors[ImGuiMouseCursor_NotAllowed] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NO); + // Check and store if we are on Wayland + g_MouseCanUseGlobalState = strncmp(SDL_GetCurrentVideoDriver(), "wayland", 7) != 0; + #ifdef _WIN32 SDL_SysWMinfo wmInfo; SDL_VERSION(&wmInfo.version); @@ -243,7 +244,7 @@ static void ImGui_ImplSDL2_UpdateMousePosAndButtons() SDL_Window* focused_window = SDL_GetKeyboardFocus(); if (g_Window == focused_window) { - if (!g_VideoDriverIsWayland) + if (g_MouseCanUseGlobalState) { // SDL_GetMouseState() gives mouse position seemingly based on the last window entered/focused(?) // The creation of a new windows at runtime and SDL_CaptureMouse both seems to severely mess up with that, so we retrieve that position globally. From 3831d50ab96c33d24cec3e048d9c7839d2d64074 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Tue, 17 Dec 2019 16:29:12 +0200 Subject: [PATCH 5/7] Add ImBezierClosestPoint() function which returns a point on bezier curve which is closed to a specified point. --- imgui.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++++ imgui_draw.cpp | 21 ++++++++------- imgui_internal.h | 3 +++ 3 files changed, 81 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index dff12b62..d114f9ef 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1109,6 +1109,72 @@ void ImGuiIO::ClearInputCharacters() // [SECTION] MISC HELPERS/UTILITIES (Geometry, String, Format, Hash, File functions) //----------------------------------------------------------------------------- +ImVec2 ImBezierClosestPoint(const ImVec2& p, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments) +{ + IM_ASSERT(num_segments > 0); + ImVec2 p_last = p1; + ImVec2 p_closest; + float p_closest_dist2 = FLT_MAX; + float t_step = 1.0f / (float)num_segments; + for (int i_step = 1; i_step <= num_segments; i_step++) + { + ImVec2 p_current = ImBezierCalc(p1, p2, p3, p4, t_step * i_step); + ImVec2 p_line = ImLineClosestPoint(p_last, p_current, p); + float dist2 = ImLengthSqr(p - p_line); + if (dist2 < p_closest_dist2) + { + p_closest = p_line; + p_closest_dist2 = dist2; + } + p_last = p_current; + } + return p_closest; +} + +// Closely mimics PathBezierToCasteljau() in imgui_draw.cpp +static void ClosestPointBezierCasteljau(const ImVec2& p, ImVec2& p_closest, ImVec2& p_last, float& p_closest_dist2, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level) +{ + float dx = x4 - x1; + float dy = y4 - y1; + float d2 = ((x2 - x4) * dy - (y2 - y4) * dx); + float d3 = ((x3 - x4) * dy - (y3 - y4) * dx); + d2 = (d2 >= 0) ? d2 : -d2; + d3 = (d3 >= 0) ? d3 : -d3; + if ((d2+d3) * (d2+d3) < tess_tol * (dx*dx + dy*dy)) + { + ImVec2 p_current(x4, y4); + ImVec2 p_line = ImLineClosestPoint(p_last, p_current, p); + float dist2 = ImLengthSqr(p - p_line); + if (dist2 < p_closest_dist2) + { + p_closest = p_line; + p_closest_dist2 = dist2; + } + p_last = p_current; + } + else if (level < 10) + { + float x12 = (x1+x2)*0.5f, y12 = (y1+y2)*0.5f; + float x23 = (x2+x3)*0.5f, y23 = (y2+y3)*0.5f; + float x34 = (x3+x4)*0.5f, y34 = (y3+y4)*0.5f; + float x123 = (x12+x23)*0.5f, y123 = (y12+y23)*0.5f; + float x234 = (x23+x34)*0.5f, y234 = (y23+y34)*0.5f; + float x1234 = (x123+x234)*0.5f, y1234 = (y123+y234)*0.5f; + ClosestPointBezierCasteljau(p, p_closest, p_last, p_closest_dist2, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1); + ClosestPointBezierCasteljau(p, p_closest, p_last, p_closest_dist2, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1); + } +} + +ImVec2 ImBezierClosestPointCasteljau(const ImVec2& p, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float tess_tol) +{ + IM_ASSERT(tess_tol > 0.0f); + ImVec2 p_last = p1; + ImVec2 p_closest; + float p_closest_dist2 = FLT_MAX; + ClosestPointBezierCasteljau(p, p_closest, p_last, p_closest_dist2, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, tess_tol, 0); + return p_closest; +} + ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p) { ImVec2 ap = p - a; diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 9efb4731..8f913dc0 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -907,6 +907,17 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa } } +ImVec2 ImBezierCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t) +{ + float u = 1.0f - t; + float w1 = u*u*u; + float w2 = 3*u*u*t; + float w3 = 3*u*t*t; + float w4 = t*t*t; + return ImVec2(w1*p1.x + w2*p2.x + w3*p3.x + w4*p4.x, w1*p1.y + w2*p2.y + w3*p3.y + w4*p4.y); +} + +// Closely mimicked by ClosestPointBezierCasteljau() in imgui.cpp static void PathBezierToCasteljau(ImVector* path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level) { float dx = x4 - x1; @@ -945,15 +956,7 @@ void ImDrawList::PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImV { float t_step = 1.0f / (float)num_segments; for (int i_step = 1; i_step <= num_segments; i_step++) - { - float t = t_step * i_step; - float u = 1.0f - t; - float w1 = u*u*u; - float w2 = 3*u*u*t; - float w3 = 3*u*t*t; - float w4 = t*t*t; - _Path.push_back(ImVec2(w1*p1.x + w2*p2.x + w3*p3.x + w4*p4.x, w1*p1.y + w2*p2.y + w3*p3.y + w4*p4.y)); - } + _Path.push_back(ImBezierCalc(p1, p2, p3, p4, t_step * i_step)); } } diff --git a/imgui_internal.h b/imgui_internal.h index 07fb2882..bf594bc5 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -340,6 +340,9 @@ static inline float ImLinearSweep(float current, float target, float speed) static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } // Helpers: Geometry +IMGUI_API ImVec2 ImBezierCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t); +IMGUI_API ImVec2 ImBezierClosestPoint(const ImVec2& p, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments); // For curves with explicit number of segments +IMGUI_API ImVec2 ImBezierClosestPointCasteljau(const ImVec2& p, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float tess_tol); // For auto-tesselated curves, tess_tol = style.CurveTessellationTol IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p); IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); From a610f1da52273cac7f4a90cbfd8cb0fb642d5a07 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 17 Dec 2019 16:24:50 +0100 Subject: [PATCH 6/7] Bezier Tweaks, fixed parameter order of 3831d50 --- imgui.cpp | 25 ++++++++++++++++--------- imgui.h | 4 ++-- imgui_draw.cpp | 13 ++++++------- imgui_internal.h | 6 +++--- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d114f9ef..c81ff318 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -45,7 +45,8 @@ CODE // [SECTION] FORWARD DECLARATIONS // [SECTION] CONTEXT AND MEMORY ALLOCATORS // [SECTION] MAIN USER FACING STRUCTURES (ImGuiStyle, ImGuiIO) -// [SECTION] MISC HELPERS/UTILITIES (Geometry, String, Format, Hash, File functions) +// [SECTION] MISC HELPERS/UTILITIES (Geometry functions) +// [SECTION] MISC HELPERS/UTILITIES (String, Format, Hash functions) // [SECTION] MISC HELPERS/UTILITIES (File functions) // [SECTION] MISC HELPERS/UTILITIES (ImText* functions) // [SECTION] MISC HELPERS/UTILITIES (Color functions) @@ -1106,12 +1107,12 @@ void ImGuiIO::ClearInputCharacters() } //----------------------------------------------------------------------------- -// [SECTION] MISC HELPERS/UTILITIES (Geometry, String, Format, Hash, File functions) +// [SECTION] MISC HELPERS/UTILITIES (Geometry functions) //----------------------------------------------------------------------------- -ImVec2 ImBezierClosestPoint(const ImVec2& p, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments) +ImVec2 ImBezierClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, int num_segments) { - IM_ASSERT(num_segments > 0); + IM_ASSERT(num_segments > 0); // Use ImBezierClosestPointCasteljau() ImVec2 p_last = p1; ImVec2 p_closest; float p_closest_dist2 = FLT_MAX; @@ -1132,7 +1133,7 @@ ImVec2 ImBezierClosestPoint(const ImVec2& p, const ImVec2& p1, const ImVec2& p2, } // Closely mimics PathBezierToCasteljau() in imgui_draw.cpp -static void ClosestPointBezierCasteljau(const ImVec2& p, ImVec2& p_closest, ImVec2& p_last, float& p_closest_dist2, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level) +static void BezierClosestPointCasteljauStep(const ImVec2& p, ImVec2& p_closest, ImVec2& p_last, float& p_closest_dist2, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level) { float dx = x4 - x1; float dy = y4 - y1; @@ -1160,18 +1161,20 @@ static void ClosestPointBezierCasteljau(const ImVec2& p, ImVec2& p_closest, ImVe float x123 = (x12+x23)*0.5f, y123 = (y12+y23)*0.5f; float x234 = (x23+x34)*0.5f, y234 = (y23+y34)*0.5f; float x1234 = (x123+x234)*0.5f, y1234 = (y123+y234)*0.5f; - ClosestPointBezierCasteljau(p, p_closest, p_last, p_closest_dist2, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1); - ClosestPointBezierCasteljau(p, p_closest, p_last, p_closest_dist2, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1); + BezierClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1); + BezierClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1); } } -ImVec2 ImBezierClosestPointCasteljau(const ImVec2& p, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float tess_tol) +// tess_tol is generally the same value you would find in ImGui::GetStyle().CurveTessellationTol +// Because those ImXXX functions are lower-level than ImGui:: we cannot access this value automatically. +ImVec2 ImBezierClosestPointCasteljau(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float tess_tol) { IM_ASSERT(tess_tol > 0.0f); ImVec2 p_last = p1; ImVec2 p_closest; float p_closest_dist2 = FLT_MAX; - ClosestPointBezierCasteljau(p, p_closest, p_last, p_closest_dist2, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, tess_tol, 0); + BezierClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, tess_tol, 0); return p_closest; } @@ -1223,6 +1226,10 @@ ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, return proj_ca; } +//----------------------------------------------------------------------------- +// [SECTION] MISC HELPERS/UTILITIES (String, Format, Hash functions) +//----------------------------------------------------------------------------- + // Consider using _stricmp/_strnicmp under Windows or strcasecmp/strncasecmp. We don't actually use either ImStricmp/ImStrnicmp in the codebase any more. int ImStricmp(const char* str1, const char* str2) { diff --git a/imgui.h b/imgui.h index 704a7211..83bb2558 100644 --- a/imgui.h +++ b/imgui.h @@ -1942,7 +1942,7 @@ struct ImDrawList IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL); IMGUI_API void AddPolyline(const ImVec2* points, int num_points, ImU32 col, bool closed, float thickness); IMGUI_API void AddConvexPolyFilled(const ImVec2* points, int num_points, ImU32 col); // Note: Anti-aliased filling requires points to be in clockwise order. - IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0); + IMGUI_API void AddBezierCurve(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments = 0); // Image primitives // - Read FAQ to understand what ImTextureID is. @@ -1960,7 +1960,7 @@ struct ImDrawList inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness); _Path.Size = 0; } IMGUI_API void PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments = 10); IMGUI_API void PathArcToFast(const ImVec2& center, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle - IMGUI_API void PathBezierCurveTo(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, int num_segments = 0); + IMGUI_API void PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0); IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, ImDrawCornerFlags rounding_corners = ImDrawCornerFlags_All); // Advanced diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 8f913dc0..58acacf5 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -917,7 +917,7 @@ ImVec2 ImBezierCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const return ImVec2(w1*p1.x + w2*p2.x + w3*p3.x + w4*p4.x, w1*p1.y + w2*p2.y + w3*p3.y + w4*p4.y); } -// Closely mimicked by ClosestPointBezierCasteljau() in imgui.cpp +// Closely mimics BezierClosestPointCasteljauStep() in imgui.cpp static void PathBezierToCasteljau(ImVector* path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level) { float dx = x4 - x1; @@ -938,7 +938,6 @@ static void PathBezierToCasteljau(ImVector* path, float x1, float y1, fl float x123 = (x12+x23)*0.5f, y123 = (y12+y23)*0.5f; float x234 = (x23+x34)*0.5f, y234 = (y23+y34)*0.5f; float x1234 = (x123+x234)*0.5f, y1234 = (y123+y234)*0.5f; - PathBezierToCasteljau(path, x1,y1, x12,y12, x123,y123, x1234,y1234, tess_tol, level+1); PathBezierToCasteljau(path, x1234,y1234, x234,y234, x34,y34, x4,y4, tess_tol, level+1); } @@ -949,8 +948,7 @@ void ImDrawList::PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImV ImVec2 p1 = _Path.back(); if (num_segments == 0) { - // Auto-tessellated - PathBezierToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0); + PathBezierToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0); // Auto-tessellated } else { @@ -1131,13 +1129,14 @@ void ImDrawList::AddNgonFilled(const ImVec2& center, float radius, ImU32 col, in PathFillConvex(col); } -void ImDrawList::AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments) +// Cubic Bezier takes 4 controls points +void ImDrawList::AddBezierCurve(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments) { if ((col & IM_COL32_A_MASK) == 0) return; - PathLineTo(pos0); - PathBezierCurveTo(cp0, cp1, pos1, num_segments); + PathLineTo(p1); + PathBezierCurveTo(p2, p3, p4, num_segments); PathStroke(col, false, thickness); } diff --git a/imgui_internal.h b/imgui_internal.h index bf594bc5..ea58b65c 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -340,9 +340,9 @@ static inline float ImLinearSweep(float current, float target, float speed) static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } // Helpers: Geometry -IMGUI_API ImVec2 ImBezierCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t); -IMGUI_API ImVec2 ImBezierClosestPoint(const ImVec2& p, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments); // For curves with explicit number of segments -IMGUI_API ImVec2 ImBezierClosestPointCasteljau(const ImVec2& p, const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float tess_tol); // For auto-tesselated curves, tess_tol = style.CurveTessellationTol +IMGUI_API ImVec2 ImBezierCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t); // Cubic Bezier +IMGUI_API ImVec2 ImBezierClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, int num_segments); // For curves with explicit number of segments +IMGUI_API ImVec2 ImBezierClosestPointCasteljau(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float tess_tol);// For auto-tessellated curves you can use tess_tol = style.CurveTessellationTol IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p); IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); From e01fb5462d4fc8b30cf7e23229ee5be4b8d7b3e9 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 18 Dec 2019 18:26:28 +0100 Subject: [PATCH 7/7] Internals: Separator: Simplify duplicated code. --- imgui_widgets.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 684dbe55..135715ff 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1259,21 +1259,14 @@ void ImGui::SeparatorEx(ImGuiSeparatorFlags flags) // We don't provide our width to the layout so that it doesn't get feed back into AutoFit const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y + thickness_draw)); ItemSize(ImVec2(0.0f, thickness_layout)); - if (!ItemAdd(bb, 0)) + const bool item_visible = ItemAdd(bb, 0); + if (item_visible) { - if (columns) - { - PopColumnsBackground(); - columns->LineMinY = window->DC.CursorPos.y; - } - return; + // Draw + window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x, bb.Min.y), GetColorU32(ImGuiCol_Separator)); + if (g.LogEnabled) + LogRenderedText(&bb.Min, "--------------------------------"); } - - // Draw - window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x, bb.Min.y), GetColorU32(ImGuiCol_Separator)); - if (g.LogEnabled) - LogRenderedText(&bb.Min, "--------------------------------"); - if (columns) { PopColumnsBackground();