From c6e0284ac58b3f205c95365478888f7b53b077e2 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 4 Sep 2023 15:16:55 +0200 Subject: [PATCH 01/15] Fixed minor warning. --- imgui_demo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index e3752b50..ab529e37 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -4833,7 +4833,7 @@ static void ShowDemoWindowTables() ImGui::TableNextColumn(); ImGui::Text("CellPadding.y = %.2f", style.CellPadding.y); if ((row % 3) == 2) - ImGui::PopStyleVar();; + ImGui::PopStyleVar(); } ImGui::EndTable(); } From c4dc8fd10190d97fa55055bd3a47381b98e3e9bf Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 5 Sep 2023 10:54:04 +0200 Subject: [PATCH 02/15] Docs: Update FONTS.md (#6781, #6632, #6339, #5763, #5330, #2234, #2042, #1259, #951, #220) --- docs/FONTS.md | 82 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 24 deletions(-) diff --git a/docs/FONTS.md b/docs/FONTS.md index fa68dad2..b0876a36 100644 --- a/docs/FONTS.md +++ b/docs/FONTS.md @@ -14,12 +14,13 @@ In the [misc/fonts/](https://github.com/ocornut/imgui/tree/master/misc/fonts) fo - [Troubleshooting](#troubleshooting) - [How should I handle DPI in my application?](#how-should-i-handle-dpi-in-my-application) - [Fonts Loading Instructions](#fonts-loading-instructions) +- [Loading Font Data from Memory](#loading-font-data-from-memory) +- [Loading Font Data Embedded In Source Code](#loading-font-data-embedded-in-source-code) - [Using Icon Fonts](#using-icon-fonts) - [Using FreeType Rasterizer (imgui_freetype)](#using-freetype-rasterizer-imgui_freetype) - [Using Colorful Glyphs/Emojis](#using-colorful-glyphsemojis) - [Using Custom Glyph Ranges](#using-custom-glyph-ranges) - [Using Custom Colorful Icons](#using-custom-colorful-icons) -- [Using Font Data Embedded In Source Code](#using-font-data-embedded-in-source-code) - [About Filenames](#about-filenames) - [About UTF-8 Encoding](#about-utf-8-encoding) - [Debug Tools](#debug-tools) @@ -61,6 +62,7 @@ Some solutions: ##### [Return to Index](#index) +--------------------------------------- ## How should I handle DPI in my application? @@ -68,6 +70,7 @@ See [FAQ entry](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md#q-how-s ##### [Return to Index](#index) +--------------------------------------- ## Fonts Loading Instructions @@ -139,7 +142,6 @@ io.Fonts->AddFontFromFileTTF("font.ttf", size_pixels, nullptr, io.Fonts->GetGlyp ``` See [Using Custom Glyph Ranges](#using-custom-glyph-ranges) section to create your own ranges. - **Example loading and using a Japanese font:** ```cpp @@ -161,6 +163,48 @@ ImGui::SliderFloat("float", &f, 0.0f, 1.0f); ##### [Return to Index](#index) +--------------------------------------- + +## Loading Font Data from Memory + +```cpp +ImFont* font = io.Fonts->AddFontFromMemoryTTF(data, data_size, size_pixels, ...); +``` + +IMPORTANT: `AddFontFromMemoryTTF()` by default transfer ownership of the data buffer to the font atlas, which will attempt to free it on destruction. +This was to avoid an unnecessary copy, and is perhaps not a good API (a future version will redesign it). +If you want to keep ownership of the data and free it yourself, you need to clear the `FontDataOwnedByAtlas` field: + +```cpp +ImFontConfig font_cfg; +font_cfg.FontDataOwnedByAtlas = false; +ImFont* font = io.Fonts->AddFontFromMemoryTTF(data, data_size, size_pixels, &font_cfg); +``` + +##### [Return to Index](#index) + +--------------------------------------- + +## Loading Font Data Embedded In Source Code + +- Compile and use [binary_to_compressed_c.cpp](https://github.com/ocornut/imgui/blob/master/misc/fonts/binary_to_compressed_c.cpp) to create a compressed C style array that you can embed in source code. +- See the documentation in [binary_to_compressed_c.cpp](https://github.com/ocornut/imgui/blob/master/misc/fonts/binary_to_compressed_c.cpp) for instructions on how to use the tool. +- You may find a precompiled version binary_to_compressed_c.exe for Windows inside the demo binaries package (see [README](https://github.com/ocornut/imgui/blob/master/docs/README.md)). +- The tool can optionally output Base85 encoding to reduce the size of _source code_ but the read-only arrays in the actual binary will be about 20% bigger. + +Then load the font with: +```cpp +ImFont* font = io.Fonts->AddFontFromMemoryCompressedTTF(compressed_data, compressed_data_size, size_pixels, ...); +``` +or +```cpp +ImFont* font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(compressed_data_base85, size_pixels, ...); +``` + +##### [Return to Index](#index) + +--------------------------------------- + ## Using Icon Fonts Using an icon font (such as [FontAwesome](http://fontawesome.io) or [OpenFontIcons](https://github.com/traverseda/OpenFontIcons)) is an easy and practical way to use icons in your Dear ImGui application. @@ -204,6 +248,8 @@ Here's an application using icons ("Avoyd", https://www.avoyd.com): ##### [Return to Index](#index) +--------------------------------------- + ## Using FreeType Rasterizer (imgui_freetype) - Dear ImGui uses imstb\_truetype.h to rasterize fonts (with optional oversampling). This technique and its implementation are not ideal for fonts rendered at small sizes, which may appear a little blurry or hard to read. @@ -214,6 +260,8 @@ Here's an application using icons ("Avoyd", https://www.avoyd.com): ##### [Return to Index](#index) +--------------------------------------- + ## Using Colorful Glyphs/Emojis - Rendering of colored emojis is supported by imgui_freetype with FreeType 2.10+. @@ -236,6 +284,8 @@ io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\seguiemj.ttf", 16.0f, &cfg, ra ##### [Return to Index](#index) +--------------------------------------- + ## Using Custom Glyph Ranges You can use the `ImFontGlyphRangesBuilder` helper to create glyph ranges based on text input. For example: for a game where your script is known, if you can feed your entire script to it and only build the characters the game needs. @@ -253,6 +303,8 @@ io.Fonts->Build(); // Build the atlas while ##### [Return to Index](#index) +--------------------------------------- + ## Using Custom Colorful Icons As an alternative to rendering colorful glyphs using imgui_freetype with `ImGuiFreeTypeBuilderFlags_LoadColor`, you may allocate your own space in the texture atlas and write yourself into it. **(This is a BETA api, use if you are familiar with dear imgui and with your rendering backend)** @@ -295,25 +347,7 @@ for (int rect_n = 0; rect_n < IM_ARRAYSIZE(rect_ids); rect_n++) ##### [Return to Index](#index) -## Using Font Data Embedded In Source Code - -- Compile and use [binary_to_compressed_c.cpp](https://github.com/ocornut/imgui/blob/master/misc/fonts/binary_to_compressed_c.cpp) to create a compressed C style array that you can embed in source code. -- See the documentation in [binary_to_compressed_c.cpp](https://github.com/ocornut/imgui/blob/master/misc/fonts/binary_to_compressed_c.cpp) for instructions on how to use the tool. -- You may find a precompiled version binary_to_compressed_c.exe for Windows inside the demo binaries package (see [README](https://github.com/ocornut/imgui/blob/master/docs/README.md)). -- The tool can optionally output Base85 encoding to reduce the size of _source code_ but the read-only arrays in the actual binary will be about 20% bigger. - -Then load the font with: -```cpp -ImFont* font = io.Fonts->AddFontFromMemoryCompressedTTF(compressed_data, compressed_data_size, size_pixels, ...); -``` -or -```cpp -ImFont* font = io.Fonts->AddFontFromMemoryCompressedBase85TTF(compressed_data_base85, size_pixels, ...); -``` - -##### [Return to Index](#index) - --- +--------------------------------------- ## About Filenames @@ -335,7 +369,7 @@ io.Fonts->AddFontFromFileTTF("../MyImage01.jpg", ...); // Load from the paren ``` ##### [Return to Index](#index) --- +--------------------------------------- ## About UTF-8 Encoding @@ -382,7 +416,7 @@ ImGui::Text(U8("こんにちは")); ``` ##### [Return to Index](#index) --- +--------------------------------------- ## Debug Tools @@ -398,7 +432,7 @@ You can use the `UTF-8 Encoding viewer` in `Metrics/Debugger` to verify the cont ##### [Return to Index](#index) --- +--------------------------------------- ## Credits/Licenses For Fonts Included In Repository From f24387fa2bdfd8083314717d65838f76c9ccee7a Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 4 Sep 2023 17:21:09 +0200 Subject: [PATCH 03/15] Version 1.89.9 (fixed changelog header) --- docs/CHANGELOG.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 3d3df032..2a50c77d 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -37,9 +37,11 @@ HOW TO UPDATE? ----------------------------------------------------------------------- - VERSION 1.89.9 WIP (In Progress) + VERSION 1.89.9 (Released 2023-09-04) ----------------------------------------------------------------------- +Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.89.9 + Breaking changes: - Clipper: Renamed IncludeRangeByIndices(), also called ForceDisplayRangeByIndices() From fb9b0068659173e0fe92338e34fd341b8fbd9699 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 5 Sep 2023 16:45:17 +0200 Subject: [PATCH 04/15] Version 1.90 WIP --- docs/CHANGELOG.txt | 9 +++++++++ imgui.cpp | 2 +- imgui.h | 6 +++--- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- imgui_tables.cpp | 2 +- 7 files changed, 17 insertions(+), 8 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 2a50c77d..1c0dded3 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -36,6 +36,15 @@ HOW TO UPDATE? - Please report any issue! +----------------------------------------------------------------------- + VERSION 1.90 WIP (In Progress) +----------------------------------------------------------------------- + +Breaking changes: + +Other changes: + + ----------------------------------------------------------------------- VERSION 1.89.9 (Released 2023-09-04) ----------------------------------------------------------------------- diff --git a/imgui.cpp b/imgui.cpp index 07e4ad5a..1a9267bc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.89.9 +// dear imgui, v1.90 WIP // (main code and documentation) // Help: diff --git a/imgui.h b/imgui.h index c7f53448..c390b91a 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.89.9 +// dear imgui, v1.90 WIP // (headers) // Help: @@ -25,8 +25,8 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') -#define IMGUI_VERSION "1.89.9" -#define IMGUI_VERSION_NUM 18990 +#define IMGUI_VERSION "1.90 WIP" +#define IMGUI_VERSION_NUM 18991 #define IMGUI_HAS_TABLE /* diff --git a/imgui_demo.cpp b/imgui_demo.cpp index ab529e37..6d4b86a0 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.89.9 +// dear imgui, v1.90 WIP // (demo code) // Help: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 205ce76f..1332a52d 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.89.9 +// dear imgui, v1.90 WIP // (drawing and font code) /* diff --git a/imgui_internal.h b/imgui_internal.h index 70a62334..7f6dbe35 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.89.9 +// dear imgui, v1.90 WIP // (internal structures/api) // You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility. diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 8fdcbcf8..c4026ce3 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.89.9 +// dear imgui, v1.90 WIP // (tables and columns code) /* From cf1c4a0cb1596d01083b8040fb25157ed559db85 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 5 Sep 2023 16:47:00 +0200 Subject: [PATCH 05/15] BeginListBox(): fixed not consuming SetNextWindowXXX data when returning false. --- docs/CHANGELOG.txt | 2 ++ imgui_widgets.cpp | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 1c0dded3..9bbdf182 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -44,6 +44,8 @@ Breaking changes: Other changes: +- BeginListBox(): fixed not consuming SetNextWindowXXX data when returning false. + ----------------------------------------------------------------------- VERSION 1.89.9 (Released 2023-09-04) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index ec3eca36..5a59ddb3 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.89.9 +// dear imgui, v1.90 WIP // (widgets code) /* @@ -6630,6 +6630,7 @@ bool ImGui::BeginListBox(const char* label, const ImVec2& size_arg) { ItemSize(bb.GetSize(), style.FramePadding.y); ItemAdd(bb, 0, &frame_bb); + g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values return false; } From d8ef864b02c44f46aa6e71401527fe1f17c4564d Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 6 Sep 2023 11:28:14 +0200 Subject: [PATCH 06/15] InputTextMultiline: Fixed a crash pressing Down on last empty line of a multiline buffer. (#6783, #6000) Amend 57a5b73a4c --- docs/CHANGELOG.txt | 4 +++- imgui_widgets.cpp | 2 +- imstb_textedit.h | 5 ++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 9bbdf182..fb503eb0 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -44,7 +44,9 @@ Breaking changes: Other changes: -- BeginListBox(): fixed not consuming SetNextWindowXXX data when returning false. +- InputTextMultiline: Fixed a crash pressing Down on last empty line of a multiline buffer. + (regression from 1.89.2, only happened in some states). (#6783, #6000) +- BeginListBox(): Fixed not consuming SetNextWindowXXX data when returning false. ----------------------------------------------------------------------- diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 5a59ddb3..d63a629f 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -3693,7 +3693,7 @@ namespace ImStb { static int STB_TEXTEDIT_STRINGLEN(const ImGuiInputTextState* obj) { return obj->CurLenW; } -static ImWchar STB_TEXTEDIT_GETCHAR(const ImGuiInputTextState* obj, int idx) { return obj->TextW[idx]; } +static ImWchar STB_TEXTEDIT_GETCHAR(const ImGuiInputTextState* obj, int idx) { IM_ASSERT(idx <= obj->CurLenW); return obj->TextW[idx]; } static float STB_TEXTEDIT_GETWIDTH(ImGuiInputTextState* obj, int line_start_idx, int char_idx) { ImWchar c = obj->TextW[line_start_idx + char_idx]; if (c == '\n') return STB_TEXTEDIT_GETWIDTH_NEWLINE; ImGuiContext& g = *obj->Ctx; return g.Font->GetCharAdvance(c) * (g.FontSize / g.Font->FontSize); } static int STB_TEXTEDIT_KEYTOTEXT(int key) { return key >= 0x200000 ? 0 : key; } static ImWchar STB_TEXTEDIT_NEWLINE = '\n'; diff --git a/imstb_textedit.h b/imstb_textedit.h index a8a82311..062d13d6 100644 --- a/imstb_textedit.h +++ b/imstb_textedit.h @@ -2,7 +2,7 @@ // This is a slightly modified version of stb_textedit.h 1.14. // Those changes would need to be pushed into nothings/stb: // - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321) -// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000) +// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000 + #6783) // Grep for [DEAR IMGUI] to find the changes. // stb_textedit.h - v1.14 - public domain - Sean Barrett @@ -549,7 +549,10 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s i += r.num_chars; find->y += r.baseline_y_delta; if (i == z) // [DEAR IMGUI] + { + r.num_chars = 0; // [DEAR IMGUI] break; // [DEAR IMGUI] + } } find->first_char = first = i; From 56a7b8b724fbd189a34161fef2f40eaea0d0bc21 Mon Sep 17 00:00:00 2001 From: Deal Date: Wed, 6 Sep 2023 17:41:19 +0800 Subject: [PATCH 07/15] Backends: GLFW: Clear emscripten's MouseWheel callback before shutdown. (#6790, #6096, #4019) --- backends/imgui_impl_glfw.cpp | 3 +++ docs/CHANGELOG.txt | 1 + 2 files changed, 4 insertions(+) diff --git a/backends/imgui_impl_glfw.cpp b/backends/imgui_impl_glfw.cpp index ad798ae7..e0342605 100644 --- a/backends/imgui_impl_glfw.cpp +++ b/backends/imgui_impl_glfw.cpp @@ -629,6 +629,9 @@ void ImGui_ImplGlfw_Shutdown() if (bd->InstalledCallbacks) ImGui_ImplGlfw_RestoreCallbacks(bd->Window); +#ifdef __EMSCRIPTEN__ + emscripten_set_wheel_callback(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, nullptr, false, nullptr); +#endif for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) glfwDestroyCursor(bd->MouseCursors[cursor_n]); diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index fb503eb0..76feb98f 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -47,6 +47,7 @@ Other changes: - InputTextMultiline: Fixed a crash pressing Down on last empty line of a multiline buffer. (regression from 1.89.2, only happened in some states). (#6783, #6000) - BeginListBox(): Fixed not consuming SetNextWindowXXX data when returning false. +- Backends: GLFW: Clear emscripten's MouseWheel callback before shutdown. (#6790, #6096, #4019) [@halx99] ----------------------------------------------------------------------- From fa2e5710acbc55c16ef01c52c81b63bae895cf15 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 6 Sep 2023 12:39:39 +0200 Subject: [PATCH 08/15] MenuBar: Fixed an issue where layouting an item in the menu-bar would erroneously egister contents size. (#6789) In dire need of removing BeginGroup()/EndGroup() from menu-bar code, fo r sanity. --- docs/CHANGELOG.txt | 3 +++ imgui_internal.h | 16 ++++++++-------- imgui_widgets.cpp | 10 ++++++++-- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 76feb98f..2717fc94 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -47,6 +47,9 @@ Other changes: - InputTextMultiline: Fixed a crash pressing Down on last empty line of a multiline buffer. (regression from 1.89.2, only happened in some states). (#6783, #6000) - BeginListBox(): Fixed not consuming SetNextWindowXXX data when returning false. +- MenuBar: Fixed an issue where layouting an item in the menu-bar would erroneously + register contents size in a way that would affect the scrolling layer. + Was most often noticable when using an horizontal scrollbar. (#6789) - Backends: GLFW: Clear emscripten's MouseWheel callback before shutdown. (#6790, #6096, #4019) [@halx99] diff --git a/imgui_internal.h b/imgui_internal.h index 7f6dbe35..65201ca6 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1868,14 +1868,14 @@ struct ImGuiContext ImGuiNextWindowData NextWindowData; // Storage for SetNextWindow** functions // Shared stacks - ImVector ColorStack; // Stack for PushStyleColor()/PopStyleColor() - inherited by Begin() - ImVector StyleVarStack; // Stack for PushStyleVar()/PopStyleVar() - inherited by Begin() - ImVector FontStack; // Stack for PushFont()/PopFont() - inherited by Begin() - ImVector FocusScopeStack; // Stack for PushFocusScope()/PopFocusScope() - inherited by BeginChild(), pushed into by Begin() - ImVectorItemFlagsStack; // Stack for PushItemFlag()/PopItemFlag() - inherited by Begin() - ImVectorGroupStack; // Stack for BeginGroup()/EndGroup() - not inherited by Begin() - ImVectorOpenPopupStack; // Which popups are open (persistent) - ImVectorBeginPopupStack; // Which level of BeginPopup() we are in (reset every frame) + ImVector ColorStack; // Stack for PushStyleColor()/PopStyleColor() - inherited by Begin() + ImVector StyleVarStack; // Stack for PushStyleVar()/PopStyleVar() - inherited by Begin() + ImVector FontStack; // Stack for PushFont()/PopFont() - inherited by Begin() + ImVector FocusScopeStack; // Stack for PushFocusScope()/PopFocusScope() - inherited by BeginChild(), pushed into by Begin() + ImVector ItemFlagsStack; // Stack for PushItemFlag()/PopItemFlag() - inherited by Begin() + ImVector GroupStack; // Stack for BeginGroup()/EndGroup() - not inherited by Begin() + ImVector OpenPopupStack; // Which popups are open (persistent) + ImVector BeginPopupStack; // Which level of BeginPopup() we are in (reset every frame) ImVector NavTreeNodeStack; // Stack for TreeNode() when a NavLeft requested is emitted. int BeginMenuCount; diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index d63a629f..e4ade8c7 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7035,12 +7035,18 @@ void ImGui::EndMenuBar() PopClipRect(); PopID(); window->DC.MenuBarOffset.x = window->DC.CursorPos.x - window->Pos.x; // Save horizontal position so next append can reuse it. This is kinda equivalent to a per-layer CursorPos. - g.GroupStack.back().EmitItem = false; - EndGroup(); // Restore position on layer 0 + + // FIXME: Extremely confusing, cleanup by (a) working on WorkRect stack system (b) not using a Group confusingly here. + ImGuiGroupData& group_data = g.GroupStack.back(); + group_data.EmitItem = false; + ImVec2 restore_cursor_max_pos = group_data.BackupCursorMaxPos; + window->DC.IdealMaxPos.x = ImMax(window->DC.IdealMaxPos.x, window->DC.CursorMaxPos.x - window->Scroll.x); // Convert ideal extents for scrolling layer equivalent. + EndGroup(); // Restore position on layer 0 // FIXME: Misleading to use a group for that backup/restore window->DC.LayoutType = ImGuiLayoutType_Vertical; window->DC.IsSameLine = false; window->DC.NavLayerCurrent = ImGuiNavLayer_Main; window->DC.MenuBarAppending = false; + window->DC.CursorMaxPos = restore_cursor_max_pos; } // Important: calling order matters! From e3d9b875c9724cb0ab32903c0824bb3f69a3e2ea Mon Sep 17 00:00:00 2001 From: Leonardo Serrano Date: Thu, 22 Aug 2019 21:50:02 -0700 Subject: [PATCH 09/15] ImDrawList: added PathEllipticalArcTo(), AddEllipse(), AddEllipseFilled(). (#2743) Rebased with mods by ocornut: defaults to num_segments==0, supports for auto-tesselation, tweak demo. --- docs/CHANGELOG.txt | 1 + imgui.h | 3 +++ imgui_demo.cpp | 8 +++++--- imgui_draw.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+), 3 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 2717fc94..183c1151 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -50,6 +50,7 @@ Other changes: - MenuBar: Fixed an issue where layouting an item in the menu-bar would erroneously register contents size in a way that would affect the scrolling layer. Was most often noticable when using an horizontal scrollbar. (#6789) +- ImDrawList: Added AddEllipse(), AddEllipseFilled(), PathEllipticalArcTo(). (#2743) [@Doohl] - Backends: GLFW: Clear emscripten's MouseWheel callback before shutdown. (#6790, #6096, #4019) [@halx99] diff --git a/imgui.h b/imgui.h index c390b91a..8cc1b437 100644 --- a/imgui.h +++ b/imgui.h @@ -2675,6 +2675,8 @@ struct ImDrawList IMGUI_API void AddCircleFilled(const ImVec2& center, float radius, ImU32 col, int num_segments = 0); IMGUI_API void AddNgon(const ImVec2& center, float radius, ImU32 col, int num_segments, float thickness = 1.0f); IMGUI_API void AddNgonFilled(const ImVec2& center, float radius, ImU32 col, int num_segments); + IMGUI_API void AddEllipse(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0, float thickness = 1.0f); + IMGUI_API void AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0); IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL); 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, ImDrawFlags flags, float thickness); @@ -2699,6 +2701,7 @@ struct ImDrawList inline void PathStroke(ImU32 col, ImDrawFlags flags = 0, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, flags, thickness); _Path.Size = 0; } IMGUI_API void PathArcTo(const ImVec2& center, float radius, float a_min, float a_max, int num_segments = 0); 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 PathEllipticalArcTo(const ImVec2& center, float radius_x, float radius_y, float rot, float a_min, float a_max, int num_segments = 0); // Ellipse IMGUI_API void PathBezierCubicCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments = 0); // Cubic Bezier (4 control points) IMGUI_API void PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments = 0); // Quadratic Bezier (3 control points) IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, ImDrawFlags flags = 0); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 6d4b86a0..6351ed1c 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -7772,6 +7772,7 @@ 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->AddEllipse(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, sz*0.3f, col, -0.3f, circle_segments, th); x += sz + spacing; // Ellipse 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 @@ -7792,8 +7793,9 @@ static void ShowExampleAppCustomRendering(bool* p_open) x = p.x + 4; y += sz + spacing; } - draw_list->AddNgonFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz*0.5f, col, ngon_sides); x += sz + spacing; // N-gon - draw_list->AddCircleFilled(ImVec2(x + sz*0.5f, y + sz*0.5f), sz*0.5f, col, circle_segments); x += sz + spacing; // Circle + draw_list->AddNgonFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz * 0.5f, col, ngon_sides); x += sz + spacing; // N-gon + draw_list->AddCircleFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz * 0.5f, col, circle_segments); x += sz + spacing; // Circle + draw_list->AddEllipseFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz * 0.5f, sz * 0.3f, col, -0.3f, circle_segments); x += sz + spacing;// Ellipse draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col); x += sz + spacing; // Square draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f); x += sz + spacing; // Square with all rounded corners draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col, 10.0f, corners_tl_br); x += sz + spacing; // Square with two rounded corners @@ -7804,7 +7806,7 @@ static void ShowExampleAppCustomRendering(bool* p_open) draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + 1, y + 1), col); x += sz; // Pixel (faster than AddLine) draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x + sz, y + sz), IM_COL32(0, 0, 0, 255), IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255)); - ImGui::Dummy(ImVec2((sz + spacing) * 10.2f, (sz + spacing) * 3.0f)); + ImGui::Dummy(ImVec2((sz + spacing) * 11.2f, (sz + spacing) * 3.0f)); ImGui::PopItemWidth(); ImGui::EndTabItem(); } diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 1332a52d..b40f6b72 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1217,6 +1217,27 @@ void ImDrawList::PathArcTo(const ImVec2& center, float radius, float a_min, floa } } +void ImDrawList::PathEllipticalArcTo(const ImVec2& center, float radius_x, float radius_y, float rot, float a_min, float a_max, int num_segments) +{ + if (num_segments <= 0) + num_segments = _CalcCircleAutoSegmentCount(ImMax(radius_x, radius_y)); // A bit pessimistic, maybe there's a better computation to do here. + + _Path.reserve(_Path.Size + (num_segments + 1)); + + const float cos_rot = ImCos(rot); + const float sin_rot = ImSin(rot); + for (int i = 0; i <= num_segments; i++) + { + const float a = a_min + ((float)i / (float)num_segments) * (a_max - a_min); + ImVec2 point(ImCos(a) * radius_x, ImSin(a) * radius_y); + const float rel_x = (point.x * cos_rot) - (point.y * sin_rot); + const float rel_y = (point.x * sin_rot) + (point.y * cos_rot); + point.x = rel_x + center.x; + point.y = rel_y + center.y; + _Path.push_back(point); + } +} + ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t) { float u = 1.0f - t; @@ -1547,6 +1568,35 @@ void ImDrawList::AddNgonFilled(const ImVec2& center, float radius, ImU32 col, in PathFillConvex(col); } +// Ellipse +void ImDrawList::AddEllipse(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot, int num_segments, float thickness) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + + if (num_segments <= 0) + num_segments = _CalcCircleAutoSegmentCount(ImMax(radius_x, radius_y)); // A bit pessimistic, maybe there's a better computation to do here. + + // Because we are filling a closed shape we remove 1 from the count of segments/points + const float a_max = IM_PI * 2.0f * ((float)num_segments - 1.0f) / (float)num_segments; + PathEllipticalArcTo(center, radius_x, radius_y, rot, 0.0f, a_max, num_segments - 1); + PathStroke(col, true, thickness); +} + +void ImDrawList::AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot, int num_segments) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + + if (num_segments <= 0) + num_segments = _CalcCircleAutoSegmentCount(ImMax(radius_x, radius_y)); // A bit pessimistic, maybe there's a better computation to do here. + + // Because we are filling a closed shape we remove 1 from the count of segments/points + const float a_max = IM_PI * 2.0f * ((float)num_segments - 1.0f) / (float)num_segments; + PathEllipticalArcTo(center, radius_x, radius_y, rot, 0.0f, a_max, num_segments - 1); + PathFillConvex(col); +} + // Cubic Bezier takes 4 controls points void ImDrawList::AddBezierCubic(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, ImU32 col, float thickness, int num_segments) { From c9d3c29aa33aee77c99b46a8135469cde544b2ca Mon Sep 17 00:00:00 2001 From: sneakyevil Date: Tue, 5 Sep 2023 13:20:48 +0200 Subject: [PATCH 10/15] Backend: Win32: support keyboard codepage conversion for when compiling in MBCS mode and creating a non-Unicode window. (#6785, #6782, #5725) --- backends/imgui_impl_win32.cpp | 18 +++++++++++++++++- docs/CHANGELOG.txt | 2 ++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/backends/imgui_impl_win32.cpp b/backends/imgui_impl_win32.cpp index 0993ecf8..f3c33914 100644 --- a/backends/imgui_impl_win32.cpp +++ b/backends/imgui_impl_win32.cpp @@ -36,6 +36,7 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*); // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2023-09-07: Inputs: Added support for keyboard codepage conversion for when application is compiled in MBCS mode and using a non-Unicode window. // 2023-04-19: Added ImGui_ImplWin32_InitForOpenGL() to facilitate combining raw Win32/Winapi with OpenGL. (#3218) // 2023-04-04: Inputs: Added support for io.AddMouseSourceEvent() to discriminate ImGuiMouseSource_Mouse/ImGuiMouseSource_TouchScreen/ImGuiMouseSource_Pen. (#2702) // 2023-02-15: Inputs: Use WM_NCMOUSEMOVE / WM_NCMOUSELEAVE to track mouse position over non-client area (e.g. OS decorations) when app is not focused. (#6045, #6162) @@ -94,6 +95,7 @@ struct ImGui_ImplWin32_Data INT64 Time; INT64 TicksPerSecond; ImGuiMouseCursor LastMouseCursor; + UINT32 KeyboardCodePage; #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD bool HasGamepad; @@ -116,6 +118,16 @@ static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData() } // Functions +static void ImGui_ImplWin32_UpdateKeyboardCodePage() +{ + // Retrieve keyboard code page, required for handling of non-Unicode Windows. + ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); + HKL keyboard_layout = ::GetKeyboardLayout(0); + LCID keyboard_lcid = MAKELCID(HIWORD(keyboard_layout), SORT_DEFAULT); + if (::GetLocaleInfoA(keyboard_lcid, (LOCALE_RETURN_NUMBER | LOCALE_IDEFAULTANSICODEPAGE), (LPSTR)&bd->KeyboardCodePage, sizeof(bd->KeyboardCodePage)) == 0) + bd->KeyboardCodePage = CP_ACP; // Fallback to default ANSI code page when fails. +} + static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc) { ImGuiIO& io = ImGui::GetIO(); @@ -138,6 +150,7 @@ static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc) bd->TicksPerSecond = perf_frequency; bd->Time = perf_counter; bd->LastMouseCursor = ImGuiMouseCursor_COUNT; + ImGui_ImplWin32_UpdateKeyboardCodePage(); // Set platform dependent data in viewport ImGui::GetMainViewport()->PlatformHandleRaw = (void*)hwnd; @@ -671,6 +684,9 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA case WM_KILLFOCUS: io.AddFocusEvent(msg == WM_SETFOCUS); return 0; + case WM_INPUTLANGCHANGE: + ImGui_ImplWin32_UpdateKeyboardCodePage(); + return 0; case WM_CHAR: if (::IsWindowUnicode(hwnd)) { @@ -681,7 +697,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA else { wchar_t wch = 0; - ::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, (char*)&wParam, 1, &wch, 1); + ::MultiByteToWideChar(bd->KeyboardCodePage, MB_PRECOMPOSED, (char*)&wParam, 1, &wch, 1); io.AddInputCharacter(wch); } return 0; diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 183c1151..2d85903c 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -52,6 +52,8 @@ Other changes: Was most often noticable when using an horizontal scrollbar. (#6789) - ImDrawList: Added AddEllipse(), AddEllipseFilled(), PathEllipticalArcTo(). (#2743) [@Doohl] - Backends: GLFW: Clear emscripten's MouseWheel callback before shutdown. (#6790, #6096, #4019) [@halx99] +- Backends: Win32: Added support for keyboard codepage conversion for when application + is compiled in MBCS mode and using a non-Unicode window. (#6785, #6782, #5725, #5961) [@sneakyevil] ----------------------------------------------------------------------- From 727c4620696e9d187ffa1a653de8fd4bff633a42 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 8 Sep 2023 11:08:14 +0200 Subject: [PATCH 11/15] Internals: Added ImTextFindPreviousUtf8Codepoint() helper + comments. --- imgui.cpp | 12 ++++++++++++ imgui.h | 2 +- imgui_internal.h | 23 ++++++++++++----------- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 1a9267bc..b00d9b5a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2265,6 +2265,18 @@ int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_e } return bytes_count; } + +const char* ImTextFindPreviousUtf8Codepoint(const char* in_text_start, const char* in_text_curr) +{ + while (in_text_curr > in_text_start) + { + in_text_curr--; + if ((*in_text_curr & 0xC0) != 0x80) + return in_text_curr; + } + return in_text_start; +} + IM_MSVC_RUNTIME_CHECKS_RESTORE //----------------------------------------------------------------------------- diff --git a/imgui.h b/imgui.h index 8cc1b437..2ab95304 100644 --- a/imgui.h +++ b/imgui.h @@ -2039,7 +2039,7 @@ struct ImGuiIO // (default to use native imm32 api on Windows) void (*SetPlatformImeDataFn)(ImGuiViewport* viewport, ImGuiPlatformImeData* data); #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - void* ImeWindowHandle; // = NULL // [Obsolete] Set ImGuiViewport::PlatformHandleRaw instead. Set this to your HWND to get automatic IME cursor positioning. + void* ImeWindowHandle; // = NULL // [Obsoleted in 1.87] Set ImGuiViewport::PlatformHandleRaw instead. Set this to your HWND to get automatic IME cursor positioning. #else void* _UnusedPadding; // Unused field to keep data structure the same size. #endif diff --git a/imgui_internal.h b/imgui_internal.h index 65201ca6..70d1cecc 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -348,18 +348,18 @@ static inline bool ImIsPowerOfTwo(ImU64 v) { return v != 0 && (v & static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } // Helpers: String -IMGUI_API int ImStricmp(const char* str1, const char* str2); -IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count); -IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); -IMGUI_API char* ImStrdup(const char* str); -IMGUI_API char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* str); -IMGUI_API const char* ImStrchrRange(const char* str_begin, const char* str_end, char c); -IMGUI_API int ImStrlenW(const ImWchar* str); +IMGUI_API int ImStricmp(const char* str1, const char* str2); // Case insensitive compare. +IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count); // Case insensitive compare to a certain count. +IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); // Copy to a certain count and always zero terminate (strncpy doesn't). +IMGUI_API char* ImStrdup(const char* str); // Duplicate a string. +IMGUI_API char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* str); // Copy in provided buffer, recreate buffer if needed. +IMGUI_API const char* ImStrchrRange(const char* str_begin, const char* str_end, char c); // Find first occurrence of 'c' in string range. IMGUI_API const char* ImStreolRange(const char* str, const char* str_end); // End end-of-line -IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line -IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end); -IMGUI_API void ImStrTrimBlanks(char* str); -IMGUI_API const char* ImStrSkipBlank(const char* str); +IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end); // Find a substring in a string range. +IMGUI_API void ImStrTrimBlanks(char* str); // Remove leading and trailing blanks from a buffer. +IMGUI_API const char* ImStrSkipBlank(const char* str); // Find first non-blank character. +IMGUI_API int ImStrlenW(const ImWchar* str); // Computer string length (ImWchar string) +IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line (ImWchar string) IM_MSVC_RUNTIME_CHECKS_OFF static inline char ImToUpper(char c) { return (c >= 'a' && c <= 'z') ? c &= ~32 : c; } static inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; } @@ -386,6 +386,7 @@ IMGUI_API int ImTextStrFromUtf8(ImWchar* out_buf, int out_buf_size, co IMGUI_API int ImTextCountCharsFromUtf8(const char* in_text, const char* in_text_end); // return number of UTF-8 code-points (NOT bytes count) IMGUI_API int ImTextCountUtf8BytesFromChar(const char* in_text, const char* in_text_end); // return number of bytes to express one char in UTF-8 IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end); // return number of bytes to express string in UTF-8 +IMGUI_API const char* ImTextFindPreviousUtf8Codepoint(const char* in_text_start, const char* in_text_curr); // return previous UTF-8 code-point. // Helpers: File System #ifdef IMGUI_DISABLE_FILE_FUNCTIONS From becd75676f48d0f76669a6432f55d8027f49e856 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 8 Sep 2023 11:27:59 +0200 Subject: [PATCH 12/15] Commented out obsolete redirecting function: GetWindowContentRegionWidth(). --- docs/CHANGELOG.txt | 4 ++++ imgui.cpp | 4 +++- imgui.h | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 2d85903c..602478b7 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -42,6 +42,10 @@ HOW TO UPDATE? Breaking changes: + - Commented out obsolete redirecting functions names that were marked obsolete: + - GetWindowContentRegionWidth() -> use GetWindowContentRegionMax().x - GetWindowContentRegionMin().x. + - Consider that generally 'GetContentRegionAvail().x' is more useful. + Other changes: - InputTextMultiline: Fixed a crash pressing Down on last empty line of a multiline buffer. diff --git a/imgui.cpp b/imgui.cpp index b00d9b5a..ef7fe134 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -425,7 +425,9 @@ CODE When you are not sure about an 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. - - 2023/08/25 (1.89.9) - Clipper: Renamed IncludeRangeByIndices() (also called ForceDisplayRangeByIndices() before 1.89.6) to IncludeItemsByIndex(). Kept inline redirection function. Sorry! + - 2023/09/08 (1.90) - commented out obsolete redirecting functions: + - GetWindowContentRegionWidth() -> use GetWindowContentRegionMax().x - GetWindowContentRegionMin().x. Consider that generally 'GetContentRegionAvail().x' is more useful. + - 2023/08/25 (1.89.9) - clipper: Renamed IncludeRangeByIndices() (also called ForceDisplayRangeByIndices() before 1.89.6) to IncludeItemsByIndex(). Kept inline redirection function. Sorry! - 2023/07/12 (1.89.8) - ImDrawData: CmdLists now owned, changed from ImDrawList** to ImVector. Majority of users shouldn't be affected, but you cannot compare to NULL nor reassign manually anymore. Instead use AddDrawList(). (#6406, #4879, #1878) - 2023/06/28 (1.89.7) - overlapping items: obsoleted 'SetItemAllowOverlap()' (called after item) in favor of calling 'SetNextItemAllowOverlap()' (called before item). 'SetItemAllowOverlap()' didn't and couldn't work reliably since 1.89 (2022-11-15). - 2023/06/28 (1.89.7) - overlapping items: renamed 'ImGuiTreeNodeFlags_AllowItemOverlap' to 'ImGuiTreeNodeFlags_AllowOverlap', 'ImGuiSelectableFlags_AllowItemOverlap' to 'ImGuiSelectableFlags_AllowOverlap'. Kept redirecting enums (will obsolete). diff --git a/imgui.h b/imgui.h index 2ab95304..f9ac71af 100644 --- a/imgui.h +++ b/imgui.h @@ -3110,10 +3110,10 @@ namespace ImGui static inline void CaptureMouseFromApp(bool want_capture_mouse = true) { SetNextFrameWantCaptureMouse(want_capture_mouse); } // Renamed as name was misleading + removed default value. // OBSOLETED in 1.86 (from November 2021) IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // Calculate coarse clipping for large list of evenly sized items. Prefer using ImGuiListClipper. - // OBSOLETED in 1.85 (from August 2021) - static inline float GetWindowContentRegionWidth() { return GetWindowContentRegionMax().x - GetWindowContentRegionMin().x; } // Some of the older obsolete names along with their replacement (commented out so they are not reported in IDE) + //-- OBSOLETED in 1.85 (from August 2021) + //static inline float GetWindowContentRegionWidth() { return GetWindowContentRegionMax().x - GetWindowContentRegionMin().x; } //-- OBSOLETED in 1.81 (from February 2021) //static inline bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0, 0)) { return BeginListBox(label, size); } //static inline bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1) { float height = GetTextLineHeightWithSpacing() * ((height_in_items < 0 ? ImMin(items_count, 7) : height_in_items) + 0.25f) + GetStyle().FramePadding.y * 2.0f; return BeginListBox(label, ImVec2(0.0f, height)); } // Helper to calculate size from items_count and height_in_items From 44a6b493ee924c82012a0e7c4b5cb0b32ef97923 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 8 Sep 2023 12:14:11 +0200 Subject: [PATCH 13/15] Commented out obsolete ImDrawCornerFlags_XXX. Commented out runtime support for hardcoded ~0 or 0x01..0x0F rounding flags values for AddRect()/AddRectFilled()/PathRect()/AddImageRounded() Amend 5185329, 3f5b2a3, c2d6d26, 39432bf, 033dfd9 --- docs/CHANGELOG.txt | 9 +++++++-- imgui.cpp | 6 ++++-- imgui.h | 30 +++++++++++++++--------------- imgui_draw.cpp | 33 +++++++++++---------------------- 4 files changed, 37 insertions(+), 41 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 602478b7..a99dc5e6 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -42,9 +42,14 @@ HOW TO UPDATE? Breaking changes: - - Commented out obsolete redirecting functions names that were marked obsolete: + - Commented out obsolete redirecting enums/functions that were marked obsolete two years ago: - GetWindowContentRegionWidth() -> use GetWindowContentRegionMax().x - GetWindowContentRegionMin().x. - - Consider that generally 'GetContentRegionAvail().x' is more useful. + Consider that generally 'GetContentRegionAvail().x' is more useful. + - ImDrawCornerFlags_XXX -> use ImDrawFlags_RoundCornersXXX names. + Read 1.82 changelog for details + grep commented names in sources + . + - Commented out runtime support for hardcoded ~0 or 0x01..0x0F rounding flags values for + AddRect()/AddRectFilled()/PathRect()/AddImageRounded(). -> Use ImDrawFlags_RoundCornersXXX flags. + Read 1.82 Changelog for details. Other changes: diff --git a/imgui.cpp b/imgui.cpp index ef7fe134..6d762970 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -425,8 +425,10 @@ CODE When you are not sure about an 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. - - 2023/09/08 (1.90) - commented out obsolete redirecting functions: - - GetWindowContentRegionWidth() -> use GetWindowContentRegionMax().x - GetWindowContentRegionMin().x. Consider that generally 'GetContentRegionAvail().x' is more useful. + - 2023/09/08 (1.90.0) - commented out obsolete redirecting functions: + - GetWindowContentRegionWidth() -> use GetWindowContentRegionMax().x - GetWindowContentRegionMin().x. Consider that generally 'GetContentRegionAvail().x' is more useful. + - ImDrawCornerFlags_XXX -> use ImDrawFlags_RoundCornersXXX flags. Read 1.82 Changelog for details + grep commented names in sources. + - commented out runtime support for hardcoded ~0 or 0x01..0x0F rounding flags values for AddRect()/AddRectFilled()/PathRect()/AddImageRounded() -> use ImDrawFlags_RoundCornersXXX flags. Read 1.82 Changelog for details - 2023/08/25 (1.89.9) - clipper: Renamed IncludeRangeByIndices() (also called ForceDisplayRangeByIndices() before 1.89.6) to IncludeItemsByIndex(). Kept inline redirection function. Sorry! - 2023/07/12 (1.89.8) - ImDrawData: CmdLists now owned, changed from ImDrawList** to ImVector. Majority of users shouldn't be affected, but you cannot compare to NULL nor reassign manually anymore. Instead use AddDrawList(). (#6406, #4879, #1878) - 2023/06/28 (1.89.7) - overlapping items: obsoleted 'SetItemAllowOverlap()' (called after item) in favor of calling 'SetNextItemAllowOverlap()' (called before item). 'SetItemAllowOverlap()' didn't and couldn't work reliably since 1.89 (2022-11-15). diff --git a/imgui.h b/imgui.h index f9ac71af..81ee64a9 100644 --- a/imgui.h +++ b/imgui.h @@ -3164,21 +3164,21 @@ namespace ImGui //static inline void SetScrollPosHere() { SetScrollHere(); } // OBSOLETED in 1.42 } -// OBSOLETED in 1.82 (from Mars 2021): flags for AddRect(), AddRectFilled(), AddImageRounded(), PathRect() -typedef ImDrawFlags ImDrawCornerFlags; -enum ImDrawCornerFlags_ -{ - ImDrawCornerFlags_None = ImDrawFlags_RoundCornersNone, // Was == 0 prior to 1.82, this is now == ImDrawFlags_RoundCornersNone which is != 0 and not implicit - ImDrawCornerFlags_TopLeft = ImDrawFlags_RoundCornersTopLeft, // Was == 0x01 (1 << 0) prior to 1.82. Order matches ImDrawFlags_NoRoundCorner* flag (we exploit this internally). - ImDrawCornerFlags_TopRight = ImDrawFlags_RoundCornersTopRight, // Was == 0x02 (1 << 1) prior to 1.82. - ImDrawCornerFlags_BotLeft = ImDrawFlags_RoundCornersBottomLeft, // Was == 0x04 (1 << 2) prior to 1.82. - ImDrawCornerFlags_BotRight = ImDrawFlags_RoundCornersBottomRight, // Was == 0x08 (1 << 3) prior to 1.82. - ImDrawCornerFlags_All = ImDrawFlags_RoundCornersAll, // 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, -}; +//-- OBSOLETED in 1.82 (from Mars 2021): flags for AddRect(), AddRectFilled(), AddImageRounded(), PathRect() +//typedef ImDrawFlags ImDrawCornerFlags; +//enum ImDrawCornerFlags_ +//{ +// ImDrawCornerFlags_None = ImDrawFlags_RoundCornersNone, // Was == 0 prior to 1.82, this is now == ImDrawFlags_RoundCornersNone which is != 0 and not implicit +// ImDrawCornerFlags_TopLeft = ImDrawFlags_RoundCornersTopLeft, // Was == 0x01 (1 << 0) prior to 1.82. Order matches ImDrawFlags_NoRoundCorner* flag (we exploit this internally). +// ImDrawCornerFlags_TopRight = ImDrawFlags_RoundCornersTopRight, // Was == 0x02 (1 << 1) prior to 1.82. +// ImDrawCornerFlags_BotLeft = ImDrawFlags_RoundCornersBottomLeft, // Was == 0x04 (1 << 2) prior to 1.82. +// ImDrawCornerFlags_BotRight = ImDrawFlags_RoundCornersBottomRight, // Was == 0x08 (1 << 3) prior to 1.82. +// ImDrawCornerFlags_All = ImDrawFlags_RoundCornersAll, // 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, +//}; // RENAMED and MERGED both ImGuiKey_ModXXX and ImGuiModFlags_XXX into ImGuiMod_XXX (from September 2022) // RENAMED ImGuiKeyModFlags -> ImGuiModFlags in 1.88 (from April 2022). Exceptionally commented out ahead of obscolescence schedule to reduce confusion and because they were not meant to be used in the first place. diff --git a/imgui_draw.cpp b/imgui_draw.cpp index b40f6b72..126eef0e 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1333,33 +1333,22 @@ void ImDrawList::PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, } } -IM_STATIC_ASSERT(ImDrawFlags_RoundCornersTopLeft == (1 << 4)); static inline ImDrawFlags FixRectCornerFlags(ImDrawFlags flags) { + /* + IM_STATIC_ASSERT(ImDrawFlags_RoundCornersTopLeft == (1 << 4)); #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - // Obsoleted in 1.82 (from February 2021) - // Legacy Support for hard coded ~0 (used to be a suggested equivalent to ImDrawCornerFlags_All) - // ~0 --> ImDrawFlags_RoundCornersAll or 0 - if (flags == ~0) - return ImDrawFlags_RoundCornersAll; - - // Legacy Support for hard coded 0x01 to 0x0F (matching 15 out of 16 old flags combinations) - // 0x01 --> ImDrawFlags_RoundCornersTopLeft (VALUE 0x01 OVERLAPS ImDrawFlags_Closed but ImDrawFlags_Closed is never valid in this path!) - // 0x02 --> ImDrawFlags_RoundCornersTopRight - // 0x03 --> ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersTopRight - // 0x04 --> ImDrawFlags_RoundCornersBotLeft - // 0x05 --> ImDrawFlags_RoundCornersTopLeft | ImDrawFlags_RoundCornersBotLeft - // ... - // 0x0F --> ImDrawFlags_RoundCornersAll or 0 - // (See all values in ImDrawCornerFlags_) - if (flags >= 0x01 && flags <= 0x0F) - return (flags << 4); - + // Obsoleted in 1.82 (from February 2021). This code was stripped/simplified and mostly commented in 1.90 (from September 2023) + // - Legacy Support for hard coded ~0 (used to be a suggested equivalent to ImDrawCornerFlags_All) + if (flags == ~0) { return ImDrawFlags_RoundCornersAll; } + // - Legacy Support for hard coded 0x01 to 0x0F (matching 15 out of 16 old flags combinations). Read details in older version of this code. + if (flags >= 0x01 && flags <= 0x0F) { return (flags << 4); } // We cannot support hard coded 0x00 with 'float rounding > 0.0f' --> replace with ImDrawFlags_RoundCornersNone or use 'float rounding = 0.0f' #endif - - // If this triggers, please update your code replacing hardcoded values with new ImDrawFlags_RoundCorners* values. - // Note that ImDrawFlags_Closed (== 0x01) is an invalid flag for AddRect(), AddRectFilled(), PathRect() etc... + */ + // If this assert triggers, please update your code replacing hardcoded values with new ImDrawFlags_RoundCorners* values. + // Note that ImDrawFlags_Closed (== 0x01) is an invalid flag for AddRect(), AddRectFilled(), PathRect() etc. anyway. + // See details in 1.82 Changelog as well as 2021/03/12 and 2023/09/08 entries in "API BREAKING CHANGES" section. IM_ASSERT((flags & 0x0F) == 0 && "Misuse of legacy hardcoded ImDrawCornerFlags values!"); if ((flags & ImDrawFlags_RoundCornersMask_) == 0) From 7812039402086177cbe0af490b911206e593371d Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 8 Sep 2023 15:30:46 +0200 Subject: [PATCH 14/15] ImVector: Added find_index() helper. --- docs/CHANGELOG.txt | 1 + imgui.cpp | 2 -- imgui.h | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index a99dc5e6..35a5ec6c 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -60,6 +60,7 @@ Other changes: register contents size in a way that would affect the scrolling layer. Was most often noticable when using an horizontal scrollbar. (#6789) - ImDrawList: Added AddEllipse(), AddEllipseFilled(), PathEllipticalArcTo(). (#2743) [@Doohl] +- ImVector: Added find_index() helper. - Backends: GLFW: Clear emscripten's MouseWheel callback before shutdown. (#6790, #6096, #4019) [@halx99] - Backends: Win32: Added support for keyboard codepage conversion for when application is compiled in MBCS mode and using a non-Unicode window. (#6785, #6782, #5725, #5961) [@sneakyevil] diff --git a/imgui.cpp b/imgui.cpp index 6d762970..e1aa61e2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2698,8 +2698,6 @@ void ImGuiTextIndex::append(const char* base, int old_size, int new_size) //----------------------------------------------------------------------------- // [SECTION] ImGuiListClipper -// This is currently not as flexible/powerful as it should be and really confusing/spaghetti, mostly because we changed -// the API mid-way through development and support two ways to using the clipper, needs some rework (see TODO) //----------------------------------------------------------------------------- // FIXME-TABLE: This prevents us from using ImGuiListClipper _inside_ a table cell. diff --git a/imgui.h b/imgui.h index 81ee64a9..b5665ab1 100644 --- a/imgui.h +++ b/imgui.h @@ -1868,6 +1868,7 @@ struct ImVector inline bool contains(const T& v) const { const T* data = Data; const T* data_end = Data + Size; while (data < data_end) if (*data++ == v) return true; return false; } inline T* find(const T& v) { T* data = Data; const T* data_end = Data + Size; while (data < data_end) if (*data == v) break; else ++data; return data; } inline const T* find(const T& v) const { const T* data = Data; const T* data_end = Data + Size; while (data < data_end) if (*data == v) break; else ++data; return data; } + inline int find_index(const T& v) const { const T* data_end = Data + Size; const T* it = find(v); if (it == data_end) return -1; const ptrdiff_t off = it - Data; return (int)off; } inline bool find_erase(const T& v) { const T* it = find(v); if (it < Data + Size) { erase(it); return true; } return false; } inline bool find_erase_unsorted(const T& v) { const T* it = find(v); if (it < Data + Size) { erase_unsorted(it); return true; } return false; } inline int index_from_ptr(const T* it) const { IM_ASSERT(it >= Data && it < Data + Size); const ptrdiff_t off = it - Data; return (int)off; } From 0962c9fb723ee1498a533f0e592d81f7e6c1ffd8 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 8 Sep 2023 17:16:19 +0200 Subject: [PATCH 15/15] TypingSelect: Added first version of GetTypingSelectRequest() API. # Conflicts: # imgui_internal.h # imgui_widgets.cpp --- imgui_internal.h | 41 ++++++++++++++++++++ imgui_widgets.cpp | 98 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) diff --git a/imgui_internal.h b/imgui_internal.h index 70d1cecc..bc7b2ff9 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -23,6 +23,7 @@ Index of this file: // [SECTION] Inputs support // [SECTION] Clipper support // [SECTION] Navigation support +// [SECTION] Typing-select support // [SECTION] Columns support // [SECTION] Multi-select support // [SECTION] Docking support @@ -153,6 +154,8 @@ struct ImGuiTableInstanceData; // Storage for one instance of a same table struct ImGuiTableTempData; // Temporary storage for one table (one per table in the stack), shared between tables. struct ImGuiTableSettings; // Storage for a table .ini settings struct ImGuiTableColumnsSettings; // Storage for a column .ini settings +struct ImGuiTypingSelectData; // Storage for GetTypingSelectRequest() +struct ImGuiTypingSelectRequest; // Storage for GetTypingSelectRequest() (aimed to be public) struct ImGuiWindow; // Storage for one window struct ImGuiWindowTempData; // Temporary storage for one window (that's the data which in theory we could ditch at the end of the frame, in practice we currently keep it for each window) struct ImGuiWindowSettings; // Storage for a window .ini settings (we keep one of those even if the actual window wasn't instanced during this session) @@ -178,6 +181,7 @@ typedef int ImGuiScrollFlags; // -> enum ImGuiScrollFlags_ // F typedef int ImGuiSeparatorFlags; // -> enum ImGuiSeparatorFlags_ // Flags: for SeparatorEx() typedef int ImGuiTextFlags; // -> enum ImGuiTextFlags_ // Flags: for TextEx() typedef int ImGuiTooltipFlags; // -> enum ImGuiTooltipFlags_ // Flags: for BeginTooltipEx() +typedef int ImGuiTypingSelectFlags; // -> enum ImGuiTypingSelectFlags_ // Flags: for GetTypingSelectRequest() typedef void (*ImGuiErrorLogCallback)(void* user_data, const char* fmt, ...); @@ -1532,6 +1536,39 @@ struct ImGuiNavItemData void Clear() { Window = NULL; ID = FocusScopeId = 0; InFlags = 0; DistBox = DistCenter = DistAxial = FLT_MAX; } }; +//----------------------------------------------------------------------------- +// [SECTION] Typing-select support +//----------------------------------------------------------------------------- + +// Flags for GetTypingSelectRequest() +enum ImGuiTypingSelectFlags_ +{ + ImGuiTypingSelectFlags_None = 0, + ImGuiTypingSelectFlags_AllowBackspace = 1 << 0, // Backspace to delete character inputs. If using: ensure GetTypingSelectRequest() is not called more than once per frame (filter by e.g. focus state) +}; + +// Returned by GetTypingSelectRequest(), designed to eventually be public. +struct IMGUI_API ImGuiTypingSelectRequest +{ + const char* SearchBuffer; + int SearchBufferLen; + bool SelectRequest; // Set when buffer was modified this frame, requesting a selection. + bool RepeatCharMode; // Notify when buffer contains same character repeated, to implement special mode. + ImS8 RepeatCharSize; // Length in bytes of first letter codepoint (1 for ascii, 2-4 for UTF-8). If (SearchBufferLen==RepeatCharSize) only 1 letter has been input. +}; + +// Storage for GetTypingSelectRequest() +struct IMGUI_API ImGuiTypingSelectData +{ + ImGuiTypingSelectRequest Request; // User-facing data + char SearchBuffer[64]; // Search buffer: no need to make dynamic as this search is very transient. + ImGuiID FocusScope; + int LastRequestFrame = 0; + float LastRequestTime = 0.0f; + + ImGuiTypingSelectData() { memset(this, 0, sizeof(*this)); } +}; + //----------------------------------------------------------------------------- // [SECTION] Columns support //----------------------------------------------------------------------------- @@ -2019,6 +2056,7 @@ struct ImGuiContext short TooltipOverrideCount; ImVector ClipboardHandlerData; // If no custom clipboard handler is defined ImVector MenusIdSubmittedThisFrame; // A list of menu IDs that were rendered at least once + ImGuiTypingSelectData TypingSelectData; // Platform support ImGuiPlatformImeData PlatformImeData; // Data updated by current frame @@ -3057,6 +3095,9 @@ namespace ImGui IMGUI_API bool IsDragDropPayloadBeingAccepted(); IMGUI_API void RenderDragDropTargetRect(const ImRect& bb); + // Typing-Select API + IMGUI_API const ImGuiTypingSelectRequest* GetTypingSelectRequest(ImGuiTypingSelectFlags flags = ImGuiTypingSelectFlags_None); + // Internal Columns API (this is not exposed because we will encourage transitioning to the Tables API) IMGUI_API void SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect); IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiOldColumnFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index e4ade8c7..339f2800 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -18,6 +18,7 @@ Index of this file: // [SECTION] Widgets: ColorEdit, ColorPicker, ColorButton, etc. // [SECTION] Widgets: TreeNode, CollapsingHeader, etc. // [SECTION] Widgets: Selectable +// [SECTION] Widgets: Typing-Select support // [SECTION] Widgets: ListBox // [SECTION] Widgets: PlotLines, PlotHistogram // [SECTION] Widgets: Value helpers @@ -6597,6 +6598,103 @@ bool ImGui::Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags return false; } + +//------------------------------------------------------------------------- +// [SECTION] Widgets: Typing-Select support +//------------------------------------------------------------------------- + +// [Experimental] Currently not exposed in public API. +// Consume character inputs and return search request, if any. +// This would typically only be called on the focused window or location you want to grab inputs for, e.g. +// if (ImGui::IsWindowFocused(...)) +// if (const ImGuiTypingSelectRequest* req = ImGui::GetTypingSelectRequest()) +// if (req->SearchRequest) +// // perform search +// However the code is written in a way where calling it from multiple locations is safe (e.g. to obtain buffer). +const ImGuiTypingSelectRequest* ImGui::GetTypingSelectRequest(ImGuiTypingSelectFlags flags) +{ + ImGuiContext& g = *GImGui; + ImGuiTypingSelectData* data = &g.TypingSelectData; + ImGuiTypingSelectRequest* out_request = &data->Request; + + // Clear buffer + if (data->SearchBuffer[0] != 0) + { + const float TYPING_SELECT_RESET_TIMER = 1.70f; // FIXME: Potentially move to IO config. + bool clear_buffer = false; + clear_buffer |= (g.NavFocusScopeId != data->FocusScope); + clear_buffer |= (data->LastRequestTime + TYPING_SELECT_RESET_TIMER < g.Time); + clear_buffer |= g.NavAnyRequest; + clear_buffer |= g.ActiveId != 0 && g.NavActivateId == 0; // Allow temporary SPACE activation to not interfere + clear_buffer |= IsKeyPressed(ImGuiKey_Escape) || IsKeyPressed(ImGuiKey_Enter); + clear_buffer |= IsKeyPressed(ImGuiKey_Backspace) && (flags & ImGuiTypingSelectFlags_AllowBackspace) == 0; + //if (clear_buffer) { IMGUI_DEBUG_LOG("GetTypingSelectRequest(): Clear SearchBuffer.\n"); } + if (clear_buffer) + data->SearchBuffer[0] = 0; + } + + // Append to buffer + const int buffer_max_len = IM_ARRAYSIZE(data->SearchBuffer) - 1; + int buffer_len = (int)strlen(data->SearchBuffer); + bool buffer_changed = false; + for (ImWchar w : g.IO.InputQueueCharacters) + { + if (w < 32 || (buffer_len == 0 && ImCharIsBlankW(w))) // Ignore leading blanks + continue; + int utf8_len = ImTextCountUtf8BytesFromStr(&w, &w + 1); + if (buffer_len + utf8_len > buffer_max_len) + break; + ImTextCharToUtf8(data->SearchBuffer + buffer_len, (unsigned int)w); + buffer_len += utf8_len; + buffer_changed = true; + } + g.IO.InputQueueCharacters.resize(0); + if ((flags & ImGuiTypingSelectFlags_AllowBackspace) && IsKeyPressed(ImGuiKey_Backspace, 0, ImGuiInputFlags_Repeat)) + { + char* p = (char*)(void*)ImTextFindPreviousUtf8Codepoint(data->SearchBuffer, data->SearchBuffer + buffer_len); + *p = 0; + buffer_len = (int)(p - data->SearchBuffer); + } + if (buffer_len == 0) + return NULL; + + // Return request if any + if (buffer_changed) + { + data->FocusScope = g.NavFocusScopeId; + data->LastRequestFrame = g.FrameCount; + data->LastRequestTime = (float)g.Time; + } + out_request->SearchBuffer = data->SearchBuffer; + out_request->SearchBufferLen = buffer_len; + out_request->SelectRequest = (data->LastRequestFrame == g.FrameCount); + out_request->RepeatCharMode = false; + out_request->RepeatCharSize = 0; + + // Calculate if buffer contains the same character repeated. + // - This can be used to implement a special search mode on first character. + // - Performed on UTF-8 codepoint for correctness. + // - RepeatCharMode is always set for first input character, because it usually leads to a "next". + const char* buf_begin = out_request->SearchBuffer; + const char* buf_end = out_request->SearchBuffer + out_request->SearchBufferLen; + const int c0_len = ImTextCountUtf8BytesFromChar(buf_begin, buf_end); + const char* p = buf_begin + c0_len; + for (; p < buf_end; p += c0_len) + if (memcmp(buf_begin, p, (size_t)c0_len) != 0) + break; + out_request->RepeatCharMode = (p == buf_end); + out_request->RepeatCharSize = out_request->RepeatCharMode ? (ImS8)c0_len : 0; + + return out_request; +} + + +//------------------------------------------------------------------------- +// [SECTION] Widgets: Multi-Select support +//------------------------------------------------------------------------- + +// + //------------------------------------------------------------------------- // [SECTION] Widgets: ListBox //-------------------------------------------------------------------------