From 39432bfd9cbcc73c9c4a607a8f606257fae58da0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 11 Mar 2021 12:25:24 +0100 Subject: [PATCH] Amend 0c93238a ImDrawList: upgraded AddRect(), AddRectFilled(), PathRect() to use general ImDrawFlags instead of ImDrawCornersFlags --- docs/CHANGELOG.txt | 22 ++++++++++++++++---- imgui.cpp | 12 +++++++++++ imgui.h | 51 +++++++++++++++++++++++++++------------------- imgui_demo.cpp | 6 ++---- imgui_draw.cpp | 51 ++++++++++++++++++---------------------------- 5 files changed, 82 insertions(+), 60 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 47d2dc57..8f2b1871 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -41,9 +41,25 @@ Breaking Changes: - ImGui::SetScrollHere() --> use ImGui::SetScrollHereY() - ImDrawList: upgraded AddPolyline()/PathStroke()'s "bool closed" parameter to use "ImDrawFlags flags". The matching ImDrawFlags_Closed value is guaranteed to always stay == 1 in the future. - - bool closed = false --> use ImDrawFlags_None, or 0 - - bool closed = true --> use ImDrawFlags_Closed + - bool closed = false --> use ImDrawFlags_None, or 0 + - bool closed = true --> use ImDrawFlags_Closed Difference may not be noticeable for most but zealous type-checking tools may report a need to change. +- ImDrawList: upgraded AddRect(), AddRectFilled(), PathRect() to use general ImDrawFlags instead of ImDrawCornersFlags. + The old ImDrawCornersFlags used an awkward default value of ~0 or 0xF (4 lower bits set) to signify "round all + corners". We still support old flags, but note that the new named flags are opt-out instead of opt-in. [@rokups] + - AddRect(..., rounding, ImDrawCornerFlags_TopLeft) --> AddRect(..., ImDrawFlags_NoRoundCorners ^ ImDrawFlags_NoRoundCornerTL) + - Flags now sanely default to 0 instead of defaulting to ~0 or ImDrawCornerFlags_All, consistent with everywhere else. + - In practice, this shouldn't have an effect as those flags were rarely used. + - All meaningful old uses are supported: + - Default flags will behave the same. + - Use of old named flags will behave the same (but will be obsoleted later) + - Use of hardcoded ~0 or 0xF, previously suggested as a convenience, will behave the same (but will be obsoleted later). + - Not supported: + - Use of hardcoded values between 0x01 and 0x0E not using named flags are NOT supported (will assert). + - Use of new ImDrawFlags together with ImDrawCornerFlags in the same call (will assert). + - Use of rounding > 0.0f along old flags explicitely set as hardcoded 0 would have previously overidden the + rounding value back into "no rounding", whereas it will now behave as "round all corners". + This is technically the only real breaking change which we can't solve automatically. - ImDrawList: clarified that PathArcTo()/PathArcToFast() won't render with radius < 0.0f. Previously it sorts of accidentally worked but would lead to counter-clockwise paths which and have an effect on anti-aliasing. - Style: renamed rarely used style.CircleSegmentMaxError (old default = 1.60f) @@ -52,8 +68,6 @@ Breaking Changes: disable those default functions for MinGW. MinGW users should: either link with -limm32, either set their imconfig file with '#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS'. (#2590, #738) [@actboy168] - Backends: Win32: Pragma linking with dwmapi.lib (Vista-era, ~9 kb). MinGW users will need to link with -ldwmapi. -- ImDrawList: Merged ImDrawCornerFlags to ImDrawFlags. Hardcoded use of 0x0F or ~0 as ImDrawCornerFlags should be - replaced with ImDrawFlags_None or 0. [@rokups] Other Changes: diff --git a/imgui.cpp b/imgui.cpp index e97fdefc..bae08a06 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -376,6 +376,18 @@ 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. + - 2021/03/11 (1.82) - upgraded ImDrawList::AddRect(), AddRectFilled(), PathRect() to use general ImDrawFlags instead of ImDrawCornersFlags. + the old ImDrawCornersFlags used an awkward default value of ~0 or 0xF (4 lower bits set) to signify "round all corners". We still support old flags, but note that the new named flags are opt-out instead of opt-in! + - AddRect(..., rounding, ImDrawCornerFlags_TopLeft) --> AddRect(..., ImDrawFlags_NoRoundCorners ^ ImDrawFlags_NoRoundCornerTL) + flags now sanely defaults to 0 instead of defaulting to ~0 or ImDrawCornerFlags_All, consistent with everywhere else in the codebase. + in practice, this shouldn't have an effect as those flags were rarely used. all meaningful old uses are supported: + - default flags will behave the same. + - use of old named flags will behave the same (but will be obsoleted later). + - use of hardcoded ~0 or 0xF, previously suggested as a convenience, will behave the same (but will be obsoleted later). + not supported: + - use of hardcoded values between 0x01 and 0x0E not using named flags are NOT supported (will assert). + - use of new ImDrawFlags together with ImDrawCornerFlags in the same call (will assert). + - use of rounding > 0.0f along old flags explicitely set as hard coded 0 would have previously overidden the rounding value back into "no rounding", whereas it will now behave as "round all corners". This is technically the only real breaking change which we can't solve automatically. - 2021/03/11 (1.82) - removed redirecting functions/enums names that were marked obsolete in 1.66 (September 2018): - ImGui::SetScrollHere() -> use ImGui::SetScrollHereY() - 2021/03/11 (1.82) - clarified that ImDrawList::PathArcTo(), ImDrawList::PathArcToFast() won't render with radius < 0.0f. Previously it sorts of accidentally worked but would generally lead to counter-clockwise paths and have an effect on anti-aliasing. diff --git a/imgui.h b/imgui.h index 5e055877..881afc38 100644 --- a/imgui.h +++ b/imgui.h @@ -162,7 +162,7 @@ typedef int ImGuiMouseCursor; // -> enum ImGuiMouseCursor_ // Enum: A typedef int ImGuiSortDirection; // -> enum ImGuiSortDirection_ // Enum: A sorting direction (ascending or descending) typedef int ImGuiStyleVar; // -> enum ImGuiStyleVar_ // Enum: A variable identifier for styling typedef int ImGuiTableBgTarget; // -> enum ImGuiTableBgTarget_ // Enum: A color target for TableSetBgColor() -typedef int ImDrawFlags; // -> enum ImDrawFlags_ // Flags: for ImDrawList functions: AddPolyline(), PathStroke() etc. +typedef int ImDrawFlags; // -> enum ImDrawFlags_ // Flags: for ImDrawList functions typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList instance typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas build typedef int ImGuiBackendFlags; // -> enum ImGuiBackendFlags_ // Flags: for io.BackendFlags @@ -2277,33 +2277,25 @@ struct ImDrawListSplitter IMGUI_API void SetCurrentChannel(ImDrawList* draw_list, int channel_idx); }; -// Flags for some ImDrawList functions +// Flags for ImDrawList functions +// (Before version 1.82: functions like AddRect(), AddRectFilled(), AddImageRounded(), PathRect() used ImDrawCornerFlags, +// we have moved those in 1.82 to ImDrawList but using opposite "opt-out" logic instead of "opt-in" logic: +// Old: ImDrawCornerFlags_BotLeft New: ImDrawFlags_NoRoundCornerBL +// The old enums are defined under ImDrawCornerFlags_ in the "Obsolete functions and types" section of this header) +// (Legacy: bit 0 must always correspond to ImDrawFlags_Closed to be backward compatible with old API using a bool. Bits 1..3 must b unused) enum ImDrawFlags_ { ImDrawFlags_None = 0, - ImDrawFlags_Closed = 1 << 0, // PathStroke(), AddPolyline(): specify that (LEGACY: this must always stay == 1 to be backward compatible with old API using a bool) - // (bits 1..3 unused to facilitate handling of legacy behavior and detection of Flags = 0x0F) - ImDrawFlags_NoRoundCornerTL = 1 << 4, - ImDrawFlags_NoRoundCornerTR = 1 << 5, - ImDrawFlags_NoRoundCornerBL = 1 << 6, - ImDrawFlags_NoRoundCornerBR = 1 << 7, + ImDrawFlags_Closed = 1 << 0, // PathStroke(), AddPolyline(): specify that shape should be closed (Important: this is always == 1 for legacy reason) + ImDrawFlags_NoRoundCornerTL = 1 << 4, // AddRect(), AddRectFilled(), PathRect(): disable rounding top-left corner when rounding > 0.0f + ImDrawFlags_NoRoundCornerTR = 1 << 5, // AddRect(), AddRectFilled(), PathRect(): disable rounding top-right corner when rounding > 0.0f + ImDrawFlags_NoRoundCornerBL = 1 << 6, // AddRect(), AddRectFilled(), PathRect(): disable rounding bottom-left corner when rounding > 0.0f + ImDrawFlags_NoRoundCornerBR = 1 << 7, // AddRect(), AddRectFilled(), PathRect(): disable rounding bottom-right corner when rounding > 0.0f ImDrawFlags_NoRoundCornerT = ImDrawFlags_NoRoundCornerTL | ImDrawFlags_NoRoundCornerTR, ImDrawFlags_NoRoundCornerR = ImDrawFlags_NoRoundCornerTR | ImDrawFlags_NoRoundCornerBR, ImDrawFlags_NoRoundCornerL = ImDrawFlags_NoRoundCornerTL | ImDrawFlags_NoRoundCornerBL, ImDrawFlags_NoRoundCornerB = ImDrawFlags_NoRoundCornerBL | ImDrawFlags_NoRoundCornerBR, - ImDrawFlags_NoRoundCorners = ImDrawFlags_NoRoundCornerTL | ImDrawFlags_NoRoundCornerTR | ImDrawFlags_NoRoundCornerBL | ImDrawFlags_NoRoundCornerBR, -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - ImDrawCornerFlags_None = ImDrawFlags_NoRoundCorners, - ImDrawCornerFlags_TopLeft = 1 << 28, // Order is identical to ImDrawFlags_NoRoundCorner* flag order and is exploited by FixImDrawCornerFlags() for support of legacy code. - ImDrawCornerFlags_TopRight = 1 << 29, - ImDrawCornerFlags_BotLeft = 1 << 30, - ImDrawCornerFlags_BotRight = 1 << 31, - ImDrawCornerFlags_Top = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_TopRight, - ImDrawCornerFlags_Bot = ImDrawCornerFlags_BotLeft | ImDrawCornerFlags_BotRight, - ImDrawCornerFlags_Left = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotLeft, - ImDrawCornerFlags_Right = ImDrawCornerFlags_TopRight | ImDrawCornerFlags_BotRight, - ImDrawCornerFlags_All = 0x0F -#endif + ImDrawFlags_NoRoundCorners = ImDrawFlags_NoRoundCornerTL | ImDrawFlags_NoRoundCornerTR | ImDrawFlags_NoRoundCornerBL | ImDrawFlags_NoRoundCornerBR }; // Flags for ImDrawList instance. Those are set automatically by ImGui:: functions from ImGuiIO settings, and generally not manipulated directly. @@ -2795,6 +2787,23 @@ namespace ImGui // OBSOLETED in 1.69 (from Mar 2019) static inline ImDrawList* GetOverlayDrawList() { return GetForegroundDrawList(); } } + +// OBSOLETED in 1.82 (from Mars 2021): flags for AddRect(), AddRectFilled(), AddImageRounded(), PathRect() +typedef ImDrawFlags ImDrawCornerFlags; +enum ImDrawCornerFlags_ +{ + ImDrawCornerFlags_None = ImDrawFlags_NoRoundCorners, + ImDrawCornerFlags_TopLeft = 1 << 24, // Was (1 << 0) prior to 1.82. Order matches ImDrawFlags_NoRoundCorner* flag (we exploit this internally). + ImDrawCornerFlags_TopRight = 1 << 25, // Was (1 << 1) prior to 1.82. + ImDrawCornerFlags_BotLeft = 1 << 26, // Was (1 << 2) prior to 1.82. + ImDrawCornerFlags_BotRight = 1 << 27, // Was (1 << 3) prior to 1.82. + ImDrawCornerFlags_All = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_TopRight | ImDrawCornerFlags_BotLeft | ImDrawCornerFlags_BotRight, // Was (0x0F) prior to 1.82 + ImDrawCornerFlags_Top = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_TopRight, + ImDrawCornerFlags_Bot = ImDrawCornerFlags_BotLeft | ImDrawCornerFlags_BotRight, + ImDrawCornerFlags_Left = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotLeft, + ImDrawCornerFlags_Right = ImDrawCornerFlags_TopRight | ImDrawCornerFlags_BotRight +}; + #endif // #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS //----------------------------------------------------------------------------- diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 21e27eb0..31fca904 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -7205,8 +7205,6 @@ static void ShowExampleAppCustomRendering(bool* p_open) const ImVec2 p = ImGui::GetCursorScreenPos(); const ImU32 col = ImColor(colf); const float spacing = 10.0f; - const ImDrawFlags corners_none = ImDrawFlags_NoRoundCorners; - const ImDrawFlags corners_all = 0; const ImDrawFlags corners_tl_br = ImDrawFlags_NoRoundCornerTR | ImDrawFlags_NoRoundCornerBL; const float rounding = sz / 5.0f; const int circle_segments = circle_segments_override ? circle_segments_override_v : 0; @@ -7219,8 +7217,8 @@ static void ShowExampleAppCustomRendering(bool* p_open) float th = (n == 0) ? 1.0f : thickness; draw_list->AddNgon(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, ngon_sides, th); x += sz + spacing; // N-gon draw_list->AddCircle(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments, th); x += sz + spacing; // Circle - draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, corners_none, th); x += sz + spacing; // Square - draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, corners_all, th); x += sz + spacing; // Square with all rounded corners + draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 0.0f, ImDrawFlags_None, th); x += sz + spacing; // Square + draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, ImDrawFlags_None, th); x += sz + spacing; // Square with all rounded corners draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col, rounding, corners_tl_br, th); x += sz + spacing; // Square with two rounded corners draw_list->AddTriangle(ImVec2(x+sz*0.5f,y), ImVec2(x+sz, y+sz-0.5f), ImVec2(x, y+sz-0.5f), col, th);x += sz + spacing; // Triangle //draw_list->AddTriangle(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col, th);x+= sz*0.4f + spacing; // Thin triangle diff --git a/imgui_draw.cpp b/imgui_draw.cpp index e3bb551e..b91b5fce 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1280,40 +1280,34 @@ void ImDrawList::PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, } #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS -static inline ImDrawFlags FixImDrawCornerFlags(ImDrawFlags flags) +static inline ImDrawFlags FixDrawCornerFlags(ImDrawFlags flags) { - // If following asserts trigger, please update your code replacing all uses of ImDrawCornerFlags_* with ImDrawFlags_*. - if ((flags & ImDrawCornerFlags_All) == ImDrawCornerFlags_All) - { - // All round corners, set new flags to 0 if: - // Legacy Rule 1: first 4 bits of flags are set, ImDrawCornerFlags_All was used - // Legacy Rule 2: first all bits of flags are set, ~0 was used - IM_ASSERT((flags == ImDrawCornerFlags_All || flags == ~0) && "Mixing new and legacy flags is not allowed."); + // If any of following asserts triggers, please update your code replacing all uses of ImDrawCornerFlags_* with ImDrawFlags_*. + // Legacy Rule 1: Support for hard coded 0x0F or ~0 (used to be equivalent to ImDrawCornerFlags_All) + if (flags == ~0 || flags == 0x0F) return 0; - } - else if ((flags & (ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_TopRight | ImDrawCornerFlags_BotLeft | ImDrawCornerFlags_BotRight)) != 0) + + // Legacy Rule 2: if any of old ImDrawCornerFlags flags, move them to corresponding positions of non-legacy flags and invert them. + if ((flags & ImDrawCornerFlags_All) != 0) { - // Legacy Rule 3: if any of last 4 bits are set, move them to corresponding positions of non-legacy flags and invert them. - IM_ASSERT((flags & 0x0FFFFFFF) == 0 && "Mixing new and legacy flags is not allowed."); - const int legacy_flags_bit_offset = 24; // 32 - num_legacy_flags (4) - new_flags_first_bit (4) - return (flags >> legacy_flags_bit_offset) ^ (ImDrawFlags_NoRoundCornerT | ImDrawFlags_NoRoundCornerB); - } - else - { - IM_ASSERT((flags & 0x0E) == 0 && "Bits 1..3 are unused."); - return flags; + IM_ASSERT((flags & ~ImDrawCornerFlags_All) == 0 && "Mixing legacy ImDrawCornerFlags and new ImDrawFlags is not allowed."); + IM_STATIC_ASSERT((ImDrawCornerFlags_TopLeft >> 20) == ImDrawFlags_NoRoundCornerTL); + return (flags >> 20) ^ ImDrawFlags_NoRoundCorners; } + + // Bits 1..3 are unused, did you use old hard coded values?! In which case, check the old values in ImDrawCornerFlags_ definition. + // If you used ~0 or 0x0F you can now change them to 0 or ImDrawFlags_None. + IM_ASSERT((flags & 0x0E) == 0); + return flags; } +#else +// Assert and return same value +#define FixDrawCornerFlags(FLAGS) (IM_ASSERT((FLAGS & 0x0E) == 0), FLAGS) #endif void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, ImDrawFlags flags) { -#ifdef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - // Legacy use of ~0 or 0x0F as ImDrawCornerFlags value. Please update your code to use ImDrawFlags_NoRoundCorner* flags. - IM_ASSERT((flags & 0x0E) == 0); -#else - flags = FixImDrawCornerFlags(flags); -#endif + flags = FixDrawCornerFlags(flags); rounding = ImMin(rounding, ImFabs(b.x - a.x) * ( ((flags & ImDrawFlags_NoRoundCornerT) == 0) || ((flags & ImDrawFlags_NoRoundCornerB) == 0) ? 0.5f : 1.0f ) - 1.0f); rounding = ImMin(rounding, ImFabs(b.y - a.y) * ( ((flags & ImDrawFlags_NoRoundCornerL) == 0) || ((flags & ImDrawFlags_NoRoundCornerR) == 0) ? 0.5f : 1.0f ) - 1.0f); @@ -1606,12 +1600,7 @@ void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& p_mi if ((col & IM_COL32_A_MASK) == 0) return; -#ifdef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - // Legacy use of ~0 or 0x0F as ImDrawCornerFlags value. Please update your code to use ImDrawFlags_NoRoundCorner* flags. - IM_ASSERT((flags & 0x0E) == 0); -#else - flags = FixImDrawCornerFlags(flags); -#endif + flags = FixDrawCornerFlags(flags); if (rounding <= 0.0f || (flags & ImDrawFlags_NoRoundCorners) == ImDrawFlags_NoRoundCorners) { AddImage(user_texture_id, p_min, p_max, uv_min, uv_max, col);