build: Update ImGui

This commit is contained in:
WerWolv 2025-11-30 14:04:38 +01:00
parent ebee8ff0a6
commit f3a2fe5b0d
9 changed files with 1208 additions and 813 deletions

View File

@ -1,35 +1,36 @@
// dear imgui, v1.92.3
// dear imgui, v1.92.5
// (headers)
// Help:
// - See links below.
// - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp. All applications in examples/ are doing that.
// - Read top of imgui.cpp for more details, links and comments.
// - Add '#define IMGUI_DEFINE_MATH_OPERATORS' before including this file (or in imconfig.h) to access courtesy maths operators for ImVec2 and ImVec4.
// - Add '#define IMGUI_DEFINE_MATH_OPERATORS' before including imgui.h (or in imconfig.h) to access courtesy maths operators for ImVec2 and ImVec4.
// Resources:
// - FAQ ........................ https://dearimgui.com/faq (in repository as docs/FAQ.md)
// - Homepage ................... https://github.com/ocornut/imgui
// - Releases & changelog ....... https://github.com/ocornut/imgui/releases
// - Releases & Changelog ....... https://github.com/ocornut/imgui/releases
// - Gallery .................... https://github.com/ocornut/imgui/issues?q=label%3Agallery (please post your screenshots/video there!)
// - Wiki ....................... https://github.com/ocornut/imgui/wiki (lots of good stuff there)
// - Getting Started https://github.com/ocornut/imgui/wiki/Getting-Started (how to integrate in an existing app by adding ~25 lines of code)
// - Third-party Extensions https://github.com/ocornut/imgui/wiki/Useful-Extensions (ImPlot & many more)
// - Bindings/Backends https://github.com/ocornut/imgui/wiki/Bindings (language bindings, backends for various tech/engines)
// - Glossary https://github.com/ocornut/imgui/wiki/Glossary
// - Bindings/Backends https://github.com/ocornut/imgui/wiki/Bindings (language bindings + backends for various tech/engines)
// - Debug Tools https://github.com/ocornut/imgui/wiki/Debug-Tools
// - Glossary https://github.com/ocornut/imgui/wiki/Glossary
// - Software using Dear ImGui https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui
// - Issues & support ........... https://github.com/ocornut/imgui/issues
// - Test Engine & Automation ... https://github.com/ocornut/imgui_test_engine (test suite, test engine to automate your apps)
// - Web version of the Demo .... https://pthom.github.io/imgui_manual_online/manual/imgui_manual.html (w/ source code browser)
// For first-time users having issues compiling/linking/running/loading fonts:
// For FIRST-TIME users having issues compiling/linking/running:
// please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above.
// Everything else should be asked in 'Issues'! We are building a database of cross-linked knowledge there.
// EVERYTHING ELSE should be asked in 'Issues'! We are building a database of cross-linked knowledge there.
// Since 1.92, we encourage font loading questions to also be posted in 'Issues'.
// Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.92.3"
#define IMGUI_VERSION_NUM 19230
#define IMGUI_VERSION "1.92.5"
#define IMGUI_VERSION_NUM 19250
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
#define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch.
@ -91,12 +92,15 @@ Index of this file:
#endif
// Helper Macros
// (note: compiling with NDEBUG will usually strip out assert() to nothing, which is NOT recommended because we use asserts to notify of programmer mistakes.)
#ifndef IM_ASSERT
#include <assert.h>
#define IM_ASSERT(_EXPR) assert(_EXPR) // You can override the default assert handler by editing imconfig.h
#endif
#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR)))) // Size of a static C-style array. Don't use on pointers!
#define IM_UNUSED(_VAR) ((void)(_VAR)) // Used to silence "unused variable warnings". Often useful as asserts may be stripped out from final builds.
#define IM_STRINGIFY_HELPER(_EXPR) #_EXPR
#define IM_STRINGIFY(_EXPR) IM_STRINGIFY_HELPER(_EXPR) // Preprocessor idiom to stringify e.g. an integer or a macro.
// Check that version and structures layouts are matching between compiled imgui code and caller. Read comments above DebugCheckVersionAndDataLayout() for details.
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
@ -215,9 +219,9 @@ struct ImGuiWindowClass; // Window class (rare/advanced uses: provide
// Enumerations
// - We don't use strongly typed enums much because they add constraints (can't extend in private code, can't store typed in bit fields, extra casting on iteration)
// - 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: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments.
// - In Visual Studio: Ctrl+Comma ("Edit.GoToAll") can follow symbols inside comments, whereas Ctrl+F12 ("Edit.GoToImplementation") cannot.
// - In Visual Studio w/ Visual Assist installed: Alt+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
// - In VS Code, CLion, etc.: Ctrl+Click can follow symbols inside comments.
enum ImGuiDir : int; // -> enum ImGuiDir // Enum: A cardinal direction (Left, Right, Up, Down)
enum ImGuiKey : int; // -> enum ImGuiKey // Enum: A key identifier (ImGuiKey_XXX or ImGuiMod_XXX value)
enum ImGuiMouseSource : int; // -> enum ImGuiMouseSource // Enum; A mouse input source identifier (Mouse, TouchScreen, Pen)
@ -232,9 +236,9 @@ typedef int ImGuiTableBgTarget; // -> enum ImGuiTableBgTarget_ // Enum: A
// Flags (declared as int to allow using as flags without overhead, 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: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments.
// - In Visual Studio: Ctrl+Comma ("Edit.GoToAll") can follow symbols inside comments, whereas Ctrl+F12 ("Edit.GoToImplementation") cannot.
// - In Visual Studio w/ Visual Assist installed: Alt+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
// - In VS Code, CLion, etc.: Ctrl+Click can follow symbols inside comments.
typedef int ImDrawFlags; // -> enum ImDrawFlags_ // Flags: for ImDrawList functions
typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList instance
typedef int ImDrawTextFlags; // -> enum ImDrawTextFlags_ // Internal, do not use!
@ -335,7 +339,7 @@ IM_MSVC_RUNTIME_CHECKS_RESTORE
// - You may decide to store a higher-level structure containing texture, sampler, shader etc. with various
// constructors if you like. You will need to implement ==/!= operators.
// History:
// - In v1.91.4 (2024/10/08): the default type for ImTextureID was changed from 'void*' to 'ImU64'. This allowed backends requirig 64-bit worth of data to build on 32-bit architectures. Use intermediary intptr_t cast and read FAQ if you have casting warnings.
// - In v1.91.4 (2024/10/08): the default type for ImTextureID was changed from 'void*' to 'ImU64'. This allowed backends requiring 64-bit worth of data to build on 32-bit architectures. Use intermediary intptr_t cast and read FAQ if you have casting warnings.
// - In v1.92.0 (2025/06/11): added ImTextureRef which carry either a ImTextureID either a pointer to internal texture atlas. All user facing functions taking ImTextureID changed to ImTextureRef
#ifndef ImTextureID
typedef ImU64 ImTextureID; // Default: store up to 64-bits (any pointer or integer). A majority of backends are ok with that.
@ -667,13 +671,13 @@ namespace ImGui
IMGUI_API bool Combo(const char* label, int* current_item, const char* (*getter)(void* user_data, int idx), void* user_data, int items_count, int popup_max_height_in_items = -1);
// Widgets: Drag Sliders
// - CTRL+Click on any drag box to turn them into an input box. Manually input values aren't clamped by default and can go off-bounds. Use ImGuiSliderFlags_AlwaysClamp to always clamp.
// - Ctrl+Click on any drag box to turn them into an input box. Manually input values aren't clamped by default and can go off-bounds. Use ImGuiSliderFlags_AlwaysClamp to always clamp.
// - For all the Float2/Float3/Float4/Int2/Int3/Int4 versions of every function, note that a 'float v[X]' function argument is the same as 'float* v',
// the array syntax is just a way to document the number of elements that are expected to be accessible. You can pass address of your first element out of a contiguous set, e.g. &myvector.x
// - Adjust format string to decorate the value with a prefix, a suffix, or adapt the editing and display precision e.g. "%.3f" -> 1.234; "%5.2f secs" -> 01.23 secs; "Biscuit: %.0f" -> Biscuit: 1; etc.
// - Format string may also be set to NULL or use the default format ("%f" or "%d").
// - Speed are per-pixel of mouse movement (v_speed=0.2f: mouse needs to move by 5 pixels to increase value by 1). For keyboard/gamepad navigation, minimum speed is Max(v_speed, minimum_step_at_given_precision).
// - Use v_min < v_max to clamp edits to given limits. Note that CTRL+Click manual input can override those limits if ImGuiSliderFlags_AlwaysClamp is not used.
// - Use v_min < v_max to clamp edits to given limits. Note that Ctrl+Click manual input can override those limits if ImGuiSliderFlags_AlwaysClamp is not used.
// - Use v_max = FLT_MAX / INT_MAX etc to avoid clamping to a maximum, same with v_min = -FLT_MAX / INT_MIN to avoid clamping to a minimum.
// - We use the same sets of flags for DragXXX() and SliderXXX() functions as the features are the same and it makes it easier to swap them.
// - Legacy: Pre-1.78 there are DragXXX() function signatures that take a final `float power=1.0f' argument instead of the `ImGuiSliderFlags flags=0' argument.
@ -692,7 +696,7 @@ namespace ImGui
IMGUI_API bool DragScalarN(const char* label, ImGuiDataType data_type, void* p_data, int components, float v_speed = 1.0f, const void* p_min = NULL, const void* p_max = NULL, const char* format = NULL, ImGuiSliderFlags flags = 0);
// Widgets: Regular Sliders
// - CTRL+Click on any slider to turn them into an input box. Manually input values aren't clamped by default and can go off-bounds. Use ImGuiSliderFlags_AlwaysClamp to always clamp.
// - Ctrl+Click on any slider to turn them into an input box. Manually input values aren't clamped by default and can go off-bounds. Use ImGuiSliderFlags_AlwaysClamp to always clamp.
// - Adjust format string to decorate the value with a prefix, a suffix, or adapt the editing and display precision e.g. "%.3f" -> 1.234; "%5.2f secs" -> 01.23 secs; "Biscuit: %.0f" -> Biscuit: 1; etc.
// - Format string may also be set to NULL or use the default format ("%f" or "%d").
// - Legacy: Pre-1.78 there are SliderXXX() function signatures that take a final `float power=1.0f' argument instead of the `ImGuiSliderFlags flags=0' argument.
@ -713,7 +717,7 @@ namespace ImGui
IMGUI_API bool VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max, const char* format = NULL, ImGuiSliderFlags flags = 0);
// Widgets: Input with Keyboard
// - If you want to use InputText() with std::string or any custom dynamic string type, see misc/cpp/imgui_stdlib.h and comments in imgui_demo.cpp.
// - If you want to use InputText() with std::string or any custom dynamic string type, use the wrapper in misc/cpp/imgui_stdlib.h/.cpp!
// - Most of the ImGuiInputTextFlags flags are only useful for InputText() and not for InputFloatX, InputIntX, InputDouble etc.
IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
IMGUI_API bool InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
@ -743,7 +747,7 @@ namespace ImGui
// Widgets: Trees
// - TreeNode functions return true when the node is open, in which case you need to also call TreePop() when you are finished displaying the tree node contents.
IMGUI_API bool TreeNode(const char* label);
IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...) IM_FMTARGS(2); // helper variation to easily decorelate the id from the displayed string. Read the FAQ about why and how to use ID. to align arbitrary text at the same level as a TreeNode() you can use Bullet().
IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...) IM_FMTARGS(2); // helper variation to easily decorrelate the id from the displayed string. Read the FAQ about why and how to use ID. to align arbitrary text at the same level as a TreeNode() you can use Bullet().
IMGUI_API bool TreeNode(const void* ptr_id, const char* fmt, ...) IM_FMTARGS(2); // "
IMGUI_API bool TreeNodeV(const char* str_id, const char* fmt, va_list args) IM_FMTLIST(2);
IMGUI_API bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args) IM_FMTLIST(2);
@ -768,7 +772,7 @@ namespace ImGui
IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0, 0)); // "bool* p_selected" point to the selection state (read-write), as a convenient helper.
// Multi-selection system for Selectable(), Checkbox(), TreeNode() functions [BETA]
// - This enables standard multi-selection/range-selection idioms (CTRL+Mouse/Keyboard, SHIFT+Mouse/Keyboard, etc.) in a way that also allow a clipper to be used.
// - This enables standard multi-selection/range-selection idioms (Ctrl+Mouse/Keyboard, Shift+Mouse/Keyboard, etc.) in a way that also allow a clipper to be used.
// - ImGuiSelectionUserData is often used to store your item index within the current view (but may store something else).
// - Read comments near ImGuiMultiSelectIO for instructions/details and see 'Demo->Widgets->Selection State & Multi-Select' for demo.
// - TreeNode() is technically supported but... using this correctly is more complicated. You need some sort of linear/random access to your tree,
@ -956,18 +960,24 @@ namespace ImGui
IMGUI_API void SetTabItemClosed(const char* tab_or_docked_window_label); // notify TabBar or Docking system of a closed tab/window ahead (useful to reduce visual flicker on reorderable tab bars). For tab-bar: call after BeginTabBar() and before Tab submissions. Otherwise call with a window name.
// Docking
// [BETA API] Enable with io.ConfigFlags |= ImGuiConfigFlags_DockingEnable.
// Note: You can use most Docking facilities without calling any API. You DO NOT need to call DockSpace() to use Docking!
// - Drag from window title bar or their tab to dock/undock. Hold SHIFT to disable docking.
// - Drag from window menu button (upper-left button) to undock an entire node (all windows).
// - When io.ConfigDockingWithShift == true, you instead need to hold SHIFT to enable docking.
// About dockspaces:
// - Use DockSpaceOverViewport() to create a window covering the screen or a specific viewport + a dockspace inside it.
// This is often used with ImGuiDockNodeFlags_PassthruCentralNode to make it transparent.
// - Use DockSpace() to create an explicit dock node _within_ an existing window. See Docking demo for details.
// - Important: Dockspaces need to be submitted _before_ any window they can host. Submit it early in your frame!
// - Important: Dockspaces need to be kept alive if hidden, otherwise windows docked into it will be undocked.
// e.g. if you have multiple tabs with a dockspace inside each tab: submit the non-visible dockspaces with ImGuiDockNodeFlags_KeepAliveOnly.
// - Read https://github.com/ocornut/imgui/wiki/Docking for details.
// - Enable with io.ConfigFlags |= ImGuiConfigFlags_DockingEnable.
// - You can use most Docking facilities without calling any API. You don't necessarily need to call a DockSpaceXXX function to use Docking!
// - Drag from window title bar or their tab to dock/undock. Hold SHIFT to disable docking.
// - Drag from window menu button (upper-left button) to undock an entire node (all windows).
// - When io.ConfigDockingWithShift == true, you instead need to hold SHIFT to enable docking.
// - Dockspaces:
// - If you want to dock windows into the edge of your screen, most application can simply call DockSpaceOverViewport():
// e.g. ImGui::NewFrame(); then ImGui::DockSpaceOverViewport(); // Create a dockspace in main viewport.
// or: ImGui::NewFrame(); then ImGui::DockSpaceOverViewport(0, nullptr, ImGuiDockNodeFlags_PassthruCentralNode); // Create a dockspace in main viewport, where central node is transparent.
// - A dockspace is an explicit dock node within an existing window.
// - DockSpaceOverViewport() basically creates an invisible window covering a viewport, and submit a DockSpace() into it.
// - IMPORTANT: Dockspaces need to be submitted _before_ any window they can host. Submit them early in your frame!
// - IMPORTANT: Dockspaces need to be kept alive if hidden, otherwise windows docked into it will be undocked.
// If you have e.g. multiple tabs with a dockspace inside each tab: submit the non-visible dockspaces with ImGuiDockNodeFlags_KeepAliveOnly.
// - Programmatic docking:
// - There is no public API yet other than the very limited SetNextWindowDockID() function. Sorry for that!
// - Read https://github.com/ocornut/imgui/wiki/Docking for examples of how to use current internal API.
IMGUI_API ImGuiID DockSpace(ImGuiID dockspace_id, const ImVec2& size = ImVec2(0, 0), ImGuiDockNodeFlags flags = 0, const ImGuiWindowClass* window_class = NULL);
IMGUI_API ImGuiID DockSpaceOverViewport(ImGuiID dockspace_id = 0, const ImGuiViewport* viewport = NULL, ImGuiDockNodeFlags flags = 0, const ImGuiWindowClass* window_class = NULL);
IMGUI_API void SetNextWindowDockID(ImGuiID dock_id, ImGuiCond cond = 0); // set next window dock id
@ -1001,7 +1011,7 @@ namespace ImGui
// Disabling [BETA API]
// - Disable all user interactions and dim items visuals (applying style.DisabledAlpha over current colors)
// - Those can be nested but it cannot be used to enable an already disabled section (a single BeginDisabled(true) in the stack is enough to keep everything disabled)
// - Tooltips windows by exception are opted out of disabling.
// - Tooltips windows are automatically opted out of disabling. Note that IsItemHovered() by default returns false on disabled items, unless using ImGuiHoveredFlags_AllowWhenDisabled.
// - BeginDisabled(false)/EndDisabled() essentially does nothing but is provided to facilitate use of boolean expressions (as a micro-optimization: if you have tens of thousands of BeginDisabled(false)/EndDisabled() pairs, you might want to reformulate your code to avoid making those calls)
IMGUI_API void BeginDisabled(bool disabled = true);
IMGUI_API void EndDisabled();
@ -1171,7 +1181,7 @@ namespace ImGui
IMGUI_API void UpdatePlatformWindows(); // call in main loop. will call CreateWindow/ResizeWindow/etc. platform functions for each secondary viewport, and DestroyWindow for each inactive viewport.
IMGUI_API void RenderPlatformWindowsDefault(void* platform_render_arg = NULL, void* renderer_render_arg = NULL); // call in main loop. will call RenderWindow/SwapBuffers platform functions for each secondary viewport which doesn't have the ImGuiViewportFlags_Minimized flag set. May be reimplemented by user for custom rendering needs.
IMGUI_API void DestroyPlatformWindows(); // call DestroyWindow platform functions for all viewports. call from backend Shutdown() if you need to close platform windows before imgui shutdown. otherwise will be called by DestroyContext().
IMGUI_API ImGuiViewport* FindViewportByID(ImGuiID id); // this is a helper for backends.
IMGUI_API ImGuiViewport* FindViewportByID(ImGuiID viewport_id); // this is a helper for backends.
IMGUI_API ImGuiViewport* FindViewportByPlatformHandle(void* platform_handle); // this is a helper for backends. the type platform_handle is decided by the backend (e.g. HWND, MyWindow*, GLFWwindow* etc.)
} // namespace ImGui
@ -1202,7 +1212,7 @@ enum ImGuiWindowFlags_
ImGuiWindowFlags_AlwaysVerticalScrollbar= 1 << 14, // Always show vertical scrollbar (even if ContentSize.y < Size.y)
ImGuiWindowFlags_AlwaysHorizontalScrollbar=1<< 15, // Always show horizontal scrollbar (even if ContentSize.x < Size.x)
ImGuiWindowFlags_NoNavInputs = 1 << 16, // No keyboard/gamepad navigation within the window
ImGuiWindowFlags_NoNavFocus = 1 << 17, // No focusing toward this window with keyboard/gamepad navigation (e.g. skipped by CTRL+TAB)
ImGuiWindowFlags_NoNavFocus = 1 << 17, // No focusing toward this window with keyboard/gamepad navigation (e.g. skipped by Ctrl+Tab)
ImGuiWindowFlags_UnsavedDocument = 1 << 18, // Display a dot next to the title. When used in a tab/docking context, tab is selected when clicking the X + closure is not assumed (will wait for user to stop submitting the tab). Otherwise closure is assumed when pressing the X, so if you keep submitting the tab may reappear at end of tab bar.
ImGuiWindowFlags_NoDocking = 1 << 19, // Disable docking of this window
ImGuiWindowFlags_NoNav = ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus,
@ -1219,8 +1229,8 @@ enum ImGuiWindowFlags_
// Obsolete names
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
ImGuiWindowFlags_NavFlattened = 1 << 29, // Obsoleted in 1.90.9: Use ImGuiChildFlags_NavFlattened in BeginChild() call.
ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 30, // Obsoleted in 1.90.0: Use ImGuiChildFlags_AlwaysUseWindowPadding in BeginChild() call.
//ImGuiWindowFlags_NavFlattened = 1 << 29, // Obsoleted in 1.90.9: moved to ImGuiChildFlags. BeginChild(name, size, 0, ImGuiWindowFlags_NavFlattened) --> BeginChild(name, size, ImGuiChildFlags_NavFlattened, 0)
//ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 30, // Obsoleted in 1.90.0: moved to ImGuiChildFlags. BeginChild(name, size, 0, ImGuiWindowFlags_AlwaysUseWindowPadding) --> BeginChild(name, size, ImGuiChildFlags_AlwaysUseWindowPadding, 0)
#endif
};
@ -1248,7 +1258,7 @@ enum ImGuiChildFlags_
// Obsolete names
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
ImGuiChildFlags_Border = ImGuiChildFlags_Borders, // Renamed in 1.91.1 (August 2024) for consistency.
//ImGuiChildFlags_Border = ImGuiChildFlags_Borders, // Renamed in 1.91.1 (August 2024) for consistency.
#endif
};
@ -1311,7 +1321,7 @@ enum ImGuiInputTextFlags_
// - It is much slower than regular text fields.
// Ballpark estimate of cost on my 2019 desktop PC: for a 100 KB text buffer: +~0.3 ms (Optimized) / +~1.0 ms (Debug build).
// The CPU cost is very roughly proportional to text length, so a 10 KB buffer should cost about ten times less.
ImGuiInputTextFlags_WordWrap = 1 << 24, // InputTextMultine(): word-wrap lines that are too long.
ImGuiInputTextFlags_WordWrap = 1 << 24, // InputTextMultiline(): word-wrap lines that are too long.
// Obsolete names
//ImGuiInputTextFlags_AlwaysInsertMode = ImGuiInputTextFlags_AlwaysOverwrite // [renamed in 1.82] name was not matching behavior
@ -1338,7 +1348,7 @@ enum ImGuiTreeNodeFlags_
ImGuiTreeNodeFlags_SpanAllColumns = 1 << 14, // Frame will span all columns of its container table (label will still fit in current column)
ImGuiTreeNodeFlags_LabelSpanAllColumns = 1 << 15, // Label will span all columns of its container table
//ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 16, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible
ImGuiTreeNodeFlags_NavLeftJumpsToParent = 1 << 17, // Nav: left arrow moves back to parent. This is processed in TreePop() when there's an unfullfilled Left nav request remaining.
ImGuiTreeNodeFlags_NavLeftJumpsToParent = 1 << 17, // Nav: left arrow moves back to parent. This is processed in TreePop() when there's an unfulfilled Left nav request remaining.
ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_NoAutoOpenOnLog,
// [EXPERIMENTAL] Draw lines connecting TreeNode hierarchy. Discuss in GitHub issue #2920.
@ -1350,7 +1360,7 @@ enum ImGuiTreeNodeFlags_
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
ImGuiTreeNodeFlags_NavLeftJumpsBackHere = ImGuiTreeNodeFlags_NavLeftJumpsToParent, // Renamed in 1.92.0
ImGuiTreeNodeFlags_SpanTextWidth = ImGuiTreeNodeFlags_SpanLabelWidth, // Renamed in 1.90.7
ImGuiTreeNodeFlags_AllowItemOverlap = ImGuiTreeNodeFlags_AllowOverlap, // Renamed in 1.89.7
//ImGuiTreeNodeFlags_AllowItemOverlap = ImGuiTreeNodeFlags_AllowOverlap, // Renamed in 1.89.7
#endif
};
@ -1393,7 +1403,7 @@ enum ImGuiSelectableFlags_
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
ImGuiSelectableFlags_DontClosePopups = ImGuiSelectableFlags_NoAutoClosePopups, // Renamed in 1.91.0
ImGuiSelectableFlags_AllowItemOverlap = ImGuiSelectableFlags_AllowOverlap, // Renamed in 1.89.7
//ImGuiSelectableFlags_AllowItemOverlap = ImGuiSelectableFlags_AllowOverlap, // Renamed in 1.89.7
#endif
};
@ -1488,7 +1498,7 @@ enum ImGuiHoveredFlags_
// Tooltips mode
// - typically used in IsItemHovered() + SetTooltip() sequence.
// - this is a shortcut to pull flags from 'style.HoverFlagsForTooltipMouse' or 'style.HoverFlagsForTooltipNav' where you can reconfigure desired behavior.
// e.g. 'TooltipHoveredFlagsForMouse' defaults to 'ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort'.
// e.g. 'HoverFlagsForTooltipMouse' defaults to 'ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_AllowWhenDisabled'.
// - for frequently actioned or hovered items providing a tooltip, you want may to use ImGuiHoveredFlags_ForTooltip (stationary + delay) so the tooltip doesn't show too often.
// - for items which main purpose is to be hovered, or items with low affordance, or in less consistent apps, prefer no delay or shorter delay.
ImGuiHoveredFlags_ForTooltip = 1 << 12, // Shortcut for standard flags when using IsItemHovered() + SetTooltip() sequence.
@ -1541,6 +1551,7 @@ enum ImGuiDragDropFlags_
ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 10, // AcceptDragDropPayload() will returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered.
ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 11, // Do not draw the default highlight rectangle when hovering over target.
ImGuiDragDropFlags_AcceptNoPreviewTooltip = 1 << 12, // Request hiding the BeginDragDropSource tooltip from the BeginDragDropTarget site.
ImGuiDragDropFlags_AcceptDrawAsHovered = 1 << 13, // Accepting item will render as if hovered. Useful for e.g. a Button() used as a drop target.
ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect, // For peeking ahead and inspecting the payload before delivery.
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
@ -1714,9 +1725,9 @@ enum ImGuiKey : int
ImGuiMod_Mask_ = 0xF000, // 4-bits
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
ImGuiKey_COUNT = ImGuiKey_NamedKey_END, // Obsoleted in 1.91.5 because it was extremely misleading (since named keys don't start at 0 anymore)
ImGuiKey_COUNT = ImGuiKey_NamedKey_END, // Obsoleted in 1.91.5 because it was misleading (since named keys don't start at 0 anymore)
ImGuiMod_Shortcut = ImGuiMod_Ctrl, // Removed in 1.90.7, you can now simply use ImGuiMod_Ctrl
ImGuiKey_ModCtrl = ImGuiMod_Ctrl, ImGuiKey_ModShift = ImGuiMod_Shift, ImGuiKey_ModAlt = ImGuiMod_Alt, ImGuiKey_ModSuper = ImGuiMod_Super, // Renamed in 1.89
//ImGuiKey_ModCtrl = ImGuiMod_Ctrl, ImGuiKey_ModShift = ImGuiMod_Shift, ImGuiKey_ModAlt = ImGuiMod_Alt, ImGuiKey_ModSuper = ImGuiMod_Super, // Renamed in 1.89
//ImGuiKey_KeyPadEnter = ImGuiKey_KeypadEnter, // Renamed in 1.87
#endif
};
@ -1738,7 +1749,7 @@ enum ImGuiInputFlags_
ImGuiInputFlags_RouteAlways = 1 << 13, // Do not register route, poll keys directly.
// - Routing options
ImGuiInputFlags_RouteOverFocused = 1 << 14, // Option: global route: higher priority than focused route (unless active item in focused route).
ImGuiInputFlags_RouteOverActive = 1 << 15, // Option: global route: higher priority than active item. Unlikely you need to use that: will interfere with every active items, e.g. CTRL+A registered by InputText will be overridden by this. May not be fully honored as user/internal code is likely to always assume they can access keys when active.
ImGuiInputFlags_RouteOverActive = 1 << 15, // Option: global route: higher priority than active item. Unlikely you need to use that: will interfere with every active items, e.g. Ctrl+A registered by InputText will be overridden by this. May not be fully honored as user/internal code is likely to always assume they can access keys when active.
ImGuiInputFlags_RouteUnlessBgFocused = 1 << 16, // Option: global route: will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications.
ImGuiInputFlags_RouteFromRootWindow = 1 << 17, // Option: route evaluated from the point of view of root window rather than current window.
@ -1785,10 +1796,11 @@ enum ImGuiBackendFlags_
ImGuiBackendFlags_RendererHasVtxOffset = 1 << 3, // Backend Renderer supports ImDrawCmd::VtxOffset. This enables output of large meshes (64K+ vertices) while still using 16-bit indices.
ImGuiBackendFlags_RendererHasTextures = 1 << 4, // Backend Renderer supports ImTextureData requests to create/update/destroy textures. This enables incremental texture updates and texture reloads. See https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md for instructions on how to upgrade your custom backend.
// [BETA] Viewports
ImGuiBackendFlags_PlatformHasViewports = 1 << 10, // Backend Platform supports multiple viewports.
ImGuiBackendFlags_HasMouseHoveredViewport=1 << 11, // Backend Platform supports calling io.AddMouseViewportEvent() with the viewport under the mouse. IF POSSIBLE, ignore viewports with the ImGuiViewportFlags_NoInputs flag (Win32 backend, GLFW 3.30+ backend can do this, SDL backend cannot). If this cannot be done, Dear ImGui needs to use a flawed heuristic to find the viewport under.
ImGuiBackendFlags_RendererHasViewports = 1 << 12, // Backend Renderer supports multiple viewports.
// [BETA] Multi-Viewports
ImGuiBackendFlags_RendererHasViewports = 1 << 10, // Backend Renderer supports multiple viewports.
ImGuiBackendFlags_PlatformHasViewports = 1 << 11, // Backend Platform supports multiple viewports.
ImGuiBackendFlags_HasMouseHoveredViewport=1 << 12, // Backend Platform supports calling io.AddMouseViewportEvent() with the viewport under the mouse. IF POSSIBLE, ignore viewports with the ImGuiViewportFlags_NoInputs flag (Win32 backend, GLFW 3.30+ backend can do this, SDL backend cannot). If this cannot be done, Dear ImGui needs to use a flawed heuristic to find the viewport under.
ImGuiBackendFlags_HasParentViewport = 1 << 13, // Backend Platform supports honoring viewport->ParentViewport/ParentViewportId value, by applying the corresponding parent/child relation at the Platform level.
};
// Enumeration for PushStyleColor() / PopStyleColor()
@ -1849,10 +1861,12 @@ enum ImGuiCol_
ImGuiCol_TextLink, // Hyperlink color
ImGuiCol_TextSelectedBg, // Selected text inside an InputText
ImGuiCol_TreeLines, // Tree node hierarchy outlines when using ImGuiTreeNodeFlags_DrawLines
ImGuiCol_DragDropTarget, // Rectangle highlighting a drop target
ImGuiCol_DragDropTarget, // Rectangle border highlighting a drop target
ImGuiCol_DragDropTargetBg, // Rectangle background highlighting a drop target
ImGuiCol_UnsavedMarker, // Unsaved Document marker (in window title and tabs)
ImGuiCol_NavCursor, // Color of keyboard/gamepad navigation cursor/rectangle, when visible
ImGuiCol_NavWindowingHighlight, // Highlight window when using CTRL+TAB
ImGuiCol_NavWindowingDimBg, // Darken/colorize entire screen behind the CTRL+TAB window list, when active
ImGuiCol_NavWindowingHighlight, // Highlight window when using Ctrl+Tab
ImGuiCol_NavWindowingDimBg, // Darken/colorize entire screen behind the Ctrl+Tab window list, when active
ImGuiCol_ModalWindowDimBg, // Darken/colorize entire screen behind a modal window, when one is active
ImGuiCol_WindowShadow, // Window shadows
ImGuiCol_COUNT,
@ -1869,9 +1883,9 @@ enum ImGuiCol_
// - 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: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments.
// - In Visual Studio: Ctrl+Comma ("Edit.GoToAll") can follow symbols inside comments, whereas Ctrl+F12 ("Edit.GoToImplementation") cannot.
// - In Visual Studio w/ Visual Assist installed: Alt+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
// - In VS Code, CLion, etc.: Ctrl+Click can follow symbols inside 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_
{
@ -1979,7 +1993,7 @@ enum ImGuiColorEditFlags_
// Obsolete names
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
ImGuiColorEditFlags_AlphaPreview = 0, // [Removed in 1.91.8] This is the default now. Will display a checkerboard unless ImGuiColorEditFlags_AlphaNoBg is set.
ImGuiColorEditFlags_AlphaPreview = 0, // Removed in 1.91.8. This is the default now. Will display a checkerboard unless ImGuiColorEditFlags_AlphaNoBg is set.
#endif
//ImGuiColorEditFlags_RGB = ImGuiColorEditFlags_DisplayRGB, ImGuiColorEditFlags_HSV = ImGuiColorEditFlags_DisplayHSV, ImGuiColorEditFlags_HEX = ImGuiColorEditFlags_DisplayHex // [renamed in 1.69]
};
@ -1992,9 +2006,9 @@ enum ImGuiSliderFlags_
ImGuiSliderFlags_None = 0,
ImGuiSliderFlags_Logarithmic = 1 << 5, // Make the widget logarithmic (linear otherwise). Consider using ImGuiSliderFlags_NoRoundToFormat with this if using a format-string with small amount of digits.
ImGuiSliderFlags_NoRoundToFormat = 1 << 6, // Disable rounding underlying value to match precision of the display format string (e.g. %.3f values are rounded to those 3 digits).
ImGuiSliderFlags_NoInput = 1 << 7, // Disable CTRL+Click or Enter key allowing to input text directly into the widget.
ImGuiSliderFlags_NoInput = 1 << 7, // Disable Ctrl+Click or Enter key allowing to input text directly into the widget.
ImGuiSliderFlags_WrapAround = 1 << 8, // Enable wrapping around from max to min and from min to max. Only supported by DragXXX() functions for now.
ImGuiSliderFlags_ClampOnInput = 1 << 9, // Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds.
ImGuiSliderFlags_ClampOnInput = 1 << 9, // Clamp value to min/max bounds when input manually with Ctrl+Click. By default Ctrl+Click allows going out of bounds.
ImGuiSliderFlags_ClampZeroRange = 1 << 10, // Clamp even if min==max==0.0f. Otherwise due to legacy reason DragXXX functions don't clamp with those values. When your clamping limits are dynamic you almost always want to use it.
ImGuiSliderFlags_NoSpeedTweaks = 1 << 11, // Disable keyboard modifiers altering tweak speed. Useful if you want to alter tweak speed yourself based on your own logic.
ImGuiSliderFlags_AlwaysClamp = ImGuiSliderFlags_ClampOnInput | ImGuiSliderFlags_ClampZeroRange,
@ -2364,7 +2378,7 @@ struct ImGuiStyle
float ColumnsMinSpacing; // Minimum horizontal spacing between two columns. Preferably > (FramePadding.x + 1).
float ScrollbarSize; // Width of the vertical scrollbar, Height of the horizontal scrollbar.
float ScrollbarRounding; // Radius of grab corners for scrollbar.
float ScrollbarPadding; // Padding of scrollbar grab within its frame (same for both axises).
float ScrollbarPadding; // Padding of scrollbar grab within its frame (same for both axes).
float GrabMinSize; // Minimum width/height of a grab box for slider/scrollbar.
float GrabRounding; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs.
float LogSliderDeadzone; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero.
@ -2382,6 +2396,9 @@ struct ImGuiStyle
ImGuiTreeNodeFlags TreeLinesFlags; // Default way to draw lines connecting TreeNode hierarchy. ImGuiTreeNodeFlags_DrawLinesNone or ImGuiTreeNodeFlags_DrawLinesFull or ImGuiTreeNodeFlags_DrawLinesToNodes.
float TreeLinesSize; // Thickness of outlines when using ImGuiTreeNodeFlags_DrawLines.
float TreeLinesRounding; // Radius of lines connecting child nodes to the vertical line.
float DragDropTargetRounding; // Radius of the drag and drop target frame.
float DragDropTargetBorderSize; // Thickness of the drag and drop target border.
float DragDropTargetPadding; // Size to expand the drag and drop target from actual target item size.
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. 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.
@ -2469,7 +2486,7 @@ struct ImGuiIO
// Font system
ImFontAtlas*Fonts; // <auto> // Font atlas: load, rasterize and pack one or more fonts into a single texture.
ImFont* FontDefault; // = NULL // Font to use on NewFrame(). Use NULL to uses Fonts->Fonts[0].
bool FontAllowUserScaling; // = false // [OBSOLETE] Allow user scaling text of individual window with CTRL+Wheel.
bool FontAllowUserScaling; // = false // Allow user scaling text of individual window with Ctrl+Wheel.
// Keyboard/Gamepad Navigation options
bool ConfigNavSwapGamepadButtons; // = false // Swap Activate<>Cancel (A<>B) buttons, matching typical "Nintendo/Japanese style" gamepad layout.
@ -2482,6 +2499,7 @@ struct ImGuiIO
// Docking options (when ImGuiConfigFlags_DockingEnable is set)
bool ConfigDockingNoSplit; // = false // Simplified docking mode: disable window splitting, so docking is limited to merging multiple windows together into tab-bars.
bool ConfigDockingNoDockingOver; // = false // Simplified docking mode: disable window merging into a same tab-bar, so docking is limited to splitting windows.
bool ConfigDockingWithShift; // = false // Enable docking with holding Shift key (reduce visual noise, allows dropping in wider space)
bool ConfigDockingAlwaysTabBar; // = false // [BETA] [FIXME: This currently creates regression with auto-sizing and general overhead] Make every single floating window display within a docking node.
bool ConfigDockingTransparentPayload;// = false // [BETA] Make window or viewport transparent when docking and only display docking boxes on the target viewport. Useful if rendering of multiple viewport cannot be synced. Best used with ConfigViewportsNoAutoMerge.
@ -2490,8 +2508,8 @@ struct ImGuiIO
bool ConfigViewportsNoAutoMerge; // = false; // Set to make all floating imgui windows always create their own viewport. Otherwise, they are merged into the main host viewports when overlapping it. May also set ImGuiViewportFlags_NoAutoMerge on individual viewport.
bool ConfigViewportsNoTaskBarIcon; // = false // Disable default OS task bar icon flag for secondary viewports. When a viewport doesn't want a task bar icon, ImGuiViewportFlags_NoTaskBarIcon will be set on it.
bool ConfigViewportsNoDecoration; // = true // Disable default OS window decoration flag for secondary viewports. When a viewport doesn't want window decorations, ImGuiViewportFlags_NoDecoration will be set on it. Enabling decoration can create subsequent issues at OS levels (e.g. minimum window size).
bool ConfigViewportsNoDefaultParent; // = false // Disable default OS parenting to main viewport for secondary viewports. By default, viewports are marked with ParentViewportId = <main_viewport>, expecting the platform backend to setup a parent/child relationship between the OS windows (some backend may ignore this). Set to true if you want the default to be 0, then all viewports will be top-level OS windows.
bool ConfigViewportPlatformFocusSetsImGuiFocus; //= true // When a platform window is focused (e.g. using Alt+Tab, clicking Platform Title Bar), apply corresponding focus on imgui windows (may clear focus/active id from imgui windows location in other platform windows). In principle this is better enabled but we provide an opt-out, because some Linux window managers tend to eagerly focus windows (e.g. on mouse hover, or even a simple window pos/size change).
bool ConfigViewportsNoDefaultParent; // = true // When false: set secondary viewports' ParentViewportId to main viewport ID by default. Expects the platform backend to setup a parent/child relationship between the OS windows based on this value. Some backend may ignore this. Set to true if you want viewports to automatically be parent of main viewport, otherwise all viewports will be top-level OS windows.
bool ConfigViewportsPlatformFocusSetsImGuiFocus;//= true // When a platform window is focused (e.g. using Alt+Tab, clicking Platform Title Bar), apply corresponding focus on imgui windows (may clear focus/active id from imgui windows location in other platform windows). In principle this is better enabled but we provide an opt-out, because some Linux window managers tend to eagerly focus windows (e.g. on mouse hover, or even a simple window pos/size change).
// DPI/Scaling options
// This may keep evolving during 1.92.x releases. Expect some turbulence.
@ -2508,7 +2526,7 @@ struct ImGuiIO
bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard.
bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires ImGuiBackendFlags_HasMouseCursors for better mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag)
bool ConfigWindowsMoveFromTitleBarOnly; // = false // Enable allowing to move windows only when clicking on their title bar. Does not apply to windows without a title bar.
bool ConfigWindowsCopyContentsWithCtrlC; // = false // [EXPERIMENTAL] CTRL+C copy the contents of focused window into the clipboard. Experimental because: (1) has known issues with nested Begin/End pairs (2) text output quality varies (3) text output is in submission order rather than spatial order.
bool ConfigWindowsCopyContentsWithCtrlC; // = false // [EXPERIMENTAL] Ctrl+C copy the contents of focused window into the clipboard. Experimental because: (1) has known issues with nested Begin/End pairs (2) text output quality varies (3) text output is in submission order rather than spatial order.
bool ConfigScrollbarScrollByPage; // = true // Enable scrolling page by page when clicking outside the scrollbar grab. When disabled, always scroll to clicked location. When enabled, Shift+Click scrolls to clicked location.
float ConfigMemoryCompactTimer; // = 60.0f // Timer (in seconds) to free transient windows/tables memory buffers when unused. Set to -1.0f to disable.
@ -2606,9 +2624,6 @@ struct ImGuiIO
IMGUI_API void ClearEventsQueue(); // Clear all incoming events.
IMGUI_API void ClearInputKeys(); // Clear current keyboard/gamepad state + current frame text input buffer. Equivalent to releasing all keys/buttons.
IMGUI_API void ClearInputMouse(); // Clear current mouse state.
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
IMGUI_API void ClearInputCharacters(); // [Obsoleted in 1.89.8] Clear the current frame text input buffer. Now included within ClearInputKeys().
#endif
//------------------------------------------------------------------
// Output - Updated by NewFrame() or EndFrame()/Render()
@ -2641,7 +2656,7 @@ struct ImGuiIO
// (reading from those variables is fair game, as they are extremely unlikely to be moving anywhere)
ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX, -FLT_MAX) if mouse is unavailable (on another screen, etc.)
bool MouseDown[5]; // Mouse buttons: 0=left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Other buttons allow us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API.
float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text. >0 scrolls Up, <0 scrolls Down. Hold SHIFT to turn vertical scroll into horizontal scroll.
float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text. >0 scrolls Up, <0 scrolls Down. Hold Shift to turn vertical scroll into horizontal scroll.
float MouseWheelH; // Mouse wheel Horizontal. >0 scrolls Left, <0 scrolls Right. Most users don't have a mouse with a horizontal wheel, may not be filled by all backends.
ImGuiMouseSource MouseSource; // Mouse actual input peripheral (Mouse/TouchScreen/Pen).
ImGuiID MouseHoveredViewport; // (Optional) Modify using io.AddMouseViewportEvent(). With multi-viewports: viewport the OS mouse is hovering. If possible _IGNORING_ viewports with the ImGuiViewportFlags_NoInputs flag is much better (few backends can handle that). Set io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport if you can provide this info. If you don't imgui will infer the value using the rectangles and last focused time of the viewports it knows about (ignoring other OS windows).
@ -2665,8 +2680,8 @@ struct ImGuiIO
double MouseReleasedTime[5]; // Time of last released (rarely used! but useful to handle delayed single-click when trying to disambiguate them from double-click).
bool MouseDownOwned[5]; // Track if button was clicked inside a dear imgui window or over void blocked by a popup. We don't request mouse capture from the application if click started outside ImGui bounds.
bool MouseDownOwnedUnlessPopupClose[5]; // Track if button was clicked inside a dear imgui window.
bool MouseWheelRequestAxisSwap; // On a non-Mac system, holding SHIFT requests WheelY to perform the equivalent of a WheelX event. On a Mac system this is already enforced by the system.
bool MouseCtrlLeftAsRightClick; // (OSX) Set to true when the current click was a Ctrl+click that spawned a simulated right click
bool MouseWheelRequestAxisSwap; // On a non-Mac system, holding Shift requests WheelY to perform the equivalent of a WheelX event. On a Mac system this is already enforced by the system.
bool MouseCtrlLeftAsRightClick; // (OSX) Set to true when the current click was a Ctrl+Click that spawned a simulated right click
float MouseDownDuration[5]; // Duration the mouse button has been down (0.0f == just clicked)
float MouseDownDurationPrev[5]; // Previous time the mouse button has been down
ImVec2 MouseDragMaxDistanceAbs[5]; // Maximum distance, absolute, on each axis, of how much mouse has traveled from the clicking point
@ -2695,6 +2710,8 @@ struct ImGuiIO
const char* (*GetClipboardTextFn)(void* user_data);
void (*SetClipboardTextFn)(void* user_data, const char* text);
void* ClipboardUserData;
//void ClearInputCharacters() { InputQueueCharacters.resize(0); } // [Obsoleted in 1.89.8] Clear the current frame text input buffer. Now included within ClearInputKeys(). Removed this as it is ambiguous/misleading and generally incorrect to use with the existence of a higher-level input queue.
#endif
IMGUI_API ImGuiIO();
@ -2981,7 +2998,7 @@ struct ImGuiListClipper
IMGUI_API void SeekCursorForItem(int item_index);
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
inline void IncludeRangeByIndices(int item_begin, int item_end) { IncludeItemsByIndex(item_begin, item_end); } // [renamed in 1.89.9]
//inline void IncludeRangeByIndices(int item_begin, int item_end) { IncludeItemsByIndex(item_begin, item_end); } // [renamed in 1.89.9]
//inline void ForceDisplayRangeByIndices(int item_begin, int item_end) { IncludeItemsByIndex(item_begin, item_end); } // [renamed in 1.89.6]
//inline ImGuiListClipper(int items_count, float items_height = -1.0f) { memset(this, 0, sizeof(*this)); ItemsCount = -1; Begin(items_count, items_height); } // [removed in 1.79]
#endif
@ -3075,7 +3092,7 @@ struct ImColor
// Multi-selection system
// Documentation at: https://github.com/ocornut/imgui/wiki/Multi-Select
// - Refer to 'Demo->Widgets->Selection State & Multi-Select' for demos using this.
// - This system implements standard multi-selection idioms (CTRL+Mouse/Keyboard, SHIFT+Mouse/Keyboard, etc)
// - This system implements standard multi-selection idioms (Ctrl+Mouse/Keyboard, Shift+Mouse/Keyboard, etc)
// with support for clipper (skipping non-visible items), box-select and many other details.
// - Selectable(), Checkbox() are supported but custom widgets may use it as well.
// - TreeNode() is technically supported but... using this correctly is more complicated: you need some sort of linear/random access to your tree,
@ -3113,7 +3130,7 @@ enum ImGuiMultiSelectFlags_
{
ImGuiMultiSelectFlags_None = 0,
ImGuiMultiSelectFlags_SingleSelect = 1 << 0, // Disable selecting more than one item. This is available to allow single-selection code to share same code/logic if desired. It essentially disables the main purpose of BeginMultiSelect() tho!
ImGuiMultiSelectFlags_NoSelectAll = 1 << 1, // Disable CTRL+A shortcut to select all.
ImGuiMultiSelectFlags_NoSelectAll = 1 << 1, // Disable Ctrl+A shortcut to select all.
ImGuiMultiSelectFlags_NoRangeSelect = 1 << 2, // Disable Shift+selection mouse/keyboard support (useful for unordered 2D selection). With BoxSelect is also ensure contiguous SetRange requests are not combined into one. This allows not handling interpolation in SetRange requests.
ImGuiMultiSelectFlags_NoAutoSelect = 1 << 3, // Disable selecting items when navigating (useful for e.g. supporting range-select in a list of checkboxes).
ImGuiMultiSelectFlags_NoAutoClear = 1 << 4, // Disable clearing selection when navigating or selecting another one (generally used with ImGuiMultiSelectFlags_NoAutoSelect. useful for e.g. supporting range-select in a list of checkboxes).
@ -3129,6 +3146,7 @@ enum ImGuiMultiSelectFlags_
ImGuiMultiSelectFlags_SelectOnClickRelease = 1 << 14, // Apply selection on mouse release when clicking an unselected item. Allow dragging an unselected item without altering selection.
//ImGuiMultiSelectFlags_RangeSelect2d = 1 << 15, // Shift+Selection uses 2d geometry instead of linear sequence, so possible to use Shift+up/down to select vertically in grid. Analogous to what BoxSelect does.
ImGuiMultiSelectFlags_NavWrapX = 1 << 16, // [Temporary] Enable navigation wrapping on X axis. Provided as a convenience because we don't have a design for the general Nav API for this yet. When the more general feature be public we may obsolete this flag in favor of new one.
ImGuiMultiSelectFlags_NoSelectOnRightClick = 1 << 17, // Disable default right-click processing, which selects item on mouse down, and is designed for context-menus.
};
// Main IO structure returned by BeginMultiSelect()/EndMultiSelect().
@ -3511,8 +3529,8 @@ struct ImDrawList
// Obsolete names
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
inline void PushTextureID(ImTextureRef tex_ref) { PushTexture(tex_ref); } // RENAMED in 1.92.x
inline void PopTextureID() { PopTexture(); } // RENAMED in 1.92.x
inline void PushTextureID(ImTextureRef tex_ref) { PushTexture(tex_ref); } // RENAMED in 1.92.0
inline void PopTextureID() { PopTexture(); } // RENAMED in 1.92.0
#endif
//inline 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) { AddEllipse(center, ImVec2(radius_x, radius_y), col, rot, num_segments, thickness); } // OBSOLETED in 1.90.5 (Mar 2024)
//inline void AddEllipseFilled(const ImVec2& center, float radius_x, float radius_y, ImU32 col, float rot = 0.0f, int num_segments = 0) { AddEllipseFilled(center, ImVec2(radius_x, radius_y), col, rot, num_segments); } // OBSOLETED in 1.90.5 (Mar 2024)
@ -3549,7 +3567,7 @@ struct ImDrawData
ImVec2 DisplaySize; // Size of the viewport to render (== GetMainViewport()->Size for the main viewport, == io.DisplaySize in most single-viewport applications)
ImVec2 FramebufferScale; // Amount of pixels for each unit of DisplaySize. Copied from viewport->FramebufferScale (== io.DisplayFramebufferScale for main viewport). Generally (1,1) on normal display, (2,2) on OSX with Retina display.
ImGuiViewport* OwnerViewport; // Viewport carrying the ImDrawData instance, might be of use to the renderer (generally not).
ImVector<ImTextureData*>* Textures; // List of textures to update. Most of the times the list is shared by all ImDrawData, has only 1 texture and it doesn't need any update. This almost always points to ImGui::GetPlatformIO().Textures[]. May be overriden or set to NULL if you want to manually update textures.
ImVector<ImTextureData*>* Textures; // List of textures to update. Most of the times the list is shared by all ImDrawData, has only 1 texture and it doesn't need any update. This almost always points to ImGui::GetPlatformIO().Textures[]. May be overridden or set to NULL if you want to manually update textures.
// Functions
ImDrawData() { Clear(); }
@ -3636,8 +3654,10 @@ struct ImTextureData
ImTextureID GetTexID() const { return TexID; }
// Called by Renderer backend
void SetTexID(ImTextureID tex_id) { TexID = tex_id; } // Call after creating or destroying the texture. Never modify TexID directly!
void SetStatus(ImTextureStatus status) { Status = status; } // Call after honoring a request. Never modify Status directly!
// - Call SetTexID() and SetStatus() after honoring texture requests. Never modify TexID and Status directly!
// - A backend may decide to destroy a texture that we did not request to destroy, which is fine (e.g. freeing resources), but we immediately set the texture back in _WantCreate mode.
void SetTexID(ImTextureID tex_id) { TexID = tex_id; }
void SetStatus(ImTextureStatus status) { Status = status; if (status == ImTextureStatus_Destroyed && !WantDestroyNextFrame) Status = ImTextureStatus_WantCreate; }
};
//-----------------------------------------------------------------------------
@ -3669,7 +3689,7 @@ struct ImFontConfig
char Name[40]; // <auto> // Name (strictly to ease debugging, hence limited size buffer)
void* FontData; // // TTF/OTF data
int FontDataSize; // // TTF/OTF data size
bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself).
bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the owner ImFontAtlas (will delete memory itself).
// Options
bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights.
@ -3790,7 +3810,7 @@ struct ImFontAtlas
IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_font_data_base85, float size_pixels = 0.0f, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 parameter.
IMGUI_API void RemoveFont(ImFont* font);
IMGUI_API void Clear(); // Clear everything (input fonts, output glyphs/textures)
IMGUI_API void Clear(); // Clear everything (input fonts, output glyphs/textures).
IMGUI_API void CompactCache(); // Compact cached glyphs and texture.
IMGUI_API void SetFontLoader(const ImFontLoader* font_loader); // Change font loader at runtime.
@ -3843,7 +3863,7 @@ struct ImFontAtlas
// Register and retrieve custom rectangles
// - You can request arbitrary rectangles to be packed into the atlas, for your own purpose.
// - Since 1.92.X, packing is done immediately in the function call (previously packing was done during the Build call)
// - Since 1.92.0, packing is done immediately in the function call (previously packing was done during the Build call)
// - You can render your pixels into the texture right after calling the AddCustomRect() functions.
// - VERY IMPORTANT:
// - Texture may be created/resized at any time when calling ImGui or ImFontAtlas functions.
@ -3882,7 +3902,7 @@ struct ImFontAtlas
#ifdef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
ImTextureRef TexRef; // Latest texture identifier == TexData->GetTexRef().
#else
union { ImTextureRef TexRef; ImTextureRef TexID; }; // Latest texture identifier == TexData->GetTexRef(). // RENAMED TexID to TexRef in 1.92.x
union { ImTextureRef TexRef; ImTextureRef TexID; }; // Latest texture identifier == TexData->GetTexRef(). // RENAMED TexID to TexRef in 1.92.0.
#endif
ImTextureData* TexData; // Latest texture.
@ -3917,15 +3937,15 @@ struct ImFontAtlas
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
// Legacy: You can request your rectangles to be mapped as font glyph (given a font + Unicode point), so you can render e.g. custom colorful icons and use them as regular glyphs. --> Prefer using a custom ImFontLoader.
ImFontAtlasRect TempRect; // For old GetCustomRectByIndex() API
inline ImFontAtlasRectId AddCustomRectRegular(int w, int h) { return AddCustomRect(w, h); } // RENAMED in 1.92.X
inline const ImFontAtlasRect* GetCustomRectByIndex(ImFontAtlasRectId id) { return GetCustomRect(id, &TempRect) ? &TempRect : NULL; } // OBSOLETED in 1.92.X
inline void CalcCustomRectUV(const ImFontAtlasRect* r, ImVec2* out_uv_min, ImVec2* out_uv_max) const { *out_uv_min = r->uv0; *out_uv_max = r->uv1; } // OBSOLETED in 1.92.X
IMGUI_API ImFontAtlasRectId AddCustomRectFontGlyph(ImFont* font, ImWchar codepoint, int w, int h, float advance_x, const ImVec2& offset = ImVec2(0, 0)); // OBSOLETED in 1.92.X: Use custom ImFontLoader in ImFontConfig
IMGUI_API ImFontAtlasRectId AddCustomRectFontGlyphForSize(ImFont* font, float font_size, ImWchar codepoint, int w, int h, float advance_x, const ImVec2& offset = ImVec2(0, 0)); // ADDED AND OBSOLETED in 1.92.X
inline ImFontAtlasRectId AddCustomRectRegular(int w, int h) { return AddCustomRect(w, h); } // RENAMED in 1.92.0
inline const ImFontAtlasRect* GetCustomRectByIndex(ImFontAtlasRectId id) { return GetCustomRect(id, &TempRect) ? &TempRect : NULL; } // OBSOLETED in 1.92.0
inline void CalcCustomRectUV(const ImFontAtlasRect* r, ImVec2* out_uv_min, ImVec2* out_uv_max) const { *out_uv_min = r->uv0; *out_uv_max = r->uv1; } // OBSOLETED in 1.92.0
IMGUI_API ImFontAtlasRectId AddCustomRectFontGlyph(ImFont* font, ImWchar codepoint, int w, int h, float advance_x, const ImVec2& offset = ImVec2(0, 0)); // OBSOLETED in 1.92.0: Use custom ImFontLoader in ImFontConfig
IMGUI_API ImFontAtlasRectId AddCustomRectFontGlyphForSize(ImFont* font, float font_size, ImWchar codepoint, int w, int h, float advance_x, const ImVec2& offset = ImVec2(0, 0)); // ADDED AND OBSOLETED in 1.92.0
#endif
//unsigned int FontBuilderFlags; // OBSOLETED in 1.92.X: Renamed to FontLoaderFlags.
//int TexDesiredWidth; // OBSOLETED in 1.92.X: Force texture width before calling Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height.
//typedef ImFontAtlasRect ImFontAtlasCustomRect; // OBSOLETED in 1.92.X
//unsigned int FontBuilderFlags; // OBSOLETED in 1.92.0: Renamed to FontLoaderFlags.
//int TexDesiredWidth; // OBSOLETED in 1.92.0: Force texture width before calling Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height.
//typedef ImFontAtlasRect ImFontAtlasCustomRect; // OBSOLETED in 1.92.0
//typedef ImFontAtlasCustomRect CustomRect; // OBSOLETED in 1.72+
//typedef ImFontGlyphRangesBuilder GlyphRangesBuilder; // OBSOLETED in 1.67+
};
@ -3953,7 +3973,7 @@ struct ImFontBaked
unsigned int LoadNoRenderOnLayout:1;// 0 // // Enable a two-steps mode where CalcTextSize() calls will load AdvanceX *without* rendering/packing glyphs. Only advantagous if you know that the glyph is unlikely to actually be rendered, otherwise it is slower because we'd do one query on the first CalcTextSize and one query on the first Draw.
int LastUsedFrame; // 4 // // Record of that time this was bounds
ImGuiID BakedId; // 4 // // Unique ID for this baked storage
ImFont* ContainerFont; // 4-8 // in // Parent font
ImFont* OwnerFont; // 4-8 // in // Parent font
void* FontLoaderDatas; // 4-8 // // Font loader opaque storage (per baked font * sources): single contiguous buffer allocated by imgui, passed to loader.
// Functions
@ -3977,14 +3997,14 @@ enum ImFontFlags_
// Font runtime data and rendering
// - ImFontAtlas automatically loads a default embedded font for you if you didn't load one manually.
// - Since 1.92.X a font may be rendered as any size! Therefore a font doesn't have one specific size.
// - Since 1.92.0 a font may be rendered as any size! Therefore a font doesn't have one specific size.
// - Use 'font->GetFontBaked(size)' to retrieve the ImFontBaked* corresponding to a given size.
// - If you used g.Font + g.FontSize (which is frequent from the ImGui layer), you can use g.FontBaked as a shortcut, as g.FontBaked == g.Font->GetFontBaked(g.FontSize).
struct ImFont
{
// [Internal] Members: Hot ~12-20 bytes
ImFontBaked* LastBaked; // 4-8 // Cache last bound baked. NEVER USE DIRECTLY. Use GetFontBaked().
ImFontAtlas* ContainerAtlas; // 4-8 // What we have been loaded into.
ImFontAtlas* OwnerAtlas; // 4-8 // What we have been loaded into.
ImFontFlags Flags; // 4 // Font flags.
float CurrentRasterizerDensity; // Current rasterizer density. This is a varying state of the font.
@ -3992,7 +4012,7 @@ struct ImFont
// Conceptually Sources[] is the list of font sources merged to create this font.
ImGuiID FontId; // Unique identifier for the font
float LegacySize; // 4 // in // Font size passed to AddFont(). Use for old code calling PushFont() expecting to use that size. (use ImGui::GetFontBaked() to get font baked at current bound size).
ImVector<ImFontConfig*> Sources; // 16 // in // List of sources. Pointers within ContainerAtlas->Sources[]
ImVector<ImFontConfig*> Sources; // 16 // in // List of sources. Pointers within OwnerAtlas->Sources[]
ImWchar EllipsisChar; // 2-4 // out // Character used for ellipsis rendering ('...').
ImWchar FallbackChar; // 2-4 // out // Character used if a glyph isn't found (U+FFFD, '?')
ImU8 Used8kPagesMap[(IM_UNICODE_CODEPOINT_MAX+1)/8192/8]; // 1 bytes if ImWchar=ImWchar16, 16 bytes if ImWchar==ImWchar32. Store 1-bit for each block of 4K codepoints that has one active glyph. This is mainly used to facilitate iterations across all used codepoints.
@ -4006,7 +4026,7 @@ struct ImFont
IMGUI_API ImFont();
IMGUI_API ~ImFont();
IMGUI_API bool IsGlyphInFont(ImWchar c);
bool IsLoaded() const { return ContainerAtlas != NULL; }
bool IsLoaded() const { return OwnerAtlas != NULL; }
const char* GetDebugName() const { return Sources.Size ? Sources[0]->Name : "<unknown>"; } // Fill ImFontConfig::Name.
// [Internal] Don't use!
@ -4089,6 +4109,7 @@ struct ImGuiViewport
ImVec2 WorkSize; // Work Area: Size of the viewport minus task bars, menu bars, status bars (<= Size)
float DpiScale; // 1.0f = 96 DPI = No extra scale.
ImGuiID ParentViewportId; // (Advanced) 0: no parent. Instruct the platform backend to setup a parent/child relationship between platform windows.
ImGuiViewport* ParentViewport; // (Advanced) Direct shortcut to ImGui::FindViewportByID(ParentViewportId). NULL: no parent.
ImDrawData* DrawData; // The ImDrawData corresponding to this viewport. Valid after Render() and until the next call to NewFrame().
// Platform/Backend Dependent Data
@ -4179,7 +4200,7 @@ struct ImGuiPlatformIO
void* Platform_ClipboardUserData;
// Optional: Open link/folder/file in OS Shell
// (default to use ShellExecuteW() on Windows, system() on Linux/Mac)
// (default to use ShellExecuteW() on Windows, system() on Linux/Mac. expected to return false on failure, but some platforms may always return true)
bool (*Platform_OpenInShellFn)(ImGuiContext* ctx, const char* path);
void* Platform_OpenInShellUserData;
@ -4265,6 +4286,13 @@ struct ImGuiPlatformIO
// Viewports list (the list is updated by calling ImGui::EndFrame or ImGui::Render)
// (in the future we will attempt to organize this feature to remove the need for a "main viewport")
ImVector<ImGuiViewport*> Viewports; // Main viewports, followed by all secondary viewports.
//------------------------------------------------------------------
// Functions
//------------------------------------------------------------------
IMGUI_API void ClearPlatformHandlers(); // Clear all Platform_XXX fields. Typically called on Platform Backend shutdown.
IMGUI_API void ClearRendererHandlers(); // Clear all Renderer_XXX fields. Typically called on Renderer Backend shutdown.
};
// (Optional) This is required when enabling multi-viewport. Represent the bounds of each connected monitor/display and their DPI.
@ -4320,10 +4348,10 @@ namespace ImGui
inline void ShowStackToolWindow(bool* p_open = NULL) { ShowIDStackToolWindow(p_open); }
IMGUI_API bool Combo(const char* label, int* current_item, bool (*old_callback)(void* user_data, int idx, const char** out_text), void* user_data, int items_count, int popup_max_height_in_items = -1);
IMGUI_API bool ListBox(const char* label, int* current_item, bool (*old_callback)(void* user_data, int idx, const char** out_text), void* user_data, int items_count, int height_in_items = -1);
// OBSOLETED in 1.89.7 (from June 2023)
IMGUI_API void SetItemAllowOverlap(); // Use SetNextItemAllowOverlap() before item.
// Some of the older obsolete names along with their replacement (commented out so they are not reported in IDE)
// OBSOLETED in 1.89.7 (from June 2023)
//IMGUI_API void SetItemAllowOverlap(); // Use SetNextItemAllowOverlap() _before_ item.
//-- OBSOLETED in 1.89.4 (from March 2023)
//static inline void PushAllowKeyboardFocus(bool tab_stop) { PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop); }
//static inline void PopAllowKeyboardFocus() { PopItemFlag(); }
@ -4389,7 +4417,7 @@ namespace ImGui
//static inline void SetScrollPosHere() { SetScrollHere(); } // OBSOLETED in 1.42
}
//-- OBSOLETED in 1.92.x: ImFontAtlasCustomRect becomes ImTextureRect
//-- OBSOLETED in 1.92.0: ImFontAtlasCustomRect becomes ImTextureRect
// - ImFontAtlasCustomRect::X,Y --> ImTextureRect::x,y
// - ImFontAtlasCustomRect::Width,Height --> ImTextureRect::w,h
// - ImFontAtlasCustomRect::GlyphColored --> if you need to write to this, instead you can write to 'font->Glyphs.back()->Colored' after calling AddCustomRectFontGlyph()
@ -4425,7 +4453,7 @@ typedef ImFontAtlasRect ImFontAtlasCustomRect;
//};
// 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.
// RENAMED ImGuiKeyModFlags -> ImGuiModFlags in 1.88 (from April 2022). Exceptionally commented out ahead of obsolescence schedule to reduce confusion and because they were not meant to be used in the first place.
//typedef ImGuiKeyChord ImGuiModFlags; // == int. We generally use ImGuiKeyChord to mean "a ImGuiKey or-ed with any number of ImGuiMod_XXX value", so you may store mods in there.
//enum ImGuiModFlags_ { ImGuiModFlags_None = 0, ImGuiModFlags_Ctrl = ImGuiMod_Ctrl, ImGuiModFlags_Shift = ImGuiMod_Shift, ImGuiModFlags_Alt = ImGuiMod_Alt, ImGuiModFlags_Super = ImGuiMod_Super };
//typedef ImGuiKeyChord ImGuiKeyModFlags; // == int

View File

@ -1,4 +1,4 @@
// dear imgui, v1.92.3
// dear imgui, v1.92.5
// (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.
@ -216,6 +216,7 @@ typedef int ImGuiSeparatorFlags; // -> enum ImGuiSeparatorFlags_ // F
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 int ImGuiWindowBgClickFlags; // -> enum ImGuiWindowBgClickFlags_ // Flags: for overriding behavior of clicking on window background/void.
typedef int ImGuiWindowRefreshFlags; // -> enum ImGuiWindowRefreshFlags_ // Flags: for SetNextWindowRefreshPolicy()
// Table column indexing
@ -289,10 +290,8 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255
#define IM_TRUNC(_VAL) ((float)(int)(_VAL)) // ImTrunc() is not inlined in MSVC debug builds
#define IM_ROUND(_VAL) ((float)(int)((_VAL) + 0.5f)) //
#define IM_STRINGIFY_HELPER(_X) #_X
#define IM_STRINGIFY(_X) IM_STRINGIFY_HELPER(_X) // Preprocessor idiom to stringify e.g. an integer.
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
#define IM_FLOOR IM_TRUNC
#define IM_FLOOR IM_TRUNC // [OBSOLETE] Renamed in 1.90.0 (Sept 2023)
#endif
// Hint for branch prediction
@ -439,7 +438,8 @@ 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.
IMGUI_API const char* ImTextFindPreviousUtf8Codepoint(const char* in_text_start, const char* in_p); // return previous UTF-8 code-point.
IMGUI_API const char* ImTextFindValidUtf8CodepointEnd(const char* in_text_start, const char* in_text_end, const char* in_p); // return previous UTF-8 code-point if 'in_p' is not the end of a valid one.
IMGUI_API int ImTextCountLines(const char* in_text, const char* in_text_end); // return number of lines taken by text. trailing carriage return doesn't count as an extra line.
// Helpers: High-level text functions (DO NOT USE!!! THIS IS A MINIMAL SUBSET OF LARGER UPCOMING CHANGES)
@ -1189,6 +1189,7 @@ struct IMGUI_API ImGuiGroupData
ImVec2 BackupCurrLineSize;
float BackupCurrLineTextBaseOffset;
ImGuiID BackupActiveIdIsAlive;
bool BackupActiveIdHasBeenEditedThisFrame;
bool BackupDeactivatedIdIsAlive;
bool BackupHoveredIdIsAlive;
bool BackupIsSameLine;
@ -1298,6 +1299,12 @@ enum ImGuiWindowRefreshFlags_
// Refresh policy/frequency, Load Balancing etc.
};
enum ImGuiWindowBgClickFlags_
{
ImGuiWindowBgClickFlags_None = 0,
ImGuiWindowBgClickFlags_Move = 1 << 0, // Click on bg/void + drag to move window. Cleared by default when using io.ConfigWindowsMoveFromTitleBarOnly.
};
enum ImGuiNextWindowDataFlags_
{
ImGuiNextWindowDataFlags_None = 0,
@ -1583,12 +1590,12 @@ struct ImGuiKeyRoutingData
{
ImGuiKeyRoutingIndex NextEntryIndex;
ImU16 Mods; // Technically we'd only need 4-bits but for simplify we store ImGuiMod_ values which need 16-bits.
ImU8 RoutingCurrScore; // [DEBUG] For debug display
ImU8 RoutingNextScore; // Lower is better (0: perfect score)
ImU16 RoutingCurrScore; // [DEBUG] For debug display
ImU16 RoutingNextScore; // Lower is better (0: perfect score)
ImGuiID RoutingCurr;
ImGuiID RoutingNext;
ImGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingCurrScore = RoutingNextScore = 255; RoutingCurr = RoutingNext = ImGuiKeyOwner_NoOwner; }
ImGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingCurrScore = RoutingNextScore = 0; RoutingCurr = RoutingNext = ImGuiKeyOwner_NoOwner; }
};
// Routing table: maintain a desired owner for each possible key-chord (key + mods), and setup owner in NewFrame() when mods are matching.
@ -1742,7 +1749,7 @@ enum ImGuiNavMoveFlags_
ImGuiNavMoveFlags_WrapMask_ = ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_LoopY | ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_WrapY,
ImGuiNavMoveFlags_AllowCurrentNavId = 1 << 4, // Allow scoring and considering the current NavId as a move target candidate. This is used when the move source is offset (e.g. pressing PageDown actually needs to send a Up move request, if we are pressing PageDown from the bottom-most item we need to stay in place)
ImGuiNavMoveFlags_AlsoScoreVisibleSet = 1 << 5, // Store alternate result in NavMoveResultLocalVisible that only comprise elements that are already fully visible (used by PageUp/PageDown)
ImGuiNavMoveFlags_ScrollToEdgeY = 1 << 6, // Force scrolling to min/max (used by Home/End) // FIXME-NAV: Aim to remove or reword, probably unnecessary
ImGuiNavMoveFlags_ScrollToEdgeY = 1 << 6, // Force scrolling to min/max (used by Home/End) // FIXME-NAV: Aim to remove or reword as ImGuiScrollFlags
ImGuiNavMoveFlags_Forwarded = 1 << 7,
ImGuiNavMoveFlags_DebugNoResult = 1 << 8, // Dummy scoring for debug purpose, don't apply result
ImGuiNavMoveFlags_FocusApi = 1 << 9, // Requests from focus API can land/focus/activate items even if they are marked with _NoTabStop (see NavProcessItemForTabbingRequest() for details)
@ -2088,6 +2095,7 @@ enum ImGuiWindowDockStyleCol
ImGuiWindowDockStyleCol_TabDimmed,
ImGuiWindowDockStyleCol_TabDimmedSelected,
ImGuiWindowDockStyleCol_TabDimmedSelectedOverline,
ImGuiWindowDockStyleCol_UnsavedMarker,
ImGuiWindowDockStyleCol_COUNT
};
@ -2311,27 +2319,34 @@ struct ImGuiMetricsConfig
struct ImGuiStackLevelInfo
{
ImGuiID ID;
ImS8 QueryFrameCount; // >= 1: Query in progress
bool QuerySuccess; // Obtained result from DebugHookIdInfo()
ImS8 QueryFrameCount; // >= 1: Sub-query in progress
bool QuerySuccess; // Sub-query obtained result from DebugHookIdInfo()
ImS8 DataType; // ImGuiDataType
int DescOffset; // -1 or offset into parent's ResultPathsBuf
int DescOffset; // -1 or offset into parent's ResultsPathsBuf
ImGuiStackLevelInfo() { memset(this, 0, sizeof(*this)); DescOffset = -1; }
ImGuiStackLevelInfo() { memset(this, 0, sizeof(*this)); DataType = -1; DescOffset = -1; }
};
struct ImGuiDebugItemPathQuery
{
ImGuiID MainID; // ID to query details for.
bool Active; // Used to disambiguate the case when ID == 0 and e.g. some code calls PushOverrideID(0).
bool Complete; // All sub-queries are finished (some may have failed).
ImS8 Step; // -1: query stack + init Results, >= 0: filling individual stack level.
ImVector<ImGuiStackLevelInfo> Results;
ImGuiTextBuffer ResultsDescBuf;
ImGuiTextBuffer ResultPathBuf;
ImGuiDebugItemPathQuery() { memset(this, 0, sizeof(*this)); }
};
// State for ID Stack tool queries
struct ImGuiIDStackTool
{
int LastActiveFrame;
int StackLevel; // -1: query stack and resize Results, >= 0: individual stack level
ImGuiID QueryMainId; // ID to query details for
ImVector<ImGuiStackLevelInfo> Results;
bool QueryHookActive; // Used to disambiguate the case where DebugHookIdInfoId == 0 which is valid.
bool OptHexEncodeNonAsciiChars;
bool OptCopyToClipboardOnCtrlC;
int LastActiveFrame;
float CopyToClipboardLastTime;
ImGuiTextBuffer ResultPathsBuf;
ImGuiTextBuffer ResultTempBuf;
ImGuiIDStackTool() { memset(this, 0, sizeof(*this)); LastActiveFrame = -1; OptHexEncodeNonAsciiChars = true; CopyToClipboardLastTime = -FLT_MAX; }
};
@ -2361,6 +2376,15 @@ struct ImGuiContextHook
struct ImGuiContext
{
bool Initialized;
bool WithinFrameScope; // Set by NewFrame(), cleared by EndFrame()
bool WithinFrameScopeWithImplicitWindow; // Set by NewFrame(), cleared by EndFrame() when the implicit debug window has been pushed
bool TestEngineHookItems; // Will call test engine hooks: ImGuiTestEngineHook_ItemAdd(), ImGuiTestEngineHook_ItemInfo(), ImGuiTestEngineHook_Log()
int FrameCount;
int FrameCountEnded;
int FrameCountPlatformEnded;
int FrameCountRendered;
double Time;
char ContextName[16]; // Storage for a context name (to facilitate debugging multi-context setups)
ImGuiIO IO;
ImGuiPlatformIO PlatformIO;
ImGuiStyle Style;
@ -2375,18 +2399,8 @@ struct ImGuiContext
float FontRasterizerDensity; // Current font density. Used by all calls to GetFontBaked().
float CurrentDpiScale; // Current window/viewport DpiScale == CurrentViewport->DpiScale
ImDrawListSharedData DrawListSharedData;
double Time;
int FrameCount;
int FrameCountEnded;
int FrameCountPlatformEnded;
int FrameCountRendered;
ImGuiID WithinEndChildID; // Set within EndChild()
bool WithinFrameScope; // Set by NewFrame(), cleared by EndFrame()
bool WithinFrameScopeWithImplicitWindow; // Set by NewFrame(), cleared by EndFrame() when the implicit debug window has been pushed
bool GcCompactAll; // Request full GC
bool TestEngineHookItems; // Will call test engine hooks: ImGuiTestEngineHook_ItemAdd(), ImGuiTestEngineHook_ItemInfo(), ImGuiTestEngineHook_Log()
void* TestEngine; // Test engine user data
char ContextName[16]; // Storage for a context name (to facilitate debugging multi-context setups)
// Inputs
ImVector<ImGuiInputEvent> InputEventsQueue; // Input events which will be trickled/written into IO structure.
@ -2437,11 +2451,11 @@ struct ImGuiContext
bool ActiveIdHasBeenEditedBefore; // Was the value associated to the widget Edited over the course of the Active state.
bool ActiveIdHasBeenEditedThisFrame;
bool ActiveIdFromShortcut;
ImS8 ActiveIdMouseButton;
ImGuiID ActiveIdDisabledId; // When clicking a disabled item we set ActiveId=window->MoveId to avoid interference with widget code. Actual item ID is stored here.
int ActiveIdMouseButton : 8;
ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior)
ImGuiWindow* ActiveIdWindow;
ImGuiInputSource ActiveIdSource; // Activating source: ImGuiInputSource_Mouse OR ImGuiInputSource_Keyboard OR ImGuiInputSource_Gamepad
ImGuiWindow* ActiveIdWindow;
ImGuiID ActiveIdPreviousFrame;
ImGuiDeactivatedItemData DeactivatedItemData;
ImGuiDataTypeStorage ActiveIdValueOnActivation; // Backup of initial value at the time of activation. ONLY SET BY SPECIFIC WIDGETS: DragXXX and SliderXXX.
@ -2471,6 +2485,7 @@ struct ImGuiContext
ImGuiLastItemData LastItemData; // Storage for last submitted item (setup by ItemAdd)
ImGuiNextWindowData NextWindowData; // Storage for SetNextWindow** functions
bool DebugShowGroupRects;
bool GcCompactAll; // Request full GC
// Shared stacks
ImGuiCol DebugFlashStyleColorIdx; // (Keep close to ColorStack to share cache line)
@ -2516,7 +2531,7 @@ struct ImGuiContext
float NavHighlightActivatedTimer;
ImGuiID NavNextActivateId; // Set by ActivateItemByID(), queued until next frame.
ImGuiActivateFlags NavNextActivateFlags;
ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS CAN ONLY BE ImGuiInputSource_Keyboard or ImGuiInputSource_Mouse
ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS CAN ONLY BE ImGuiInputSource_Keyboard or ImGuiInputSource_Gamepad
ImGuiSelectionUserData NavLastValidSelectionUserData; // Last valid data passed to SetNextItemSelectionUser(), or -1. For current window. Not reset when focusing an item that doesn't have selection data.
ImS8 NavCursorHideFrames;
//ImGuiID NavActivateInputId; // Removed in 1.89.4 (July 2023). This is now part of g.NavActivateId and sets g.NavActivateFlags |= ImGuiActivateFlags_PreferInput. See commit c9a53aa74, issue #5606.
@ -2553,13 +2568,13 @@ struct ImGuiContext
bool NavJustMovedToIsTabbing; // Copy of ImGuiNavMoveFlags_IsTabbing. Maybe we should store whole flags.
bool NavJustMovedToHasSelectionData; // Copy of move result's ItemFlags & ImGuiItemFlags_HasSelectionUserData). Maybe we should just store ImGuiNavItemData.
// Navigation: Windowing (CTRL+TAB for list, or Menu button + keys or directional pads to move/resize)
bool ConfigNavWindowingWithGamepad; // = true. Enable CTRL+TAB by holding ImGuiKey_GamepadFaceLeft (== ImGuiKey_NavGamepadMenu). When false, the button may still be used to toggle Menu layer.
// Navigation: Windowing (Ctrl+Tab for list, or Menu button + keys or directional pads to move/resize)
bool ConfigNavWindowingWithGamepad; // = true. Enable Ctrl+Tab by holding ImGuiKey_GamepadFaceLeft (== ImGuiKey_NavGamepadMenu). When false, the button may still be used to toggle Menu layer.
ImGuiKeyChord ConfigNavWindowingKeyNext; // = ImGuiMod_Ctrl | ImGuiKey_Tab (or ImGuiMod_Super | ImGuiKey_Tab on OS X). For reconfiguration (see #4828)
ImGuiKeyChord ConfigNavWindowingKeyPrev; // = ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Tab (or ImGuiMod_Super | ImGuiMod_Shift | ImGuiKey_Tab on OS X)
ImGuiWindow* NavWindowingTarget; // Target window when doing CTRL+Tab (or Pad Menu + FocusPrev/Next), this window is temporarily displayed top-most!
ImGuiWindow* NavWindowingTarget; // Target window when doing Ctrl+Tab (or Pad Menu + FocusPrev/Next), this window is temporarily displayed top-most!
ImGuiWindow* NavWindowingTargetAnim; // Record of last valid NavWindowingTarget until DimBgRatio and NavWindowingHighlightAlpha becomes 0.0f, so the fade-out can stay on it.
ImGuiWindow* NavWindowingListWindow; // Internal window actually listing the CTRL+Tab contents
ImGuiWindow* NavWindowingListWindow; // Internal window actually listing the Ctrl+Tab contents
float NavWindowingTimer;
float NavWindowingHighlightAlpha;
ImGuiInputSource NavWindowingInputSource;
@ -2569,7 +2584,7 @@ struct ImGuiContext
ImVec2 NavWindowingAccumDeltaSize;
// Render
float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list)
float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and Ctrl+Tab list)
// Drag and Drop
bool DragDropActive;
@ -2582,7 +2597,9 @@ struct ImGuiContext
ImRect DragDropTargetRect; // Store rectangle of current target candidate (we favor small targets when overlapping)
ImRect DragDropTargetClipRect; // Store ClipRect at the time of item's drawing
ImGuiID DragDropTargetId;
ImGuiDragDropFlags DragDropAcceptFlags;
ImGuiID DragDropTargetFullViewport;
ImGuiDragDropFlags DragDropAcceptFlagsCurr;
ImGuiDragDropFlags DragDropAcceptFlagsPrev;
float DragDropAcceptIdCurrRectSurface; // Target item surface (we resolve overlapping targets by prioritizing the smaller surface)
ImGuiID DragDropAcceptIdCurr; // Target item id (set at the time of accepting the payload)
ImGuiID DragDropAcceptIdPrev; // Target item id from previous frame (we need to store this to allow for overlapping drag and drop targets)
@ -2636,7 +2653,7 @@ struct ImGuiContext
ImGuiInputTextDeactivatedState InputTextDeactivatedState;
ImFontBaked InputTextPasswordFontBackupBaked;
ImFontFlags InputTextPasswordFontBackupFlags;
ImGuiID TempInputId; // Temporary text input when CTRL+clicking on a slider, etc.
ImGuiID TempInputId; // Temporary text input when using Ctrl+Click on a slider, etc.
ImGuiDataTypeStorage DataTypeZeroValue; // 0 for all data types
int BeginMenuDepth;
int BeginComboDepth;
@ -2691,14 +2708,14 @@ struct ImGuiContext
// Capture/Logging
bool LogEnabled; // Currently capturing
bool LogLineFirstItem;
ImGuiLogFlags LogFlags; // Capture flags/type
ImGuiWindow* LogWindow;
ImFileHandle LogFile; // If != NULL log to stdout/ file
ImGuiTextBuffer LogBuffer; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators.
const char* LogNextPrefix;
const char* LogNextPrefix; // See comment in LogSetNextTextDecoration(): doesn't copy underlying data, use carefully!
const char* LogNextSuffix;
float LogLinePosY;
bool LogLineFirstItem;
int LogDepthRef;
int LogDepthToExpand;
int LogDepthToExpandDefault; // Default/stored value for LogDepthMaxExpand if not specified in the LogXXX function call.
@ -2714,7 +2731,7 @@ struct ImGuiContext
// Debug Tools
// (some of the highly frequently used data are interleaved in other structures above: DebugBreakXXX fields, DebugHookIdInfo, DebugLocateId etc.)
int DebugDrawIdConflictsCount; // Locked count (preserved when holding CTRL)
int DebugDrawIdConflictsCount; // Locked count (preserved when holding Ctrl)
ImGuiDebugLogFlags DebugLogFlags;
ImGuiTextBuffer DebugLogBuf;
ImGuiTextIndex DebugLogIndex;
@ -2731,6 +2748,7 @@ struct ImGuiContext
float DebugFlashStyleColorTime;
ImVec4 DebugFlashStyleColorBackup;
ImGuiMetricsConfig DebugMetricsConfig;
ImGuiDebugItemPathQuery DebugItemPathQuery;
ImGuiIDStackTool DebugIDStackTool;
ImGuiDebugAllocInfo DebugAllocInfo;
ImGuiDockNode* DebugHoveredDockNode; // Hovered dock node.
@ -2751,6 +2769,7 @@ struct ImGuiContext
char TempKeychordName[64];
ImGuiContext(ImFontAtlas* shared_font_atlas);
~ImGuiContext();
};
//-----------------------------------------------------------------------------
@ -2876,13 +2895,14 @@ struct IMGUI_API ImGuiWindow
short BeginOrderWithinParent; // Begin() order within immediate parent window, if we are a child window. Otherwise 0.
short BeginOrderWithinContext; // Begin() order within entire imgui context. This is mostly used for debugging submission order related issues.
short FocusOrder; // Order within WindowsFocusOrder[], altered when windows are focused.
ImGuiDir AutoPosLastDirection;
ImS8 AutoFitFramesX, AutoFitFramesY;
bool AutoFitOnlyGrows;
ImGuiDir AutoPosLastDirection;
ImS8 HiddenFramesCanSkipItems; // Hide the window for N frames
ImS8 HiddenFramesCannotSkipItems; // Hide the window for N frames while allowing items to be submitted so we can measure their size
ImS8 HiddenFramesForRenderOnly; // Hide the window until frame N at Render() time only
ImS8 DisableInputsFrames; // Disable window interactions for N frames
ImGuiWindowBgClickFlags BgClickFlags : 8; // Configure behavior of click+dragging on window bg/void or over items. Default sets by io.ConfigWindowsMoveFromTitleBarOnly. If you use this please report in #3379.
ImGuiCond SetWindowPosAllowFlags : 8; // store acceptable condition flags for SetNextWindowPos() use.
ImGuiCond SetWindowSizeAllowFlags : 8; // store acceptable condition flags for SetNextWindowSize() use.
ImGuiCond SetWindowCollapsedAllowFlags : 8; // store acceptable condition flags for SetNextWindowCollapsed() use.
@ -2925,7 +2945,7 @@ struct IMGUI_API ImGuiWindow
ImGuiWindow* RootWindowDockTree; // Point to ourself or first ancestor that is not a child window. Cross through dock nodes.
ImGuiWindow* RootWindowForTitleBarHighlight; // Point to ourself or first ancestor which will display TitleBgActive color when this window is active.
ImGuiWindow* RootWindowForNav; // Point to ourself or first ancestor which doesn't have the NavFlattened flag.
ImGuiWindow* ParentWindowForFocusRoute; // Set to manual link a window to its logical parent so that Shortcut() chain are honoerd (e.g. Tool linked to Document)
ImGuiWindow* ParentWindowForFocusRoute; // Set to manual link a window to its logical parent so that Shortcut() chain are honored (e.g. Tool linked to Document)
ImGuiWindow* NavLastChildNavWindow; // When going to the menu bar, we remember the child window we came from. (This could probably be made implicit if we kept g.Windows sorted by last focused including child window.)
ImGuiID NavLastIds[ImGuiNavLayer_COUNT]; // Last known NavId for this window, per layer (0/1)
@ -2963,7 +2983,7 @@ public:
ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight)); }
ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight; return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight); }
// [Obsolete] ImGuiWindow::CalcFontSize() was removed in 1.92.x because error-prone/misleading. You can use window->FontRefSize for a copy of g.FontSize at the time of the last Begin() call for this window.
// [OBSOLETE] ImGuiWindow::CalcFontSize() was removed in 1.92.0 because error-prone/misleading. You can use window->FontRefSize for a copy of g.FontSize at the time of the last Begin() call for this window.
//float CalcFontSize() const { ImGuiContext& g = *Ctx; return g.FontSizeBase * FontWindowScale * FontDpiScale * FontWindowScaleParents;
};
@ -3018,7 +3038,7 @@ struct IMGUI_API ImGuiTabBar
ImGuiID ID; // Zero for tab-bars used by docking
ImGuiID SelectedTabId; // Selected tab/window
ImGuiID NextSelectedTabId; // Next selected tab/window. Will also trigger a scrolling animation
ImGuiID VisibleTabId; // Can occasionally be != SelectedTabId (e.g. when previewing contents for CTRL+TAB preview)
ImGuiID VisibleTabId; // Can occasionally be != SelectedTabId (e.g. when previewing contents for Ctrl+Tab preview)
int CurrFrameVisible;
int PrevFrameVisible;
ImRect BarRect;
@ -3258,7 +3278,7 @@ struct IMGUI_API ImGuiTable
bool IsContextPopupOpen; // Set when default context menu is open (also see: ContextPopupColumn, InstanceInteracted).
bool DisableDefaultContextMenu; // Disable default context menu. You may submit your own using TableBeginContextMenuPopup()/EndPopup()
bool IsSettingsRequestLoad;
bool IsSettingsDirty; // Set when table settings have changed and needs to be reported into ImGuiTableSetttings data.
bool IsSettingsDirty; // Set when table settings have changed and needs to be reported into ImGuiTableSettings data.
bool IsDefaultDisplayOrder; // Set when display order is unchanged from default (DisplayOrder contains 0...Count-1)
bool IsResetAllRequest;
bool IsResetDisplayOrderRequest;
@ -3282,6 +3302,7 @@ struct IMGUI_API ImGuiTable
// sizeof() ~ 136 bytes.
struct IMGUI_API ImGuiTableTempData
{
ImGuiID WindowID; // Shortcut to g.Tables[TableIndex]->OuterWindow->ID.
int TableIndex; // Index in g.Tables.Buf[] pool
float LastTimeActive; // Last timestamp this structure was used
float AngledHeadersExtraWidth; // Used in EndTable()
@ -3362,6 +3383,7 @@ namespace ImGui
IMGUI_API void UpdateWindowSkipRefresh(ImGuiWindow* window);
IMGUI_API ImVec2 CalcWindowNextAutoFitSize(ImGuiWindow* window);
IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent, bool popup_hierarchy, bool dock_hierarchy);
IMGUI_API bool IsWindowInBeginStack(ImGuiWindow* window);
IMGUI_API bool IsWindowWithinBeginStackOf(ImGuiWindow* window, ImGuiWindow* potential_parent);
IMGUI_API bool IsWindowAbove(ImGuiWindow* potential_above, ImGuiWindow* potential_below);
IMGUI_API bool IsWindowNavFocusable(ImGuiWindow* window);
@ -3621,7 +3643,7 @@ namespace ImGui
// Legacy functions use ImGuiKeyOwner_Any meaning that they typically ignore ownership, unless a call to SetKeyOwner() explicitly used ImGuiInputFlags_LockThisFrame or ImGuiInputFlags_LockUntilRelease.
// - Binding generators may want to ignore those for now, or suffix them with Ex() until we decide if this gets moved into public API.
IMGUI_API bool IsKeyDown(ImGuiKey key, ImGuiID owner_id);
IMGUI_API bool IsKeyPressed(ImGuiKey key, ImGuiInputFlags flags, ImGuiID owner_id = 0); // Important: when transitioning from old to new IsKeyPressed(): old API has "bool repeat = true", so would default to repeat. New API requiress explicit ImGuiInputFlags_Repeat.
IMGUI_API bool IsKeyPressed(ImGuiKey key, ImGuiInputFlags flags, ImGuiID owner_id = 0); // Important: when transitioning from old to new IsKeyPressed(): old API has "bool repeat = true", so would default to repeat. New API requires explicit ImGuiInputFlags_Repeat.
IMGUI_API bool IsKeyReleased(ImGuiKey key, ImGuiID owner_id);
IMGUI_API bool IsKeyChordPressed(ImGuiKeyChord key_chord, ImGuiInputFlags flags, ImGuiID owner_id = 0);
IMGUI_API bool IsMouseDown(ImGuiMouseButton button, ImGuiID owner_id);
@ -3718,9 +3740,11 @@ namespace ImGui
// Drag and Drop
IMGUI_API bool IsDragDropActive();
IMGUI_API bool BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id);
IMGUI_API bool BeginDragDropTargetViewport(ImGuiViewport* viewport, const ImRect* p_bb = NULL);
IMGUI_API void ClearDragDrop();
IMGUI_API bool IsDragDropPayloadBeingAccepted();
IMGUI_API void RenderDragDropTargetRect(const ImRect& bb, const ImRect& item_clip_rect);
IMGUI_API void RenderDragDropTargetRectForItem(const ImRect& bb);
IMGUI_API void RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb);
// Typing-Select API
// (provide Windows Explorer style "select items by typing partial name" + "cycle through items by typing same letter" feature)
@ -4144,6 +4168,7 @@ IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildDestroy(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildMain(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildSetupFontLoader(ImFontAtlas* atlas, const ImFontLoader* font_loader);
IMGUI_API void ImFontAtlasBuildNotifySetFont(ImFontAtlas* atlas, ImFont* old_font, ImFont* new_font);
IMGUI_API void ImFontAtlasBuildUpdatePointers(ImFontAtlas* atlas);
IMGUI_API void ImFontAtlasBuildRenderBitmapFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char);
IMGUI_API void ImFontAtlasBuildClear(ImFontAtlas* atlas); // Clear output and custom rects
@ -4221,7 +4246,7 @@ extern const char* ImGuiTestEngine_FindItemDebugLabel(ImGuiContext* ctx, ImGuiI
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) if (g.TestEngineHookItems) ImGuiTestEngineHook_ItemInfo(&g, _ID, _LABEL, _FLAGS) // Register item label and status flags (optional)
#define IMGUI_TEST_ENGINE_LOG(_FMT,...) ImGuiTestEngineHook_Log(&g, _FMT, __VA_ARGS__) // Custom log entry from user land into test log
#else
#define IMGUI_TEST_ENGINE_ITEM_ADD(_BB,_ID) ((void)0)
#define IMGUI_TEST_ENGINE_ITEM_ADD(_ID,_BB,_ITEM_DATA) ((void)0)
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) ((void)g)
#endif

View File

@ -5,7 +5,8 @@
// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000 + #6783)
// - Added name to struct or it may be forward declared in our code.
// - Added UTF-8 support (see https://github.com/nothings/stb/issues/188 + https://github.com/ocornut/imgui/pull/7925)
// Grep for [DEAR IMGUI] to find the changes.
// - Changed STB_TEXTEDIT_INSERTCHARS() to return inserted count (instead of 0/1 bool), allowing partial insertion.
// Grep for [DEAR IMGUI] to find some changes.
// - Also renamed macros used or defined outside of IMSTB_TEXTEDIT_IMPLEMENTATION block from STB_TEXTEDIT_* to IMSTB_TEXTEDIT_*
// stb_textedit.h - v1.14 - public domain - Sean Barrett
@ -39,6 +40,7 @@
//
// VERSION HISTORY
//
// !!!! (2025-10-23) changed STB_TEXTEDIT_INSERTCHARS() to return inserted count (instead of 0/1 bool), allowing partial insertion.
// 1.14 (2021-07-11) page up/down, various fixes
// 1.13 (2019-02-07) fix bug in undo size management
// 1.12 (2018-01-29) user can change STB_TEXTEDIT_KEYTYPE, fix redo to avoid crash
@ -147,7 +149,8 @@
// as manually wordwrapping for end-of-line positioning
//
// STB_TEXTEDIT_DELETECHARS(obj,i,n) delete n characters starting at i
// STB_TEXTEDIT_INSERTCHARS(obj,i,c*,n) insert n characters at i (pointed to by STB_TEXTEDIT_CHARTYPE*)
// STB_TEXTEDIT_INSERTCHARS(obj,i,c*,n) try to insert n characters at i (pointed to by STB_TEXTEDIT_CHARTYPE*)
// returns number of characters actually inserted. [DEAR IMGUI]
//
// STB_TEXTEDIT_K_SHIFT a power of two that is or'd in to a keyboard input to represent the shift key
//
@ -775,7 +778,8 @@ static int stb_textedit_paste_internal(IMSTB_TEXTEDIT_STRING *str, STB_TexteditS
stb_textedit_clamp(str, state);
stb_textedit_delete_selection(str,state);
// try to insert the characters
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, len)) {
len = STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, len);
if (len) {
stb_text_makeundo_insert(state, state->cursor, len);
state->cursor += len;
state->has_preferred_x = 0;
@ -800,13 +804,15 @@ static void stb_textedit_text(IMSTB_TEXTEDIT_STRING* str, STB_TexteditState* sta
if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) {
stb_text_makeundo_replace(str, state, state->cursor, 1, 1);
STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1);
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, text_len)) {
text_len = STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, text_len);
if (text_len) {
state->cursor += text_len;
state->has_preferred_x = 0;
}
} else {
stb_textedit_delete_selection(str, state); // implicitly clamps
if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, text_len)) {
text_len = STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, text_len);
if (text_len) {
stb_text_makeundo_insert(state, state->cursor, text_len);
state->cursor += text_len;
state->has_preferred_x = 0;
@ -1352,7 +1358,7 @@ static void stb_text_undo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
// check type of recorded action:
if (u.insert_length) {
// easy case: was a deletion, so we need to insert n characters
STB_TEXTEDIT_INSERTCHARS(str, u.where, &s->undo_char[u.char_storage], u.insert_length);
u.insert_length = STB_TEXTEDIT_INSERTCHARS(str, u.where, &s->undo_char[u.char_storage], u.insert_length);
s->undo_char_point -= u.insert_length;
}
@ -1403,7 +1409,7 @@ static void stb_text_redo(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state)
if (r.insert_length) {
// easy case: need to insert n characters
STB_TEXTEDIT_INSERTCHARS(str, r.where, &s->undo_char[r.char_storage], r.insert_length);
r.insert_length = STB_TEXTEDIT_INSERTCHARS(str, r.where, &s->undo_char[r.char_storage], r.insert_length);
s->redo_char_point += r.insert_length;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
// dear imgui, v1.92.3
// dear imgui, v1.92.5
// (demo code)
// Help:
@ -59,9 +59,9 @@
// Because we can't assume anything about your support of maths operators, we cannot use them in imgui_demo.cpp.
// Navigating this file:
// - In Visual Studio: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments.
// - In Visual Studio: Ctrl+Comma ("Edit.GoToAll") can follow symbols inside comments, whereas Ctrl+F12 ("Edit.GoToImplementation") cannot.
// - In Visual Studio w/ Visual Assist installed: Alt+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
// - In VS Code, CLion, etc.: Ctrl+Click can follow symbols inside comments.
// - You can search/grep for all sections listed in the index to find the section.
/*
@ -300,7 +300,7 @@ extern ImGuiDemoMarkerCallback GImGuiDemoMarkerCallback;
extern void* GImGuiDemoMarkerCallbackUserData;
ImGuiDemoMarkerCallback GImGuiDemoMarkerCallback = NULL;
void* GImGuiDemoMarkerCallbackUserData = NULL;
#define IMGUI_DEMO_MARKER(section) do { if (GImGuiDemoMarkerCallback != NULL) GImGuiDemoMarkerCallback(__FILE__, __LINE__, section, GImGuiDemoMarkerCallbackUserData); } while (0)
#define IMGUI_DEMO_MARKER(section) do { if (GImGuiDemoMarkerCallback != NULL) GImGuiDemoMarkerCallback("imgui_demo.cpp", __LINE__, section, GImGuiDemoMarkerCallbackUserData); } while (0)
//-----------------------------------------------------------------------------
// [SECTION] Demo Window / ShowDemoWindow()
@ -533,6 +533,8 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::Indent();
ImGui::Checkbox("io.ConfigDockingNoSplit", &io.ConfigDockingNoSplit);
ImGui::SameLine(); HelpMarker("Simplified docking mode: disable window splitting, so docking is limited to merging multiple windows together into tab-bars.");
ImGui::Checkbox("io.ConfigDockingNoDockingOver", &io.ConfigDockingNoDockingOver);
ImGui::SameLine(); HelpMarker("Simplified docking mode: disable window merging into a same tab-bar, so docking is limited to splitting windows.");
ImGui::Checkbox("io.ConfigDockingWithShift", &io.ConfigDockingWithShift);
ImGui::SameLine(); HelpMarker("Enable docking when holding Shift only (allow to drop in wider space, reduce visual noise)");
ImGui::Checkbox("io.ConfigDockingAlwaysTabBar", &io.ConfigDockingAlwaysTabBar);
@ -551,12 +553,12 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::Checkbox("io.ConfigViewportsNoAutoMerge", &io.ConfigViewportsNoAutoMerge);
ImGui::SameLine(); HelpMarker("Set to make all floating imgui windows always create their own viewport. Otherwise, they are merged into the main host viewports when overlapping it.");
ImGui::Checkbox("io.ConfigViewportsNoTaskBarIcon", &io.ConfigViewportsNoTaskBarIcon);
ImGui::SameLine(); HelpMarker("Toggling this at runtime is normally unsupported (most platform backends won't refresh the task bar icon state right away).");
ImGui::SameLine(); HelpMarker("(note: some platform backends may not reflect a change of this value for existing viewports, and may need the viewport to be recreated)");
ImGui::Checkbox("io.ConfigViewportsNoDecoration", &io.ConfigViewportsNoDecoration);
ImGui::SameLine(); HelpMarker("Toggling this at runtime is normally unsupported (most platform backends won't refresh the decoration right away).");
ImGui::SameLine(); HelpMarker("(note: some platform backends may not reflect a change of this value for existing viewports, and may need the viewport to be recreated)");
ImGui::Checkbox("io.ConfigViewportsNoDefaultParent", &io.ConfigViewportsNoDefaultParent);
ImGui::SameLine(); HelpMarker("Toggling this at runtime is normally unsupported (most platform backends won't refresh the parenting right away).");
ImGui::Checkbox("io.ConfigViewportPlatformFocusSetsImGuiFocus", &io.ConfigViewportPlatformFocusSetsImGuiFocus);
ImGui::SameLine(); HelpMarker("(note: some platform backends may not reflect a change of this value for existing viewports, and may need the viewport to be recreated)");
ImGui::Checkbox("io.ConfigViewportsPlatformFocusSetsImGuiFocus", &io.ConfigViewportsPlatformFocusSetsImGuiFocus);
ImGui::SameLine(); HelpMarker("When a platform window is focused (e.g. using Alt+Tab, clicking Platform Title Bar), apply corresponding focus on imgui windows (may clear focus/active id from imgui windows location in other platform windows). In principle this is better enabled but we provide an opt-out, because some Linux window managers tend to eagerly focus windows (e.g. on mouse hover, or even a simple window pos/size change).");
ImGui::Unindent();
}
@ -572,7 +574,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::SameLine(); HelpMarker("Enable resizing of windows from their edges and from the lower-left corner.\nThis requires ImGuiBackendFlags_HasMouseCursors for better mouse cursor feedback.");
ImGui::Checkbox("io.ConfigWindowsMoveFromTitleBarOnly", &io.ConfigWindowsMoveFromTitleBarOnly);
ImGui::Checkbox("io.ConfigWindowsCopyContentsWithCtrlC", &io.ConfigWindowsCopyContentsWithCtrlC); // [EXPERIMENTAL]
ImGui::SameLine(); HelpMarker("*EXPERIMENTAL* CTRL+C copy the contents of focused window into the clipboard.\n\nExperimental because:\n- (1) has known issues with nested Begin/End pairs.\n- (2) text output quality varies.\n- (3) text output is in submission order rather than spatial order.");
ImGui::SameLine(); HelpMarker("*EXPERIMENTAL* Ctrl+C copy the contents of focused window into the clipboard.\n\nExperimental because:\n- (1) has known issues with nested Begin/End pairs.\n- (2) text output quality varies.\n- (3) text output is in submission order rather than spatial order.");
ImGui::Checkbox("io.ConfigScrollbarScrollByPage", &io.ConfigScrollbarScrollByPage);
ImGui::SameLine(); HelpMarker("Enable scrolling page by page when clicking outside the scrollbar grab.\nWhen disabled, always scroll to clicked location.\nWhen enabled, Shift+Click scrolls to clicked location.");
@ -640,6 +642,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", &io.BackendFlags, ImGuiBackendFlags_HasSetMousePos);
ImGui::CheckboxFlags("io.BackendFlags: PlatformHasViewports", &io.BackendFlags, ImGuiBackendFlags_PlatformHasViewports);
ImGui::CheckboxFlags("io.BackendFlags: HasMouseHoveredViewport",&io.BackendFlags, ImGuiBackendFlags_HasMouseHoveredViewport);
ImGui::CheckboxFlags("io.BackendFlags: HasParentViewport", &io.BackendFlags, ImGuiBackendFlags_HasParentViewport);
ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", &io.BackendFlags, ImGuiBackendFlags_RendererHasVtxOffset);
ImGui::CheckboxFlags("io.BackendFlags: RendererHasTextures", &io.BackendFlags, ImGuiBackendFlags_RendererHasTextures);
ImGui::CheckboxFlags("io.BackendFlags: RendererHasViewports", &io.BackendFlags, ImGuiBackendFlags_RendererHasViewports);
@ -955,19 +958,20 @@ static void DemoWindowWidgetsBasic()
ImGui::SeparatorText("Inputs");
{
// To wire InputText() with std::string or any other custom string type,
// see the "Text Input > Resize Callback" section of this demo, and the misc/cpp/imgui_stdlib.h file.
// If you want to use InputText() with std::string or any custom dynamic string type:
// - For std::string: use the wrapper in misc/cpp/imgui_stdlib.h/.cpp
// - Otherwise, see the 'Dear ImGui Demo->Widgets->Text Input->Resize Callback' for using ImGuiInputTextFlags_CallbackResize.
IMGUI_DEMO_MARKER("Widgets/Basic/InputText");
static char str0[128] = "Hello, world!";
ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0));
ImGui::SameLine(); HelpMarker(
"USER:\n"
"Hold SHIFT or use mouse to select text.\n"
"CTRL+Left/Right to word jump.\n"
"CTRL+A or Double-Click to select all.\n"
"CTRL+X,CTRL+C,CTRL+V for clipboard.\n"
"CTRL+Z to undo, CTRL+Y/CTRL+SHIFT+Z to redo.\n"
"ESCAPE to revert.\n\n"
"Hold Shift or use mouse to select text.\n"
"Ctrl+Left/Right to word jump.\n"
"Ctrl+A or Double-Click to select all.\n"
"Ctrl+X,Ctrl+C,Ctrl+V for clipboard.\n"
"Ctrl+Z to undo, Ctrl+Y/Ctrl+Shift+Z to redo.\n"
"Escape to revert.\n\n"
"PROGRAMMER:\n"
"You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputText() "
"to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example (this is not demonstrated "
@ -1004,8 +1008,8 @@ static void DemoWindowWidgetsBasic()
ImGui::DragInt("drag int", &i1, 1);
ImGui::SameLine(); HelpMarker(
"Click and drag to edit value.\n"
"Hold SHIFT/ALT for faster/slower edit.\n"
"Double-click or CTRL+click to input value.");
"Hold Shift/Alt for faster/slower edit.\n"
"Double-Click or Ctrl+Click to input value.");
ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%d%%", ImGuiSliderFlags_AlwaysClamp);
ImGui::DragInt("drag int wrap 100..200", &i3, 1, 100, 200, "%d", ImGuiSliderFlags_WrapAround);
@ -1021,7 +1025,7 @@ static void DemoWindowWidgetsBasic()
IMGUI_DEMO_MARKER("Widgets/Basic/SliderInt, SliderFloat");
static int i1 = 0;
ImGui::SliderInt("slider int", &i1, -1, 3);
ImGui::SameLine(); HelpMarker("CTRL+click to input value.");
ImGui::SameLine(); HelpMarker("Ctrl+Click to input value.");
static float f1 = 0.123f, f2 = 0.0f;
ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f");
@ -1039,7 +1043,7 @@ static void DemoWindowWidgetsBasic()
static int elem = Element_Fire;
const char* elems_names[Element_COUNT] = { "Fire", "Earth", "Air", "Water" };
const char* elem_name = (elem >= 0 && elem < Element_COUNT) ? elems_names[elem] : "Unknown";
ImGui::SliderInt("slider enum", &elem, 0, Element_COUNT - 1, elem_name); // Use ImGuiSliderFlags_NoInput flag to disable CTRL+Click here.
ImGui::SliderInt("slider enum", &elem, 0, Element_COUNT - 1, elem_name); // Use ImGuiSliderFlags_NoInput flag to disable Ctrl+Click here.
ImGui::SameLine(); HelpMarker("Using the format string parameter to display a name instead of the underlying integer.");
}
@ -1053,8 +1057,8 @@ static void DemoWindowWidgetsBasic()
ImGui::SameLine(); HelpMarker(
"Click on the color square to open a color picker.\n"
"Click and hold to use drag and drop.\n"
"Right-click on the color square to show options.\n"
"CTRL+click on individual component to input value.\n");
"Right-Click on the color square to show options.\n"
"Ctrl+Click on individual component to input value.\n");
ImGui::ColorEdit4("color 2", col2);
}
@ -1172,7 +1176,7 @@ static void DemoWindowWidgetsColorAndPickers()
ImGui::Text("Color widget:");
ImGui::SameLine(); HelpMarker(
"Click on the color square to open a color picker.\n"
"CTRL+click on individual component to input value.\n");
"Ctrl+Click on individual component to input value.\n");
ImGui::ColorEdit3("MyColor##1", (float*)&color, base_flags);
IMGUI_DEMO_MARKER("Widgets/Color/ColorEdit (HSV, with Alpha)");
@ -1504,7 +1508,7 @@ static void DemoWindowWidgetsDataTypes()
ImGui::Checkbox("Clamp integers to 0..50", &drag_clamp);
ImGui::SameLine(); HelpMarker(
"As with every widget in dear imgui, we never modify values unless there is a user interaction.\n"
"You can override the clamping limits by using CTRL+Click to input a value.");
"You can override the clamping limits by using Ctrl+Click to input a value.");
ImGui::DragScalar("drag s8", ImGuiDataType_S8, &s8_v, drag_speed, drag_clamp ? &s8_zero : NULL, drag_clamp ? &s8_fifty : NULL);
ImGui::DragScalar("drag u8", ImGuiDataType_U8, &u8_v, drag_speed, drag_clamp ? &u8_zero : NULL, drag_clamp ? &u8_fifty : NULL, "%u ms");
ImGui::DragScalar("drag s16", ImGuiDataType_S16, &s16_v, drag_speed, drag_clamp ? &s16_zero : NULL, drag_clamp ? &s16_fifty : NULL);
@ -1764,7 +1768,7 @@ static void DemoWindowWidgetsDragsAndSliders()
static ImGuiSliderFlags flags = ImGuiSliderFlags_None;
ImGui::CheckboxFlags("ImGuiSliderFlags_AlwaysClamp", &flags, ImGuiSliderFlags_AlwaysClamp);
ImGui::CheckboxFlags("ImGuiSliderFlags_ClampOnInput", &flags, ImGuiSliderFlags_ClampOnInput);
ImGui::SameLine(); HelpMarker("Clamp value to min/max bounds when input manually with CTRL+Click. By default CTRL+Click allows going out of bounds.");
ImGui::SameLine(); HelpMarker("Clamp value to min/max bounds when input manually with Ctrl+Click. By default Ctrl+Click allows going out of bounds.");
ImGui::CheckboxFlags("ImGuiSliderFlags_ClampZeroRange", &flags, ImGuiSliderFlags_ClampZeroRange);
ImGui::SameLine(); HelpMarker("Clamp even if min==max==0.0f. Otherwise DragXXX functions don't clamp.");
ImGui::CheckboxFlags("ImGuiSliderFlags_Logarithmic", &flags, ImGuiSliderFlags_Logarithmic);
@ -1772,7 +1776,7 @@ static void DemoWindowWidgetsDragsAndSliders()
ImGui::CheckboxFlags("ImGuiSliderFlags_NoRoundToFormat", &flags, ImGuiSliderFlags_NoRoundToFormat);
ImGui::SameLine(); HelpMarker("Disable rounding underlying value to match precision of the format string (e.g. %.3f values are rounded to those 3 digits).");
ImGui::CheckboxFlags("ImGuiSliderFlags_NoInput", &flags, ImGuiSliderFlags_NoInput);
ImGui::SameLine(); HelpMarker("Disable CTRL+Click or Enter key allowing to input text directly into the widget.");
ImGui::SameLine(); HelpMarker("Disable Ctrl+Click or Enter key allowing to input text directly into the widget.");
ImGui::CheckboxFlags("ImGuiSliderFlags_NoSpeedTweaks", &flags, ImGuiSliderFlags_NoSpeedTweaks);
ImGui::SameLine(); HelpMarker("Disable keyboard modifiers altering tweak speed. Useful if you want to alter tweak speed yourself based on your own logic.");
ImGui::CheckboxFlags("ImGuiSliderFlags_WrapAround", &flags, ImGuiSliderFlags_WrapAround);
@ -2730,6 +2734,10 @@ static void DemoWindowWidgetsSelectionAndMultiSelect(ImGuiDemoWindowData* demo_d
{
HelpMarker("Selections can be built using Selectable(), TreeNode() or other widgets. Selection state is owned by application code/data.");
ImGui::BulletText("Wiki page:");
ImGui::SameLine();
ImGui::TextLinkOpenURL("imgui/wiki/Multi-Select", "https://github.com/ocornut/imgui/wiki/Multi-Select");
// Without any fancy API: manage single-selection yourself.
IMGUI_DEMO_MARKER("Widgets/Selection State/Single-Select");
if (ImGui::TreeNode("Single-Select"))
@ -2746,11 +2754,11 @@ static void DemoWindowWidgetsSelectionAndMultiSelect(ImGuiDemoWindowData* demo_d
}
// Demonstrate implementation a most-basic form of multi-selection manually
// This doesn't support the SHIFT modifier which requires BeginMultiSelect()!
// This doesn't support the Shift modifier which requires BeginMultiSelect()!
IMGUI_DEMO_MARKER("Widgets/Selection State/Multi-Select (manual/simplified, without BeginMultiSelect)");
if (ImGui::TreeNode("Multi-Select (manual/simplified, without BeginMultiSelect)"))
{
HelpMarker("Hold CTRL and click to select multiple items.");
HelpMarker("Hold Ctrl and Click to select multiple items.");
static bool selection[5] = { false, false, false, false, false };
for (int n = 0; n < 5; n++)
{
@ -2758,7 +2766,7 @@ static void DemoWindowWidgetsSelectionAndMultiSelect(ImGuiDemoWindowData* demo_d
sprintf(buf, "Object %d", n);
if (ImGui::Selectable(buf, selection[n]))
{
if (!ImGui::GetIO().KeyCtrl) // Clear selection when CTRL is not held
if (!ImGui::GetIO().KeyCtrl) // Clear selection when Ctrl is not held
memset(selection, 0, sizeof(selection));
selection[n] ^= 1; // Toggle current item
}
@ -2767,7 +2775,7 @@ static void DemoWindowWidgetsSelectionAndMultiSelect(ImGuiDemoWindowData* demo_d
}
// Demonstrate handling proper multi-selection using the BeginMultiSelect/EndMultiSelect API.
// SHIFT+Click w/ CTRL and other standard features are supported.
// Shift+Click w/ Ctrl and other standard features are supported.
// We use the ImGuiSelectionBasicStorage helper which you may freely reimplement.
IMGUI_DEMO_MARKER("Widgets/Selection State/Multi-Select");
if (ImGui::TreeNode("Multi-Select"))
@ -2776,7 +2784,7 @@ static void DemoWindowWidgetsSelectionAndMultiSelect(ImGuiDemoWindowData* demo_d
ImGui::BulletText("Keyboard navigation (arrows, page up/down, home/end, space).");
ImGui::BulletText("Ctrl modifier to preserve and toggle selection.");
ImGui::BulletText("Shift modifier for range selection.");
ImGui::BulletText("CTRL+A to select all.");
ImGui::BulletText("Ctrl+A to select all.");
ImGui::BulletText("Escape to clear selection.");
ImGui::BulletText("Click and drag to box-select.");
ImGui::Text("Tip: Use 'Demo->Tools->Debug Log->Selection' to see selection requests as they happen.");
@ -3263,6 +3271,7 @@ static void DemoWindowWidgetsSelectionAndMultiSelect(ImGuiDemoWindowData* demo_d
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoAutoSelect", &flags, ImGuiMultiSelectFlags_NoAutoSelect);
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoAutoClear", &flags, ImGuiMultiSelectFlags_NoAutoClear);
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoAutoClearOnReselect", &flags, ImGuiMultiSelectFlags_NoAutoClearOnReselect);
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoSelectOnRightClick", &flags, ImGuiMultiSelectFlags_NoSelectOnRightClick);
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_BoxSelect1d", &flags, ImGuiMultiSelectFlags_BoxSelect1d);
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_BoxSelect2d", &flags, ImGuiMultiSelectFlags_BoxSelect2d);
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_BoxSelectNoScroll", &flags, ImGuiMultiSelectFlags_BoxSelectNoScroll);
@ -3774,8 +3783,10 @@ static void DemoWindowWidgetsTextInput()
IMGUI_DEMO_MARKER("Widgets/Text Input/Multi-line Text Input");
if (ImGui::TreeNode("Multi-line Text Input"))
{
// Note: we are using a fixed-sized buffer for simplicity here. See ImGuiInputTextFlags_CallbackResize
// and the code in misc/cpp/imgui_stdlib.h for how to setup InputText() for dynamically resizing strings.
// WE ARE USING A FIXED-SIZE BUFFER FOR SIMPLICITY HERE.
// If you want to use InputText() with std::string or any custom dynamic string type:
// - For std::string: use the wrapper in misc/cpp/imgui_stdlib.h/.cpp
// - Otherwise, see the 'Dear ImGui Demo->Widgets->Text Input->Resize Callback' for using ImGuiInputTextFlags_CallbackResize.
static char text[1024 * 16] =
"/*\n"
" The Pentium F00F bug, shorthand for F0 0F C7 C8,\n"
@ -4147,7 +4158,7 @@ static void DemoWindowWidgetsTreeNodes()
{
HelpMarker(
"This is a more typical looking tree with selectable nodes.\n"
"Click to select, CTRL+Click to toggle, click on arrows or double-click to open.");
"Click to select, Ctrl+Click to toggle, click on arrows or double-click to open.");
static ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth;
static bool align_label_with_current_x_position = false;
static bool test_drag_and_drop = false;
@ -4234,7 +4245,7 @@ static void DemoWindowWidgetsTreeNodes()
// Update selection state
// (process outside of tree loop to avoid visual inconsistencies during the clicking frame)
if (ImGui::GetIO().KeyCtrl)
selection_mask ^= (1 << node_clicked); // CTRL+click to toggle
selection_mask ^= (1 << node_clicked); // Ctrl+Click to toggle
else //if (!(selection_mask & (1 << node_clicked))) // Depending on selection behavior you want, may want to preserve selection when clicking on item that is part of the selection
selection_mask = (1 << node_clicked); // Click to single-select
}
@ -4878,15 +4889,18 @@ static void DemoWindowLayout()
ImGui::Checkbox("Decoration", &enable_extra_decorations);
ImGui::PushItemWidth(ImGui::GetFontSize() * 10);
enable_track |= ImGui::DragInt("##item", &track_item, 0.25f, 0, 99, "Item = %d");
ImGui::SameLine();
ImGui::Checkbox("Track", &enable_track);
ImGui::PushItemWidth(100);
ImGui::SameLine(140); enable_track |= ImGui::DragInt("##item", &track_item, 0.25f, 0, 99, "Item = %d");
bool scroll_to_off = ImGui::Button("Scroll Offset");
ImGui::SameLine(140); scroll_to_off |= ImGui::DragFloat("##off", &scroll_to_off_px, 1.00f, 0, FLT_MAX, "+%.0f px");
bool scroll_to_off = ImGui::DragFloat("##off", &scroll_to_off_px, 1.00f, 0, FLT_MAX, "+%.0f px");
ImGui::SameLine();
scroll_to_off |= ImGui::Button("Scroll Offset");
bool scroll_to_pos = ImGui::Button("Scroll To Pos");
ImGui::SameLine(140); scroll_to_pos |= ImGui::DragFloat("##pos", &scroll_to_pos_px, 1.00f, -10, FLT_MAX, "X/Y = %.0f px");
bool scroll_to_pos = ImGui::DragFloat("##pos", &scroll_to_pos_px, 1.00f, -10, FLT_MAX, "X/Y = %.0f px");
ImGui::SameLine();
scroll_to_pos |= ImGui::Button("Scroll To Pos");
ImGui::PopItemWidth();
if (scroll_to_off || scroll_to_pos)
@ -5395,7 +5409,7 @@ static void DemoWindowPopups()
if (ImGui::BeginPopupContextItem()) // <-- use last item id as popup id
{
selected = n;
ImGui::Text("This a popup for \"%s\"!", names[n]);
ImGui::Text("This is a popup for \"%s\"!", names[n]);
if (ImGui::Button("Close"))
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
@ -5538,7 +5552,7 @@ static void DemoWindowPopups()
ImGui::TextWrapped("Below we are testing adding menu items to a regular window. It's rather unusual but should work!");
ImGui::Separator();
ImGui::MenuItem("Menu item", "CTRL+M");
ImGui::MenuItem("Menu item", "Ctrl+M");
if (ImGui::BeginMenu("Menu inside a regular window"))
{
ShowExampleMenuFile();
@ -7103,7 +7117,7 @@ static void DemoWindowTables()
// [2.3] Right-click in columns to open another custom popup
HelpMarker(
"Demonstrate mixing table context menu (over header), item context button (over button) "
"and custom per-colunm context menu (over column body).");
"and custom per-column context menu (over column body).");
ImGuiTableFlags flags2 = ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders;
if (ImGui::BeginTable("table_context_menu_2", COLUMNS_COUNT, flags2))
{
@ -7969,16 +7983,16 @@ static void DemoWindowInputs()
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImVec4(1.0f, 0.0f, 1.0f, 0.1f));
ImGui::BeginChild("WindowA", ImVec2(-FLT_MIN, line_height * 14), true);
ImGui::Text("Press CTRL+A and see who receives it!");
ImGui::Text("Press Ctrl+A and see who receives it!");
ImGui::Separator();
// 1: Window polling for CTRL+A
// 1: Window polling for Ctrl+A
ImGui::Text("(in WindowA)");
ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, flags) ? "PRESSED" : "...");
// 2: InputText also polling for CTRL+A: it always uses _RouteFocused internally (gets priority when active)
// 2: InputText also polling for Ctrl+A: it always uses _RouteFocused internally (gets priority when active)
// (Commented because the owner-aware version of Shortcut() is still in imgui_internal.h)
//char str[16] = "Press CTRL+A";
//char str[16] = "Press Ctrl+A";
//ImGui::Spacing();
//ImGui::InputText("InputTextB", str, IM_ARRAYSIZE(str), ImGuiInputTextFlags_ReadOnly);
//ImGuiID item_id = ImGui::GetItemID();
@ -7991,7 +8005,7 @@ static void DemoWindowInputs()
ImGui::Text("IsWindowFocused: %d", ImGui::IsWindowFocused());
ImGui::EndChild();
// 4: Child window polling for CTRL+A. It is deeper than WindowA and gets priority when focused.
// 4: Child window polling for Ctrl+A. It is deeper than WindowA and gets priority when focused.
ImGui::BeginChild("ChildE", ImVec2(-FLT_MIN, line_height * 4), true);
ImGui::Text("(in ChildE: using same Shortcut)");
ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, flags) ? "PRESSED" : "...");
@ -8048,7 +8062,7 @@ static void DemoWindowInputs()
IMGUI_DEMO_MARKER("Inputs & Focus/Tabbing");
if (ImGui::TreeNode("Tabbing"))
{
ImGui::Text("Use TAB/SHIFT+TAB to cycle through keyboard editable fields.");
ImGui::Text("Use Tab/Shift+Tab to cycle through keyboard editable fields.");
static char buf[32] = "hello";
ImGui::InputText("1", buf, IM_ARRAYSIZE(buf));
ImGui::InputText("2", buf, IM_ARRAYSIZE(buf));
@ -8263,6 +8277,25 @@ void ImGui::ShowAboutWindow(bool* p_open)
#ifdef IMGUI_HAS_DOCK
ImGui::Text("define: IMGUI_HAS_DOCK");
#endif
#ifdef NDEBUG
ImGui::Text("define: NDEBUG");
#endif
// Heuristic to detect no-op IM_ASSERT() macros
// - This is designed so people opening bug reports would convey and notice that they have disabled asserts for Dear ImGui code.
// - 16 is > strlen("((void)(_EXPR))") which we suggested in our imconfig.h template as a possible way to disable.
int assert_runs_expression = 0;
IM_ASSERT(++assert_runs_expression);
int assert_expand_len = (int)strlen(IM_STRINGIFY((IM_ASSERT(true))));
bool assert_maybe_disabled = (!assert_runs_expression || assert_expand_len <= 16);
ImGui::Text("IM_ASSERT: runs expression: %s. expand size: %s%s",
assert_runs_expression ? "OK" : "KO", (assert_expand_len > 16) ? "OK" : "KO", assert_maybe_disabled ? " (MAYBE DISABLED?!)" : "");
if (assert_maybe_disabled)
{
ImGui::SameLine();
HelpMarker("IM_ASSERT() calls assert() by default. Compiling with NDEBUG will usually strip out assert() to nothing, which is NOT recommended because we use asserts to notify of programmer mistakes!");
}
ImGui::Separator();
ImGui::Text("io.BackendPlatformName: %s", io.BackendPlatformName ? io.BackendPlatformName : "NULL");
ImGui::Text("io.BackendRendererName: %s", io.BackendRendererName ? io.BackendRendererName : "NULL");
@ -8282,6 +8315,7 @@ void ImGui::ShowAboutWindow(bool* p_open)
if (io.ConfigViewportsNoDecoration) ImGui::Text("io.ConfigViewportsNoDecoration");
if (io.ConfigViewportsNoDefaultParent) ImGui::Text("io.ConfigViewportsNoDefaultParent");
if (io.ConfigDockingNoSplit) ImGui::Text("io.ConfigDockingNoSplit");
if (io.ConfigDockingNoDockingOver) ImGui::Text("io.ConfigDockingNoDockingOver");
if (io.ConfigDockingWithShift) ImGui::Text("io.ConfigDockingWithShift");
if (io.ConfigDockingAlwaysTabBar) ImGui::Text("io.ConfigDockingAlwaysTabBar");
if (io.ConfigDockingTransparentPayload) ImGui::Text("io.ConfigDockingTransparentPayload");
@ -8298,6 +8332,7 @@ void ImGui::ShowAboutWindow(bool* p_open)
if (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos) ImGui::Text(" HasSetMousePos");
if (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports) ImGui::Text(" PlatformHasViewports");
if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport)ImGui::Text(" HasMouseHoveredViewport");
if (io.BackendFlags & ImGuiBackendFlags_HasParentViewport) ImGui::Text(" HasParentViewport");
if (io.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset) ImGui::Text(" RendererHasVtxOffset");
if (io.BackendFlags & ImGuiBackendFlags_RendererHasTextures) ImGui::Text(" RendererHasTextures");
if (io.BackendFlags & ImGuiBackendFlags_RendererHasViewports) ImGui::Text(" RendererHasViewports");
@ -8618,7 +8653,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
ShowFontAtlas(atlas);
// Post-baking font scaling. Note that this is NOT the nice way of scaling fonts, read below.
// (we enforce hard clamping manually as by default DragFloat/SliderFloat allows CTRL+Click text to get out of bounds).
// (we enforce hard clamping manually as by default DragFloat/SliderFloat allows Ctrl+Click text to get out of bounds).
/*
SeparatorText("Legacy Scaling");
const float MIN_SCALE = 0.3f;
@ -8736,27 +8771,27 @@ void ImGui::ShowUserGuide()
ImGuiIO& io = GetIO();
BulletText("Double-click on title bar to collapse window.");
BulletText(
"Click and drag on lower corner to resize window\n"
"(double-click to auto fit window to its contents).");
BulletText("CTRL+Click on a slider or drag box to input value as text.");
BulletText("TAB/SHIFT+TAB to cycle through keyboard editable fields.");
BulletText("CTRL+Tab to select a window.");
"Click and drag on lower corner or border to resize window.\n"
"(double-click to auto fit window to its contents)");
BulletText("Ctrl+Click on a slider or drag box to input value as text.");
BulletText("Tab/Shift+Tab to cycle through keyboard editable fields.");
BulletText("Ctrl+Tab/Ctrl+Shift+Tab to focus windows.");
if (io.FontAllowUserScaling)
BulletText("CTRL+Mouse Wheel to zoom window contents.");
BulletText("Ctrl+Mouse Wheel to zoom window contents.");
BulletText("While inputting text:\n");
Indent();
BulletText("CTRL+Left/Right to word jump.");
BulletText("CTRL+A or double-click to select all.");
BulletText("CTRL+X/C/V to use clipboard cut/copy/paste.");
BulletText("CTRL+Z to undo, CTRL+Y/CTRL+SHIFT+Z to redo.");
BulletText("ESCAPE to revert.");
BulletText("Ctrl+Left/Right to word jump.");
BulletText("Ctrl+A or double-click to select all.");
BulletText("Ctrl+X/C/V to use clipboard cut/copy/paste.");
BulletText("Ctrl+Z to undo, Ctrl+Y/Ctrl+Shift+Z to redo.");
BulletText("Escape to revert.");
Unindent();
BulletText("With keyboard navigation enabled:");
Indent();
BulletText("Arrow keys to navigate.");
BulletText("Arrow keys or Home/End/PageUp/PageDown to navigate.");
BulletText("Space to activate a widget.");
BulletText("Return to input text into a widget.");
BulletText("Escape to deactivate a widget, close popup, exit child window.");
BulletText("Escape to deactivate a widget, close popup,\nexit a child window or the menu layer, clear focus.");
BulletText("Alt to jump to the menu layer of a window.");
Unindent();
}
@ -8783,12 +8818,12 @@ static void ShowExampleAppMainMenuBar()
}
if (ImGui::BeginMenu("Edit"))
{
if (ImGui::MenuItem("Undo", "CTRL+Z")) {}
if (ImGui::MenuItem("Redo", "CTRL+Y", false, false)) {} // Disabled item
if (ImGui::MenuItem("Undo", "Ctrl+Z")) {}
if (ImGui::MenuItem("Redo", "Ctrl+Y", false, false)) {} // Disabled item
ImGui::Separator();
if (ImGui::MenuItem("Cut", "CTRL+X")) {}
if (ImGui::MenuItem("Copy", "CTRL+C")) {}
if (ImGui::MenuItem("Paste", "CTRL+V")) {}
if (ImGui::MenuItem("Cut", "Ctrl+X")) {}
if (ImGui::MenuItem("Copy", "Ctrl+C")) {}
if (ImGui::MenuItem("Paste", "Ctrl+V")) {}
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();
@ -9793,7 +9828,7 @@ static void ShowExampleAppConstrainedResize(bool* p_open)
}
else
{
ImGui::Text("(Hold SHIFT to display a dummy viewport)");
ImGui::Text("(Hold Shift to display a dummy viewport)");
if (ImGui::IsWindowDocked())
ImGui::Text("Warning: Sizing Constraints won't work if the window is docked!");
if (ImGui::Button("Set 200x200")) { ImGui::SetWindowSize(ImVec2(200, 200)); } ImGui::SameLine();
@ -10421,37 +10456,27 @@ static void ShowExampleAppCustomRendering(bool* p_open)
// [SECTION] Example App: Docking, DockSpace / ShowExampleAppDockSpace()
//-----------------------------------------------------------------------------
// Demonstrate using DockSpace() to create an explicit docking node within an existing window.
// Note: You can use most Docking facilities without calling any API. You DO NOT need to call DockSpace() to use Docking!
// - Drag from window title bar or their tab to dock/undock. Hold SHIFT to disable docking.
// - Drag from window menu button (upper-left button) to undock an entire node (all windows).
// - When io.ConfigDockingWithShift == true, you instead need to hold SHIFT to enable docking.
// About dockspaces:
// - Use DockSpace() to create an explicit dock node _within_ an existing window.
// - Use DockSpaceOverViewport() to create an explicit dock node covering the screen or a specific viewport.
// This is often used with ImGuiDockNodeFlags_PassthruCentralNode.
// - Important: Dockspaces need to be submitted _before_ any window they can host. Submit it early in your frame! (*)
// - Important: Dockspaces need to be kept alive if hidden, otherwise windows docked into it will be undocked.
// e.g. if you have multiple tabs with a dockspace inside each tab: submit the non-visible dockspaces with ImGuiDockNodeFlags_KeepAliveOnly.
// (*) because of this constraint, the implicit \"Debug\" window can not be docked into an explicit DockSpace() node,
// because that window is submitted as part of the part of the NewFrame() call. An easy workaround is that you can create
// your own implicit "Debug##2" window after calling DockSpace() and leave it in the window stack for anyone to use.
// Demonstrate using DockSpace() to create an explicit docking node within an existing window, with various options.
// THIS IS A DEMO FOR ADVANCED USAGE OF DockSpace().
// MOST REGULAR APPLICATIONS WHO WANT TO ALLOW DOCKING WINDOWS ON THE EDGE OF YOUR SCREEN CAN SIMPLY USE:
// ImGui::NewFrame();
// ImGui::DockSpaceOverViewport(); // Create a dockspace in main viewport
// OR:
// ImGui::NewFrame();
// ImGui::DockSpaceOverViewport(0, nullptr, ImGuiDockNodeFlags_PassthruCentralNode); // Create a dockspace in main viewport, where central node is transparent.
// Read https://github.com/ocornut/imgui/wiki/Docking for details.
// The reasons we do not use DockSpaceOverViewport() in this demo is because:
// - (1) we allow the host window to be floating/moveable instead of filling the viewport (when opt_fullscreen == false)
// which is mostly to showcase the idea that DockSpace() may be submitted anywhere.
// - (2) we allow the host window to have padding (when opt_padding == true)
// - (3) we expose many flags and need a way to have them visible.
// - (4) we have a local menu bar in the host window (vs. you could use BeginMainMenuBar() + DockSpaceOverViewport()
// in your code, but we don't here because we allow the window to be floating)
void ShowExampleAppDockSpace(bool* p_open)
{
// READ THIS !!!
// TL;DR; this demo is more complicated than what most users you would normally use.
// If we remove all options we are showcasing, this demo would become:
// void ShowExampleAppDockSpace()
// {
// ImGui::DockSpaceOverViewport(0, ImGui::GetMainViewport());
// }
// In most cases you should be able to just call DockSpaceOverViewport() and ignore all the code below!
// If we remove all options we are showcasing, this demo would become a simple call to ImGui::DockSpaceOverViewport() !!
// In this specific demo, we are not using DockSpaceOverViewport() because:
// - (1) we allow the host window to be floating/moveable instead of filling the viewport (when opt_fullscreen == false)
// - (2) we allow the host window to have padding (when opt_padding == true)
// - (3) we expose many flags and need a way to have them visible.
// - (4) we have a local menu bar in the host window (vs. you could use BeginMainMenuBar() + DockSpaceOverViewport()
// in your code, but we don't here because we allow the window to be floating)
static bool opt_fullscreen = true;
static bool opt_padding = false;
@ -10496,6 +10521,8 @@ void ShowExampleAppDockSpace(bool* p_open)
ImGui::PopStyleVar(2);
// Submit the DockSpace
// REMINDER: THIS IS A DEMO FOR ADVANCED USAGE OF DockSpace()!
// MOST REGULAR APPLICATIONS WILL SIMPLY WANT TO CALL DockSpaceOverViewport(). READ COMMENTS ABOVE.
ImGuiIO& io = ImGui::GetIO();
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable)
{
@ -10507,6 +10534,7 @@ void ShowExampleAppDockSpace(bool* p_open)
ShowDockingDisabledMessage();
}
// Show demo options and help
if (ImGui::BeginMenuBar())
{
if (ImGui::BeginMenu("Options"))
@ -10529,16 +10557,23 @@ void ShowExampleAppDockSpace(bool* p_open)
*p_open = false;
ImGui::EndMenu();
}
HelpMarker(
"When docking is enabled, you can ALWAYS dock MOST window into another! Try it now!" "\n"
"- Drag from window title bar or their tab to dock/undock." "\n"
"- Drag from window menu button (upper-left button) to undock an entire node (all windows)." "\n"
"- Hold SHIFT to disable docking (if io.ConfigDockingWithShift == false, default)" "\n"
"- Hold SHIFT to enable docking (if io.ConfigDockingWithShift == true)" "\n"
"This demo app has nothing to do with enabling docking!" "\n\n"
"This demo app only demonstrate the use of ImGui::DockSpace() which allows you to manually create a docking node _within_ another window." "\n\n"
"Read comments in ShowExampleAppDockSpace() for more details.");
if (ImGui::BeginMenu("Help"))
{
ImGui::TextUnformatted(
"This demo has nothing to do with enabling docking!" "\n"
"This demo only demonstrate the use of ImGui::DockSpace() which allows you to manually\ncreate a docking node _within_ another window." "\n"
"Most application can simply call ImGui::DockSpaceOverViewport() and be done with it.");
ImGui::Separator();
ImGui::TextUnformatted("When docking is enabled, you can ALWAYS dock MOST window into another! Try it now!" "\n"
"- Drag from window title bar or their tab to dock/undock." "\n"
"- Drag from window menu button (upper-left button) to undock an entire node (all windows)." "\n"
"- Hold SHIFT to disable docking (if io.ConfigDockingWithShift == false, default)" "\n"
"- Hold SHIFT to enable docking (if io.ConfigDockingWithShift == true)");
ImGui::Separator();
ImGui::TextUnformatted("More details:"); ImGui::Bullet(); ImGui::SameLine(); ImGui::TextLinkOpenURL("Docking Wiki page", "https://github.com/ocornut/imgui/wiki/Docking");
ImGui::BulletText("Read comments in ShowExampleAppDockSpace()");
ImGui::EndMenu();
}
ImGui::EndMenuBar();
}
@ -11091,7 +11126,7 @@ struct ExampleAssetsBrowser
ImGui::SeparatorText("Layout");
ImGui::SliderFloat("Icon Size", &IconSize, 16.0f, 128.0f, "%.0f");
ImGui::SameLine(); HelpMarker("Use CTRL+Wheel to zoom");
ImGui::SameLine(); HelpMarker("Use Ctrl+Wheel to zoom");
ImGui::SliderInt("Icon Spacing", &IconSpacing, 0, 32);
ImGui::SliderInt("Icon Hit Spacing", &IconHitSpacing, 0, 32);
ImGui::Checkbox("Stretch Spacing", &StretchSpacing);
@ -11283,7 +11318,7 @@ struct ExampleAssetsBrowser
if (want_delete)
Selection.ApplyDeletionPostLoop(ms_io, Items, item_curr_idx_to_focus);
// Zooming with CTRL+Wheel
// Zooming with Ctrl+Wheel
if (ImGui::IsWindowAppearing())
ZoomWheelAccum = 0.0f;
if (ImGui::IsWindowHovered() && io.MouseWheel != 0.0f && ImGui::IsKeyDown(ImGuiMod_Ctrl) && ImGui::IsAnyItemActive() == false)

View File

@ -1,4 +1,4 @@
// dear imgui, v1.92.3
// dear imgui, v1.92.5
// (drawing and font code)
/*
@ -244,6 +244,8 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst)
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
colors[ImGuiCol_TreeLines] = colors[ImGuiCol_Border];
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
colors[ImGuiCol_DragDropTargetBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_UnsavedMarker] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
colors[ImGuiCol_NavCursor] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
@ -312,6 +314,8 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f);
colors[ImGuiCol_TreeLines] = colors[ImGuiCol_Border];
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
colors[ImGuiCol_DragDropTargetBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_UnsavedMarker] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f);
colors[ImGuiCol_NavCursor] = colors[ImGuiCol_HeaderHovered];
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
@ -381,6 +385,8 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
colors[ImGuiCol_TreeLines] = colors[ImGuiCol_Border];
colors[ImGuiCol_DragDropTarget] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
colors[ImGuiCol_DragDropTargetBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_UnsavedMarker] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
colors[ImGuiCol_NavCursor] = colors[ImGuiCol_HeaderHovered];
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(0.70f, 0.70f, 0.70f, 0.70f);
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.20f);
@ -856,7 +862,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
const bool use_texture = (Flags & ImDrawListFlags_AntiAliasedLinesUseTex) && (integer_thickness < IM_DRAWLIST_TEX_LINES_WIDTH_MAX) && (fractional_thickness <= 0.00001f) && (AA_SIZE == 1.0f);
// We should never hit this, because NewFrame() doesn't set ImDrawListFlags_AntiAliasedLinesUseTex unless ImFontAtlasFlags_NoBakedLines is off
IM_ASSERT_PARANOID(!use_texture || !(_Data->Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoBakedLines));
IM_ASSERT_PARANOID(!use_texture || !(_Data->Font->OwnerAtlas->Flags & ImFontAtlasFlags_NoBakedLines));
const int idx_count = use_texture ? (count * 6) : (thick_line ? count * 18 : count * 12);
const int vtx_count = use_texture ? (points_count * 2) : (thick_line ? points_count * 4 : points_count * 3);
@ -1754,8 +1760,7 @@ void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32
clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z);
clip_rect.w = ImMin(clip_rect.w, cpu_fine_clip_rect->w);
}
font->RenderText(this, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip_rect != NULL);
font->RenderText(this, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, (cpu_fine_clip_rect != NULL) ? ImDrawTextFlags_CpuFineClip : ImDrawTextFlags_None);
}
void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end)
@ -2603,8 +2608,8 @@ void ImDrawList::AddShadowConvexPoly(const ImVec2* points, int points_count, ImU
const ImVec4 uvs = _Data->ShadowRectUvs[9];
int tex_width = _Data->Font->ContainerAtlas->TexData->Width;
int tex_height = _Data->Font->ContainerAtlas->TexData->Height;
int tex_width = _Data->Font->OwnerAtlas->TexData->Width;
int tex_height = _Data->Font->OwnerAtlas->TexData->Height;
float inv_tex_width = 1.0f / (float)tex_width;
float inv_tex_height = 1.0f / (float)tex_height;
@ -3408,6 +3413,7 @@ ImFontAtlas::~ImFontAtlas()
TexData = NULL;
}
// If you call this mid-frame, you would need to add new font and bind them!
void ImFontAtlas::Clear()
{
bool backup_renderer_has_textures = RendererHasTextures;
@ -3461,6 +3467,8 @@ void ImFontAtlas::ClearFonts()
{
// FIXME-NEWATLAS: Illegal to remove currently bound font.
IM_ASSERT(!Locked && "Cannot modify a locked ImFontAtlas!");
for (ImFont* font : Fonts)
ImFontAtlasBuildNotifySetFont(this, font, NULL);
ImFontAtlasBuildDestroy(this);
ClearInputData();
Fonts.clear_delete();
@ -3551,21 +3559,29 @@ void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count, bool rendere
if (tex->Status == ImTextureStatus_WantCreate && atlas->RendererHasTextures)
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL && "Backend set texture's TexID/BackendUserData but did not update Status to OK.");
// Request destroy
// - Keep bool to true in order to differentiate a planned destroy vs a destroy decided by the backend.
// - We don't destroy pixels right away, as backend may have an in-flight copy from RAM.
if (tex->WantDestroyNextFrame && tex->Status != ImTextureStatus_Destroyed && tex->Status != ImTextureStatus_WantDestroy)
{
IM_ASSERT(tex->Status == ImTextureStatus_OK || tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates);
tex->Status = ImTextureStatus_WantDestroy;
}
// If a texture has never reached the backend, they don't need to know about it.
// (note: backends between 1.92.0 and 1.92.4 could set an already destroyed texture to ImTextureStatus_WantDestroy
// when invalidating graphics objects twice, which would previously remove it from the list and crash.)
if (tex->Status == ImTextureStatus_WantDestroy && tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL)
tex->Status = ImTextureStatus_Destroyed;
// Process texture being destroyed
if (tex->Status == ImTextureStatus_Destroyed)
{
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL && "Backend set texture Status to Destroyed but did not clear TexID/BackendUserData!");
if (tex->WantDestroyNextFrame)
remove_from_list = true; // Destroy was scheduled by us
else
tex->Status = ImTextureStatus_WantCreate; // Destroy was done was backend (e.g. freed resources mid-run)
}
else if (tex->WantDestroyNextFrame && tex->Status != ImTextureStatus_WantDestroy)
{
// Request destroy.
// - Keep bool to true in order to differentiate a planned destroy vs a destroy decided by the backend.
// - We don't destroy pixels right away, as backend may have an in-flight copy from RAM.
IM_ASSERT(tex->Status == ImTextureStatus_OK || tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates);
tex->Status = ImTextureStatus_WantDestroy;
tex->Status = ImTextureStatus_WantCreate; // Destroy was done was backend: recreate it (e.g. freed resources mid-run)
}
// The backend may need defer destroying by a few frames, to handle texture used by previous in-flight rendering.
@ -3573,13 +3589,10 @@ void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count, bool rendere
if (tex->Status == ImTextureStatus_WantDestroy)
tex->UnusedFrames++;
// If a texture has never reached the backend, they don't need to know about it.
if (tex->Status == ImTextureStatus_WantDestroy && tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL)
remove_from_list = true;
// Destroy and remove
if (remove_from_list)
{
IM_ASSERT(atlas->TexData != tex);
tex->DestroyPixels();
IM_DELETE(tex);
atlas->TexList.erase(atlas->TexList.begin() + tex_n);
@ -3950,7 +3963,7 @@ ImFont* ImFontAtlas::AddFontFromMemoryCompressedBase85TTF(const char* compressed
// On font removal we need to remove references (otherwise we could queue removal?)
// We allow old_font == new_font which forces updating all values (e.g. sizes)
static void ImFontAtlasBuildNotifySetFont(ImFontAtlas* atlas, ImFont* old_font, ImFont* new_font)
void ImFontAtlasBuildNotifySetFont(ImFontAtlas* atlas, ImFont* old_font, ImFont* new_font)
{
for (ImDrawListSharedData* shared_data : atlas->DrawListSharedDatas)
{
@ -3995,7 +4008,7 @@ void ImFontAtlas::RemoveFont(ImFont* font)
ImFontAtlasBuildUpdatePointers(this);
font->ContainerAtlas = NULL;
font->OwnerAtlas = NULL;
IM_DELETE(font);
// Notify external systems
@ -4375,7 +4388,7 @@ void ImFontAtlasFontSourceAddToFont(ImFontAtlas* atlas, ImFont* font, ImFontConf
{
font->ClearOutputData();
//font->FontSize = src->SizePixels;
font->ContainerAtlas = atlas;
font->OwnerAtlas = atlas;
IM_ASSERT(font->Sources[0] == src);
}
atlas->TexIsBuilt = false; // For legacy backends
@ -4385,6 +4398,11 @@ void ImFontAtlasFontSourceAddToFont(ImFontAtlas* atlas, ImFont* font, ImFontConf
void ImFontAtlasFontDestroySourceData(ImFontAtlas* atlas, ImFontConfig* src)
{
IM_UNUSED(atlas);
// IF YOU GET A CRASH IN THE IM_FREE() CALL HERE AND USED AddFontFromMemoryTTF():
// - DUE TO LEGACY REASON AddFontFromMemoryTTF() TRANSFERS MEMORY OWNERSHIP BY DEFAULT.
// - IT WILL THEREFORE CRASH WHEN PASSED DATA WHICH MAY NOT BE FREEED BY IMGUI.
// - USE `ImFontConfig font_cfg; font_cfg.FontDataOwnedByAtlas = false; io.Fonts->AddFontFromMemoryTTF(....., &cfg);` to disable passing ownership/
// WE WILL ADDRESS THIS IN A FUTURE REWORK OF THE API.
if (src->FontDataOwnedByAtlas)
IM_FREE(src->FontData);
src->FontData = NULL;
@ -4398,7 +4416,7 @@ void ImFontAtlasFontDestroySourceData(ImFontAtlas* atlas, ImFontConfig* src)
// FIXME-NEWATLAS: This borrows too much from FontLoader's FontLoadGlyph() handlers and suggest that we should add further helpers.
static ImFontGlyph* ImFontAtlasBuildSetupFontBakedEllipsis(ImFontAtlas* atlas, ImFontBaked* baked)
{
ImFont* font = baked->ContainerFont;
ImFont* font = baked->OwnerFont;
IM_ASSERT(font->EllipsisChar != 0);
const ImFontGlyph* dot_glyph = baked->FindGlyphNoFallback((ImWchar)'.');
@ -4444,7 +4462,7 @@ static void ImFontAtlasBuildSetupFontBakedFallback(ImFontBaked* baked)
{
IM_ASSERT(baked->FallbackGlyphIndex == -1);
IM_ASSERT(baked->FallbackAdvanceX == 0.0f);
ImFont* font = baked->ContainerFont;
ImFont* font = baked->OwnerFont;
ImFontGlyph* fallback_glyph = NULL;
if (font->FallbackChar != 0)
fallback_glyph = baked->FindGlyphNoFallback(font->FallbackChar);
@ -4454,7 +4472,7 @@ static void ImFontAtlasBuildSetupFontBakedFallback(ImFontBaked* baked)
ImFontGlyph glyph;
glyph.Codepoint = 0;
glyph.AdvanceX = space_glyph ? space_glyph->AdvanceX : IM_ROUND(baked->Size * 0.40f);
fallback_glyph = ImFontAtlasBakedAddFontGlyph(font->ContainerAtlas, baked, NULL, &glyph);
fallback_glyph = ImFontAtlasBakedAddFontGlyph(font->OwnerAtlas, baked, NULL, &glyph);
}
baked->FallbackGlyphIndex = baked->Glyphs.index_from_ptr(fallback_glyph); // Storing index avoid need to update pointer on growth and simplify inner loop code
baked->FallbackAdvanceX = fallback_glyph->AdvanceX;
@ -4535,7 +4553,7 @@ ImFontBaked* ImFontAtlasBakedAdd(ImFontAtlas* atlas, ImFont* font, float font_si
baked->Size = font_size;
baked->RasterizerDensity = font_rasterizer_density;
baked->BakedId = baked_id;
baked->ContainerFont = font;
baked->OwnerFont = font;
baked->LastUsedFrame = atlas->Builder->FrameCount;
// Initialize backend data
@ -4570,7 +4588,7 @@ ImFontBaked* ImFontAtlasBakedGetClosestMatch(ImFontAtlas* atlas, ImFont* font, f
for (int baked_n = 0; baked_n < builder->BakedPool.Size; baked_n++)
{
ImFontBaked* baked = &builder->BakedPool[baked_n];
if (baked->ContainerFont != font || baked->WantDestroy)
if (baked->OwnerFont != font || baked->WantDestroy)
continue;
if (step_n == 0 && baked->RasterizerDensity != font_rasterizer_density) // First try with same density
continue;
@ -4626,7 +4644,7 @@ void ImFontAtlasFontDiscardBakes(ImFontAtlas* atlas, ImFont* font, int unused_fr
ImFontBaked* baked = &builder->BakedPool[baked_n];
if (baked->LastUsedFrame + unused_frames > atlas->Builder->FrameCount)
continue;
if (baked->ContainerFont != font || baked->WantDestroy)
if (baked->OwnerFont != font || baked->WantDestroy)
continue;
ImFontAtlasBakedDiscard(atlas, font, baked);
}
@ -4641,9 +4659,9 @@ void ImFontAtlasBuildDiscardBakes(ImFontAtlas* atlas, int unused_frames)
ImFontBaked* baked = &builder->BakedPool[baked_n];
if (baked->LastUsedFrame + unused_frames > atlas->Builder->FrameCount)
continue;
if (baked->WantDestroy || (baked->ContainerFont->Flags & ImFontFlags_LockBakedSizes))
if (baked->WantDestroy || (baked->OwnerFont->Flags & ImFontFlags_LockBakedSizes))
continue;
ImFontAtlasBakedDiscard(atlas, baked->ContainerFont, baked);
ImFontAtlasBakedDiscard(atlas, baked->OwnerFont, baked);
}
}
@ -4664,6 +4682,11 @@ void ImFontAtlasRemoveDrawListSharedData(ImFontAtlas* atlas, ImDrawListSharedDat
void ImFontAtlasUpdateDrawListsTextures(ImFontAtlas* atlas, ImTextureRef old_tex, ImTextureRef new_tex)
{
for (ImDrawListSharedData* shared_data : atlas->DrawListSharedDatas)
{
// If Context 2 uses font owned by Context 1 which already called EndFrame()/Render(), we don't want to mess with draw commands for Context 1
if (shared_data->Context && !shared_data->Context->WithinFrameScope)
continue;
for (ImDrawList* draw_list : shared_data->DrawLists)
{
// Replace in command-buffer
@ -4677,6 +4700,7 @@ void ImFontAtlasUpdateDrawListsTextures(ImFontAtlas* atlas, ImTextureRef old_tex
if (stacked_tex == old_tex)
stacked_tex = new_tex;
}
}
}
// Update texture coordinates in all draw list shared context
@ -5431,8 +5455,8 @@ static void ImFontAtlas_FontHookRemapCodepoint(ImFontAtlas* atlas, ImFont* font,
static ImFontGlyph* ImFontBaked_BuildLoadGlyph(ImFontBaked* baked, ImWchar codepoint, float* only_load_advance_x)
{
ImFont* font = baked->ContainerFont;
ImFontAtlas* atlas = font->ContainerAtlas;
ImFont* font = baked->OwnerFont;
ImFontAtlas* atlas = font->OwnerAtlas;
if (atlas->Locked || (font->Flags & ImFontFlags_NoLoadGlyphs))
{
// Lazily load fallback glyph
@ -5706,7 +5730,7 @@ static bool ImGui_ImplStbTrueType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontC
stbtt_MakeGlyphBitmapSubpixelPrefilter(&bd_font_data->FontInfo, bitmap_pixels, w, h, w,
scale_for_raster_x, scale_for_raster_y, 0, 0, oversample_h, oversample_v, &sub_x, &sub_y, glyph_index);
const float ref_size = baked->ContainerFont->Sources[0]->SizePixels;
const float ref_size = baked->OwnerFont->Sources[0]->SizePixels;
const float offsets_scale = (ref_size != 0.0f) ? (baked->Size / ref_size) : 1.0f;
float font_off_x = (src->GlyphOffset.x * offsets_scale);
float font_off_y = (src->GlyphOffset.y * offsets_scale);
@ -6033,7 +6057,9 @@ const ImWchar* ImFontAtlas::GetGlyphRangesVietnamese()
void ImFontGlyphRangesBuilder::AddText(const char* text, const char* text_end)
{
while (text_end ? (text < text_end) : *text)
if (text_end == NULL)
text_end = text + strlen(text);
while (text < text_end)
{
unsigned int c = 0;
int c_len = ImTextCharFromUtf8(&c, text, text_end);
@ -6101,7 +6127,7 @@ ImFont::~ImFont()
void ImFont::ClearOutputData()
{
if (ImFontAtlas* atlas = ContainerAtlas)
if (ImFontAtlas* atlas = OwnerAtlas)
ImFontAtlasFontDiscardBakes(atlas, this, 0);
FallbackChar = EllipsisChar = 0;
memset(Used8kPagesMap, 0, sizeof(Used8kPagesMap));
@ -6146,7 +6172,7 @@ ImFontGlyph* ImFontAtlasBakedAddFontGlyph(ImFontAtlas* atlas, ImFontBaked* baked
if (src != NULL)
{
// Clamp & recenter if needed
const float ref_size = baked->ContainerFont->Sources[0]->SizePixels;
const float ref_size = baked->OwnerFont->Sources[0]->SizePixels;
const float offsets_scale = (ref_size != 0.0f) ? (baked->Size / ref_size) : 1.0f;
float advance_x = ImClamp(glyph->AdvanceX, src->GlyphMinAdvanceX * offsets_scale, src->GlyphMaxAdvanceX * offsets_scale);
if (advance_x != glyph->AdvanceX)
@ -6172,7 +6198,7 @@ ImFontGlyph* ImFontAtlasBakedAddFontGlyph(ImFontAtlas* atlas, ImFontBaked* baked
baked->IndexAdvanceX[codepoint] = glyph->AdvanceX;
baked->IndexLookup[codepoint] = (ImU16)glyph_idx;
const int page_n = codepoint / 8192;
baked->ContainerFont->Used8kPagesMap[page_n >> 3] |= 1 << (page_n & 7);
baked->OwnerFont->Used8kPagesMap[page_n >> 3] |= 1 << (page_n & 7);
return glyph;
}
@ -6184,7 +6210,7 @@ void ImFontAtlasBakedAddFontGlyphAdvancedX(ImFontAtlas* atlas, ImFontBaked* bake
if (src != NULL)
{
// Clamp & recenter if needed
const float ref_size = baked->ContainerFont->Sources[0]->SizePixels;
const float ref_size = baked->OwnerFont->Sources[0]->SizePixels;
const float offsets_scale = (ref_size != 0.0f) ? (baked->Size / ref_size) : 1.0f;
advance_x = ImClamp(advance_x, src->GlyphMinAdvanceX * offsets_scale, src->GlyphMaxAdvanceX * offsets_scale);
@ -6206,7 +6232,7 @@ void ImFontAtlasBakedSetFontGlyphBitmap(ImFontAtlas* atlas, ImFontBaked* baked,
ImTextureData* tex = atlas->TexData;
IM_ASSERT(r->x + r->w <= tex->Width && r->y + r->h <= tex->Height);
ImFontAtlasTextureBlockConvert(src_pixels, src_fmt, src_pitch, (unsigned char*)tex->GetPixelsAt(r->x, r->y), tex->Format, tex->GetPitch(), r->w, r->h);
ImFontAtlasPostProcessData pp_data = { atlas, baked->ContainerFont, src, baked, glyph, tex->GetPixelsAt(r->x, r->y), tex->Format, tex->GetPitch(), r->w, r->h };
ImFontAtlasPostProcessData pp_data = { atlas, baked->OwnerFont, src, baked, glyph, tex->GetPixelsAt(r->x, r->y), tex->Format, tex->GetPitch(), r->w, r->h };
ImFontAtlasTextureBlockPostProcess(&pp_data);
ImFontAtlasTextureBlockQueueUpload(atlas, tex, r->x, r->y, r->w, r->h);
}
@ -6264,7 +6290,7 @@ bool ImFontBaked::IsGlyphLoaded(ImWchar c)
// This is not fast query
bool ImFont::IsGlyphInFont(ImWchar c)
{
ImFontAtlas* atlas = ContainerAtlas;
ImFontAtlas* atlas = OwnerAtlas;
ImFontAtlas_FontHookRemapCodepoint(atlas, this, &c);
for (ImFontConfig* src : Sources)
{
@ -6313,7 +6339,7 @@ ImFontBaked* ImFont::GetFontBaked(float size, float density)
if (baked && baked->Size == size && baked->RasterizerDensity == density)
return baked;
ImFontAtlas* atlas = ContainerAtlas;
ImFontAtlas* atlas = OwnerAtlas;
ImFontAtlasBuilder* builder = atlas->Builder;
baked = ImFontAtlasBakedGetOrAdd(atlas, this, size, density);
if (baked == NULL)
@ -6334,7 +6360,7 @@ ImFontBaked* ImFontAtlasBakedGetOrAdd(ImFontAtlas* atlas, ImFont* font, float fo
ImFontBaked* baked = *p_baked_in_map;
if (baked != NULL)
{
IM_ASSERT(baked->Size == font_size && baked->ContainerFont == font && baked->BakedId == baked_id);
IM_ASSERT(baked->Size == font_size && baked->OwnerFont == font && baked->BakedId == baked_id);
return baked;
}
@ -6616,7 +6642,7 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im
}
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
// DO NOT CALL DIRECTLY THIS WILL CHANGE WIDLY IN 2025-2025. Use ImDrawList::AddText().
// DO NOT CALL DIRECTLY THIS WILL CHANGE WILDLY IN 2025-2025. Use ImDrawList::AddText().
void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, ImDrawTextFlags flags)
{
// Align to be pixel perfect

View File

@ -1,4 +1,4 @@
// dear imgui, v1.92.3
// dear imgui, v1.92.5
// (tables and columns code)
/*
@ -24,9 +24,9 @@ Index of this file:
*/
// Navigating this file:
// - In Visual Studio: CTRL+comma ("Edit.GoToAll") can follow symbols inside comments, whereas CTRL+F12 ("Edit.GoToImplementation") cannot.
// - In Visual Studio w/ Visual Assist installed: ALT+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments.
// - In Visual Studio: Ctrl+Comma ("Edit.GoToAll") can follow symbols inside comments, whereas Ctrl+F12 ("Edit.GoToImplementation") cannot.
// - In Visual Studio w/ Visual Assist installed: Alt+G ("VAssistX.GoToImplementation") can also follow symbols inside comments.
// - In VS Code, CLion, etc.: Ctrl+Click can follow symbols inside comments.
//-----------------------------------------------------------------------------
// [SECTION] Commentary
@ -451,7 +451,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
// But at this point we do NOT have a correct value for .Max.y (unless a height has been explicitly passed in). It will only be updated in EndTable().
table->WorkRect = table->OuterRect = table->InnerRect = outer_rect;
table->HasScrollbarYPrev = table->HasScrollbarYCurr = false;
table->InnerWindow->DC.TreeDepth++; // This is designed to always linking ImGuiTreeNodeFlags_DrawLines linking accross a table
table->InnerWindow->DC.TreeDepth++; // This is designed to always linking ImGuiTreeNodeFlags_DrawLines linking across a table
}
// Push a standardized ID for both child-using and not-child-using tables
@ -464,6 +464,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->HostIndentX = inner_window->DC.Indent.x;
table->HostClipRect = inner_window->ClipRect;
table->HostSkipItems = inner_window->SkipItems;
temp_data->WindowID = inner_window->ID;
temp_data->HostBackupWorkRect = inner_window->WorkRect;
temp_data->HostBackupParentWorkRect = inner_window->ParentWorkRect;
temp_data->HostBackupColumnsOffset = outer_window->DC.ColumnsOffset;
@ -946,7 +947,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// (e.g. TextWrapped) too much. Otherwise what tends to happen is that TextWrapped would output a very
// large height (= first frame scrollbar display very off + clipper would skip lots of items).
// This is merely making the side-effect less extreme, but doesn't properly fixes it.
// FIXME: Move this to ->WidthGiven to avoid temporary lossyless?
// FIXME: Move this to ->WidthGiven to avoid temporary lossyness?
// FIXME: This break IsPreserveWidthAuto from not flickering if the stored WidthAuto was smaller.
if (column->AutoFitQueue > 0x01 && table->IsInitializing && !column->IsPreserveWidthAuto)
column->WidthRequest = ImMax(column->WidthRequest, table->MinColumnWidth * 4.0f); // FIXME-TABLE: Another constant/scale?
@ -1190,7 +1191,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
}
// In case the table is visible (e.g. decorations) but all columns clipped, we keep a column visible.
// Else if give no chance to a clipper-savy user to submit rows and therefore total contents height used by scrollbar.
// Else if give no chance to a clipper-savvy user to submit rows and therefore total contents height used by scrollbar.
if (has_at_least_one_column_requesting_output == false)
{
table->Columns[table->LeftMostEnabledColumn].IsRequestOutput = true;
@ -1366,7 +1367,7 @@ void ImGui::EndTable()
ImGuiWindow* inner_window = table->InnerWindow;
ImGuiWindow* outer_window = table->OuterWindow;
ImGuiTableTempData* temp_data = table->TempData;
IM_ASSERT(inner_window == g.CurrentWindow);
IM_ASSERT(inner_window == g.CurrentWindow && inner_window->ID == temp_data->WindowID);
IM_ASSERT(outer_window == inner_window || outer_window == inner_window->ParentWindow);
if (table->IsInsideRow)
@ -1559,7 +1560,7 @@ void ImGui::EndTable()
IM_ASSERT(g.CurrentWindow == outer_window && g.CurrentTable == table);
IM_ASSERT(g.TablesTempDataStacked > 0);
temp_data = (--g.TablesTempDataStacked > 0) ? &g.TablesTempData[g.TablesTempDataStacked - 1] : NULL;
g.CurrentTable = temp_data ? g.Tables.GetByIndex(temp_data->TableIndex) : NULL;
g.CurrentTable = temp_data && (temp_data->WindowID == outer_window->ID) ? g.Tables.GetByIndex(temp_data->TableIndex) : NULL;
if (g.CurrentTable)
{
g.CurrentTable->TempData = temp_data;
@ -2525,7 +2526,7 @@ void ImGui::TablePopColumnChannel()
// - NoClip --> 2+D+1 channels: bg0/1 + bg2 + foreground (same clip rect == always 1 draw call)
// - Clip --> 2+D+N channels
// - FreezeRows --> 2+D+N*2 (unless scrolling value is zero)
// - FreezeRows || FreezeColunns --> 3+D+N*2 (unless scrolling value is zero)
// - FreezeRows || FreezeColumns --> 3+D+N*2 (unless scrolling value is zero)
// Where D is 1 if any column is clipped or hidden (dummy channel) otherwise 0.
void ImGui::TableSetupDrawChannels(ImGuiTable* table)
{
@ -2818,8 +2819,13 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
continue;
// Draw in outer window so right-most column won't be clipped
// Always draw full height border when being resized/hovered, or on the delimitation of frozen column scrolling.
float draw_y2 = (is_hovered || is_resized || is_frozen_separator || (table->Flags & (ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_NoBordersInBodyUntilResize)) == 0) ? draw_y2_body : draw_y2_head;
float draw_y2 = draw_y2_head;
if (is_frozen_separator)
draw_y2 = draw_y2_body;
else if ((table->Flags & ImGuiTableFlags_NoBordersInBodyUntilResize) != 0 && (is_hovered || is_resized))
draw_y2 = draw_y2_body;
else if ((table->Flags & (ImGuiTableFlags_NoBordersInBodyUntilResize | ImGuiTableFlags_NoBordersInBody)) == 0)
draw_y2 = draw_y2_body;
if (draw_y2 > draw_y1)
inner_drawlist->AddLine(ImVec2(column->MaxX, draw_y1), ImVec2(column->MaxX, draw_y2), TableGetColumnBorderCol(table, order_n, column_n), border_size);
}
@ -3415,7 +3421,7 @@ void ImGui::TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label
// Left<>Right alignment
float line_off_curr_x = flip_label ? (label_lines - 1) * line_off_step_x : 0.0f;
float line_off_for_align_x = ImMax((((column->MaxX - column->MinX) - padding.x * 2.0f) - (label_lines * line_off_step_x)), 0.0f) * align.x;
float line_off_for_align_x = ImFloor(ImMax((((column->MaxX - column->MinX) - padding.x * 2.0f) - (label_lines * line_off_step_x)), 0.0f) * align.x);
line_off_curr_x += line_off_for_align_x - line_off_for_ascent_x;
// Register header width
@ -4022,9 +4028,9 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
bool open = TreeNode(table, "Table 0x%08X (%d columns, in '%s')%s", table->ID, table->ColumnsCount, table->OuterWindow->Name, is_active ? "" : " *Inactive*");
if (!is_active) { PopStyleColor(); }
if (IsItemHovered())
GetForegroundDrawList()->AddRect(table->OuterRect.Min, table->OuterRect.Max, IM_COL32(255, 255, 0, 255));
GetForegroundDrawList(table->OuterWindow)->AddRect(table->OuterRect.Min, table->OuterRect.Max, IM_COL32(255, 255, 0, 255));
if (IsItemVisible() && table->HoveredColumnBody != -1)
GetForegroundDrawList()->AddRect(GetItemRectMin(), GetItemRectMax(), IM_COL32(255, 255, 0, 255));
GetForegroundDrawList(table->OuterWindow)->AddRect(GetItemRectMin(), GetItemRectMax(), IM_COL32(255, 255, 0, 255));
if (!open)
return;
if (table->InstanceCurrent > 0)
@ -4078,7 +4084,7 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
if (IsItemHovered())
{
ImRect r(column->MinX, table->OuterRect.Min.y, column->MaxX, table->OuterRect.Max.y);
GetForegroundDrawList()->AddRect(r.Min, r.Max, IM_COL32(255, 255, 0, 255));
GetForegroundDrawList(table->OuterWindow)->AddRect(r.Min, r.Max, IM_COL32(255, 255, 0, 255));
}
}
if (ImGuiTableSettings* settings = TableGetBoundSettings(table))

View File

@ -1,4 +1,4 @@
// dear imgui, v1.92.3
// dear imgui, v1.92.5
// (widgets code)
/*
@ -574,8 +574,9 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
// Special mode for Drag and Drop used by openables (tree nodes, tabs etc.)
// where holding the button pressed for a long time while drag a payload item triggers the button.
if (g.DragDropActive && (flags & ImGuiButtonFlags_PressedOnDragDropHold) && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers))
if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem))
if (g.DragDropActive)
{
if ((flags & ImGuiButtonFlags_PressedOnDragDropHold) && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem))
{
hovered = true;
SetHoveredID(id);
@ -586,6 +587,9 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
FocusWindow(window);
}
}
if (g.DragDropAcceptIdPrev == id && (g.DragDropAcceptFlagsPrev & ImGuiDragDropFlags_AcceptDrawAsHovered))
hovered = true;
}
if (flatten_hovered_children)
g.HoveredWindow = backup_hovered_window;
@ -619,7 +623,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
if (flags & (ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClickReleaseAnywhere))
{
SetActiveID(id, window);
g.ActiveIdMouseButton = mouse_button_clicked;
g.ActiveIdMouseButton = (ImS8)mouse_button_clicked;
if (!(flags & ImGuiButtonFlags_NoNavFocus))
{
SetFocusID(id, window);
@ -637,7 +641,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
ClearActiveID();
else
SetActiveID(id, window); // Hold on ID
g.ActiveIdMouseButton = mouse_button_clicked;
g.ActiveIdMouseButton = (ImS8)mouse_button_clicked;
if (!(flags & ImGuiButtonFlags_NoNavFocus))
{
SetFocusID(id, window);
@ -675,32 +679,35 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
// Keyboard/Gamepad navigation handling
// We report navigated and navigation-activated items as hovered but we don't set g.HoveredId to not interfere with mouse.
if (g.NavId == id && g.NavCursorVisible && g.NavHighlightItemUnderNav)
if (!(flags & ImGuiButtonFlags_NoHoveredOnFocus))
hovered = true;
if (g.NavActivateDownId == id)
if ((item_flags & ImGuiItemFlags_Disabled) == 0)
{
bool nav_activated_by_code = (g.NavActivateId == id);
bool nav_activated_by_inputs = (g.NavActivatePressedId == id);
if (!nav_activated_by_inputs && (item_flags & ImGuiItemFlags_ButtonRepeat))
if (g.NavId == id && g.NavCursorVisible && g.NavHighlightItemUnderNav)
if (!(flags & ImGuiButtonFlags_NoHoveredOnFocus))
hovered = true;
if (g.NavActivateDownId == id)
{
// Avoid pressing multiple keys from triggering excessive amount of repeat events
const ImGuiKeyData* key1 = GetKeyData(ImGuiKey_Space);
const ImGuiKeyData* key2 = GetKeyData(ImGuiKey_Enter);
const ImGuiKeyData* key3 = GetKeyData(ImGuiKey_NavGamepadActivate);
const float t1 = ImMax(ImMax(key1->DownDuration, key2->DownDuration), key3->DownDuration);
nav_activated_by_inputs = CalcTypematicRepeatAmount(t1 - g.IO.DeltaTime, t1, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0;
}
if (nav_activated_by_code || nav_activated_by_inputs)
{
// Set active id so it can be queried by user via IsItemActive(), equivalent of holding the mouse button.
pressed = true;
SetActiveID(id, window);
g.ActiveIdSource = g.NavInputSource;
if (!(flags & ImGuiButtonFlags_NoNavFocus) && !(g.NavActivateFlags & ImGuiActivateFlags_FromShortcut))
SetFocusID(id, window);
if (g.NavActivateFlags & ImGuiActivateFlags_FromShortcut)
g.ActiveIdFromShortcut = true;
bool nav_activated_by_code = (g.NavActivateId == id);
bool nav_activated_by_inputs = (g.NavActivatePressedId == id);
if (!nav_activated_by_inputs && (item_flags & ImGuiItemFlags_ButtonRepeat))
{
// Avoid pressing multiple keys from triggering excessive amount of repeat events
const ImGuiKeyData* key1 = GetKeyData(ImGuiKey_Space);
const ImGuiKeyData* key2 = GetKeyData(ImGuiKey_Enter);
const ImGuiKeyData* key3 = GetKeyData(ImGuiKey_NavGamepadActivate);
const float t1 = ImMax(ImMax(key1->DownDuration, key2->DownDuration), key3->DownDuration);
nav_activated_by_inputs = CalcTypematicRepeatAmount(t1 - g.IO.DeltaTime, t1, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0;
}
if (nav_activated_by_code || nav_activated_by_inputs)
{
// Set active id so it can be queried by user via IsItemActive(), equivalent of holding the mouse button.
pressed = true;
SetActiveID(id, window);
g.ActiveIdSource = g.NavInputSource;
if (!(flags & ImGuiButtonFlags_NoNavFocus) && !(g.NavActivateFlags & ImGuiActivateFlags_FromShortcut))
SetFocusID(id, window);
if (g.NavActivateFlags & ImGuiActivateFlags_FromShortcut)
g.ActiveIdFromShortcut = true;
}
}
}
@ -754,7 +761,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
}
// Activation highlight (this may be a remote activation)
if (g.NavHighlightActivatedId == id)
if (g.NavHighlightActivatedId == id && (item_flags & ImGuiItemFlags_Disabled) == 0)
hovered = true;
if (out_hovered) *out_hovered = hovered;
@ -2700,7 +2707,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
if (!temp_input_is_active)
{
// Tabbing or CTRL+click on Drag turns it into an InputText
// Tabbing or Ctrl+Click on Drag turns it into an InputText
const bool clicked = hovered && IsMouseClicked(0, ImGuiInputFlags_None, id);
const bool double_clicked = (hovered && g.IO.MouseClickedCount[0] == 2 && TestKeyOwner(ImGuiKey_MouseLeft, id));
const bool make_active = (clicked || double_clicked || g.NavActivateId == id);
@ -2734,7 +2741,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
if (temp_input_is_active)
{
// Only clamp CTRL+Click input when ImGuiSliderFlags_ClampOnInput is set (generally via ImGuiSliderFlags_AlwaysClamp)
// Only clamp Ctrl+Click input when ImGuiSliderFlags_ClampOnInput is set (generally via ImGuiSliderFlags_AlwaysClamp)
bool clamp_enabled = false;
if ((flags & ImGuiSliderFlags_ClampOnInput) && (p_min != NULL || p_max != NULL))
{
@ -3304,7 +3311,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
if (!temp_input_is_active)
{
// Tabbing or CTRL+click on Slider turns it into an input box
// Tabbing or Ctrl+Click on Slider turns it into an input box
const bool clicked = hovered && IsMouseClicked(0, ImGuiInputFlags_None, id);
const bool make_active = (clicked || g.NavActivateId == id);
if (make_active && clicked)
@ -3328,7 +3335,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
if (temp_input_is_active)
{
// Only clamp CTRL+Click input when ImGuiSliderFlags_ClampOnInput is set (generally via ImGuiSliderFlags_AlwaysClamp)
// Only clamp Ctrl+Click input when ImGuiSliderFlags_ClampOnInput is set (generally via ImGuiSliderFlags_AlwaysClamp)
const bool clamp_enabled = (flags & ImGuiSliderFlags_ClampOnInput) != 0;
return TempInputScalar(frame_bb, id, label, data_type, p_data, format, clamp_enabled ? p_min : NULL, clamp_enabled ? p_max : NULL);
}
@ -3665,7 +3672,7 @@ int ImParseFormatPrecision(const char* fmt, int default_precision)
return (precision == INT_MAX) ? default_precision : precision;
}
// Create text input in place of another active widget (e.g. used when doing a CTRL+Click on drag/slider widgets)
// Create text input in place of another active widget (e.g. used when doing a Ctrl+Click on drag/slider widgets)
// FIXME: Facilitate using this in variety of other situations.
// FIXME: Among other things, setting ImGuiItemFlags_AllowDuplicateId in LastItemData is currently correct but
// the expected relationship between TempInputXXX functions and LastItemData is a little fishy.
@ -3691,7 +3698,7 @@ bool ImGui::TempInputText(const ImRect& bb, ImGuiID id, const char* label, char*
}
// Note that Drag/Slider functions are only forwarding the min/max values clamping values if the ImGuiSliderFlags_AlwaysClamp flag is set!
// This is intended: this way we allow CTRL+Click manual input to set a value out of bounds, for maximum flexibility.
// This is intended: this way we allow Ctrl+Click manual input to set a value out of bounds, for maximum flexibility.
// However this may not be ideal for all uses, as some user code may break on out of bound values.
bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format, const void* p_clamp_min, const void* p_clamp_max)
{
@ -3926,6 +3933,7 @@ namespace ImStb
#include "imstb_textedit.h"
}
// If you want to use InputText() with std::string or any custom dynamic string type, use the wrapper in misc/cpp/imgui_stdlib.h/.cpp!
bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
{
IM_ASSERT(!(flags & ImGuiInputTextFlags_Multiline)); // call InputTextMultiline()
@ -3947,6 +3955,7 @@ static ImVec2 InputTextCalcTextSize(ImGuiContext* ctx, const char* text_begin, c
{
ImGuiContext& g = *ctx;
ImGuiInputTextState* obj = &g.InputTextState;
IM_ASSERT(text_end_display >= text_begin && text_end_display <= text_end);
return ImFontCalcTextSizeEx(g.Font, g.FontSize, FLT_MAX, obj->WrapWidth, text_begin, text_end_display, text_end, out_remaining, out_offset, flags);
}
@ -4009,7 +4018,7 @@ static bool ImCharIsSeparatorW(unsigned int c)
static int is_word_boundary_from_right(ImGuiInputTextState* obj, int idx)
{
// When ImGuiInputTextFlags_Password is set, we don't want actions such as CTRL+Arrow to leak the fact that underlying data are blanks or separators.
// When ImGuiInputTextFlags_Password is set, we don't want actions such as Ctrl+Arrow to leak the fact that underlying data are blanks or separators.
if ((obj->Flags & ImGuiInputTextFlags_Password) || idx <= 0)
return 0;
@ -4147,21 +4156,23 @@ static void STB_TEXTEDIT_DELETECHARS(ImGuiInputTextState* obj, int pos, int n)
obj->TextLen -= n;
}
static bool STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const char* new_text, int new_text_len)
static int STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const char* new_text, int new_text_len)
{
const bool is_resizable = (obj->Flags & ImGuiInputTextFlags_CallbackResize) != 0;
const int text_len = obj->TextLen;
IM_ASSERT(pos <= text_len);
if (!is_resizable && (new_text_len + obj->TextLen + 1 > obj->BufCapacity))
return false;
// We support partial insertion (with a mod in stb_textedit.h)
const int avail = obj->BufCapacity - 1 - obj->TextLen;
if (!is_resizable && new_text_len > avail)
new_text_len = (int)(ImTextFindValidUtf8CodepointEnd(new_text, new_text + new_text_len, new_text + avail) - new_text); // Truncate to closest UTF-8 codepoint. Alternative: return 0 to cancel insertion.
if (new_text_len == 0)
return 0;
// Grow internal buffer if needed
IM_ASSERT(obj->TextSrc == obj->TextA.Data);
if (new_text_len + text_len + 1 > obj->TextA.Size)
if (text_len + new_text_len + 1 > obj->TextA.Size && is_resizable)
{
if (!is_resizable)
return false;
obj->TextA.resize(text_len + ImClamp(new_text_len, 32, ImMax(256, new_text_len)) + 1);
obj->TextSrc = obj->TextA.Data;
}
@ -4175,7 +4186,7 @@ static bool STB_TEXTEDIT_INSERTCHARS(ImGuiInputTextState* obj, int pos, const ch
obj->TextLen += new_text_len;
obj->TextA[obj->TextLen] = '\0';
return true;
return new_text_len;
}
// We don't use an enum so we can build even with conflicting symbols (if another user of stb_textedit.h leak their STB_TEXTEDIT_K_* symbols)
@ -4210,7 +4221,8 @@ static void stb_textedit_replace(ImGuiInputTextState* str, STB_TexteditState* st
state->cursor = state->select_start = state->select_end = 0;
if (text_len <= 0)
return;
if (ImStb::STB_TEXTEDIT_INSERTCHARS(str, 0, text, text_len))
int text_len_inserted = ImStb::STB_TEXTEDIT_INSERTCHARS(str, 0, text, text_len);
if (text_len_inserted > 0)
{
state->cursor = state->select_start = state->select_end = text_len;
state->has_preferred_x = 0;
@ -4305,15 +4317,20 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
ImGuiContext& g = *Ctx;
ImGuiInputTextState* obj = &g.InputTextState;
IM_ASSERT(obj->ID != 0 && g.ActiveId == obj->ID);
const bool is_resizable = (Flags & ImGuiInputTextFlags_CallbackResize) != 0;
const bool is_readonly = (Flags & ImGuiInputTextFlags_ReadOnly) != 0;
int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)ImStrlen(new_text);
// We support partial insertion (with a mod in stb_textedit.h)
const int avail = BufSize - 1 - BufTextLen;
if (!is_resizable && new_text_len > avail)
new_text_len = (int)(ImTextFindValidUtf8CodepointEnd(new_text, new_text + new_text_len, new_text + avail) - new_text); // Truncate to closest UTF-8 codepoint. Alternative: return 0 to cancel insertion.
if (new_text_len == 0)
return;
// Grow internal buffer if needed
const bool is_resizable = (Flags & ImGuiInputTextFlags_CallbackResize) != 0;
const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)ImStrlen(new_text);
if (new_text_len + BufTextLen + 1 > obj->TextA.Size && (Flags & ImGuiInputTextFlags_ReadOnly) == 0)
if (new_text_len + BufTextLen + 1 > obj->TextA.Size && is_resizable && !is_readonly)
{
if (!is_resizable)
return;
IM_ASSERT(Buf == obj->TextA.Data);
int new_buf_size = BufTextLen + ImClamp(new_text_len * 4, 32, ImMax(256, new_text_len)) + 1;
obj->TextA.resize(new_buf_size + 1);
@ -4327,11 +4344,12 @@ void ImGuiInputTextCallbackData::InsertChars(int pos, const char* new_text, cons
memcpy(Buf + pos, new_text, (size_t)new_text_len * sizeof(char));
Buf[BufTextLen + new_text_len] = '\0';
if (CursorPos >= pos)
CursorPos += new_text_len;
SelectionStart = SelectionEnd = CursorPos;
BufDirty = true;
BufTextLen += new_text_len;
if (CursorPos >= pos)
CursorPos += new_text_len;
CursorPos = ImClamp(CursorPos, 0, BufTextLen);
SelectionStart = SelectionEnd = CursorPos;
}
void ImGui::PushPasswordFont()
@ -4616,9 +4634,7 @@ static ImVec2 InputTextLineIndexGetPosOffset(ImGuiContext& g, ImGuiInputTextStat
// This is so we can easily call InputText() on static arrays using ARRAYSIZE() and to match
// Note that in std::string world, capacity() would omit 1 byte used by the zero-terminator.
// - When active, hold on a privately held copy of the text (and apply back to 'buf'). So changing 'buf' while the InputText is active has no effect.
// - If you want to use ImGui::InputText() with std::string, see misc/cpp/imgui_stdlib.h
// (FIXME: Rather confusing and messy function, among the worse part of our codebase, expecting to rewrite a V2 at some point.. Partly because we are
// doing UTF8 > U16 > UTF8 conversions on the go to easily interface with stb_textedit. Ideally should stay in UTF-8 all the time. See https://github.com/nothings/stb/issues/188)
// - If you want to use InputText() with std::string or any custom dynamic string type, use the wrapper in misc/cpp/imgui_stdlib.h/.cpp!
bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* callback_user_data)
{
ImGuiWindow* window = GetCurrentWindow();
@ -4752,8 +4768,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
state->TextLen = new_len;
memcpy(state->TextA.Data, buf, state->TextLen + 1);
state->Stb->select_start = state->ReloadSelectionStart;
state->Stb->cursor = state->Stb->select_end = state->ReloadSelectionEnd;
state->CursorClamp();
state->Stb->cursor = state->Stb->select_end = state->ReloadSelectionEnd; // will be clamped to bounds below
}
else if ((init_state && g.ActiveId != id) || init_changed_specs)
{
@ -4793,9 +4808,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Recycle existing cursor/selection/undo stack but clamp position
// Note a single mouse click will override the cursor/position immediately by calling stb_textedit_click handler.
if (recycle_state)
state->CursorClamp();
else
if (!recycle_state)
stb_textedit_initialize_state(state->Stb, !is_multiline);
if (!is_multiline)
@ -4824,7 +4837,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
{
// Declare some inputs, the other are registered and polled via Shortcut() routing system.
// FIXME: The reason we don't use Shortcut() is we would need a routing flag to specify multiple mods, or to all mods combination into individual shortcuts.
const ImGuiKey always_owned_keys[] = { ImGuiKey_LeftArrow, ImGuiKey_RightArrow, ImGuiKey_Enter, ImGuiKey_KeypadEnter, ImGuiKey_Delete, ImGuiKey_Backspace, ImGuiKey_Home, ImGuiKey_End };
const ImGuiKey always_owned_keys[] = { ImGuiKey_LeftArrow, ImGuiKey_RightArrow, ImGuiKey_Delete, ImGuiKey_Backspace, ImGuiKey_Home, ImGuiKey_End };
for (ImGuiKey key : always_owned_keys)
SetKeyOwner(key, id);
if (user_clicked)
@ -4852,6 +4865,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Read-only mode always ever read from source buffer. Refresh TextLen when active.
if (is_readonly && state != NULL)
state->TextLen = (int)ImStrlen(buf);
if (state != NULL)
state->CursorClamp();
//if (is_readonly && state != NULL)
// state->TextA.clear(); // Uncomment to facilitate debugging, but we otherwise prefer to keep/amortize th allocation.
}
@ -4918,7 +4933,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
if ((multiclick_count % 2) == 0)
{
// Double-click: Select word
// We always use the "Mac" word advance for double-click select vs CTRL+Right which use the platform dependent variant:
// We always use the "Mac" word advance for double-click select vs Ctrl+Right which use the platform dependent variant:
// FIXME: There are likely many ways to improve this behavior, but there's no "right" behavior (depends on use-case, software, OS)
const bool is_bol = (state->Stb->cursor == 0) || ImStb::STB_TEXTEDIT_GETCHAR(state, state->Stb->cursor - 1) == '\n';
if (STB_TEXT_HAS_SELECTION(state->Stb) || !is_bol)
@ -4987,7 +5002,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
}
// Process regular text input (before we check for Return because using some IME will effectively send a Return?)
// We ignore CTRL inputs, but need to allow ALT+CTRL as some keyboards (e.g. German) use AltGR (which _is_ Alt+Ctrl) to input certain characters.
// We ignore Ctrl inputs, but need to allow Alt+Ctrl as some keyboards (e.g. German) use AltGR (which _is_ Alt+Ctrl) to input certain characters.
const bool ignore_char_inputs = (io.KeyCtrl && !io.KeyAlt) || (is_osx && io.KeyCtrl);
if (io.InputQueueCharacters.Size > 0)
{
@ -5020,7 +5035,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
const bool is_wordmove_key_down = is_osx ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl
const bool is_startend_key_down = is_osx && io.KeyCtrl && !io.KeySuper && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End
// Using Shortcut() with ImGuiInputFlags_RouteFocused (default policy) to allow routing operations for other code (e.g. calling window trying to use CTRL+A and CTRL+B: former would be handled by InputText)
// Using Shortcut() with ImGuiInputFlags_RouteFocused (default policy) to allow routing operations for other code (e.g. calling window trying to use Ctrl+A and Ctrl+B: former would be handled by InputText)
// Otherwise we could simply assume that we own the keys as we are active.
const ImGuiInputFlags f_repeat = ImGuiInputFlags_Repeat;
const bool is_cut = (Shortcut(ImGuiMod_Ctrl | ImGuiKey_X, f_repeat, id) || Shortcut(ImGuiMod_Shift | ImGuiKey_Delete, f_repeat, id)) && !is_readonly && !is_password && (!is_multiline || state->HasSelection());
@ -5032,7 +5047,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// We allow validate/cancel with Nav source (gamepad) to makes it easier to undo an accidental NavInput press with no keyboard wired, but otherwise it isn't very useful.
const bool nav_gamepad_active = (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (io.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0;
const bool is_enter_pressed = IsKeyPressed(ImGuiKey_Enter, true) || IsKeyPressed(ImGuiKey_KeypadEnter, true);
const bool is_enter = Shortcut(ImGuiKey_Enter, f_repeat, id) || Shortcut(ImGuiKey_KeypadEnter, f_repeat, id);
const bool is_ctrl_enter = Shortcut(ImGuiMod_Ctrl | ImGuiKey_Enter, f_repeat, id) || Shortcut(ImGuiMod_Ctrl | ImGuiKey_KeypadEnter, f_repeat, id);
const bool is_gamepad_validate = nav_gamepad_active && (IsKeyPressed(ImGuiKey_NavGamepadActivate, false) || IsKeyPressed(ImGuiKey_NavGamepadInput, false));
const bool is_cancel = Shortcut(ImGuiKey_Escape, f_repeat, id) || (nav_gamepad_active && Shortcut(ImGuiKey_NavGamepadCancel, f_repeat, id));
@ -5067,11 +5083,11 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
}
state->OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask);
}
else if (is_enter_pressed || is_gamepad_validate)
else if (is_enter || is_ctrl_enter || is_gamepad_validate)
{
// Determine if we turn Enter into a \n character
bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0;
if (!is_multiline || is_gamepad_validate || (ctrl_enter_for_new_line != io.KeyCtrl))
if (!is_multiline || is_gamepad_validate || (ctrl_enter_for_new_line != is_ctrl_enter))
{
validated = true;
if (io.ConfigInputTextEnterKeepActive && !is_multiline)
@ -5081,7 +5097,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
}
else if (!is_readonly)
{
unsigned int c = '\n'; // Insert new line
// Insert new line
unsigned int c = '\n';
if (InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data))
state->OnCharPressed(c);
}
@ -5143,12 +5160,13 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
{
// Filter pasted buffer
const int clipboard_len = (int)ImStrlen(clipboard);
const char* clipboard_end = clipboard + clipboard_len;
ImVector<char> clipboard_filtered;
clipboard_filtered.reserve(clipboard_len + 1);
for (const char* s = clipboard; *s != 0; )
{
unsigned int c;
int in_len = ImTextCharFromUtf8(&c, s, NULL);
int in_len = ImTextCharFromUtf8(&c, s, clipboard_end);
s += in_len;
if (!InputTextFilterCharacter(&g, &c, flags, callback, callback_user_data, true))
continue;
@ -5195,7 +5213,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
apply_new_text_length = state->TextToRevertTo.Size - 1;
// Restore initial value. Only return true if restoring to the initial value changes the current buffer contents.
// Push records into the undo stack so we can CTRL+Z the revert operation itself
// Push records into the undo stack so we can Ctrl+Z the revert operation itself
value_changed = true;
stb_textedit_replace(state, state->Stb, state->TextToRevertTo.Data, state->TextToRevertTo.Size - 1);
}
@ -5264,10 +5282,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
callback_data.BufTextLen = state->TextLen;
callback_data.BufSize = state->BufCapacity;
callback_data.BufDirty = false;
const int utf8_cursor_pos = callback_data.CursorPos = state->Stb->cursor;
const int utf8_selection_start = callback_data.SelectionStart = state->Stb->select_start;
const int utf8_selection_end = callback_data.SelectionEnd = state->Stb->select_end;
callback_data.CursorPos = state->Stb->cursor;
callback_data.SelectionStart = state->Stb->select_start;
callback_data.SelectionEnd = state->Stb->select_end;
// Call user code
callback(&callback_data);
@ -5277,11 +5294,12 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
IM_ASSERT(callback_data.Buf == callback_buf); // Invalid to modify those fields
IM_ASSERT(callback_data.BufSize == state->BufCapacity);
IM_ASSERT(callback_data.Flags == flags);
const bool buf_dirty = callback_data.BufDirty;
if (callback_data.CursorPos != utf8_cursor_pos || buf_dirty) { state->Stb->cursor = callback_data.CursorPos; state->CursorFollow = true; }
if (callback_data.SelectionStart != utf8_selection_start || buf_dirty) { state->Stb->select_start = (callback_data.SelectionStart == callback_data.CursorPos) ? state->Stb->cursor : callback_data.SelectionStart; }
if (callback_data.SelectionEnd != utf8_selection_end || buf_dirty) { state->Stb->select_end = (callback_data.SelectionEnd == callback_data.SelectionStart) ? state->Stb->select_start : callback_data.SelectionEnd; }
if (buf_dirty)
if (callback_data.BufDirty || callback_data.CursorPos != state->Stb->cursor)
state->CursorFollow = true;
state->Stb->cursor = ImClamp(callback_data.CursorPos, 0, callback_data.BufTextLen);
state->Stb->select_start = ImClamp(callback_data.SelectionStart, 0, callback_data.BufTextLen);
state->Stb->select_end = ImClamp(callback_data.SelectionEnd, 0, callback_data.BufTextLen);
if (callback_data.BufDirty)
{
// Callback may update buffer and thus set buf_dirty even in read-only mode.
IM_ASSERT(callback_data.BufTextLen == (int)ImStrlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text!
@ -5405,7 +5423,12 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
line_index->Offsets.resize(0);
int line_count = 1;
if (is_multiline)
line_count = InputTextLineIndexBuild(flags, line_index, buf_display, buf_display_end, wrap_width, (render_cursor && state && state->CursorFollow) ? INT_MAX : line_visible_n1 + 1, buf_display_end ? NULL : &buf_display_end);
{
// If scrolling is expected to change build full index.
// FIXME-OPT: Could append to index when new value of line_visible_n1 becomes bigger, see second call to CalcClipRectVisibleItemsY() below.
bool will_scroll_y = state && ((state->CursorFollow && render_cursor) || (state->CursorCenterY && (render_cursor || render_selection)));
line_count = InputTextLineIndexBuild(flags, line_index, buf_display, buf_display_end, wrap_width, will_scroll_y ? INT_MAX : line_visible_n1 + 1, buf_display_end ? NULL : &buf_display_end);
}
line_index->EndOffset = (int)(buf_display_end - buf_display);
line_visible_n1 = ImMin(line_visible_n1, line_count);
@ -5531,7 +5554,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
text_col, clip_rect.AsVec4(),
line_index->get_line_begin(buf_display, line_visible_n0),
line_index->get_line_end(buf_display, line_visible_n1 - 1),
wrap_width, ImDrawTextFlags_WrapKeepBlanks);
wrap_width, ImDrawTextFlags_WrapKeepBlanks | ImDrawTextFlags_CpuFineClip);
// Render blinking cursor
if (render_cursor)
@ -5690,7 +5713,7 @@ static void ColorEditRestoreHS(const float* col, float* H, float* S, float* V)
// Edit colors components (each component in 0.0f..1.0f range).
// See enum ImGuiColorEditFlags_ for available options. e.g. Only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set.
// With typical options: Left-click on color square to open color picker. Right-click to open option menu. CTRL+Click over input fields to edit them and TAB to go to next item.
// With typical options: Left-click on color square to open color picker. Right-click to open option menu. Ctrl+Click over input fields to edit them and TAB to go to next item.
bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags)
{
ImGuiWindow* window = GetCurrentWindow();
@ -7930,7 +7953,7 @@ ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, int sel
}
}
// Shortcut: Select all (CTRL+A)
// Shortcut: Select all (Ctrl+A)
if (!(flags & ImGuiMultiSelectFlags_SingleSelect) && !(flags & ImGuiMultiSelectFlags_NoSelectAll))
if (Shortcut(ImGuiMod_Ctrl | ImGuiKey_A))
request_select_all = true;
@ -8075,7 +8098,7 @@ void ImGui::MultiSelectItemHeader(ImGuiID id, bool* p_selected, ImGuiButtonFlags
if (ms->LoopRequestSetAll != -1)
selected = (ms->LoopRequestSetAll == 1);
// When using SHIFT+Nav: because it can incur scrolling we cannot afford a frame of lag with the selection highlight (otherwise scrolling would happen before selection)
// When using Shift+Nav: because it can incur scrolling we cannot afford a frame of lag with the selection highlight (otherwise scrolling would happen before selection)
// For this to work, we need someone to set 'RangeSrcPassedBy = true' at some point (either clipper either SetNextItemSelectionUserData() function)
if (ms->IsKeyboardSetRange)
{
@ -8106,7 +8129,7 @@ void ImGui::MultiSelectItemHeader(ImGuiID id, bool* p_selected, ImGuiButtonFlags
// Alter button behavior flags
// To handle drag and drop of multiple items we need to avoid clearing selection on click.
// Enabling this test makes actions using CTRL+SHIFT delay their effect on MouseUp which is annoying, but it allows drag and drop of multiple items.
// Enabling this test makes actions using Ctrl+Shift delay their effect on MouseUp which is annoying, but it allows drag and drop of multiple items.
if (p_button_flags != NULL)
{
ImGuiButtonFlags button_flags = *p_button_flags;
@ -8210,8 +8233,8 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
}
// Right-click handling.
// FIXME-MULTISELECT: Currently filtered out by ImGuiMultiSelectFlags_NoAutoSelect but maybe should be moved to Selectable(). See https://github.com/ocornut/imgui/pull/5816
if (hovered && IsMouseClicked(1) && (flags & ImGuiMultiSelectFlags_NoAutoSelect) == 0)
// FIXME-MULTISELECT: Maybe should be moved to Selectable()? Also see #5816, #8200, #9015
if (hovered && IsMouseClicked(1) && (flags & (ImGuiMultiSelectFlags_NoAutoSelect | ImGuiMultiSelectFlags_NoSelectOnRightClick)) == 0)
{
if (g.ActiveId != 0 && g.ActiveId != id)
ClearActiveID();
@ -8305,7 +8328,7 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
MultiSelectAddSetRange(ms, range_selected, range_direction, storage->RangeSrcItem, item_data);
}
// Update/store the selection state of the Source item (used by CTRL+SHIFT, when Source is unselected we perform a range unselect)
// Update/store the selection state of the Source item (used by Ctrl+Shift, when Source is unselected we perform a range unselect)
if (storage->RangeSrcItem == item_data)
storage->RangeSelected = selected ? 1 : 0;
@ -8519,7 +8542,7 @@ void ImGuiSelectionBasicStorage::ApplyRequests(ImGuiMultiSelectIO* ms_io)
else
{
// Append insertion + single sort likely be faster.
// Use req.RangeDirection to set order field so that shift+clicking from 1 to 5 is different than shift+clicking from 5 to 1
// Use req.RangeDirection to set order field so that Shift+Clicking from 1 to 5 is different than Shift+Clicking from 5 to 1
const int size_before_amends = _Storage.Data.Size;
int selection_order = _SelectionOrder + ((req.RangeDirection < 0) ? selection_changes - 1 : 0);
for (int idx = (int)req.RangeFirstItem; idx <= (int)req.RangeLastItem; idx++, selection_order += req.RangeDirection)
@ -9054,9 +9077,9 @@ bool ImGui::BeginViewportSideBar(const char* name, ImGuiViewport* viewport_p, Im
}
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDocking;
SetNextWindowViewport(viewport->ID); // Enforce viewport so we don't create our own viewport when ImGuiConfigFlags_ViewportsNoMerge is set.
// Create window
SetNextWindowViewport(viewport->ID); // Enforce viewport so we don't create our own viewport when ImGuiConfigFlags_ViewportsNoMerge is set.
PushStyleColor(ImGuiCol_WindowShadow, ImVec4(0, 0, 0, 0));
PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0, 0)); // Lift normal size constraint
@ -10502,7 +10525,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
}
// Lock visibility
// (Note: tab_contents_visible != tab_selected... because CTRL+TAB operations may preview some tabs without selecting them!)
// (Note: tab_contents_visible != tab_selected... because Ctrl+Tab operations may preview some tabs without selecting them!)
bool tab_contents_visible = (tab_bar->VisibleTabId == id);
if (tab_contents_visible)
tab_bar->VisibleTabWasSubmitted = true;
@ -10844,8 +10867,8 @@ void ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
const bool unsaved_marker_visible = (flags & ImGuiTabItemFlags_UnsavedDocument) != 0 && (button_pos.x + button_sz <= bb.Max.x) && (!close_button_visible || !is_hovered);
if (unsaved_marker_visible)
{
const ImRect bullet_bb(button_pos, button_pos + ImVec2(button_sz, button_sz));
RenderBullet(draw_list, bullet_bb.GetCenter(), GetColorU32(ImGuiCol_Text));
ImVec2 bullet_pos = button_pos + ImVec2(button_sz, button_sz) * 0.5f;
RenderBullet(draw_list, bullet_pos, GetColorU32(ImGuiCol_UnsavedMarker));
}
else if (close_button_visible)
{

View File

@ -445,7 +445,7 @@ static bool ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* s
IM_UNUSED(atlas);
float size = baked->Size;
if (src->MergeMode && src->SizePixels != 0.0f)
size *= (src->SizePixels / baked->ContainerFont->Sources[0]->SizePixels);
size *= (src->SizePixels / baked->OwnerFont->Sources[0]->SizePixels);
ImGui_ImplFreeType_FontSrcData* bd_font_data = (ImGui_ImplFreeType_FontSrcData*)src->FontLoaderData;
bd_font_data->BakedLastActivated = baked;
@ -570,7 +570,7 @@ static bool ImGui_ImplFreeType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontConf
uint32_t* temp_buffer = (uint32_t*)atlas->Builder->TempBuffer.Data;
ImGui_ImplFreeType_BlitGlyph(ft_bitmap, temp_buffer, w);
const float ref_size = baked->ContainerFont->Sources[0]->SizePixels;
const float ref_size = baked->OwnerFont->Sources[0]->SizePixels;
const float offsets_scale = (ref_size != 0.0f) ? (baked->Size / ref_size) : 1.0f;
float font_off_x = (src->GlyphOffset.x * offsets_scale);
float font_off_y = (src->GlyphOffset.y * offsets_scale) + baked->Ascent;