From 110f506ec0dd10999ed685c87c609553cb162028 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 19 Mar 2020 18:35:08 +0100 Subject: [PATCH 01/13] Comments in imgui.h --- imgui.h | 50 +++++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/imgui.h b/imgui.h index d45e873b..44a011d6 100644 --- a/imgui.h +++ b/imgui.h @@ -112,6 +112,7 @@ Index of this file: // Forward declarations and basic types //----------------------------------------------------------------------------- +// Forward declarations struct ImDrawChannel; // Temporary storage to output draw commands out of order, used by ImDrawListSplitter and ImDrawList::ChannelsSplit() struct ImDrawCmd; // A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call, unless it is a callback) struct ImDrawData; // All draw command lists required to render the frame + pos/size coordinates to use for the projection matrix. @@ -135,19 +136,12 @@ struct ImGuiSizeCallbackData; // Callback data when using SetNextWindowSiz struct ImGuiStorage; // Helper for key->value storage struct ImGuiStyle; // Runtime data for styling/colors struct ImGuiTextBuffer; // Helper to hold and append into a text buffer (~string builder) -struct ImGuiTextFilter; // Helper to parse and apply text filters (e.g. "aaaaa[,bbbb][,ccccc]") +struct ImGuiTextFilter; // Helper to parse and apply text filters (e.g. "aaaaa[,bbbbb][,ccccc]") -// Typedefs and Enums/Flags (declared as int for compatibility with old C++, to allow using as flags and to not pollute the top of this file) -// Use your programming IDE "Go to definition" facility on the names in the central column below to find the actual flags/enum lists. -#ifndef ImTextureID -typedef void* ImTextureID; // User data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp) -#endif -typedef unsigned int ImGuiID; // Unique ID used by widgets (typically hashed from a stack of string) -#ifndef ImWchar -#define ImWchar ImWchar16 -#endif -typedef unsigned short ImWchar16; // A single U16 character for keyboard input/display. We encode them as multi bytes UTF-8 when used in strings. -typedef unsigned int ImWchar32; // A single U32 character for keyboard input/display. Define ImWchar to ImWchar32 to use it. See imconfig.h . +// Enums/Flags (declared as int for compatibility with old C++, to allow using as flags and to not pollute the top of this file) +// - Tip: Use your programming IDE navigation facilities on the names in the _central column_ below to find the actual flags/enum lists! +// In Visual Studio IDE: CTRL+comma ("Edit.NavigateTo") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. +// With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments. typedef int ImGuiCol; // -> enum ImGuiCol_ // Enum: A color identifier for styling typedef int ImGuiCond; // -> enum ImGuiCond_ // Enum: A condition for many Set*() functions typedef int ImGuiDataType; // -> enum ImGuiDataType_ // Enum: A primary data type @@ -174,10 +168,21 @@ typedef int ImGuiTabBarFlags; // -> enum ImGuiTabBarFlags_ // Flags: f typedef int ImGuiTabItemFlags; // -> enum ImGuiTabItemFlags_ // Flags: for BeginTabItem() typedef int ImGuiTreeNodeFlags; // -> enum ImGuiTreeNodeFlags_ // Flags: for TreeNode(), TreeNodeEx(), CollapsingHeader() typedef int ImGuiWindowFlags; // -> enum ImGuiWindowFlags_ // Flags: for Begin(), BeginChild() + +// Other types +#ifndef ImTextureID // ImTextureID [configurable type: override in imconfig.h] +typedef void* ImTextureID; // User data for rendering back-end to identify a texture. This is whatever to you want it to be! read the FAQ about ImTextureID for details. +#endif +#ifndef ImWchar // ImWchar [configurable type: override in imconfig.h] +#define ImWchar ImWchar16 // Storage for a single decoded character/code point, default to 16-bit. Set to ImWchar32 to support larger Unicode planes. Note that we generally support UTF-8 encoded string, this is storage for a decoded character. +#endif +typedef unsigned int ImGuiID; // A unique ID used by widgets, typically hashed from a stack of string. +typedef unsigned short ImWchar16; // A single decoded U16 character/code point for keyboard input/display. We encode them as multi bytes UTF-8 when used in strings. +typedef unsigned int ImWchar32; // A single decoded U32 character/code point for keyboard input/display. To enable, use '#define ImWchar ImWchar32' in imconfig.h. typedef int (*ImGuiInputTextCallback)(ImGuiInputTextCallbackData *data); typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data); -// Scalar data types +// Basic scalar data types typedef signed char ImS8; // 8-bit signed integer typedef unsigned char ImU8; // 8-bit unsigned integer typedef signed short ImS16; // 16-bit signed integer @@ -196,7 +201,7 @@ typedef signed long long ImS64; // 64-bit signed integer (post C++11) typedef unsigned long long ImU64; // 64-bit unsigned integer (post C++11) #endif -// 2D vector (often used to store positions, sizes, etc.) +// 2D vector (often used to store positions or sizes) struct ImVec2 { float x, y; @@ -234,7 +239,6 @@ namespace ImGui IMGUI_API void DestroyContext(ImGuiContext* ctx = NULL); // NULL = destroy current context IMGUI_API ImGuiContext* GetCurrentContext(); IMGUI_API void SetCurrentContext(ImGuiContext* ctx); - IMGUI_API bool DebugCheckVersionAndDataLayout(const char* version_str, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_drawvert, size_t sz_drawidx); // Main IMGUI_API ImGuiIO& GetIO(); // access the IO structure (mouse/keyboard/gamepad inputs, time, various configuration options/flags) @@ -633,7 +637,7 @@ namespace ImGui IMGUI_API void LogText(const char* fmt, ...) IM_FMTARGS(1); // pass text data straight to log (without being displayed) // Drag and Drop - // [BETA API] API may evolve! + // - [BETA API] API may evolve! IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0); // call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t sz, ImGuiCond cond = 0); // type is a user defined string of maximum 32 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. IMGUI_API void EndDragDropSource(); // only call EndDragDropSource() if BeginDragDropSource() returns true! @@ -726,7 +730,8 @@ namespace ImGui IMGUI_API void SetMouseCursor(ImGuiMouseCursor cursor_type); // set desired cursor type IMGUI_API void CaptureMouseFromApp(bool want_capture_mouse_value = true); // attention: misleading name! manually override io.WantCaptureMouse flag next frame (said flag is entirely left for your application to handle). This is equivalent to setting "io.WantCaptureMouse = want_capture_mouse_value;" after the next NewFrame() call. - // Clipboard Utilities (also see the LogToClipboard() function to capture or output text data to the clipboard) + // Clipboard Utilities + // - Also see the LogToClipboard() function to capture GUI into clipboard, or easily output text data to the clipboard. IMGUI_API const char* GetClipboardText(); IMGUI_API void SetClipboardText(const char* text); @@ -738,6 +743,9 @@ namespace ImGui IMGUI_API void SaveIniSettingsToDisk(const char* ini_filename); // this is automatically called (if io.IniFilename is not empty) a few seconds after any modification that should be reflected in the .ini file (and also by DestroyContext). IMGUI_API const char* SaveIniSettingsToMemory(size_t* out_ini_size = NULL); // return a zero-terminated string with the .ini data which you can save by your own mean. call when io.WantSaveIniSettings is set, then save data by your own mean and clear io.WantSaveIniSettings. + // Debug Utilities + IMGUI_API bool DebugCheckVersionAndDataLayout(const char* version_str, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_drawvert, size_t sz_drawidx); // This is called by IMGUI_CHECKVERSION() macro. + // Memory Allocators // - All those functions are not reliant on the current context. // - If you reload the contents of imgui.cpp at runtime, you may need to call SetCurrentContext() + SetAllocatorFunctions() again because we use global storage for those. @@ -1825,7 +1833,7 @@ struct ImColor // Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList. //----------------------------------------------------------------------------- -// Draw callbacks for advanced uses. +// ImDrawCallback: Draw callbacks for advanced uses [configurable type: override in imconfig.h] // NB: You most likely do NOT need to use draw callbacks just to create your own widget or customized UI rendering, // you can poke into the draw list for that! Draw callback may be useful for example to: // A) Change your GPU render state, @@ -1858,9 +1866,9 @@ struct ImDrawCmd ImDrawCmd() { ElemCount = 0; TextureId = (ImTextureID)NULL; VtxOffset = IdxOffset = 0; UserCallback = NULL; UserCallbackData = NULL; } }; -// Vertex index -// (to allow large meshes with 16-bit indices: set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' and handle ImDrawCmd::VtxOffset in the renderer back-end) -// (to use 32-bit indices: override with '#define ImDrawIdx unsigned int' in imconfig.h) +// Vertex index, default to 16-bit +// To allow large meshes with 16-bit indices: set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset' and handle ImDrawCmd::VtxOffset in the renderer back-end (recommended). +// To use 32-bit indices: override with '#define ImDrawIdx unsigned int' in imconfig.h. #ifndef ImDrawIdx typedef unsigned short ImDrawIdx; #endif From 4986dba270131850d892c0fbe028878358aad4a0 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Mar 2020 11:56:21 +0100 Subject: [PATCH 02/13] Scrolling: Fixed scrolling centering API leading to non-integer scrolling values and initial cursor position. (#3073) This would often get fixed after the fix item submission, but using the ImGuiListClipper as the first thing after Begin() could largely break size calculations. (#3073) --- docs/CHANGELOG.txt | 3 +++ imgui.cpp | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 96d02a88..226e79ed 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -45,6 +45,9 @@ Other Changes: when the menu is not open. (#3030) - InputText: Fixed password fields displaying ASCII spaces as blanks instead of using the '*' glyph. (#2149, #515) +- Scrolling: Fixed scrolling centering API leading to non-integer scrolling values and initial + cursor position. This would often get fixed after the fix item submission, but using the + ImGuiListClipper as the first thing after Begin() could largely break size calculations. (#3073) - Added optional support for Unicode plane 1-16 (#2538, #2541, #2815) [@cloudwu, @samhocevar] - Compile-time enable with '#define ImWchar ImWchar32' in imconfig.h. - Generally more consistent support for unsupported codepoints (0xFFFD), in particular when diff --git a/imgui.cpp b/imgui.cpp index 9d344aee..477b0f67 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7283,7 +7283,8 @@ static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool s target_y = window->ContentSize.y + window->WindowPadding.y * 2.0f; scroll.y = target_y - cr_y * (window->SizeFull.y - window->ScrollbarSizes.y - decoration_up_height); } - scroll = ImMax(scroll, ImVec2(0.0f, 0.0f)); + scroll.x = IM_FLOOR(ImMax(scroll.x, 0.0f)); + scroll.y = IM_FLOOR(ImMax(scroll.y, 0.0f)); if (!window->Collapsed && !window->SkipItems) { scroll.x = ImMin(scroll.x, window->ScrollMax.x); From ac4262ad01cdfa8a089e3a43e8cafd1c3887d2ff Mon Sep 17 00:00:00 2001 From: David Kalnischkies Date: Thu, 20 Feb 2020 15:49:15 +0100 Subject: [PATCH 03/13] Backends: OpenGL3: Support older 2.x series of glbinding as loader for OpenGL3 (#3061) This removes the unversioned definition IMGUI_IMPL_OPENGL_LOADER_GLBINDING in favor of two versioned ones to choose explicitly. References: #2870, 5e2329b98e6562c9e7883e92dcf878e969d81878 --- examples/example_glfw_opengl3/Makefile | 7 +++++-- examples/example_glfw_opengl3/main.cpp | 11 +++++++++-- examples/example_sdl_opengl3/Makefile | 7 +++++-- examples/example_sdl_opengl3/main.cpp | 11 +++++++++-- examples/imgui_impl_opengl3.cpp | 18 +++++++++++++----- examples/imgui_impl_opengl3.h | 9 ++++++--- 6 files changed, 47 insertions(+), 16 deletions(-) diff --git a/examples/example_glfw_opengl3/Makefile b/examples/example_glfw_opengl3/Makefile index f0160b19..7696eaae 100644 --- a/examples/example_glfw_opengl3/Makefile +++ b/examples/example_glfw_opengl3/Makefile @@ -42,8 +42,11 @@ CXXFLAGS += -I../libs/gl3w -DIMGUI_IMPL_OPENGL_LOADER_GL3W # CXXFLAGS += -I../libs/glad/include -DIMGUI_IMPL_OPENGL_LOADER_GLAD ## Using OpenGL loader: glbinding -## (This assumes a system-wide installation) -# CXXFLAGS += -lglbinding -DIMGUI_IMPL_OPENGL_LOADER_GLBINDING +## This assumes a system-wide installation +## of either version 3.0.0 (or newer) +# CXXFLAGS += -lglbinding -DIMGUI_IMPL_OPENGL_LOADER_GLBINDING3 +## or the older version 2.x +# CXXFLAGS += -lglbinding -DIMGUI_IMPL_OPENGL_LOADER_GLBINDING2 ##--------------------------------------------------------------------- ## BUILD FLAGS PER PLATFORM diff --git a/examples/example_glfw_opengl3/main.cpp b/examples/example_glfw_opengl3/main.cpp index 55b379de..61797d3e 100644 --- a/examples/example_glfw_opengl3/main.cpp +++ b/examples/example_glfw_opengl3/main.cpp @@ -17,9 +17,13 @@ #include // Initialize with glewInit() #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) #include // Initialize with gladLoadGL() -#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING) +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) || defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) #define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors. +#if defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) +#include // Initialize with glbinding::Binding::initialize() +#else #include // Initialize with glbinding::initialize() +#endif #include using namespace gl; #else @@ -79,7 +83,10 @@ int main(int, char**) bool err = glewInit() != GLEW_OK; #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) bool err = gladLoadGL() == 0; -#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING) +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) + bool err = false; + glbinding::Binding::initialize(); +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) bool err = false; glbinding::initialize([](const char* name) { return (glbinding::ProcAddress)glfwGetProcAddress(name); }); #else diff --git a/examples/example_sdl_opengl3/Makefile b/examples/example_sdl_opengl3/Makefile index 77140b5e..ada77197 100644 --- a/examples/example_sdl_opengl3/Makefile +++ b/examples/example_sdl_opengl3/Makefile @@ -42,8 +42,11 @@ CXXFLAGS += -I../libs/gl3w -DIMGUI_IMPL_OPENGL_LOADER_GL3W # CXXFLAGS += -I../libs/glad/include -DIMGUI_IMPL_OPENGL_LOADER_GLAD ## Using OpenGL loader: glbinding -## (This assumes a system-wide installation) -# CXXFLAGS += -lglbinding -DIMGUI_IMPL_OPENGL_LOADER_GLBINDING +## This assumes a system-wide installation +## of either version 3.0.0 (or newer) +# CXXFLAGS += -lglbinding -DIMGUI_IMPL_OPENGL_LOADER_GLBINDING3 +## or the older version 2.x +# CXXFLAGS += -lglbinding -DIMGUI_IMPL_OPENGL_LOADER_GLBINDING2 ##--------------------------------------------------------------------- ## BUILD FLAGS PER PLATFORM diff --git a/examples/example_sdl_opengl3/main.cpp b/examples/example_sdl_opengl3/main.cpp index 20801a19..4eb4110f 100644 --- a/examples/example_sdl_opengl3/main.cpp +++ b/examples/example_sdl_opengl3/main.cpp @@ -19,8 +19,12 @@ #include // Initialize with glewInit() #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) #include // Initialize with gladLoadGL() -#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING) +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) || defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) +#if defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) +#include // Initialize with glbinding::Binding::initialize() +#else #include // Initialize with glbinding::initialize() +#endif #include using namespace gl; #else @@ -73,7 +77,10 @@ int main(int, char**) bool err = glewInit() != GLEW_OK; #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) bool err = gladLoadGL() == 0; -#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING) +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) + bool err = false; + glbinding::Binding::initialize(); +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) bool err = false; glbinding::initialize([](const char* name) { return (glbinding::ProcAddress)SDL_GL_GetProcAddress(name); }); #else diff --git a/examples/imgui_impl_opengl3.cpp b/examples/imgui_impl_opengl3.cpp index 9289913e..1514567d 100644 --- a/examples/imgui_impl_opengl3.cpp +++ b/examples/imgui_impl_opengl3.cpp @@ -86,14 +86,16 @@ #undef IMGUI_IMPL_OPENGL_LOADER_GL3W #undef IMGUI_IMPL_OPENGL_LOADER_GLEW #undef IMGUI_IMPL_OPENGL_LOADER_GLAD -#undef IMGUI_IMPL_OPENGL_LOADER_GLBINDING +#undef IMGUI_IMPL_OPENGL_LOADER_GLBINDING2 +#undef IMGUI_IMPL_OPENGL_LOADER_GLBINDING3 #undef IMGUI_IMPL_OPENGL_LOADER_CUSTOM #elif defined(__EMSCRIPTEN__) #define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100" #undef IMGUI_IMPL_OPENGL_LOADER_GL3W #undef IMGUI_IMPL_OPENGL_LOADER_GLEW #undef IMGUI_IMPL_OPENGL_LOADER_GLAD -#undef IMGUI_IMPL_OPENGL_LOADER_GLBINDING +#undef IMGUI_IMPL_OPENGL_LOADER_GLBINDING2 +#undef IMGUI_IMPL_OPENGL_LOADER_GLBINDING3 #undef IMGUI_IMPL_OPENGL_LOADER_CUSTOM #endif #endif @@ -118,9 +120,13 @@ #include // Needs to be initialized with glewInit() in user's code #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) #include // Needs to be initialized with gladLoadGL() in user's code -#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING) +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) || defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) #include // Initialize with glbinding::initialize() +#if defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) +#include +#else #include +#endif using namespace gl; #else #include IMGUI_IMPL_OPENGL_LOADER_CUSTOM @@ -193,8 +199,10 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version) gl_loader = "GLEW"; #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) gl_loader = "GLAD"; -#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING) - gl_loader = "glbinding"; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) + gl_loader = "glbinding2"; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) + gl_loader = "glbinding3"; #else // IMGUI_IMPL_OPENGL_LOADER_CUSTOM gl_loader = "Custom"; #endif diff --git a/examples/imgui_impl_opengl3.h b/examples/imgui_impl_opengl3.h index 98cefe7d..a9a1e199 100644 --- a/examples/imgui_impl_opengl3.h +++ b/examples/imgui_impl_opengl3.h @@ -46,7 +46,8 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects(); #if !defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) \ && !defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) \ && !defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) \ - && !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING) \ + && !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) \ + && !defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) \ && !defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) #if defined(__has_include) #if __has_include() @@ -55,8 +56,10 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects(); #define IMGUI_IMPL_OPENGL_LOADER_GLAD #elif __has_include() #define IMGUI_IMPL_OPENGL_LOADER_GL3W - #elif __has_include() - #define IMGUI_IMPL_OPENGL_LOADER_GLBINDING + #elif __has_include() + #define IMGUI_IMPL_OPENGL_LOADER_GLBINDING3 + #elif __has_include() + #define IMGUI_IMPL_OPENGL_LOADER_GLBINDING2 #else #error "Cannot detect OpenGL loader!" #endif From f2b01c3436e13be22beba4f7831bc26f40cca1c5 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Mar 2020 18:42:18 +0100 Subject: [PATCH 04/13] Changelog, tweak OpenGL3 backends. (#3061), update Gallery thread links. --- docs/CHANGELOG.txt | 3 +- docs/FAQ.md | 4 +-- docs/README.md | 4 +-- examples/README.txt | 4 +-- examples/example_glfw_opengl3/main.cpp | 21 +++++++------ examples/example_sdl_opengl3/main.cpp | 20 ++++++------ examples/imgui_impl_opengl3.cpp | 42 ++++++++++++++------------ imgui.cpp | 4 +-- imgui.h | 2 +- 9 files changed, 55 insertions(+), 49 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 226e79ed..ee49d325 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -68,6 +68,7 @@ Other Changes: - CI: Added more tests on the continuous-integration server: extra warnings for Clang/GCC, building SDL+Metal example, building imgui_freetype.cpp, more compile-time imconfig.h settings: disabling obsolete functions, enabling 32-bit ImDrawIdx, enabling 32-bit ImWchar, disabling demo. [@rokups] +- Backends: OpenGL3: Added include support for older glbinding 2.x loader. (#3061) [@DonKult] - Backends: Win32: Added ImGui_ImplWin32_EnableDpiAwareness(), ImGui_ImplWin32_GetDpiScaleForHwnd(), ImGui_ImplWin32_GetDpiScaleForMonitor() helpers functions (backported from the docking branch). Those functions makes it easier for example apps to support hi-dpi features without setting up @@ -172,7 +173,7 @@ Other Changes: - Examples: OpenGL: 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) -- Examples: OpenGL: Added support for glbindings OpenGL loader. (#2870) [@rokups] +- Examples: OpenGL: Added support for glbinding OpenGL loader. (#2870) [@rokups] - Examples: Emscripten: Demonstrating embedding fonts in Makefile and code. (#2953) [@Oipo] - Examples: Metal: Wrapped main loop in @autoreleasepool block to ensure allocations get freed even if underlying system event loop gets paused due to app nap. (#2910, #2917) [@bear24rw] diff --git a/docs/FAQ.md b/docs/FAQ.md index b173a73d..d629ff4b 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -552,7 +552,7 @@ You may take a look at: - [Quotes](https://github.com/ocornut/imgui/wiki/Quotes) - [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) -- [Gallery](https://github.com/ocornut/imgui/issues/2847) +- [Gallery](https://github.com/ocornut/imgui/issues/3075) ##### [Return to Index](#index) @@ -598,7 +598,7 @@ There is an auto-generated [c-api for Dear ImGui (cimgui)](https://github.com/ci - Individuals: you can support continued maintenance and development via PayPal donations. See [README](https://github.com/ocornut/imgui/blob/master/docs/README.md). - If you are experienced with Dear ImGui and C++, look at the [GitHub Issues](https://github.com/ocornut/imgui/issues), look at the [Wiki](https://github.com/ocornut/imgui/wiki), read [docs/TODO.txt](https://github.com/ocornut/imgui/blob/master/docs/TODO.txt) and see how you want to help and can help! - Disclose your usage of Dear ImGui via a dev blog post, a tweet, a screenshot, a mention somewhere etc. -You may post screenshot or links in the [gallery threads](https://github.com/ocornut/imgui/issues/2847). Visuals are ideal as they inspire other programmers. Disclosing your use of dear imgui help the library grow credibility, and help other teams and programmers with taking decisions. +You may post screenshot or links in the [gallery threads](https://github.com/ocornut/imgui/issues/3075). Visuals are ideal as they inspire other programmers. Disclosing your use of dear imgui help the library grow credibility, and help other teams and programmers with taking decisions. - If you have issues or if you need to hack into the library, even if you don't expect any support it is useful that you share your issues or sometimes incomplete PR. ##### [Return to Index](#index) diff --git a/docs/README.md b/docs/README.md index 8c1636ef..3e001024 100644 --- a/docs/README.md +++ b/docs/README.md @@ -131,7 +131,7 @@ Some of the goals for 2020 are: ### Gallery -For more user-submitted screenshots of projects using Dear ImGui, check out the [Gallery Threads](https://github.com/ocornut/imgui/issues/2847)! +For more user-submitted screenshots of projects using Dear ImGui, check out the [Gallery Threads](https://github.com/ocornut/imgui/issues/3075)! Custom engine [![screenshot game](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v149/gallery_TheDragonsTrap-01-thumb.jpg)](https://cloud.githubusercontent.com/assets/8225057/20628927/33e14cac-b329-11e6-80f6-9524e93b048a.png) @@ -164,7 +164,7 @@ You may also peak at the [Multi-Viewport](https://github.com/ocornut/imgui/issue **Who uses Dear ImGui?** -See the [Quotes](https://github.com/ocornut/imgui/wiki/Quotes), [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors), [Software using dear imgui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) Wiki pages for an idea of who is using Dear ImGui. Please add your game/software if you can! Also see the [Gallery Threads](https://github.com/ocornut/imgui/issues/2847)! +See the [Quotes](https://github.com/ocornut/imgui/wiki/Quotes), [Sponsors](https://github.com/ocornut/imgui/wiki/Sponsors), [Software using dear imgui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) Wiki pages for an idea of who is using Dear ImGui. Please add your game/software if you can! Also see the [Gallery Threads](https://github.com/ocornut/imgui/issues/3075)! How to help ----------- diff --git a/examples/README.txt b/examples/README.txt index 75d97729..355d616c 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -199,7 +199,7 @@ example_glfw_opengl2/ GLFW + OpenGL2 example (legacy, fixed pipeline). = main.cpp + imgui_impl_glfw.cpp + imgui_impl_opengl2.cpp **DO NOT USE OPENGL2 CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** - **Prefer using OPENGL3 code (with gl3w/glew/glad/glbindings, you can replace the OpenGL function loader)** + **Prefer using OPENGL3 code (with gl3w/glew/glad/glbinding, you can replace the OpenGL function loader)** This code is mostly provided as a reference to learn about Dear ImGui integration, because it is shorter. If your code is using GL3+ context or any semi modern OpenGL calls, using this renderer is likely to make things more complicated, will require your code to reset many OpenGL attributes to their initial @@ -248,7 +248,7 @@ example_sdl_opengl2/ SDL2 (Win32, Mac, Linux etc.) + OpenGL example (legacy, fixed pipeline). = main.cpp + imgui_impl_sdl.cpp + imgui_impl_opengl2.cpp **DO NOT USE OPENGL2 CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** - **Prefer using OPENGL3 code (with gl3w/glew/glad/glbindings, you can replace the OpenGL function loader)** + **Prefer using OPENGL3 code (with gl3w/glew/glad/glbinding, you can replace the OpenGL function loader)** This code is mostly provided as a reference to learn about Dear ImGui integration, because it is shorter. If your code is using GL3+ context or any semi modern OpenGL calls, using this renderer is likely to make things more complicated, will require your code to reset many OpenGL attributes to their initial diff --git a/examples/example_glfw_opengl3/main.cpp b/examples/example_glfw_opengl3/main.cpp index 61797d3e..8df734bd 100644 --- a/examples/example_glfw_opengl3/main.cpp +++ b/examples/example_glfw_opengl3/main.cpp @@ -12,18 +12,19 @@ // Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad). // You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own. #if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) -#include // Initialize with gl3wInit() +#include // Initialize with gl3wInit() #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) -#include // Initialize with glewInit() +#include // Initialize with glewInit() #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) -#include // Initialize with gladLoadGL() -#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) || defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) -#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors. -#if defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) -#include // Initialize with glbinding::Binding::initialize() -#else -#include // Initialize with glbinding::initialize() -#endif +#include // Initialize with gladLoadGL() +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) +#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors. +#include // Initialize with glbinding::Binding::initialize() +#include +using namespace gl; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) +#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors. +#include // Initialize with glbinding::initialize() #include using namespace gl; #else diff --git a/examples/example_sdl_opengl3/main.cpp b/examples/example_sdl_opengl3/main.cpp index 4eb4110f..ae794ef4 100644 --- a/examples/example_sdl_opengl3/main.cpp +++ b/examples/example_sdl_opengl3/main.cpp @@ -14,17 +14,19 @@ // Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad). // You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own. #if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) -#include // Initialize with gl3wInit() +#include // Initialize with gl3wInit() #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) -#include // Initialize with glewInit() +#include // Initialize with glewInit() #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) -#include // Initialize with gladLoadGL() -#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) || defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) -#if defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) -#include // Initialize with glbinding::Binding::initialize() -#else -#include // Initialize with glbinding::initialize() -#endif +#include // Initialize with gladLoadGL() +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) +#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors. +#include // Initialize with glbinding::Binding::initialize() +#include +using namespace gl; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) +#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors. +#include // Initialize with glbinding::initialize() #include using namespace gl; #else diff --git a/examples/imgui_impl_opengl3.cpp b/examples/imgui_impl_opengl3.cpp index 1514567d..2f908f46 100644 --- a/examples/imgui_impl_opengl3.cpp +++ b/examples/imgui_impl_opengl3.cpp @@ -13,7 +13,8 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) -// 2020-01-07: OpenGL: Added support for glbindings OpenGL loader. +// 2020-03-24: OpenGL: Added support for glbinding 2.x OpenGL loader. +// 2020-01-07: OpenGL: Added support for glbinding 3.x OpenGL loader. // 2019-10-25: OpenGL: Using a combination of GL define and runtime GL version to decide whether to use glDrawElementsBaseVertex(). Fix building with pre-3.2 GL loaders. // 2019-09-22: OpenGL: Detect default GL loader using __has_include compiler facility. // 2019-09-16: OpenGL: Tweak initialization code to allow application calling ImGui_ImplOpenGL3_CreateFontsTexture() before the first NewFrame() call. @@ -83,14 +84,12 @@ #if !defined(IMGUI_IMPL_OPENGL_ES2) && !defined(IMGUI_IMPL_OPENGL_ES3) #if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__)) #define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es" -#undef IMGUI_IMPL_OPENGL_LOADER_GL3W -#undef IMGUI_IMPL_OPENGL_LOADER_GLEW -#undef IMGUI_IMPL_OPENGL_LOADER_GLAD -#undef IMGUI_IMPL_OPENGL_LOADER_GLBINDING2 -#undef IMGUI_IMPL_OPENGL_LOADER_GLBINDING3 -#undef IMGUI_IMPL_OPENGL_LOADER_CUSTOM #elif defined(__EMSCRIPTEN__) #define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100" +#endif +#endif + +#if defined(IMGUI_IMPL_OPENGL_ES2) || defined(IMGUI_IMPL_OPENGL_ES3) #undef IMGUI_IMPL_OPENGL_LOADER_GL3W #undef IMGUI_IMPL_OPENGL_LOADER_GLEW #undef IMGUI_IMPL_OPENGL_LOADER_GLAD @@ -98,7 +97,6 @@ #undef IMGUI_IMPL_OPENGL_LOADER_GLBINDING3 #undef IMGUI_IMPL_OPENGL_LOADER_CUSTOM #endif -#endif // GL includes #if defined(IMGUI_IMPL_OPENGL_ES2) @@ -115,18 +113,20 @@ // Helper libraries are often used for this purpose! Here we are supporting a few common ones (gl3w, glew, glad). // You may use another loader/header of your choice (glext, glLoadGen, etc.), or chose to manually implement your own. #if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) -#include // Needs to be initialized with gl3wInit() in user's code +#include // Needs to be initialized with gl3wInit() in user's code #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) -#include // Needs to be initialized with glewInit() in user's code +#include // Needs to be initialized with glewInit() in user's code. #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) -#include // Needs to be initialized with gladLoadGL() in user's code -#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) || defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) -#include // Initialize with glbinding::initialize() -#if defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) -#include -#else -#include -#endif +#include // Needs to be initialized with gladLoadGL() in user's code. +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) +#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors. +#include // Needs to be initialized with glbinding::Binding::initialize() in user's code. +#include +using namespace gl; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) +#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition errors. +#include // Needs to be initialized with glbinding::initialize() in user's code. +#include using namespace gl; #else #include IMGUI_IMPL_OPENGL_LOADER_CUSTOM @@ -203,8 +203,10 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version) gl_loader = "glbinding2"; #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) gl_loader = "glbinding3"; -#else // IMGUI_IMPL_OPENGL_LOADER_CUSTOM - gl_loader = "Custom"; +#elif defined(IMGUI_IMPL_OPENGL_LOADER_CUSTOM) + gl_loader = "custom"; +#else + gl_loader = "none"; #endif // Make a dummy GL call (we don't actually need the result) diff --git a/imgui.cpp b/imgui.cpp index 477b0f67..9c3a9c8c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10,7 +10,7 @@ // - FAQ http://dearimgui.org/faq // - Homepage & latest https://github.com/ocornut/imgui // - Releases & changelog https://github.com/ocornut/imgui/releases -// - Gallery https://github.com/ocornut/imgui/issues/2847 (please post your screenshots/video there!) +// - Gallery https://github.com/ocornut/imgui/issues/3075 (please post your screenshots/video there!) // - Glossary https://github.com/ocornut/imgui/wiki/Glossary // - Wiki https://github.com/ocornut/imgui/wiki // - Issues & support https://github.com/ocornut/imgui/issues @@ -783,7 +783,7 @@ CODE - If you are experienced with Dear ImGui and C++, look at the github issues, look at the Wiki, read docs/TODO.txt and see how you want to help and can help! - Disclose your usage of Dear ImGui via a dev blog post, a tweet, a screenshot, a mention somewhere etc. - You may post screenshot or links in the gallery threads (github.com/ocornut/imgui/issues/2847). Visuals are ideal as they inspire other programmers. + You may post screenshot or links in the gallery threads (github.com/ocornut/imgui/issues/3075). Visuals are ideal as they inspire other programmers. But even without visuals, disclosing your use of dear imgui help the library grow credibility, and help other teams and programmers with taking decisions. - If you have issues or if you need to hack into the library, even if you don't expect any support it is useful that you share your issues (on github or privately). diff --git a/imgui.h b/imgui.h index 44a011d6..b61c4647 100644 --- a/imgui.h +++ b/imgui.h @@ -11,7 +11,7 @@ // - FAQ http://dearimgui.org/faq // - Homepage & latest https://github.com/ocornut/imgui // - Releases & changelog https://github.com/ocornut/imgui/releases -// - Gallery https://github.com/ocornut/imgui/issues/2847 (please post your screenshots/video there!) +// - Gallery https://github.com/ocornut/imgui/issues/3075 (please post your screenshots/video there!) // - Glossary https://github.com/ocornut/imgui/wiki/Glossary // - Wiki https://github.com/ocornut/imgui/wiki // - Issues & support https://github.com/ocornut/imgui/issues From 670367e51d92128fc80b90ae1469f9f0feb4db78 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 24 Mar 2020 20:11:05 +0100 Subject: [PATCH 05/13] Added IMGUI_USE_WCHAR32 instead of "#define ImWchar ImWchar32" to faclitate C-binding. (#2538, #2541, #2815) --- .github/workflows/build.yml | 2 +- docs/CHANGELOG.txt | 2 +- imconfig.h | 6 +++--- imgui.cpp | 1 + imgui.h | 21 +++++++++++++-------- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d68c8da9..b089bfb4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -202,7 +202,7 @@ jobs: - name: Build example_null (with ImWchar32) run: | - echo '#define ImWchar ImWchar32' > example_single_file.cpp + echo '#define IMGUI_USE_WCHAR32' > example_single_file.cpp echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index ee49d325..54aa11bc 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -49,7 +49,7 @@ Other Changes: cursor position. This would often get fixed after the fix item submission, but using the ImGuiListClipper as the first thing after Begin() could largely break size calculations. (#3073) - Added optional support for Unicode plane 1-16 (#2538, #2541, #2815) [@cloudwu, @samhocevar] - - Compile-time enable with '#define ImWchar ImWchar32' in imconfig.h. + - Compile-time enable with '#define IMGUI_USE_WCHAR32' in imconfig.h. - Generally more consistent support for unsupported codepoints (0xFFFD), in particular when using the default, non-fitting characters will be turned into 0xFFFD instead of being ignored. - Surrogate pairs are supported when submitting UTF-16 data via io.AddInputCharacterUTF16(), diff --git a/imconfig.h b/imconfig.h index 4f01b778..c6817de7 100644 --- a/imconfig.h +++ b/imconfig.h @@ -48,6 +48,9 @@ //---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another) //#define IMGUI_USE_BGRA_PACKED_COLOR +//---- Use 32-bit for ImWchar (default is 16-bit) to support full unicode code points. +//#define IMGUI_USE_WCHAR32 + //---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version // By default the embedded implementations are declared static and not available outside of imgui cpp files. //#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h" @@ -77,9 +80,6 @@ // Read about ImGuiBackendFlags_RendererHasVtxOffset for details. //#define ImDrawIdx unsigned int -//---- Use 32-bit for ImWchar (default is 16-bit) to support full unicode code points. -//#define ImWchar ImWchar32 - //---- Override ImDrawCallback signature (will need to modify renderer back-ends accordingly) //struct ImDrawList; //struct ImDrawCmd; diff --git a/imgui.cpp b/imgui.cpp index 9c3a9c8c..c0fa2fb9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5,6 +5,7 @@ // - Read FAQ at http://dearimgui.org/faq // - Newcomers, read 'Programmer guide' below for notes on how to setup Dear ImGui in your codebase. // - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code. All applications in examples/ are doing that. +// Read imgui.cpp for details, links and comments. // Resources: // - FAQ http://dearimgui.org/faq diff --git a/imgui.h b/imgui.h index b61c4647..712ddfa1 100644 --- a/imgui.h +++ b/imgui.h @@ -5,7 +5,7 @@ // - Read FAQ at http://dearimgui.org/faq // - Newcomers, read 'Programmer guide' in imgui.cpp for notes on how to setup Dear ImGui in your codebase. // - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code. All applications in examples/ are doing that. -// Read imgui.cpp for more details, documentation and comments. +// Read imgui.cpp for details, links and comments. // Resources: // - FAQ http://dearimgui.org/faq @@ -65,7 +65,7 @@ Index of this file: // Define attributes of all API symbols declarations (e.g. for DLL under Windows) // IMGUI_API is used for core imgui functions, IMGUI_IMPL_API is used for the default bindings files (imgui_impl_xxx.h) -// Using dear imgui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility. +// Using dear imgui via a shared library is not recommended, because we don't guarantee backward nor forward ABI compatibility (also function call overhead, as dear imgui is a call-heavy API) #ifndef IMGUI_API #define IMGUI_API #endif @@ -170,18 +170,23 @@ typedef int ImGuiTreeNodeFlags; // -> enum ImGuiTreeNodeFlags_ // Flags: f typedef int ImGuiWindowFlags; // -> enum ImGuiWindowFlags_ // Flags: for Begin(), BeginChild() // Other types -#ifndef ImTextureID // ImTextureID [configurable type: override in imconfig.h] +#ifndef ImTextureID // ImTextureID [configurable type: override in imconfig.h with '#define ImTextureID xxx'] typedef void* ImTextureID; // User data for rendering back-end to identify a texture. This is whatever to you want it to be! read the FAQ about ImTextureID for details. #endif -#ifndef ImWchar // ImWchar [configurable type: override in imconfig.h] -#define ImWchar ImWchar16 // Storage for a single decoded character/code point, default to 16-bit. Set to ImWchar32 to support larger Unicode planes. Note that we generally support UTF-8 encoded string, this is storage for a decoded character. -#endif typedef unsigned int ImGuiID; // A unique ID used by widgets, typically hashed from a stack of string. -typedef unsigned short ImWchar16; // A single decoded U16 character/code point for keyboard input/display. We encode them as multi bytes UTF-8 when used in strings. -typedef unsigned int ImWchar32; // A single decoded U32 character/code point for keyboard input/display. To enable, use '#define ImWchar ImWchar32' in imconfig.h. typedef int (*ImGuiInputTextCallback)(ImGuiInputTextCallbackData *data); typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data); +// Decoded character types +// (we generally use UTF-8 encoded string in the API. This is storage specifically for a decoded character used for keyboard input and display) +typedef unsigned short ImWchar16; // A single decoded U16 character/code point. We encode them as multi bytes UTF-8 when used in strings. +typedef unsigned int ImWchar32; // A single decoded U32 character/code point. We encode them as multi bytes UTF-8 when used in strings. +#ifdef IMGUI_USE_WCHAR32 // ImWchar [configurable type: override in imconfig.h with '#define IMGUI_USE_WCHAR32' to support Unicode planes 1-16] +typedef ImWchar32 ImWchar; +#else +typedef ImWchar16 ImWchar; +#endif + // Basic scalar data types typedef signed char ImS8; // 8-bit signed integer typedef unsigned char ImU8; // 8-bit unsigned integer From 1d4b5def51e905836f02d5d003c43bb878d2e541 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 25 Mar 2020 21:38:24 +0100 Subject: [PATCH 06/13] Alter definition of IM_UNICODE_ defines to faclitate C-binding. (#2538, #2541, #2815) --- imgui.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/imgui.h b/imgui.h index 712ddfa1..32059b3b 100644 --- a/imgui.h +++ b/imgui.h @@ -92,8 +92,6 @@ Index of this file: #else #define IM_OFFSETOF(_TYPE,_MEMBER) ((size_t)&(((_TYPE*)0)->_MEMBER)) // Offset of _MEMBER within _TYPE. Old style macro. #endif -#define IM_UNICODE_CODEPOINT_MAX (sizeof(ImWchar) == 2 ? 0xFFFF : 0x10FFFF) // Last Unicode code point supported by this build. -#define IM_UNICODE_CODEPOINT_INVALID 0xFFFD // Standard invalid Unicode code point. // Warnings #if defined(__clang__) @@ -1652,6 +1650,14 @@ typedef ImGuiInputTextCallbackData ImGuiTextEditCallbackData; // Helpers //----------------------------------------------------------------------------- +// Helper: Unicode defines +#define IM_UNICODE_CODEPOINT_INVALID 0xFFFD // Invalid Unicode code point (standard value). +#ifdef IMGUI_USE_WCHAR32 +#define IM_UNICODE_CODEPOINT_MAX 0x10FFFF // Maximum Unicode code point supported by this build. +#else +#define IM_UNICODE_CODEPOINT_MAX 0xFFFF // Maximum Unicode code point supported by this build. +#endif + // Helper: Execute a block of code at maximum once a frame. Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame. // Usage: static ImGuiOnceUponAFrame oaf; if (oaf) ImGui::Text("This will be called only once per frame"); struct ImGuiOnceUponAFrame From ac2247f5519a353ecd8bb9ab8fc5c11bbfae5b0c Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 26 Mar 2020 14:12:13 +0100 Subject: [PATCH 07/13] Selectable: Removed seemingly ineffective text clipping offset in SpanAllColumns handling path + tweaks. made max_x absolutely to reduce confusion. amend cf481e1 --- imgui_widgets.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 938e94cb..061fecaf 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -5580,14 +5580,14 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl // Fill horizontal space. ImVec2 window_padding = window->WindowPadding; - float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? GetWindowContentRegionMax().x : GetContentRegionMax().x; - float w_draw = ImMax(label_size.x, window->Pos.x + max_x - window_padding.x - pos.x); - ImVec2 size_draw((size_arg.x != 0 && !(flags & ImGuiSelectableFlags_DrawFillAvailWidth)) ? size_arg.x : w_draw, size_arg.y != 0.0f ? size_arg.y : size.y); + float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? GetWindowContentRegionMax().x + window->Pos.x : GetContentRegionMaxAbs().x; + float w_draw = ImMax(label_size.x, max_x - window_padding.x - pos.x); + ImVec2 size_draw((size_arg.x != 0 && !(flags & ImGuiSelectableFlags_DrawFillAvailWidth)) ? size_arg.x : w_draw, size.y); ImRect bb(pos, pos + size_draw); if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_DrawFillAvailWidth)) bb.Max.x += window_padding.x; - // Selectables are tightly packed together so we extend the box to cover spacing between selectable. + // Selectables are meant to be tightly packed together with no click-gap, so we extend the box to cover spacing between selectable. const float spacing_x = style.ItemSpacing.x; const float spacing_y = style.ItemSpacing.y; const float spacing_L = IM_FLOOR(spacing_x * 0.50f); @@ -5662,10 +5662,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl } if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.CurrentColumns) - { PopColumnsBackground(); - bb.Max.x -= (GetContentRegionMax().x - max_x); - } if (flags & ImGuiSelectableFlags_Disabled) PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]); RenderTextClipped(bb_inner.Min, bb_inner.Max, label, NULL, &label_size, style.SelectableTextAlign, &bb); From 7c11997bcc31e545ba3d9751212f7da0d322c4a6 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 26 Mar 2020 14:53:07 +0100 Subject: [PATCH 08/13] Selectable: Fixed honoring style.SelectableTextAlign with unspecified size. (#2347, #2601) --- docs/CHANGELOG.txt | 1 + docs/TODO.txt | 1 + imgui_widgets.cpp | 27 +++++++++++++++------------ 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 54aa11bc..05739c5c 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -45,6 +45,7 @@ Other Changes: when the menu is not open. (#3030) - InputText: Fixed password fields displaying ASCII spaces as blanks instead of using the '*' glyph. (#2149, #515) +- Selectable: Fixed honoring style.SelectableTextAlign with unspecified size. (#2347, #2601) - Scrolling: Fixed scrolling centering API leading to non-integer scrolling values and initial cursor position. This would often get fixed after the fix item submission, but using the ImGuiListClipper as the first thing after Begin() could largely break size calculations. (#3073) diff --git a/docs/TODO.txt b/docs/TODO.txt index 8d50dbe2..e0a8bc12 100644 --- a/docs/TODO.txt +++ b/docs/TODO.txt @@ -223,6 +223,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - menus: menu-bar: main menu-bar could affect clamping of windows position (~ akin to modifying DisplayMin) - menus: hovering from menu to menu on a menu-bar has 1 frame without any menu, which is a little annoying. ideally either 0 either longer. - menus: could merge draw call in most cases (how about storing an optional aabb in ImDrawCmd to move the burden of merging in a single spot). + - menus: would be nice if the Selectable() supported horizontal alignment (must be given the equivalent of WorkRect.Max.x matching the position of the shortcut column) - tree node: add treenode/treepush int variants? not there because (void*) cast from int warns on some platforms/settings? - tree node: try to apply scrolling at time of TreePop() if node was just opened and end of node is past scrolling limits? diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 061fecaf..a8f72380 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -5583,31 +5583,33 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? GetWindowContentRegionMax().x + window->Pos.x : GetContentRegionMaxAbs().x; float w_draw = ImMax(label_size.x, max_x - window_padding.x - pos.x); ImVec2 size_draw((size_arg.x != 0 && !(flags & ImGuiSelectableFlags_DrawFillAvailWidth)) ? size_arg.x : w_draw, size.y); - ImRect bb(pos, pos + size_draw); + + ImRect bb_align(pos, pos + size_draw); if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_DrawFillAvailWidth)) - bb.Max.x += window_padding.x; + bb_align.Max.x += window_padding.x; // Selectables are meant to be tightly packed together with no click-gap, so we extend the box to cover spacing between selectable. + ImRect bb_enlarged = bb_align; const float spacing_x = style.ItemSpacing.x; const float spacing_y = style.ItemSpacing.y; const float spacing_L = IM_FLOOR(spacing_x * 0.50f); const float spacing_U = IM_FLOOR(spacing_y * 0.50f); - bb.Min.x -= spacing_L; - bb.Min.y -= spacing_U; - bb.Max.x += (spacing_x - spacing_L); - bb.Max.y += (spacing_y - spacing_U); + bb_enlarged.Min.x -= spacing_L; + bb_enlarged.Min.y -= spacing_U; + bb_enlarged.Max.x += (spacing_x - spacing_L); + bb_enlarged.Max.y += (spacing_y - spacing_U); bool item_add; if (flags & ImGuiSelectableFlags_Disabled) { ImGuiItemFlags backup_item_flags = window->DC.ItemFlags; window->DC.ItemFlags |= ImGuiItemFlags_Disabled | ImGuiItemFlags_NoNavDefaultFocus; - item_add = ItemAdd(bb, id); + item_add = ItemAdd(bb_enlarged, id); window->DC.ItemFlags = backup_item_flags; } else { - item_add = ItemAdd(bb, id); + item_add = ItemAdd(bb_enlarged, id); } if (!item_add) { @@ -5630,7 +5632,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl const bool was_selected = selected; bool hovered, held; - bool pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags); + bool pressed = ButtonBehavior(bb_enlarged, id, &hovered, &held, button_flags); // Update NavId when clicking or when Hovering (this doesn't happen on most widgets), so navigation can be resumed with gamepad/keyboard if (pressed || (hovered && (flags & ImGuiSelectableFlags_SetNavIdOnHover))) @@ -5657,21 +5659,22 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl if (hovered || selected) { const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); - RenderFrame(bb.Min, bb.Max, col, false, 0.0f); - RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding); + RenderFrame(bb_enlarged.Min, bb_enlarged.Max, col, false, 0.0f); + RenderNavHighlight(bb_enlarged, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding); } if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.CurrentColumns) PopColumnsBackground(); if (flags & ImGuiSelectableFlags_Disabled) PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]); - RenderTextClipped(bb_inner.Min, bb_inner.Max, label, NULL, &label_size, style.SelectableTextAlign, &bb); + RenderTextClipped(bb_align.Min, bb_align.Max, label, NULL, &label_size, style.SelectableTextAlign, &bb_enlarged); if (flags & ImGuiSelectableFlags_Disabled) PopStyleColor(); // Automatically close popups if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !(window->DC.ItemFlags & ImGuiItemFlags_SelectableDontClosePopup)) CloseCurrentPopup(); + //if (g.IO.KeyCtrl) { window->DrawList->AddRect(bb_align.Min, bb_align.Max, IM_COL32(0, 255, 0, 255)); } IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags); return pressed; } From b4d1287011b8eb2abb48a02b4a2cb36c43d99bc7 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 26 Mar 2020 16:58:24 +0100 Subject: [PATCH 09/13] Selectable: Clarifying the code around use of ImGuiSelectableFlags_DrawFillAvailWidth (with intent of trying to remove it). Amend old 6251d379, 2bcafc86 --- imgui.cpp | 4 +++- imgui_internal.h | 2 +- imgui_widgets.cpp | 33 +++++++++++++++++---------------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c0fa2fb9..da5c5c3f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6818,6 +6818,8 @@ static void ImGui::ErrorCheckBeginEndCompareStacksSize(ImGuiWindow* window, bool //----------------------------------------------------------------------------- // Advance cursor given item size for layout. +// Register minimum needed size so it can extend the bounding box used for auto-fit calculation. +// See comments in ItemAdd() about how/why the size provided to ItemSize() vs ItemAdd() may often different. void ImGui::ItemSize(const ImVec2& size, float text_baseline_y) { ImGuiContext& g = *GImGui; @@ -6858,7 +6860,7 @@ void ImGui::ItemSize(const ImRect& bb, float text_baseline_y) // Declare item bounding box for clipping and interaction. // Note that the size can be different than the one provided to ItemSize(). Typically, widgets that spread over available surface -// declare their minimum size requirement to ItemSize() and then use a larger region for drawing/interaction, which is passed to ItemAdd(). +// declare their minimum size requirement to ItemSize() and provide a larger region to ItemAdd() which is used drawing/interaction. bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg) { ImGuiContext& g = *GImGui; diff --git a/imgui_internal.h b/imgui_internal.h index bb13be00..c4a32745 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -494,7 +494,7 @@ enum ImGuiSelectableFlagsPrivate_ ImGuiSelectableFlags_NoHoldingActiveID = 1 << 20, ImGuiSelectableFlags_SelectOnClick = 1 << 21, // Override button behavior to react on Click (default is Click+Release) ImGuiSelectableFlags_SelectOnRelease = 1 << 22, // Override button behavior to react on Release (default is Click+Release) - ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 23, // FIXME: We may be able to remove this (added in 6251d379 for menus) + ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 23, // Draw over all avail width even if we declared less for layout. FIXME: We may be able to remove this (added in 6251d379, 2bcafc86 for menus) ImGuiSelectableFlags_DrawHoveredWhenHeld= 1 << 24, // Always show active when held, even is not hovered. This concept could probably be renamed/formalized somehow. ImGuiSelectableFlags_SetNavIdOnHover = 1 << 25 }; diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index a8f72380..5d246994 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -5578,15 +5578,11 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl ImRect bb_inner(pos, pos + size); ItemSize(size, 0.0f); - // Fill horizontal space. - ImVec2 window_padding = window->WindowPadding; - float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? GetWindowContentRegionMax().x + window->Pos.x : GetContentRegionMaxAbs().x; - float w_draw = ImMax(label_size.x, max_x - window_padding.x - pos.x); - ImVec2 size_draw((size_arg.x != 0 && !(flags & ImGuiSelectableFlags_DrawFillAvailWidth)) ? size_arg.x : w_draw, size.y); - - ImRect bb_align(pos, pos + size_draw); + // Fill horizontal space + const float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? GetWindowContentRegionMax().x + window->Pos.x : GetContentRegionMaxAbs().x; if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_DrawFillAvailWidth)) - bb_align.Max.x += window_padding.x; + size.x = ImMax(label_size.x, max_x - window->WindowPadding.x - pos.x) + window->WindowPadding.x; + ImRect bb_align(pos, pos + size); // Selectables are meant to be tightly packed together with no click-gap, so we extend the box to cover spacing between selectable. ImRect bb_enlarged = bb_align; @@ -6228,10 +6224,12 @@ bool ImGui::BeginMenu(const char* label, bool enabled) else { // Menu inside a menu + // (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f. + // Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system. popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y); - float w = window->DC.MenuColumns.DeclColumns(label_size.x, 0.0f, IM_FLOOR(g.FontSize * 1.20f)); // Feedback to next frame - float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); - pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f)); + float min_w = window->DC.MenuColumns.DeclColumns(label_size.x, 0.0f, IM_FLOOR(g.FontSize * 1.20f)); // Feedback to next frame + float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w); + pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(min_w, 0.0f)); ImU32 text_col = GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled); RenderArrow(window->DrawList, pos + ImVec2(window->DC.MenuColumns.Pos[2] + extra_w + g.FontSize * 0.30f, 0.0f), text_col, ImGuiDir_Right); } @@ -6376,11 +6374,14 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo } else { - ImVec2 shortcut_size = shortcut ? CalcTextSize(shortcut, NULL) : ImVec2(0.0f, 0.0f); - float w = window->DC.MenuColumns.DeclColumns(label_size.x, shortcut_size.x, IM_FLOOR(g.FontSize * 1.20f)); // Feedback for next frame - float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); - pressed = Selectable(label, false, flags | ImGuiSelectableFlags_DrawFillAvailWidth, ImVec2(w, 0.0f)); - if (shortcut_size.x > 0.0f) + // Menu item inside a vertical menu + // (In a typical menu window where all items are BeginMenu() or MenuItem() calls, extra_w will always be 0.0f. + // Only when they are other items sticking out we're going to add spacing, yet only register minimum width into the layout system. + float shortcut_w = shortcut ? CalcTextSize(shortcut, NULL).x : 0.0f; + float min_w = window->DC.MenuColumns.DeclColumns(label_size.x, shortcut_w, IM_FLOOR(g.FontSize * 1.20f)); // Feedback for next frame + float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w); + pressed = Selectable(label, false, flags | ImGuiSelectableFlags_DrawFillAvailWidth, ImVec2(min_w, 0.0f)); + if (shortcut_w > 0.0f) { PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); RenderText(pos + ImVec2(window->DC.MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false); From 5be5add1ade50ea3e36de8a44f659b26aaea93e8 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 26 Mar 2020 18:03:43 +0100 Subject: [PATCH 10/13] Selectable: Removed extraneous WindowPadding.x worth of width when auto-sized selectable label goes off available width (would not be noticeable) + Renamed ImGuiSelectableFlags_DrawFillAvailWidth to ImGuiSelectableFlags_SpanAvailWidth. --- imgui_internal.h | 2 +- imgui_widgets.cpp | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index c4a32745..eb5c82e7 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -494,7 +494,7 @@ enum ImGuiSelectableFlagsPrivate_ ImGuiSelectableFlags_NoHoldingActiveID = 1 << 20, ImGuiSelectableFlags_SelectOnClick = 1 << 21, // Override button behavior to react on Click (default is Click+Release) ImGuiSelectableFlags_SelectOnRelease = 1 << 22, // Override button behavior to react on Release (default is Click+Release) - ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 23, // Draw over all avail width even if we declared less for layout. FIXME: We may be able to remove this (added in 6251d379, 2bcafc86 for menus) + ImGuiSelectableFlags_SpanAvailWidth = 1 << 23, // Span all avail width even if we declared less for layout purpose. FIXME: We may be able to remove this (added in 6251d379, 2bcafc86 for menus) ImGuiSelectableFlags_DrawHoveredWhenHeld= 1 << 24, // Always show active when held, even is not hovered. This concept could probably be renamed/formalized somehow. ImGuiSelectableFlags_SetNavIdOnHover = 1 << 25 }; diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 5d246994..7d0c9cbe 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -5570,21 +5570,21 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.CurrentColumns) // FIXME-OPT: Avoid if vertically clipped. PushColumnsBackground(); + // Submit label or explicit size to ItemSize(), whereas ItemAdd() will submit a larger/spanning rectangle. ImGuiID id = window->GetID(label); ImVec2 label_size = CalcTextSize(label, NULL, true); ImVec2 size(size_arg.x != 0.0f ? size_arg.x : label_size.x, size_arg.y != 0.0f ? size_arg.y : label_size.y); ImVec2 pos = window->DC.CursorPos; pos.y += window->DC.CurrLineTextBaseOffset; - ImRect bb_inner(pos, pos + size); ItemSize(size, 0.0f); // Fill horizontal space const float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? GetWindowContentRegionMax().x + window->Pos.x : GetContentRegionMaxAbs().x; - if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_DrawFillAvailWidth)) - size.x = ImMax(label_size.x, max_x - window->WindowPadding.x - pos.x) + window->WindowPadding.x; + if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_SpanAvailWidth)) + size.x = ImMax(label_size.x, max_x - pos.x); ImRect bb_align(pos, pos + size); - // Selectables are meant to be tightly packed together with no click-gap, so we extend the box to cover spacing between selectable. + // Selectables are meant to be tightly packed together with no click-gap, so we extend their box to cover spacing between selectable. ImRect bb_enlarged = bb_align; const float spacing_x = style.ItemSpacing.x; const float spacing_y = style.ItemSpacing.y; @@ -5594,6 +5594,8 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl bb_enlarged.Min.y -= spacing_U; bb_enlarged.Max.x += (spacing_x - spacing_L); bb_enlarged.Max.y += (spacing_y - spacing_U); + //if (g.IO.KeyCtrl) { GetForegroundDrawList()->AddRect(bb_align.Min, bb_align.Max, IM_COL32(255, 0, 0, 255)); } + //if (g.IO.KeyCtrl) { GetForegroundDrawList()->AddRect(bb_enlarged.Min, bb_enlarged.Max, IM_COL32(0, 255, 0, 255)); } bool item_add; if (flags & ImGuiSelectableFlags_Disabled) @@ -5670,7 +5672,6 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !(window->DC.ItemFlags & ImGuiItemFlags_SelectableDontClosePopup)) CloseCurrentPopup(); - //if (g.IO.KeyCtrl) { window->DrawList->AddRect(bb_align.Min, bb_align.Max, IM_COL32(0, 255, 0, 255)); } IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags); return pressed; } @@ -6229,7 +6230,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y); float min_w = window->DC.MenuColumns.DeclColumns(label_size.x, 0.0f, IM_FLOOR(g.FontSize * 1.20f)); // Feedback to next frame float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w); - pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(min_w, 0.0f)); + pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_NoHoldingActiveID | ImGuiSelectableFlags_SelectOnClick | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_SpanAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(min_w, 0.0f)); ImU32 text_col = GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled); RenderArrow(window->DrawList, pos + ImVec2(window->DC.MenuColumns.Pos[2] + extra_w + g.FontSize * 0.30f, 0.0f), text_col, ImGuiDir_Right); } @@ -6380,7 +6381,7 @@ bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, boo float shortcut_w = shortcut ? CalcTextSize(shortcut, NULL).x : 0.0f; float min_w = window->DC.MenuColumns.DeclColumns(label_size.x, shortcut_w, IM_FLOOR(g.FontSize * 1.20f)); // Feedback for next frame float extra_w = ImMax(0.0f, GetContentRegionAvail().x - min_w); - pressed = Selectable(label, false, flags | ImGuiSelectableFlags_DrawFillAvailWidth, ImVec2(min_w, 0.0f)); + pressed = Selectable(label, false, flags | ImGuiSelectableFlags_SpanAvailWidth, ImVec2(min_w, 0.0f)); if (shortcut_w > 0.0f) { PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); From ec2a24a5f13fe8724acda7fc77c3328db6bf076a Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 26 Mar 2020 20:15:44 +0100 Subject: [PATCH 11/13] Selectable: Allow using ImGuiSelectableFlags_SpanAllColumns in other columns than first. Comments. (#125) --- docs/CHANGELOG.txt | 1 + docs/TODO.txt | 5 +++-- imgui.cpp | 2 +- imgui.h | 10 +++++++--- imgui_demo.cpp | 6 +++--- imgui_widgets.cpp | 16 +++++++++++----- 6 files changed, 26 insertions(+), 14 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 05739c5c..07c882ba 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -46,6 +46,7 @@ Other Changes: - InputText: Fixed password fields displaying ASCII spaces as blanks instead of using the '*' glyph. (#2149, #515) - Selectable: Fixed honoring style.SelectableTextAlign with unspecified size. (#2347, #2601) +- Selectable: Allow using ImGuiSelectableFlags_SpanAllColumns in other columns than first. (#125) - Scrolling: Fixed scrolling centering API leading to non-integer scrolling values and initial cursor position. This would often get fixed after the fix item submission, but using the ImGuiListClipper as the first thing after Begin() could largely break size calculations. (#3073) diff --git a/docs/TODO.txt b/docs/TODO.txt index e0a8bc12..474b5ce5 100644 --- a/docs/TODO.txt +++ b/docs/TODO.txt @@ -71,11 +71,12 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - widgets: alignment options in style (e.g. center Selectable, Right-Align within Button, etc.) #1260 - widgets: activate by identifier (trigger button, focus given id) - widgets: a way to represent "mixed" values, so e.g. all values replaced with *, including check-boxes, colors, etc. with support for multi-components widgets (e.g. SliderFloat3, make only "Y" mixed) (#2644) - - widgets: selectable: generic BeginSelectable()/EndSelectable() mechanism. - - widgets: selectable: a way to visualize partial/mixed selection (e.g. parent tree node has children with mixed selection) - widgets: checkbox: checkbox with custom glyph inside frame. - widgets: coloredit: keep reporting as active when picker is on? - widgets: group/scalarn functions: expose more per-component information. e.g. store NextItemData.ComponentIdx set by scalarn function, groups can expose them back somehow. + - selectable: using (size.x == 0.0f) and (SelectableTextAlign.x > 0.0f) followed by SameLine() is currently not supported. + - selectable: generic BeginSelectable()/EndSelectable() mechanism. + - selectable: a way to visualize partial/mixed selection (e.g. parent tree node has children with mixed selection) - input text: clean up the mess caused by converting UTF-8 <> wchar. the code is rather inefficient right now and super fragile. - input text: reorganize event handling, allow CharFilter to modify buffers, allow multiple events? (#541) diff --git a/imgui.cpp b/imgui.cpp index da5c5c3f..5dc479f7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1023,7 +1023,7 @@ ImGuiStyle::ImGuiStyle() TabBorderSize = 0.0f; // Thickness of border around tabs. ColorButtonPosition = ImGuiDir_Right; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right. ButtonTextAlign = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text. - SelectableTextAlign = ImVec2(0.0f,0.0f);// Alignment of selectable text when button is larger than text. + SelectableTextAlign = ImVec2(0.0f,0.0f);// Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line. DisplayWindowPadding = ImVec2(19,19); // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows. DisplaySafeAreaPadding = ImVec2(3,3); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. MouseCursorScale = 1.0f; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later. diff --git a/imgui.h b/imgui.h index 32059b3b..098ff637 100644 --- a/imgui.h +++ b/imgui.h @@ -1141,8 +1141,12 @@ enum ImGuiCol_ }; // Enumeration for PushStyleVar() / PopStyleVar() to temporarily modify the ImGuiStyle structure. -// NB: the enum only refers to fields of ImGuiStyle which makes sense to be pushed/popped inside UI code. During initialization, feel free to just poke into ImGuiStyle directly. -// NB: if changing this enum, you need to update the associated internal table GStyleVarInfo[] accordingly. This is where we link enum values to members offset/type. +// - The enum only refers to fields of ImGuiStyle which makes sense to be pushed/popped inside UI code. +// During initialization or between frames, feel free to just poke into ImGuiStyle directly. +// - Tip: Use your programming IDE navigation facilities on the names in the _second column_ below to find the actual members and their description. +// In Visual Studio IDE: CTRL+comma ("Edit.NavigateTo") can follow symbols in comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot. +// With Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols in comments. +// - When changing this enum, you need to update the associated internal table GStyleVarInfo[] accordingly. This is where we link enum values to members offset/type. enum ImGuiStyleVar_ { // Enum name --------------------- // Member in ImGuiStyle structure (see ImGuiStyle for descriptions) @@ -1387,7 +1391,7 @@ struct ImGuiStyle float TabBorderSize; // Thickness of border around tabs. ImGuiDir ColorButtonPosition; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right. ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f, 0.5f) (centered). - ImVec2 SelectableTextAlign; // Alignment of selectable text when selectable is larger than text. Defaults to (0.0f, 0.0f) (top-left aligned). + ImVec2 SelectableTextAlign; // Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line. ImVec2 DisplayWindowPadding; // Window position are clamped to be visible within the display area by at least this amount. Only applies to regular windows. ImVec2 DisplaySafeAreaPadding; // If you cannot see the edges of your screen (e.g. on a TV) increase the safe area padding. Apply to popups/tooltips as well regular windows. NB: Prefer configuring your TV sets correctly! float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later. diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 2664cb14..28a5940e 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -643,9 +643,9 @@ static void ShowDemoWindowWidgets() static bool align_label_with_current_x_position = false; ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnArrow", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_OpenOnArrow); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick); - ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be layed out after the node."); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", (unsigned int*)&base_flags, ImGuiTreeNodeFlags_SpanFullWidth); - ImGui::Checkbox("Align label with current X position)", &align_label_with_current_x_position); + ImGui::Checkbox("Align label with current X position", &align_label_with_current_x_position); ImGui::Text("Hello!"); if (align_label_with_current_x_position) ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing()); @@ -980,7 +980,7 @@ static void ShowDemoWindowWidgets() } if (ImGui::TreeNode("Alignment")) { - HelpMarker("Alignment applies when a selectable is larger than its text content.\nBy default, Selectables uses style.SelectableTextAlign but it can be overriden on a per-item basis using PushStyleVar()."); + HelpMarker("By default, Selectables uses style.SelectableTextAlign but it can be overriden on a per-item basis using PushStyleVar(). You'll probably want to always keep your default situation to left-align otherwise it becomes difficult to layout multiple items on a same line"); static bool selected[3*3] = { true, false, true, false, true, false, true, false, true }; for (int y = 0; y < 3; y++) { diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 7d0c9cbe..3a360b96 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -5558,6 +5558,8 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags // Tip: pass a non-visible label (e.g. "##dummy") then you can use the space to draw other text or image. // But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID or use ##unique_id. +// With this scheme, ImGuiSelectableFlags_SpanAllColumns and ImGuiSelectableFlags_AllowItemOverlap are also frequently used flags. +// FIXME: Selectable() with (size.x == 0.0f) and (SelectableTextAlign.x > 0.0f) followed by SameLine() is currently not supported. bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags flags, const ImVec2& size_arg) { ImGuiWindow* window = GetCurrentWindow(); @@ -5579,13 +5581,17 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl ItemSize(size, 0.0f); // Fill horizontal space - const float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? GetWindowContentRegionMax().x + window->Pos.x : GetContentRegionMaxAbs().x; + const float min_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? window->ContentRegionRect.Min.x : pos.x; + const float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? window->ContentRegionRect.Max.x : GetContentRegionMaxAbs().x; if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_SpanAvailWidth)) - size.x = ImMax(label_size.x, max_x - pos.x); - ImRect bb_align(pos, pos + size); + size.x = ImMax(label_size.x, max_x - min_x); + + // Text stays at the submission position, but bounding box may be extended on both sides + const ImVec2 text_min = pos; + const ImVec2 text_max(min_x + size.x, pos.y + size.y); // Selectables are meant to be tightly packed together with no click-gap, so we extend their box to cover spacing between selectable. - ImRect bb_enlarged = bb_align; + ImRect bb_enlarged(min_x, pos.y, text_max.x, text_max.y); const float spacing_x = style.ItemSpacing.x; const float spacing_y = style.ItemSpacing.y; const float spacing_L = IM_FLOOR(spacing_x * 0.50f); @@ -5665,7 +5671,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl PopColumnsBackground(); if (flags & ImGuiSelectableFlags_Disabled) PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]); - RenderTextClipped(bb_align.Min, bb_align.Max, label, NULL, &label_size, style.SelectableTextAlign, &bb_enlarged); + RenderTextClipped(text_min, text_max, label, NULL, &label_size, style.SelectableTextAlign, &bb_enlarged); if (flags & ImGuiSelectableFlags_Disabled) PopStyleColor(); // Automatically close popups From 68c5d030cdb7c5f928bd961ac7081cdac7009b17 Mon Sep 17 00:00:00 2001 From: Dylan <24949824+dylanmit@users.noreply.github.com> Date: Mon, 30 Mar 2020 00:34:57 +1100 Subject: [PATCH 12/13] Typo in readme (#3078) --- docs/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/README.md b/docs/README.md index 3e001024..30c5d1a9 100644 --- a/docs/README.md +++ b/docs/README.md @@ -80,7 +80,7 @@ ImGui::End(); Result:
![sample code output](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v160/code_sample_03_color.gif) -Dear ImGui allows you **create elaborate tools** as well as very short-lived ones. On the extreme side of short-livedness: using the Edit&Continue (hot code reload) feature of modern compilers you can add a few widgets to tweaks variables while your application is running, and remove the code a minute later! Dear ImGui is not just for tweaking values. You can use it to trace a running algorithm by just emitting text commands. You can use it along with your own reflection data to browse your dataset live. You can use it to expose the internals of a subsystem in your engine, to create a logger, an inspection tool, a profiler, a debugger, an entire game making editor/framework, etc. +Dear ImGui allows you to **create elaborate tools** as well as very short-lived ones. On the extreme side of short-livedness: using the Edit&Continue (hot code reload) feature of modern compilers you can add a few widgets to tweaks variables while your application is running, and remove the code a minute later! Dear ImGui is not just for tweaking values. You can use it to trace a running algorithm by just emitting text commands. You can use it along with your own reflection data to browse your dataset live. You can use it to expose the internals of a subsystem in your engine, to create a logger, an inspection tool, a profiler, a debugger, an entire game making editor/framework, etc. ### How it works From 05420ea2cfaab2fa5e4a66a2abf9b134d19f6fac Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 31 Mar 2020 19:29:46 +0200 Subject: [PATCH 13/13] TreeNode: Made clicking on arrow with _OpenOnArrow toggle the open state on the Mouse Down event rather than the Mouse Down+Up sequence (this is rather standard behavior). --- docs/CHANGELOG.txt | 2 ++ imgui_widgets.cpp | 39 ++++++++++++++++++++++++--------------- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 07c882ba..8d8ea0b8 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -47,6 +47,8 @@ Other Changes: glyph. (#2149, #515) - Selectable: Fixed honoring style.SelectableTextAlign with unspecified size. (#2347, #2601) - Selectable: Allow using ImGuiSelectableFlags_SpanAllColumns in other columns than first. (#125) +- TreeNode: Made clicking on arrow with _OpenOnArrow toggle the open state on the Mouse Down + event rather than the Mouse Down+Up sequence (this is rather standard behavior). - Scrolling: Fixed scrolling centering API leading to non-integer scrolling values and initial cursor position. This would often get fixed after the fix item submission, but using the ImGuiListClipper as the first thing after Begin() could largely break size calculations. (#3073) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 3a360b96..08b09f1d 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -5319,30 +5319,39 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l return is_open; } - // Flags that affects opening behavior: - // - 0 (default) .................... single-click anywhere to open - // - OpenOnDoubleClick .............. double-click anywhere to open - // - OpenOnArrow .................... single-click on arrow to open - // - OpenOnDoubleClick|OpenOnArrow .. single-click on arrow or double-click anywhere to open - ImGuiButtonFlags button_flags = 0; + ImGuiButtonFlags button_flags = ImGuiTreeNodeFlags_None; if (flags & ImGuiTreeNodeFlags_AllowItemOverlap) button_flags |= ImGuiButtonFlags_AllowItemOverlap; - if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) - button_flags |= ImGuiButtonFlags_PressedOnDoubleClick | ((flags & ImGuiTreeNodeFlags_OpenOnArrow) ? ImGuiButtonFlags_PressedOnClickRelease : 0); - else - button_flags |= ImGuiButtonFlags_PressedOnClickRelease; if (!is_leaf) button_flags |= ImGuiButtonFlags_PressedOnDragDropHold; // We allow clicking on the arrow section with keyboard modifiers held, in order to easily // allow browsing a tree while preserving selection with code implementing multi-selection patterns. // When clicking on the rest of the tree node we always disallow keyboard modifiers. - const float hit_padding_x = style.TouchExtraPadding.x; - const float arrow_hit_x1 = (text_pos.x - text_offset_x) - hit_padding_x; - const float arrow_hit_x2 = (text_pos.x - text_offset_x) + (g.FontSize + padding.x * 2.0f) + hit_padding_x; - if (window != g.HoveredWindow || !(g.IO.MousePos.x >= arrow_hit_x1 && g.IO.MousePos.x < arrow_hit_x2)) + const float arrow_hit_x1 = (text_pos.x - text_offset_x) - style.TouchExtraPadding.x; + const float arrow_hit_x2 = (text_pos.x - text_offset_x) + (g.FontSize + padding.x * 2.0f) + style.TouchExtraPadding.x; + const bool is_mouse_x_over_arrow = (g.IO.MousePos.x >= arrow_hit_x1 && g.IO.MousePos.x < arrow_hit_x2); + if (window != g.HoveredWindow || !is_mouse_x_over_arrow) button_flags |= ImGuiButtonFlags_NoKeyModifiers; + // Open behaviors can be altered with the _OpenOnArrow and _OnOnDoubleClick flags. + // Some alteration have subtle effects (e.g. toggle on MouseUp vs MouseDown events) due to requirements for multi-selection and drag and drop support. + // - Single-click on label = Toggle on MouseUp (default) + // - Single-click on arrow = Toggle on MouseUp (when _OpenOnArrow=0) + // - Single-click on arrow = Toggle on MouseDown (when _OpenOnArrow=1) + // - Double-click on label = Toggle on MouseDoubleClick (when _OpenOnDoubleClick=1) + // - Double-click on arrow = Toggle on MouseDoubleClick (when _OpenOnDoubleClick=1 and _OpenOnArrow=0) + // This makes _OpenOnArrow have a subtle effect on _OpenOnDoubleClick: arrow click reacts on Down rather than Up. + // It is rather standard that arrow click react on Down rather than Up and we'd be tempted to make it the default + // (by removing the _OpenOnArrow test below), however this would have a perhaps surprising effect on CollapsingHeader()? + // So right now we are making this optional. May evolve later. + if (is_mouse_x_over_arrow && (flags & ImGuiTreeNodeFlags_OpenOnArrow)) + button_flags |= ImGuiButtonFlags_PressedOnClick; + else if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) + button_flags |= ImGuiButtonFlags_PressedOnDoubleClick; + else + button_flags |= ImGuiButtonFlags_PressedOnClickRelease; + bool selected = (flags & ImGuiTreeNodeFlags_Selected) != 0; const bool was_selected = selected; @@ -5356,7 +5365,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l if ((flags & (ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick)) == 0 || (g.NavActivateId == id)) toggled = true; if (flags & ImGuiTreeNodeFlags_OpenOnArrow) - toggled |= (g.IO.MousePos.x >= arrow_hit_x1 && g.IO.MousePos.x < arrow_hit_x2) && (!g.NavDisableMouseHover); // Lightweight equivalent of IsMouseHoveringRect() since ButtonBehavior() already did the job + toggled |= is_mouse_x_over_arrow && !g.NavDisableMouseHover; // Lightweight equivalent of IsMouseHoveringRect() since ButtonBehavior() already did the job if ((flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) && g.IO.MouseDoubleClicked[0]) toggled = true; if (g.DragDropActive && is_open) // When using Drag and Drop "hold to open" we keep the node highlighted after opening, but never close it again.