| // dear imgui, v1.91.5 WIP |
| // (internal structures/api) |
| |
| // You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility. |
| |
| /* |
| |
| Index of this file: |
| |
| // [SECTION] Header mess |
| // [SECTION] Forward declarations |
| // [SECTION] Context pointer |
| // [SECTION] STB libraries includes |
| // [SECTION] Macros |
| // [SECTION] Generic helpers |
| // [SECTION] ImDrawList support |
| // [SECTION] Data types support |
| // [SECTION] Widgets support: flags, enums, data structures |
| // [SECTION] Popup support |
| // [SECTION] Inputs support |
| // [SECTION] Clipper support |
| // [SECTION] Navigation support |
| // [SECTION] Typing-select support |
| // [SECTION] Columns support |
| // [SECTION] Box-select support |
| // [SECTION] Multi-select support |
| // [SECTION] Docking support |
| // [SECTION] Viewport support |
| // [SECTION] Settings support |
| // [SECTION] Localization support |
| // [SECTION] Error handling, State recovery support |
| // [SECTION] Metrics, Debug tools |
| // [SECTION] Generic context hooks |
| // [SECTION] ImGuiContext (main imgui context) |
| // [SECTION] ImGuiWindowTempData, ImGuiWindow |
| // [SECTION] Tab bar, Tab item support |
| // [SECTION] Table support |
| // [SECTION] ImGui internal API |
| // [SECTION] ImFontAtlas internal API |
| // [SECTION] Test Engine specific hooks (imgui_test_engine) |
| |
| */ |
| |
| #pragma once |
| #ifndef IMGUI_DISABLE |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Header mess |
| //----------------------------------------------------------------------------- |
| |
| #ifndef IMGUI_VERSION |
| #include "imgui.h" |
| #endif |
| |
| #include <stdio.h> // FILE*, sscanf |
| #include <stdlib.h> // NULL, malloc, free, qsort, atoi, atof |
| #include <math.h> // sqrtf, fabsf, fmodf, powf, floorf, ceilf, cosf, sinf |
| #include <limits.h> // INT_MIN, INT_MAX |
| |
| // Enable SSE intrinsics if available |
| #if (defined __SSE__ || defined __x86_64__ || defined _M_X64 || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1))) && !defined(IMGUI_DISABLE_SSE) |
| #define IMGUI_ENABLE_SSE |
| #include <immintrin.h> |
| #endif |
| |
| // Visual Studio warnings |
| #ifdef _MSC_VER |
| #pragma warning (push) |
| #pragma warning (disable: 4251) // class 'xxx' needs to have dll-interface to be used by clients of struct 'xxx' // when IMGUI_API is set to__declspec(dllexport) |
| #pragma warning (disable: 26812) // The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). [MSVC Static Analyzer) |
| #pragma warning (disable: 26495) // [Static Analyzer] Variable 'XXX' is uninitialized. Always initialize a member variable (type.6). |
| #if defined(_MSC_VER) && _MSC_VER >= 1922 // MSVC 2019 16.2 or later |
| #pragma warning (disable: 5054) // operator '|': deprecated between enumerations of different types |
| #endif |
| #endif |
| |
| // Clang/GCC warnings with -Weverything |
| #if defined(__clang__) |
| #pragma clang diagnostic push |
| #if __has_warning("-Wunknown-warning-option") |
| #pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx' |
| #endif |
| #pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx' |
| #pragma clang diagnostic ignored "-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing against same constants ok, for ImFloor() |
| #pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h |
| #pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h |
| #pragma clang diagnostic ignored "-Wold-style-cast" |
| #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" |
| #pragma clang diagnostic ignored "-Wdouble-promotion" |
| #pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision |
| #pragma clang diagnostic ignored "-Wmissing-noreturn" // warning: function 'xxx' could be declared with attribute 'noreturn' |
| #pragma clang diagnostic ignored "-Wdeprecated-enum-enum-conversion"// warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated |
| #pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access |
| #elif defined(__GNUC__) |
| #pragma GCC diagnostic push |
| #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind |
| #pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead |
| #pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion" // warning: bitwise operation between different enumeration types ('XXXFlags_' and 'XXXFlagsPrivate_') is deprecated |
| #endif |
| |
| // In 1.89.4, we moved the implementation of "courtesy maths operators" from imgui_internal.h in imgui.h |
| // As they are frequently requested, we do not want to encourage to many people using imgui_internal.h |
| #if defined(IMGUI_DEFINE_MATH_OPERATORS) && !defined(IMGUI_DEFINE_MATH_OPERATORS_IMPLEMENTED) |
| #error Please '#define IMGUI_DEFINE_MATH_OPERATORS' _BEFORE_ including imgui.h! |
| #endif |
| |
| // Legacy defines |
| #ifdef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS // Renamed in 1.74 |
| #error Use IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS |
| #endif |
| #ifdef IMGUI_DISABLE_MATH_FUNCTIONS // Renamed in 1.74 |
| #error Use IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS |
| #endif |
| |
| // Enable stb_truetype by default unless FreeType is enabled. |
| // You can compile with both by defining both IMGUI_ENABLE_FREETYPE and IMGUI_ENABLE_STB_TRUETYPE together. |
| #ifndef IMGUI_ENABLE_FREETYPE |
| #define IMGUI_ENABLE_STB_TRUETYPE |
| #endif |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Forward declarations |
| //----------------------------------------------------------------------------- |
| |
| struct ImBitVector; // Store 1-bit per value |
| struct ImRect; // An axis-aligned rectangle (2 points) |
| struct ImDrawDataBuilder; // Helper to build a ImDrawData instance |
| struct ImDrawListSharedData; // Data shared between all ImDrawList instances |
| struct ImGuiBoxSelectState; // Box-selection state (currently used by multi-selection, could potentially be used by others) |
| struct ImGuiColorMod; // Stacked color modifier, backup of modified data so we can restore it |
| struct ImGuiContext; // Main Dear ImGui context |
| struct ImGuiContextHook; // Hook for extensions like ImGuiTestEngine |
| struct ImGuiDataVarInfo; // Variable information (e.g. to access style variables from an enum) |
| struct ImGuiDataTypeInfo; // Type information associated to a ImGuiDataType enum |
| struct ImGuiErrorRecoveryState; // Storage of stack sizes for error handling and recovery |
| struct ImGuiGroupData; // Stacked storage data for BeginGroup()/EndGroup() |
| struct ImGuiInputTextState; // Internal state of the currently focused/edited text input box |
| struct ImGuiInputTextDeactivateData;// Short term storage to backup text of a deactivating InputText() while another is stealing active id |
| struct ImGuiLastItemData; // Status storage for last submitted items |
| struct ImGuiLocEntry; // A localization entry. |
| struct ImGuiMenuColumns; // Simple column measurement, currently used for MenuItem() only |
| struct ImGuiMultiSelectState; // Multi-selection persistent state (for focused selection). |
| struct ImGuiMultiSelectTempData; // Multi-selection temporary state (while traversing). |
| struct ImGuiNavItemData; // Result of a keyboard/gamepad directional navigation move query result |
| struct ImGuiMetricsConfig; // Storage for ShowMetricsWindow() and DebugNodeXXX() functions |
| struct ImGuiNextWindowData; // Storage for SetNextWindow** functions |
| struct ImGuiNextItemData; // Storage for SetNextItem** functions |
| struct ImGuiOldColumnData; // Storage data for a single column for legacy Columns() api |
| struct ImGuiOldColumns; // Storage data for a columns set for legacy Columns() api |
| struct ImGuiPopupData; // Storage for current popup stack |
| struct ImGuiSettingsHandler; // Storage for one type registered in the .ini file |
| struct ImGuiStyleMod; // Stacked style modifier, backup of modified data so we can restore it |
| struct ImGuiTabBar; // Storage for a tab bar |
| struct ImGuiTabItem; // Storage for a tab item (within a tab bar) |
| struct ImGuiTable; // Storage for a table |
| struct ImGuiTableHeaderData; // Storage for TableAngledHeadersRow() |
| struct ImGuiTableColumn; // Storage for one column of a table |
| struct ImGuiTableInstanceData; // Storage for one instance of a same table |
| struct ImGuiTableTempData; // Temporary storage for one table (one per table in the stack), shared between tables. |
| struct ImGuiTableSettings; // Storage for a table .ini settings |
| struct ImGuiTableColumnsSettings; // Storage for a column .ini settings |
| struct ImGuiTreeNodeStackData; // Temporary storage for TreeNode(). |
| struct ImGuiTypingSelectState; // Storage for GetTypingSelectRequest() |
| struct ImGuiTypingSelectRequest; // Storage for GetTypingSelectRequest() (aimed to be public) |
| struct ImGuiWindow; // Storage for one window |
| struct ImGuiWindowTempData; // Temporary storage for one window (that's the data which in theory we could ditch at the end of the frame, in practice we currently keep it for each window) |
| struct ImGuiWindowSettings; // Storage for a window .ini settings (we keep one of those even if the actual window wasn't instanced during this session) |
| |
| // Enumerations |
| // Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists. |
| enum ImGuiLocKey : int; // -> enum ImGuiLocKey // Enum: a localization entry for translation. |
| typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical |
| |
| // Flags |
| typedef int ImGuiActivateFlags; // -> enum ImGuiActivateFlags_ // Flags: for navigation/focus function (will be for ActivateItem() later) |
| typedef int ImGuiDebugLogFlags; // -> enum ImGuiDebugLogFlags_ // Flags: for ShowDebugLogWindow(), g.DebugLogFlags |
| typedef int ImGuiFocusRequestFlags; // -> enum ImGuiFocusRequestFlags_ // Flags: for FocusWindow() |
| typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for g.LastItemData.StatusFlags |
| typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns() |
| typedef int ImGuiNavRenderCursorFlags; // -> enum ImGuiNavRenderCursorFlags_//Flags: for RenderNavCursor() |
| typedef int ImGuiNavMoveFlags; // -> enum ImGuiNavMoveFlags_ // Flags: for navigation requests |
| typedef int ImGuiNextItemDataFlags; // -> enum ImGuiNextItemDataFlags_ // Flags: for SetNextItemXXX() functions |
| typedef int ImGuiNextWindowDataFlags; // -> enum ImGuiNextWindowDataFlags_// Flags: for SetNextWindowXXX() functions |
| typedef int ImGuiScrollFlags; // -> enum ImGuiScrollFlags_ // Flags: for ScrollToItem() and navigation requests |
| typedef int ImGuiSeparatorFlags; // -> enum ImGuiSeparatorFlags_ // Flags: for SeparatorEx() |
| typedef int ImGuiTextFlags; // -> enum ImGuiTextFlags_ // Flags: for TextEx() |
| typedef int ImGuiTooltipFlags; // -> enum ImGuiTooltipFlags_ // Flags: for BeginTooltipEx() |
| typedef int ImGuiTypingSelectFlags; // -> enum ImGuiTypingSelectFlags_ // Flags: for GetTypingSelectRequest() |
| typedef int ImGuiWindowRefreshFlags; // -> enum ImGuiWindowRefreshFlags_ // Flags: for SetNextWindowRefreshPolicy() |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Context pointer |
| // See implementation of this variable in imgui.cpp for comments and details. |
| //----------------------------------------------------------------------------- |
| |
| #ifndef GImGui |
| extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer |
| #endif |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Macros |
| //----------------------------------------------------------------------------- |
| |
| // Debug Printing Into TTY |
| // (since IMGUI_VERSION_NUM >= 18729: IMGUI_DEBUG_LOG was reworked into IMGUI_DEBUG_PRINTF (and removed framecount from it). If you were using a #define IMGUI_DEBUG_LOG please rename) |
| #ifndef IMGUI_DEBUG_PRINTF |
| #ifndef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS |
| #define IMGUI_DEBUG_PRINTF(_FMT,...) printf(_FMT, __VA_ARGS__) |
| #else |
| #define IMGUI_DEBUG_PRINTF(_FMT,...) ((void)0) |
| #endif |
| #endif |
| |
| // Debug Logging for ShowDebugLogWindow(). This is designed for relatively rare events so please don't spam. |
| #ifndef IMGUI_DISABLE_DEBUG_TOOLS |
| #define IMGUI_DEBUG_LOG(...) ImGui::DebugLog(__VA_ARGS__) |
| #else |
| #define IMGUI_DEBUG_LOG(...) ((void)0) |
| #endif |
| #define IMGUI_DEBUG_LOG_ERROR(...) do { ImGuiContext& g2 = *GImGui; if (g2.DebugLogFlags & ImGuiDebugLogFlags_EventError) IMGUI_DEBUG_LOG(__VA_ARGS__); else g2.DebugLogSkippedErrors++; } while (0) |
| #define IMGUI_DEBUG_LOG_ACTIVEID(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventActiveId) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) |
| #define IMGUI_DEBUG_LOG_FOCUS(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventFocus) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) |
| #define IMGUI_DEBUG_LOG_POPUP(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventPopup) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) |
| #define IMGUI_DEBUG_LOG_NAV(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventNav) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) |
| #define IMGUI_DEBUG_LOG_SELECTION(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventSelection) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) |
| #define IMGUI_DEBUG_LOG_CLIPPER(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventClipper) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) |
| #define IMGUI_DEBUG_LOG_IO(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventIO) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) |
| #define IMGUI_DEBUG_LOG_INPUTROUTING(...) do{if (g.DebugLogFlags & ImGuiDebugLogFlags_EventInputRouting)IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) |
| |
| // Static Asserts |
| #define IM_STATIC_ASSERT(_COND) static_assert(_COND, "") |
| |
| // "Paranoid" Debug Asserts are meant to only be enabled during specific debugging/work, otherwise would slow down the code too much. |
| // We currently don't have many of those so the effect is currently negligible, but onward intent to add more aggressive ones in the code. |
| //#define IMGUI_DEBUG_PARANOID |
| #ifdef IMGUI_DEBUG_PARANOID |
| #define IM_ASSERT_PARANOID(_EXPR) IM_ASSERT(_EXPR) |
| #else |
| #define IM_ASSERT_PARANOID(_EXPR) |
| #endif |
| |
| // Misc Macros |
| #define IM_PI 3.14159265358979323846f |
| #ifdef _WIN32 |
| #define IM_NEWLINE "\r\n" // Play it nice with Windows users (Update: since 2018-05, Notepad finally appears to support Unix-style carriage returns!) |
| #else |
| #define IM_NEWLINE "\n" |
| #endif |
| #ifndef IM_TABSIZE // Until we move this to runtime and/or add proper tab support, at least allow users to compile-time override |
| #define IM_TABSIZE (4) |
| #endif |
| #define IM_MEMALIGN(_OFF,_ALIGN) (((_OFF) + ((_ALIGN) - 1)) & ~((_ALIGN) - 1)) // Memory align e.g. IM_ALIGN(0,4)=0, IM_ALIGN(1,4)=4, IM_ALIGN(4,4)=4, IM_ALIGN(5,4)=8 |
| #define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose |
| #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 |
| #endif |
| |
| // Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall |
| #ifdef _MSC_VER |
| #define IMGUI_CDECL __cdecl |
| #else |
| #define IMGUI_CDECL |
| #endif |
| |
| // Warnings |
| #if defined(_MSC_VER) && !defined(__clang__) |
| #define IM_MSVC_WARNING_SUPPRESS(XXXX) __pragma(warning(suppress: XXXX)) |
| #else |
| #define IM_MSVC_WARNING_SUPPRESS(XXXX) |
| #endif |
| |
| // Debug Tools |
| // Use 'Metrics/Debugger->Tools->Item Picker' to break into the call-stack of a specific item. |
| // This will call IM_DEBUG_BREAK() which you may redefine yourself. See https://github.com/scottt/debugbreak for more reference. |
| #ifndef IM_DEBUG_BREAK |
| #if defined (_MSC_VER) |
| #define IM_DEBUG_BREAK() __debugbreak() |
| #elif defined(__clang__) |
| #define IM_DEBUG_BREAK() __builtin_debugtrap() |
| #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) |
| #define IM_DEBUG_BREAK() __asm__ volatile("int3;nop") |
| #elif defined(__GNUC__) && defined(__thumb__) |
| #define IM_DEBUG_BREAK() __asm__ volatile(".inst 0xde01") |
| #elif defined(__GNUC__) && defined(__arm__) && !defined(__thumb__) |
| #define IM_DEBUG_BREAK() __asm__ volatile(".inst 0xe7f001f0") |
| #else |
| #define IM_DEBUG_BREAK() IM_ASSERT(0) // It is expected that you define IM_DEBUG_BREAK() into something that will break nicely in a debugger! |
| #endif |
| #endif // #ifndef IM_DEBUG_BREAK |
| |
| // Format specifiers, printing 64-bit hasn't been decently standardized... |
| // In a real application you should be using PRId64 and PRIu64 from <inttypes.h> (non-windows) and on Windows define them yourself. |
| #if defined(_MSC_VER) && !defined(__clang__) |
| #define IM_PRId64 "I64d" |
| #define IM_PRIu64 "I64u" |
| #define IM_PRIX64 "I64X" |
| #else |
| #define IM_PRId64 "lld" |
| #define IM_PRIu64 "llu" |
| #define IM_PRIX64 "llX" |
| #endif |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Generic helpers |
| // Note that the ImXXX helpers functions are lower-level than ImGui functions. |
| // ImGui functions or the ImGui context are never called/used from other ImXXX functions. |
| //----------------------------------------------------------------------------- |
| // - Helpers: Hashing |
| // - Helpers: Sorting |
| // - Helpers: Bit manipulation |
| // - Helpers: String |
| // - Helpers: Formatting |
| // - Helpers: UTF-8 <> wchar conversions |
| // - Helpers: ImVec2/ImVec4 operators |
| // - Helpers: Maths |
| // - Helpers: Geometry |
| // - Helper: ImVec1 |
| // - Helper: ImVec2ih |
| // - Helper: ImRect |
| // - Helper: ImBitArray |
| // - Helper: ImBitVector |
| // - Helper: ImSpan<>, ImSpanAllocator<> |
| // - Helper: ImPool<> |
| // - Helper: ImChunkStream<> |
| // - Helper: ImGuiTextIndex |
| // - Helper: ImGuiStorage |
| //----------------------------------------------------------------------------- |
| |
| // Helpers: Hashing |
| IMGUI_API ImGuiID ImHashData(const void* data, size_t data_size, ImGuiID seed = 0); |
| IMGUI_API ImGuiID ImHashStr(const char* data, size_t data_size = 0, ImGuiID seed = 0); |
| |
| // Helpers: Sorting |
| #ifndef ImQsort |
| static inline void ImQsort(void* base, size_t count, size_t size_of_element, int(IMGUI_CDECL *compare_func)(void const*, void const*)) { if (count > 1) qsort(base, count, size_of_element, compare_func); } |
| #endif |
| |
| // Helpers: Color Blending |
| IMGUI_API ImU32 ImAlphaBlendColors(ImU32 col_a, ImU32 col_b); |
| |
| // Helpers: Bit manipulation |
| static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; } |
| static inline bool ImIsPowerOfTwo(ImU64 v) { return v != 0 && (v & (v - 1)) == 0; } |
| static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } |
| |
| // Helpers: String |
| IMGUI_API int ImStricmp(const char* str1, const char* str2); // Case insensitive compare. |
| IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count); // Case insensitive compare to a certain count. |
| IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); // Copy to a certain count and always zero terminate (strncpy doesn't). |
| IMGUI_API char* ImStrdup(const char* str); // Duplicate a string. |
| IMGUI_API char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* str); // Copy in provided buffer, recreate buffer if needed. |
| IMGUI_API const char* ImStrchrRange(const char* str_begin, const char* str_end, char c); // Find first occurrence of 'c' in string range. |
| IMGUI_API const char* ImStreolRange(const char* str, const char* str_end); // End end-of-line |
| IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end); // Find a substring in a string range. |
| IMGUI_API void ImStrTrimBlanks(char* str); // Remove leading and trailing blanks from a buffer. |
| IMGUI_API const char* ImStrSkipBlank(const char* str); // Find first non-blank character. |
| IMGUI_API int ImStrlenW(const ImWchar* str); // Computer string length (ImWchar string) |
| IMGUI_API const char* ImStrbol(const char* buf_mid_line, const char* buf_begin); // Find beginning-of-line |
| IM_MSVC_RUNTIME_CHECKS_OFF |
| static inline char ImToUpper(char c) { return (c >= 'a' && c <= 'z') ? c &= ~32 : c; } |
| static inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; } |
| static inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; } |
| static inline bool ImCharIsXdigitA(char c) { return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); } |
| IM_MSVC_RUNTIME_CHECKS_RESTORE |
| |
| // Helpers: Formatting |
| IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) IM_FMTARGS(3); |
| IMGUI_API int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) IM_FMTLIST(3); |
| IMGUI_API void ImFormatStringToTempBuffer(const char** out_buf, const char** out_buf_end, const char* fmt, ...) IM_FMTARGS(3); |
| IMGUI_API void ImFormatStringToTempBufferV(const char** out_buf, const char** out_buf_end, const char* fmt, va_list args) IM_FMTLIST(3); |
| IMGUI_API const char* ImParseFormatFindStart(const char* format); |
| IMGUI_API const char* ImParseFormatFindEnd(const char* format); |
| IMGUI_API const char* ImParseFormatTrimDecorations(const char* format, char* buf, size_t buf_size); |
| IMGUI_API void ImParseFormatSanitizeForPrinting(const char* fmt_in, char* fmt_out, size_t fmt_out_size); |
| IMGUI_API const char* ImParseFormatSanitizeForScanning(const char* fmt_in, char* fmt_out, size_t fmt_out_size); |
| IMGUI_API int ImParseFormatPrecision(const char* format, int default_value); |
| |
| // Helpers: UTF-8 <> wchar conversions |
| IMGUI_API const char* ImTextCharToUtf8(char out_buf[5], unsigned int c); // return out_buf |
| IMGUI_API int ImTextStrToUtf8(char* out_buf, int out_buf_size, const ImWchar* in_text, const ImWchar* in_text_end); // return output UTF-8 bytes count |
| IMGUI_API int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end); // read one character. return input UTF-8 bytes count |
| IMGUI_API int ImTextStrFromUtf8(ImWchar* out_buf, int out_buf_size, const char* in_text, const char* in_text_end, const char** in_remaining = NULL); // return input UTF-8 bytes count |
| 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 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: File System |
| #ifdef IMGUI_DISABLE_FILE_FUNCTIONS |
| #define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS |
| typedef void* ImFileHandle; |
| static inline ImFileHandle ImFileOpen(const char*, const char*) { return NULL; } |
| static inline bool ImFileClose(ImFileHandle) { return false; } |
| static inline ImU64 ImFileGetSize(ImFileHandle) { return (ImU64)-1; } |
| static inline ImU64 ImFileRead(void*, ImU64, ImU64, ImFileHandle) { return 0; } |
| static inline ImU64 ImFileWrite(const void*, ImU64, ImU64, ImFileHandle) { return 0; } |
| #endif |
| #ifndef IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS |
| typedef FILE* ImFileHandle; |
| IMGUI_API ImFileHandle ImFileOpen(const char* filename, const char* mode); |
| IMGUI_API bool ImFileClose(ImFileHandle file); |
| IMGUI_API ImU64 ImFileGetSize(ImFileHandle file); |
| IMGUI_API ImU64 ImFileRead(void* data, ImU64 size, ImU64 count, ImFileHandle file); |
| IMGUI_API ImU64 ImFileWrite(const void* data, ImU64 size, ImU64 count, ImFileHandle file); |
| #else |
| #define IMGUI_DISABLE_TTY_FUNCTIONS // Can't use stdout, fflush if we are not using default file functions |
| #endif |
| IMGUI_API void* ImFileLoadToMemory(const char* filename, const char* mode, size_t* out_file_size = NULL, int padding_bytes = 0); |
| |
| // Helpers: Maths |
| IM_MSVC_RUNTIME_CHECKS_OFF |
| // - Wrapper for standard libs functions. (Note that imgui_demo.cpp does _not_ use them to keep the code easy to copy) |
| #ifndef IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS |
| #define ImFabs(X) fabsf(X) |
| #define ImSqrt(X) sqrtf(X) |
| #define ImFmod(X, Y) fmodf((X), (Y)) |
| #define ImCos(X) cosf(X) |
| #define ImSin(X) sinf(X) |
| #define ImAcos(X) acosf(X) |
| #define ImAtan2(Y, X) atan2f((Y), (X)) |
| #define ImAtof(STR) atof(STR) |
| #define ImCeil(X) ceilf(X) |
| static inline float ImPow(float x, float y) { return powf(x, y); } // DragBehaviorT/SliderBehaviorT uses ImPow with either float/double and need the precision |
| static inline double ImPow(double x, double y) { return pow(x, y); } |
| static inline float ImLog(float x) { return logf(x); } // DragBehaviorT/SliderBehaviorT uses ImLog with either float/double and need the precision |
| static inline double ImLog(double x) { return log(x); } |
| static inline int ImAbs(int x) { return x < 0 ? -x : x; } |
| static inline float ImAbs(float x) { return fabsf(x); } |
| static inline double ImAbs(double x) { return fabs(x); } |
| static inline float ImSign(float x) { return (x < 0.0f) ? -1.0f : (x > 0.0f) ? 1.0f : 0.0f; } // Sign operator - returns -1, 0 or 1 based on sign of argument |
| static inline double ImSign(double x) { return (x < 0.0) ? -1.0 : (x > 0.0) ? 1.0 : 0.0; } |
| #ifdef IMGUI_ENABLE_SSE |
| static inline float ImRsqrt(float x) { return _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(x))); } |
| #else |
| static inline float ImRsqrt(float x) { return 1.0f / sqrtf(x); } |
| #endif |
| static inline double ImRsqrt(double x) { return 1.0 / sqrt(x); } |
| #endif |
| // - ImMin/ImMax/ImClamp/ImLerp/ImSwap are used by widgets which support variety of types: signed/unsigned int/long long float/double |
| // (Exceptionally using templates here but we could also redefine them for those types) |
| template<typename T> static inline T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; } |
| template<typename T> static inline T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; } |
| template<typename T> static inline T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } |
| template<typename T> static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * t); } |
| template<typename T> static inline void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; } |
| template<typename T> static inline T ImAddClampOverflow(T a, T b, T mn, T mx) { if (b < 0 && (a < mn - b)) return mn; if (b > 0 && (a > mx - b)) return mx; return a + b; } |
| template<typename T> static inline T ImSubClampOverflow(T a, T b, T mn, T mx) { if (b > 0 && (a < mn + b)) return mn; if (b < 0 && (a > mx + b)) return mx; return a - b; } |
| // - Misc maths helpers |
| static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y); } |
| static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y); } |
| static inline ImVec2 ImClamp(const ImVec2& v, const ImVec2&mn, const ImVec2&mx) { return ImVec2((v.x < mn.x) ? mn.x : (v.x > mx.x) ? mx.x : v.x, (v.y < mn.y) ? mn.y : (v.y > mx.y) ? mx.y : v.y); } |
| static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t) { return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t); } |
| static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); } |
| static inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); } |
| static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; } |
| static inline float ImLengthSqr(const ImVec2& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y); } |
| static inline float ImLengthSqr(const ImVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); } |
| static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return ImRsqrt(d); return fail_value; } |
| static inline float ImTrunc(float f) { return (float)(int)(f); } |
| static inline ImVec2 ImTrunc(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); } |
| static inline float ImFloor(float f) { return (float)((f >= 0 || (float)(int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf() |
| static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2(ImFloor(v.x), ImFloor(v.y)); } |
| static inline int ImModPositive(int a, int b) { return (a + b) % b; } |
| static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; } |
| static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); } |
| static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; } |
| static inline float ImLinearRemapClamp(float s0, float s1, float d0, float d1, float x) { return ImSaturate((x - s0) / (s1 - s0)) * (d1 - d0) + d0; } |
| static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } |
| static inline bool ImIsFloatAboveGuaranteedIntegerPrecision(float f) { return f <= -16777216 || f >= 16777216; } |
| static inline float ImExponentialMovingAverage(float avg, float sample, int n) { avg -= avg / n; avg += sample / n; return avg; } |
| IM_MSVC_RUNTIME_CHECKS_RESTORE |
| |
| // Helpers: Geometry |
| IMGUI_API ImVec2 ImBezierCubicCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, float t); |
| IMGUI_API ImVec2 ImBezierCubicClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, int num_segments); // For curves with explicit number of segments |
| IMGUI_API ImVec2 ImBezierCubicClosestPointCasteljau(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float tess_tol);// For auto-tessellated curves you can use tess_tol = style.CurveTessellationTol |
| IMGUI_API ImVec2 ImBezierQuadraticCalc(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, float t); |
| IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p); |
| IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); |
| IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); |
| IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p, float& out_u, float& out_v, float& out_w); |
| inline float ImTriangleArea(const ImVec2& a, const ImVec2& b, const ImVec2& c) { return ImFabs((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x * (a.y - b.y))) * 0.5f; } |
| inline bool ImTriangleIsClockwise(const ImVec2& a, const ImVec2& b, const ImVec2& c) { return ((b.x - a.x) * (c.y - b.y)) - ((c.x - b.x) * (b.y - a.y)) > 0.0f; } |
| |
| // Helper: ImVec1 (1D vector) |
| // (this odd construct is used to facilitate the transition between 1D and 2D, and the maintenance of some branches/patches) |
| IM_MSVC_RUNTIME_CHECKS_OFF |
| struct ImVec1 |
| { |
| float x; |
| constexpr ImVec1() : x(0.0f) { } |
| constexpr ImVec1(float _x) : x(_x) { } |
| }; |
| |
| // Helper: ImVec2ih (2D vector, half-size integer, for long-term packed storage) |
| struct ImVec2ih |
| { |
| short x, y; |
| constexpr ImVec2ih() : x(0), y(0) {} |
| constexpr ImVec2ih(short _x, short _y) : x(_x), y(_y) {} |
| constexpr explicit ImVec2ih(const ImVec2& rhs) : x((short)rhs.x), y((short)rhs.y) {} |
| }; |
| |
| // Helper: ImRect (2D axis aligned bounding-box) |
| // NB: we can't rely on ImVec2 math operators being available here! |
| struct IMGUI_API ImRect |
| { |
| ImVec2 Min; // Upper-left |
| ImVec2 Max; // Lower-right |
| |
| constexpr ImRect() : Min(0.0f, 0.0f), Max(0.0f, 0.0f) {} |
| constexpr ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {} |
| constexpr ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {} |
| constexpr ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {} |
| |
| ImVec2 GetCenter() const { return ImVec2((Min.x + Max.x) * 0.5f, (Min.y + Max.y) * 0.5f); } |
| ImVec2 GetSize() const { return ImVec2(Max.x - Min.x, Max.y - Min.y); } |
| float GetWidth() const { return Max.x - Min.x; } |
| float GetHeight() const { return Max.y - Min.y; } |
| float GetArea() const { return (Max.x - Min.x) * (Max.y - Min.y); } |
| ImVec2 GetTL() const { return Min; } // Top-left |
| ImVec2 GetTR() const { return ImVec2(Max.x, Min.y); } // Top-right |
| ImVec2 GetBL() const { return ImVec2(Min.x, Max.y); } // Bottom-left |
| ImVec2 GetBR() const { return Max; } // Bottom-right |
| bool Contains(const ImVec2& p) const { return p.x >= Min.x && p.y >= Min.y && p.x < Max.x && p.y < Max.y; } |
| bool Contains(const ImRect& r) const { return r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x <= Max.x && r.Max.y <= Max.y; } |
| bool ContainsWithPad(const ImVec2& p, const ImVec2& pad) const { return p.x >= Min.x - pad.x && p.y >= Min.y - pad.y && p.x < Max.x + pad.x && p.y < Max.y + pad.y; } |
| bool Overlaps(const ImRect& r) const { return r.Min.y < Max.y && r.Max.y > Min.y && r.Min.x < Max.x && r.Max.x > Min.x; } |
| void Add(const ImVec2& p) { if (Min.x > p.x) Min.x = p.x; if (Min.y > p.y) Min.y = p.y; if (Max.x < p.x) Max.x = p.x; if (Max.y < p.y) Max.y = p.y; } |
| void Add(const ImRect& r) { if (Min.x > r.Min.x) Min.x = r.Min.x; if (Min.y > r.Min.y) Min.y = r.Min.y; if (Max.x < r.Max.x) Max.x = r.Max.x; if (Max.y < r.Max.y) Max.y = r.Max.y; } |
| void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; } |
| void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; } |
| void Translate(const ImVec2& d) { Min.x += d.x; Min.y += d.y; Max.x += d.x; Max.y += d.y; } |
| void TranslateX(float dx) { Min.x += dx; Max.x += dx; } |
| void TranslateY(float dy) { Min.y += dy; Max.y += dy; } |
| void ClipWith(const ImRect& r) { Min = ImMax(Min, r.Min); Max = ImMin(Max, r.Max); } // Simple version, may lead to an inverted rectangle, which is fine for Contains/Overlaps test but not for display. |
| void ClipWithFull(const ImRect& r) { Min = ImClamp(Min, r.Min, r.Max); Max = ImClamp(Max, r.Min, r.Max); } // Full version, ensure both points are fully clipped. |
| void Floor() { Min.x = IM_TRUNC(Min.x); Min.y = IM_TRUNC(Min.y); Max.x = IM_TRUNC(Max.x); Max.y = IM_TRUNC(Max.y); } |
| bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; } |
| ImVec4 ToVec4() const { return ImVec4(Min.x, Min.y, Max.x, Max.y); } |
| }; |
| |
| // Helper: ImBitArray |
| #define IM_BITARRAY_TESTBIT(_ARRAY, _N) ((_ARRAY[(_N) >> 5] & ((ImU32)1 << ((_N) & 31))) != 0) // Macro version of ImBitArrayTestBit(): ensure args have side-effect or are costly! |
| #define IM_BITARRAY_CLEARBIT(_ARRAY, _N) ((_ARRAY[(_N) >> 5] &= ~((ImU32)1 << ((_N) & 31)))) // Macro version of ImBitArrayClearBit(): ensure args have side-effect or are costly! |
| inline size_t ImBitArrayGetStorageSizeInBytes(int bitcount) { return (size_t)((bitcount + 31) >> 5) << 2; } |
| inline void ImBitArrayClearAllBits(ImU32* arr, int bitcount){ memset(arr, 0, ImBitArrayGetStorageSizeInBytes(bitcount)); } |
| inline bool ImBitArrayTestBit(const ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); return (arr[n >> 5] & mask) != 0; } |
| inline void ImBitArrayClearBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] &= ~mask; } |
| inline void ImBitArraySetBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] |= mask; } |
| inline void ImBitArraySetBitRange(ImU32* arr, int n, int n2) // Works on range [n..n2) |
| { |
| n2--; |
| while (n <= n2) |
| { |
| int a_mod = (n & 31); |
| int b_mod = (n2 > (n | 31) ? 31 : (n2 & 31)) + 1; |
| ImU32 mask = (ImU32)(((ImU64)1 << b_mod) - 1) & ~(ImU32)(((ImU64)1 << a_mod) - 1); |
| arr[n >> 5] |= mask; |
| n = (n + 32) & ~31; |
| } |
| } |
| |
| typedef ImU32* ImBitArrayPtr; // Name for use in structs |
| |
| // Helper: ImBitArray class (wrapper over ImBitArray functions) |
| // Store 1-bit per value. |
| template<int BITCOUNT, int OFFSET = 0> |
| struct ImBitArray |
| { |
| ImU32 Storage[(BITCOUNT + 31) >> 5]; |
| ImBitArray() { ClearAllBits(); } |
| void ClearAllBits() { memset(Storage, 0, sizeof(Storage)); } |
| void SetAllBits() { memset(Storage, 255, sizeof(Storage)); } |
| bool TestBit(int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return IM_BITARRAY_TESTBIT(Storage, n); } |
| void SetBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArraySetBit(Storage, n); } |
| void ClearBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArrayClearBit(Storage, n); } |
| void SetBitRange(int n, int n2) { n += OFFSET; n2 += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT && n2 > n && n2 <= BITCOUNT); ImBitArraySetBitRange(Storage, n, n2); } // Works on range [n..n2) |
| bool operator[](int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return IM_BITARRAY_TESTBIT(Storage, n); } |
| }; |
| |
| // Helper: ImBitVector |
| // Store 1-bit per value. |
| struct IMGUI_API ImBitVector |
| { |
| ImVector<ImU32> Storage; |
| void Create(int sz) { Storage.resize((sz + 31) >> 5); memset(Storage.Data, 0, (size_t)Storage.Size * sizeof(Storage.Data[0])); } |
| void Clear() { Storage.clear(); } |
| bool TestBit(int n) const { IM_ASSERT(n < (Storage.Size << 5)); return IM_BITARRAY_TESTBIT(Storage.Data, n); } |
| void SetBit(int n) { IM_ASSERT(n < (Storage.Size << 5)); ImBitArraySetBit(Storage.Data, n); } |
| void ClearBit(int n) { IM_ASSERT(n < (Storage.Size << 5)); ImBitArrayClearBit(Storage.Data, n); } |
| }; |
| IM_MSVC_RUNTIME_CHECKS_RESTORE |
| |
| // Helper: ImSpan<> |
| // Pointing to a span of data we don't own. |
| template<typename T> |
| struct ImSpan |
| { |
| T* Data; |
| T* DataEnd; |
| |
| // Constructors, destructor |
| inline ImSpan() { Data = DataEnd = NULL; } |
| inline ImSpan(T* data, int size) { Data = data; DataEnd = data + size; } |
| inline ImSpan(T* data, T* data_end) { Data = data; DataEnd = data_end; } |
| |
| inline void set(T* data, int size) { Data = data; DataEnd = data + size; } |
| inline void set(T* data, T* data_end) { Data = data; DataEnd = data_end; } |
| inline int size() const { return (int)(ptrdiff_t)(DataEnd - Data); } |
| inline int size_in_bytes() const { return (int)(ptrdiff_t)(DataEnd - Data) * (int)sizeof(T); } |
| inline T& operator[](int i) { T* p = Data + i; IM_ASSERT(p >= Data && p < DataEnd); return *p; } |
| inline const T& operator[](int i) const { const T* p = Data + i; IM_ASSERT(p >= Data && p < DataEnd); return *p; } |
| |
| inline T* begin() { return Data; } |
| inline const T* begin() const { return Data; } |
| inline T* end() { return DataEnd; } |
| inline const T* end() const { return DataEnd; } |
| |
| // Utilities |
| inline int index_from_ptr(const T* it) const { IM_ASSERT(it >= Data && it < DataEnd); const ptrdiff_t off = it - Data; return (int)off; } |
| }; |
| |
| // Helper: ImSpanAllocator<> |
| // Facilitate storing multiple chunks into a single large block (the "arena") |
| // - Usage: call Reserve() N times, allocate GetArenaSizeInBytes() worth, pass it to SetArenaBasePtr(), call GetSpan() N times to retrieve the aligned ranges. |
| template<int CHUNKS> |
| struct ImSpanAllocator |
| { |
| char* BasePtr; |
| int CurrOff; |
| int CurrIdx; |
| int Offsets[CHUNKS]; |
| int Sizes[CHUNKS]; |
| |
| ImSpanAllocator() { memset(this, 0, sizeof(*this)); } |
| inline void Reserve(int n, size_t sz, int a=4) { IM_ASSERT(n == CurrIdx && n < CHUNKS); CurrOff = IM_MEMALIGN(CurrOff, a); Offsets[n] = CurrOff; Sizes[n] = (int)sz; CurrIdx++; CurrOff += (int)sz; } |
| inline int GetArenaSizeInBytes() { return CurrOff; } |
| inline void SetArenaBasePtr(void* base_ptr) { BasePtr = (char*)base_ptr; } |
| inline void* GetSpanPtrBegin(int n) { IM_ASSERT(n >= 0 && n < CHUNKS && CurrIdx == CHUNKS); return (void*)(BasePtr + Offsets[n]); } |
| inline void* GetSpanPtrEnd(int n) { IM_ASSERT(n >= 0 && n < CHUNKS && CurrIdx == CHUNKS); return (void*)(BasePtr + Offsets[n] + Sizes[n]); } |
| template<typename T> |
| inline void GetSpan(int n, ImSpan<T>* span) { span->set((T*)GetSpanPtrBegin(n), (T*)GetSpanPtrEnd(n)); } |
| }; |
| |
| // Helper: ImPool<> |
| // Basic keyed storage for contiguous instances, slow/amortized insertion, O(1) indexable, O(Log N) queries by ID over a dense/hot buffer, |
| // Honor constructor/destructor. Add/remove invalidate all pointers. Indexes have the same lifetime as the associated object. |
| typedef int ImPoolIdx; |
| template<typename T> |
| struct ImPool |
| { |
| ImVector<T> Buf; // Contiguous data |
| ImGuiStorage Map; // ID->Index |
| ImPoolIdx FreeIdx; // Next free idx to use |
| ImPoolIdx AliveCount; // Number of active/alive items (for display purpose) |
| |
| ImPool() { FreeIdx = AliveCount = 0; } |
| ~ImPool() { Clear(); } |
| T* GetByKey(ImGuiID key) { int idx = Map.GetInt(key, -1); return (idx != -1) ? &Buf[idx] : NULL; } |
| T* GetByIndex(ImPoolIdx n) { return &Buf[n]; } |
| ImPoolIdx GetIndex(const T* p) const { IM_ASSERT(p >= Buf.Data && p < Buf.Data + Buf.Size); return (ImPoolIdx)(p - Buf.Data); } |
| T* GetOrAddByKey(ImGuiID key) { int* p_idx = Map.GetIntRef(key, -1); if (*p_idx != -1) return &Buf[*p_idx]; *p_idx = FreeIdx; return Add(); } |
| bool Contains(const T* p) const { return (p >= Buf.Data && p < Buf.Data + Buf.Size); } |
| void Clear() { for (int n = 0; n < Map.Data.Size; n++) { int idx = Map.Data[n].val_i; if (idx != -1) Buf[idx].~T(); } Map.Clear(); Buf.clear(); FreeIdx = AliveCount = 0; } |
| T* Add() { int idx = FreeIdx; if (idx == Buf.Size) { Buf.resize(Buf.Size + 1); FreeIdx++; } else { FreeIdx = *(int*)&Buf[idx]; } IM_PLACEMENT_NEW(&Buf[idx]) T(); AliveCount++; return &Buf[idx]; } |
| void Remove(ImGuiID key, const T* p) { Remove(key, GetIndex(p)); } |
| void Remove(ImGuiID key, ImPoolIdx idx) { Buf[idx].~T(); *(int*)&Buf[idx] = FreeIdx; FreeIdx = idx; Map.SetInt(key, -1); AliveCount--; } |
| void Reserve(int capacity) { Buf.reserve(capacity); Map.Data.reserve(capacity); } |
| |
| // To iterate a ImPool: for (int n = 0; n < pool.GetMapSize(); n++) if (T* t = pool.TryGetMapData(n)) { ... } |
| // Can be avoided if you know .Remove() has never been called on the pool, or AliveCount == GetMapSize() |
| int GetAliveCount() const { return AliveCount; } // Number of active/alive items in the pool (for display purpose) |
| int GetBufSize() const { return Buf.Size; } |
| int GetMapSize() const { return Map.Data.Size; } // It is the map we need iterate to find valid items, since we don't have "alive" storage anywhere |
| T* TryGetMapData(ImPoolIdx n) { int idx = Map.Data[n].val_i; if (idx == -1) return NULL; return GetByIndex(idx); } |
| }; |
| |
| // Helper: ImChunkStream<> |
| // Build and iterate a contiguous stream of variable-sized structures. |
| // This is used by Settings to store persistent data while reducing allocation count. |
| // We store the chunk size first, and align the final size on 4 bytes boundaries. |
| // The tedious/zealous amount of casting is to avoid -Wcast-align warnings. |
| template<typename T> |
| struct ImChunkStream |
| { |
| ImVector<char> Buf; |
| |
| void clear() { Buf.clear(); } |
| bool empty() const { return Buf.Size == 0; } |
| int size() const { return Buf.Size; } |
| T* alloc_chunk(size_t sz) { size_t HDR_SZ = 4; sz = IM_MEMALIGN(HDR_SZ + sz, 4u); int off = Buf.Size; Buf.resize(off + (int)sz); ((int*)(void*)(Buf.Data + off))[0] = (int)sz; return (T*)(void*)(Buf.Data + off + (int)HDR_SZ); } |
| T* begin() { size_t HDR_SZ = 4; if (!Buf.Data) return NULL; return (T*)(void*)(Buf.Data + HDR_SZ); } |
| T* next_chunk(T* p) { size_t HDR_SZ = 4; IM_ASSERT(p >= begin() && p < end()); p = (T*)(void*)((char*)(void*)p + chunk_size(p)); if (p == (T*)(void*)((char*)end() + HDR_SZ)) return (T*)0; IM_ASSERT(p < end()); return p; } |
| int chunk_size(const T* p) { return ((const int*)p)[-1]; } |
| T* end() { return (T*)(void*)(Buf.Data + Buf.Size); } |
| int offset_from_ptr(const T* p) { IM_ASSERT(p >= begin() && p < end()); const ptrdiff_t off = (const char*)p - Buf.Data; return (int)off; } |
| T* ptr_from_offset(int off) { IM_ASSERT(off >= 4 && off < Buf.Size); return (T*)(void*)(Buf.Data + off); } |
| void swap(ImChunkStream<T>& rhs) { rhs.Buf.swap(Buf); } |
| }; |
| |
| // Helper: ImGuiTextIndex |
| // Maintain a line index for a text buffer. This is a strong candidate to be moved into the public API. |
| struct ImGuiTextIndex |
| { |
| ImVector<int> LineOffsets; |
| int EndOffset = 0; // Because we don't own text buffer we need to maintain EndOffset (may bake in LineOffsets?) |
| |
| void clear() { LineOffsets.clear(); EndOffset = 0; } |
| int size() { return LineOffsets.Size; } |
| const char* get_line_begin(const char* base, int n) { return base + LineOffsets[n]; } |
| const char* get_line_end(const char* base, int n) { return base + (n + 1 < LineOffsets.Size ? (LineOffsets[n + 1] - 1) : EndOffset); } |
| void append(const char* base, int old_size, int new_size); |
| }; |
| |
| // Helper: ImGuiStorage |
| IMGUI_API ImGuiStoragePair* ImLowerBound(ImGuiStoragePair* in_begin, ImGuiStoragePair* in_end, ImGuiID key); |
| //----------------------------------------------------------------------------- |
| // [SECTION] ImDrawList support |
| //----------------------------------------------------------------------------- |
| |
| // ImDrawList: Helper function to calculate a circle's segment count given its radius and a "maximum error" value. |
| // Estimation of number of circle segment based on error is derived using method described in https://stackoverflow.com/a/2244088/15194693 |
| // Number of segments (N) is calculated using equation: |
| // N = ceil ( pi / acos(1 - error / r) ) where r > 0, error <= r |
| // Our equation is significantly simpler that one in the post thanks for choosing segment that is |
| // perpendicular to X axis. Follow steps in the article from this starting condition and you will |
| // will get this result. |
| // |
| // Rendering circles with an odd number of segments, while mathematically correct will produce |
| // asymmetrical results on the raster grid. Therefore we're rounding N to next even number (7->8, 8->8, 9->10 etc.) |
| #define IM_ROUNDUP_TO_EVEN(_V) ((((_V) + 1) / 2) * 2) |
| #define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN 4 |
| #define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX 512 |
| #define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(_RAD,_MAXERROR) ImClamp(IM_ROUNDUP_TO_EVEN((int)ImCeil(IM_PI / ImAcos(1 - ImMin((_MAXERROR), (_RAD)) / (_RAD)))), IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN, IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX) |
| |
| // Raw equation from IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC rewritten for 'r' and 'error'. |
| #define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_R(_N,_MAXERROR) ((_MAXERROR) / (1 - ImCos(IM_PI / ImMax((float)(_N), IM_PI)))) |
| #define IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_ERROR(_N,_RAD) ((1 - ImCos(IM_PI / ImMax((float)(_N), IM_PI))) / (_RAD)) |
| |
| // ImDrawList: Lookup table size for adaptive arc drawing, cover full circle. |
| #ifndef IM_DRAWLIST_ARCFAST_TABLE_SIZE |
| #define IM_DRAWLIST_ARCFAST_TABLE_SIZE 48 // Number of samples in lookup table. |
| #endif |
| #define IM_DRAWLIST_ARCFAST_SAMPLE_MAX IM_DRAWLIST_ARCFAST_TABLE_SIZE // Sample index _PathArcToFastEx() for 360 angle. |
| |
| // Data shared between all ImDrawList instances |
| // You may want to create your own instance of this if you want to use ImDrawList completely without ImGui. In that case, watch out for future changes to this structure. |
| struct IMGUI_API ImDrawListSharedData |
| { |
| ImVec2 TexUvWhitePixel; // UV of white pixel in the atlas |
| ImFont* Font; // Current/default font (optional, for simplified AddText overload) |
| float FontSize; // Current/default font size (optional, for simplified AddText overload) |
| float FontScale; // Current/default font scale (== FontSize / Font->FontSize) |
| float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() |
| float CircleSegmentMaxError; // Number of circle segments to use per pixel of radius for AddCircle() etc |
| ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen() |
| ImDrawListFlags InitialFlags; // Initial flags at the beginning of the frame (it is possible to alter flags on a per-drawlist basis afterwards) |
| |
| // [Internal] Temp write buffer |
| ImVector<ImVec2> TempBuffer; |
| |
| // [Internal] Lookup tables |
| ImVec2 ArcFastVtx[IM_DRAWLIST_ARCFAST_TABLE_SIZE]; // Sample points on the quarter of the circle. |
| float ArcFastRadiusCutoff; // Cutoff radius after which arc drawing will fallback to slower PathArcTo() |
| ImU8 CircleSegmentCounts[64]; // Precomputed segment count for given radius before we calculate it dynamically (to avoid calculation overhead) |
| const ImVec4* TexUvLines; // UV of anti-aliased lines in the atlas |
| |
| ImDrawListSharedData(); |
| void SetCircleTessellationMaxError(float max_error); |
| }; |
| |
| struct ImDrawDataBuilder |
| { |
| ImVector<ImDrawList*>* Layers[2]; // Pointers to global layers for: regular, tooltip. LayersP[0] is owned by DrawData. |
| ImVector<ImDrawList*> LayerData1; |
| |
| ImDrawDataBuilder() { memset(this, 0, sizeof(*this)); } |
| }; |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Data types support |
| //----------------------------------------------------------------------------- |
| |
| struct ImGuiDataVarInfo |
| { |
| ImGuiDataType Type; |
| ImU32 Count; // 1+ |
| ImU32 Offset; // Offset in parent structure |
| void* GetVarPtr(void* parent) const { return (void*)((unsigned char*)parent + Offset); } |
| }; |
| |
| struct ImGuiDataTypeStorage |
| { |
| ImU8 Data[8]; // Opaque storage to fit any data up to ImGuiDataType_COUNT |
| }; |
| |
| // Type information associated to one ImGuiDataType. Retrieve with DataTypeGetInfo(). |
| struct ImGuiDataTypeInfo |
| { |
| size_t Size; // Size in bytes |
| const char* Name; // Short descriptive name for the type, for debugging |
| const char* PrintFmt; // Default printf format for the type |
| const char* ScanFmt; // Default scanf format for the type |
| }; |
| |
| // Extend ImGuiDataType_ |
| enum ImGuiDataTypePrivate_ |
| { |
| ImGuiDataType_String = ImGuiDataType_COUNT + 1, |
| ImGuiDataType_Pointer, |
| ImGuiDataType_ID, |
| }; |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Widgets support: flags, enums, data structures |
| //----------------------------------------------------------------------------- |
| |
| // Extend ImGuiItemFlags |
| // - input: PushItemFlag() manipulates g.CurrentItemFlags, g.NextItemData.ItemFlags, ItemAdd() calls may add extra flags too. |
| // - output: stored in g.LastItemData.ItemFlags |
| enum ImGuiItemFlagsPrivate_ |
| { |
| // Controlled by user |
| ImGuiItemFlags_Disabled = 1 << 10, // false // Disable interactions (DOES NOT affect visuals. DO NOT mix direct use of this with BeginDisabled(). See BeginDisabled()/EndDisabled() for full disable feature, and github #211). |
| ImGuiItemFlags_ReadOnly = 1 << 11, // false // [ALPHA] Allow hovering interactions but underlying value is not changed. |
| ImGuiItemFlags_MixedValue = 1 << 12, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets) |
| ImGuiItemFlags_NoWindowHoverableCheck = 1 << 13, // false // Disable hoverable check in ItemHoverable() |
| ImGuiItemFlags_AllowOverlap = 1 << 14, // false // Allow being overlapped by another widget. Not-hovered to Hovered transition deferred by a frame. |
| ImGuiItemFlags_NoNavDisableMouseHover = 1 << 15, // false // Nav keyboard/gamepad mode doesn't disable hover highlight (behave as if NavHighlightItemUnderNav==false). |
| ImGuiItemFlags_NoMarkEdited = 1 << 16, // false // Skip calling MarkItemEdited() |
| |
| // Controlled by widget code |
| ImGuiItemFlags_Inputable = 1 << 20, // false // [WIP] Auto-activate input mode when tab focused. Currently only used and supported by a few items before it becomes a generic feature. |
| ImGuiItemFlags_HasSelectionUserData = 1 << 21, // false // Set by SetNextItemSelectionUserData() |
| ImGuiItemFlags_IsMultiSelect = 1 << 22, // false // Set by SetNextItemSelectionUserData() |
| |
| ImGuiItemFlags_Default_ = ImGuiItemFlags_AutoClosePopups, // Please don't change, use PushItemFlag() instead. |
| |
| // Obsolete |
| //ImGuiItemFlags_SelectableDontClosePopup = !ImGuiItemFlags_AutoClosePopups, // Can't have a redirect as we inverted the behavior |
| }; |
| |
| // Status flags for an already submitted item |
| // - output: stored in g.LastItemData.StatusFlags |
| enum ImGuiItemStatusFlags_ |
| { |
| ImGuiItemStatusFlags_None = 0, |
| ImGuiItemStatusFlags_HoveredRect = 1 << 0, // Mouse position is within item rectangle (does NOT mean that the window is in correct z-order and can be hovered!, this is only one part of the most-common IsItemHovered test) |
| ImGuiItemStatusFlags_HasDisplayRect = 1 << 1, // g.LastItemData.DisplayRect is valid |
| ImGuiItemStatusFlags_Edited = 1 << 2, // Value exposed by item was edited in the current frame (should match the bool return value of most widgets) |
| ImGuiItemStatusFlags_ToggledSelection = 1 << 3, // Set when Selectable(), TreeNode() reports toggling a selection. We can't report "Selected", only state changes, in order to easily handle clipping with less issues. |
| ImGuiItemStatusFlags_ToggledOpen = 1 << 4, // Set when TreeNode() reports toggling their open state. |
| ImGuiItemStatusFlags_HasDeactivated = 1 << 5, // Set if the widget/group is able to provide data for the ImGuiItemStatusFlags_Deactivated flag. |
| ImGuiItemStatusFlags_Deactivated = 1 << 6, // Only valid if ImGuiItemStatusFlags_HasDeactivated is set. |
| ImGuiItemStatusFlags_HoveredWindow = 1 << 7, // Override the HoveredWindow test to allow cross-window hover testing. |
| ImGuiItemStatusFlags_Visible = 1 << 8, // [WIP] Set when item is overlapping the current clipping rectangle (Used internally. Please don't use yet: API/system will change as we refactor Itemadd()). |
| ImGuiItemStatusFlags_HasClipRect = 1 << 9, // g.LastItemData.ClipRect is valid. |
| ImGuiItemStatusFlags_HasShortcut = 1 << 10, // g.LastItemData.Shortcut valid. Set by SetNextItemShortcut() -> ItemAdd(). |
| |
| // Additional status + semantic for ImGuiTestEngine |
| #ifdef IMGUI_ENABLE_TEST_ENGINE |
| ImGuiItemStatusFlags_Openable = 1 << 20, // Item is an openable (e.g. TreeNode) |
| ImGuiItemStatusFlags_Opened = 1 << 21, // Opened status |
| ImGuiItemStatusFlags_Checkable = 1 << 22, // Item is a checkable (e.g. CheckBox, MenuItem) |
| ImGuiItemStatusFlags_Checked = 1 << 23, // Checked status |
| ImGuiItemStatusFlags_Inputable = 1 << 24, // Item is a text-inputable (e.g. InputText, SliderXXX, DragXXX) |
| #endif |
| }; |
| |
| // Extend ImGuiHoveredFlags_ |
| enum ImGuiHoveredFlagsPrivate_ |
| { |
| ImGuiHoveredFlags_DelayMask_ = ImGuiHoveredFlags_DelayNone | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_NoSharedDelay, |
| ImGuiHoveredFlags_AllowedMaskForIsWindowHovered = ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_NoPopupHierarchy | ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_Stationary, |
| ImGuiHoveredFlags_AllowedMaskForIsItemHovered = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped | ImGuiHoveredFlags_AllowWhenDisabled | ImGuiHoveredFlags_NoNavOverride | ImGuiHoveredFlags_ForTooltip | ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayMask_, |
| }; |
| |
| // Extend ImGuiInputTextFlags_ |
| enum ImGuiInputTextFlagsPrivate_ |
| { |
| // [Internal] |
| ImGuiInputTextFlags_Multiline = 1 << 26, // For internal use by InputTextMultiline() |
| ImGuiInputTextFlags_MergedItem = 1 << 27, // For internal use by TempInputText(), will skip calling ItemAdd(). Require bounding-box to strictly match. |
| ImGuiInputTextFlags_LocalizeDecimalPoint= 1 << 28, // For internal use by InputScalar() and TempInputScalar() |
| }; |
| |
| // Extend ImGuiButtonFlags_ |
| enum ImGuiButtonFlagsPrivate_ |
| { |
| ImGuiButtonFlags_PressedOnClick = 1 << 4, // return true on click (mouse down event) |
| ImGuiButtonFlags_PressedOnClickRelease = 1 << 5, // [Default] return true on click + release on same item <-- this is what the majority of Button are using |
| ImGuiButtonFlags_PressedOnClickReleaseAnywhere = 1 << 6, // return true on click + release even if the release event is not done while hovering the item |
| ImGuiButtonFlags_PressedOnRelease = 1 << 7, // return true on release (default requires click+release) |
| ImGuiButtonFlags_PressedOnDoubleClick = 1 << 8, // return true on double-click (default requires click+release) |
| ImGuiButtonFlags_PressedOnDragDropHold = 1 << 9, // return true when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers) |
| //ImGuiButtonFlags_Repeat = 1 << 10, // hold to repeat |
| ImGuiButtonFlags_FlattenChildren = 1 << 11, // allow interactions even if a child window is overlapping |
| ImGuiButtonFlags_AllowOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable. |
| //ImGuiButtonFlags_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press |
| //ImGuiButtonFlags_Disabled = 1 << 14, // disable interactions -> use BeginDisabled() or ImGuiItemFlags_Disabled |
| ImGuiButtonFlags_AlignTextBaseLine = 1 << 15, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine |
| ImGuiButtonFlags_NoKeyModsAllowed = 1 << 16, // disable mouse interaction if a key modifier is held |
| ImGuiButtonFlags_NoHoldingActiveId = 1 << 17, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only) |
| ImGuiButtonFlags_NoNavFocus = 1 << 18, // don't override navigation focus when activated (FIXME: this is essentially used every time an item uses ImGuiItemFlags_NoNav, but because legacy specs don't requires LastItemData to be set ButtonBehavior(), we can't poll g.LastItemData.ItemFlags) |
| ImGuiButtonFlags_NoHoveredOnFocus = 1 << 19, // don't report as hovered when nav focus is on this item |
| ImGuiButtonFlags_NoSetKeyOwner = 1 << 20, // don't set key/input owner on the initial click (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!) |
| ImGuiButtonFlags_NoTestKeyOwner = 1 << 21, // don't test key/input owner when polling the key (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!) |
| ImGuiButtonFlags_PressedOnMask_ = ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClickReleaseAnywhere | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_PressedOnDragDropHold, |
| ImGuiButtonFlags_PressedOnDefault_ = ImGuiButtonFlags_PressedOnClickRelease, |
| }; |
| |
| // Extend ImGuiComboFlags_ |
| enum ImGuiComboFlagsPrivate_ |
| { |
| ImGuiComboFlags_CustomPreview = 1 << 20, // enable BeginComboPreview() |
| }; |
| |
| // Extend ImGuiSliderFlags_ |
| enum ImGuiSliderFlagsPrivate_ |
| { |
| ImGuiSliderFlags_Vertical = 1 << 20, // Should this slider be orientated vertically? |
| ImGuiSliderFlags_ReadOnly = 1 << 21, // Consider using g.NextItemData.ItemFlags |= ImGuiItemFlags_ReadOnly instead. |
| }; |
| |
| // Extend ImGuiSelectableFlags_ |
| enum ImGuiSelectableFlagsPrivate_ |
| { |
| // NB: need to be in sync with last value of ImGuiSelectableFlags_ |
| ImGuiSelectableFlags_NoHoldingActiveID = 1 << 20, |
| ImGuiSelectableFlags_SelectOnNav = 1 << 21, // (WIP) Auto-select when moved into. This is not exposed in public API as to handle multi-select and modifiers we will need user to explicitly control focus scope. May be replaced with a BeginSelection() API. |
| ImGuiSelectableFlags_SelectOnClick = 1 << 22, // Override button behavior to react on Click (default is Click+Release) |
| ImGuiSelectableFlags_SelectOnRelease = 1 << 23, // Override button behavior to react on Release (default is Click+Release) |
| ImGuiSelectableFlags_SpanAvailWidth = 1 << 24, // Span all avail width even if we declared less for layout purpose. FIXME: We may be able to remove this (added in 6251d379, 2bcafc86 for menus) |
| ImGuiSelectableFlags_SetNavIdOnHover = 1 << 25, // Set Nav/Focus ID on mouse hover (used by MenuItem) |
| ImGuiSelectableFlags_NoPadWithHalfSpacing = 1 << 26, // Disable padding each side with ItemSpacing * 0.5f |
| ImGuiSelectableFlags_NoSetKeyOwner = 1 << 27, // Don't set key/input owner on the initial click (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!) |
| }; |
| |
| // Extend ImGuiTreeNodeFlags_ |
| enum ImGuiTreeNodeFlagsPrivate_ |
| { |
| ImGuiTreeNodeFlags_ClipLabelForTrailingButton = 1 << 28,// FIXME-WIP: Hard-coded for CollapsingHeader() |
| ImGuiTreeNodeFlags_UpsideDownArrow = 1 << 29,// FIXME-WIP: Turn Down arrow into an Up arrow, for reversed trees (#6517) |
| ImGuiTreeNodeFlags_OpenOnMask_ = ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_OpenOnArrow, |
| }; |
| |
| enum ImGuiSeparatorFlags_ |
| { |
| ImGuiSeparatorFlags_None = 0, |
| ImGuiSeparatorFlags_Horizontal = 1 << 0, // Axis default to current layout type, so generally Horizontal unless e.g. in a menu bar |
| ImGuiSeparatorFlags_Vertical = 1 << 1, |
| ImGuiSeparatorFlags_SpanAllColumns = 1 << 2, // Make separator cover all columns of a legacy Columns() set. |
| }; |
| |
| // Flags for FocusWindow(). This is not called ImGuiFocusFlags to avoid confusion with public-facing ImGuiFocusedFlags. |
| // FIXME: Once we finishing replacing more uses of GetTopMostPopupModal()+IsWindowWithinBeginStackOf() |
| // and FindBlockingModal() with this, we may want to change the flag to be opt-out instead of opt-in. |
| enum ImGuiFocusRequestFlags_ |
| { |
| ImGuiFocusRequestFlags_None = 0, |
| ImGuiFocusRequestFlags_RestoreFocusedChild = 1 << 0, // Find last focused child (if any) and focus it instead. |
| ImGuiFocusRequestFlags_UnlessBelowModal = 1 << 1, // Do not set focus if the window is below a modal. |
| }; |
| |
| enum ImGuiTextFlags_ |
| { |
| ImGuiTextFlags_None = 0, |
| ImGuiTextFlags_NoWidthForLargeClippedText = 1 << 0, |
| }; |
| |
| enum ImGuiTooltipFlags_ |
| { |
| ImGuiTooltipFlags_None = 0, |
| ImGuiTooltipFlags_OverridePrevious = 1 << 1, // Clear/ignore previously submitted tooltip (defaults to append) |
| }; |
| |
| // FIXME: this is in development, not exposed/functional as a generic feature yet. |
| // Horizontal/Vertical enums are fixed to 0/1 so they may be used to index ImVec2 |
| enum ImGuiLayoutType_ |
| { |
| ImGuiLayoutType_Horizontal = 0, |
| ImGuiLayoutType_Vertical = 1 |
| }; |
| |
| enum ImGuiLogType |
| { |
| ImGuiLogType_None = 0, |
| ImGuiLogType_TTY, |
| ImGuiLogType_File, |
| ImGuiLogType_Buffer, |
| ImGuiLogType_Clipboard, |
| }; |
| |
| // X/Y enums are fixed to 0/1 so they may be used to index ImVec2 |
| enum ImGuiAxis |
| { |
| ImGuiAxis_None = -1, |
| ImGuiAxis_X = 0, |
| ImGuiAxis_Y = 1 |
| }; |
| |
| enum ImGuiPlotType |
| { |
| ImGuiPlotType_Lines, |
| ImGuiPlotType_Histogram, |
| }; |
| |
| // Stacked color modifier, backup of modified data so we can restore it |
| struct ImGuiColorMod |
| { |
| ImGuiCol Col; |
| ImVec4 BackupValue; |
| }; |
| |
| // Stacked style modifier, backup of modified data so we can restore it. Data type inferred from the variable. |
| struct ImGuiStyleMod |
| { |
| ImGuiStyleVar VarIdx; |
| union { int BackupInt[2]; float BackupFloat[2]; }; |
| ImGuiStyleMod(ImGuiStyleVar idx, int v) { VarIdx = idx; BackupInt[0] = v; } |
| ImGuiStyleMod(ImGuiStyleVar idx, float v) { VarIdx = idx; BackupFloat[0] = v; } |
| ImGuiStyleMod(ImGuiStyleVar idx, ImVec2 v) { VarIdx = idx; BackupFloat[0] = v.x; BackupFloat[1] = v.y; } |
| }; |
| |
| // Storage data for BeginComboPreview()/EndComboPreview() |
| struct IMGUI_API ImGuiComboPreviewData |
| { |
| ImRect PreviewRect; |
| ImVec2 BackupCursorPos; |
| ImVec2 BackupCursorMaxPos; |
| ImVec2 BackupCursorPosPrevLine; |
| float BackupPrevLineTextBaseOffset; |
| ImGuiLayoutType BackupLayout; |
| |
| ImGuiComboPreviewData() { memset(this, 0, sizeof(*this)); } |
| }; |
| |
| // Stacked storage data for BeginGroup()/EndGroup() |
| struct IMGUI_API ImGuiGroupData |
| { |
| ImGuiID WindowID; |
| ImVec2 BackupCursorPos; |
| ImVec2 BackupCursorMaxPos; |
| ImVec2 BackupCursorPosPrevLine; |
| ImVec1 BackupIndent; |
| ImVec1 BackupGroupOffset; |
| ImVec2 BackupCurrLineSize; |
| float BackupCurrLineTextBaseOffset; |
| ImGuiID BackupActiveIdIsAlive; |
| bool BackupActiveIdPreviousFrameIsAlive; |
| bool BackupHoveredIdIsAlive; |
| bool BackupIsSameLine; |
| bool EmitItem; |
| }; |
| |
| // Simple column measurement, currently used for MenuItem() only.. This is very short-sighted/throw-away code and NOT a generic helper. |
| struct IMGUI_API ImGuiMenuColumns |
| { |
| ImU32 TotalWidth; |
| ImU32 NextTotalWidth; |
| ImU16 Spacing; |
| ImU16 OffsetIcon; // Always zero for now |
| ImU16 OffsetLabel; // Offsets are locked in Update() |
| ImU16 OffsetShortcut; |
| ImU16 OffsetMark; |
| ImU16 Widths[4]; // Width of: Icon, Label, Shortcut, Mark (accumulators for current frame) |
| |
| ImGuiMenuColumns() { memset(this, 0, sizeof(*this)); } |
| void Update(float spacing, bool window_reappearing); |
| float DeclColumns(float w_icon, float w_label, float w_shortcut, float w_mark); |
| void CalcNextTotalWidth(bool update_offsets); |
| }; |
| |
| // Internal temporary state for deactivating InputText() instances. |
| struct IMGUI_API ImGuiInputTextDeactivatedState |
| { |
| ImGuiID ID; // widget id owning the text state (which just got deactivated) |
| ImVector<char> TextA; // text buffer |
| |
| ImGuiInputTextDeactivatedState() { memset(this, 0, sizeof(*this)); } |
| void ClearFreeMemory() { ID = 0; TextA.clear(); } |
| }; |
| |
| // Forward declare imstb_textedit.h structure + make its main configuration define accessible |
| #undef IMSTB_TEXTEDIT_STRING |
| #undef IMSTB_TEXTEDIT_CHARTYPE |
| #define IMSTB_TEXTEDIT_STRING ImGuiInputTextState |
| #define IMSTB_TEXTEDIT_CHARTYPE char |
| #define IMSTB_TEXTEDIT_GETWIDTH_NEWLINE (-1.0f) |
| #define IMSTB_TEXTEDIT_UNDOSTATECOUNT 99 |
| #define IMSTB_TEXTEDIT_UNDOCHARCOUNT 999 |
| namespace ImStb { struct STB_TexteditState; } |
| typedef ImStb::STB_TexteditState ImStbTexteditState; |
| |
| // Internal state of the currently focused/edited text input box |
| // For a given item ID, access with ImGui::GetInputTextState() |
| struct IMGUI_API ImGuiInputTextState |
| { |
| ImGuiContext* Ctx; // parent UI context (needs to be set explicitly by parent). |
| ImStbTexteditState* Stb; // State for stb_textedit.h |
| ImGuiID ID; // widget id owning the text state |
| int CurLenA; // UTF-8 length of the string in TextA (in bytes) |
| ImVector<char> TextA; // main UTF8 buffer. |
| ImVector<char> InitialTextA; // value to revert to when pressing Escape = backup of end-user buffer at the time of focus (in UTF-8, unaltered) |
| ImVector<char> CallbackTextBackup; // temporary storage for callback to support automatic reconcile of undo-stack |
| int BufCapacityA; // end-user buffer capacity |
| ImVec2 Scroll; // horizontal offset (managed manually) + vertical scrolling (pulled from child window's own Scroll.y) |
| float CursorAnim; // timer for cursor blink, reset on every user action so the cursor reappears immediately |
| bool CursorFollow; // set when we want scrolling to follow the current cursor position (not always!) |
| bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection |
| bool Edited; // edited this frame |
| ImGuiInputTextFlags Flags; // copy of InputText() flags. may be used to check if e.g. ImGuiInputTextFlags_Password is set. |
| bool ReloadUserBuf; // force a reload of user buf so it may be modified externally. may be automatic in future version. |
| int ReloadSelectionStart; // POSITIONS ARE IN IMWCHAR units *NOT* UTF-8 this is why this is not exposed yet. |
| int ReloadSelectionEnd; |
| |
| ImGuiInputTextState(); |
| ~ImGuiInputTextState(); |
| void ClearText() { CurLenA = 0; TextA[0] = 0; CursorClamp(); } |
| void ClearFreeMemory() { TextA.clear(); InitialTextA.clear(); } |
| void OnKeyPressed(int key); // Cannot be inline because we call in code in stb_textedit.h implementation |
| void OnCharPressed(unsigned int c); |
| |
| // Cursor & Selection |
| void CursorAnimReset(); |
| void CursorClamp(); |
| bool HasSelection() const; |
| void ClearSelection(); |
| int GetCursorPos() const; |
| int GetSelectionStart() const; |
| int GetSelectionEnd() const; |
| void SelectAll(); |
| |
| // Reload user buf (WIP #2890) |
| // If you modify underlying user-passed const char* while active you need to call this (InputText V2 may lift this) |
| // strcpy(my_buf, "hello"); |
| // if (ImGuiInputTextState* state = ImGui::GetInputTextState(id)) // id may be ImGui::GetItemID() is last item |
| // state->ReloadUserBufAndSelectAll(); |
| void ReloadUserBufAndSelectAll(); |
| void ReloadUserBufAndKeepSelection(); |
| void ReloadUserBufAndMoveToEnd(); |
| }; |
| |
| enum ImGuiWindowRefreshFlags_ |
| { |
| ImGuiWindowRefreshFlags_None = 0, |
| ImGuiWindowRefreshFlags_TryToAvoidRefresh = 1 << 0, // [EXPERIMENTAL] Try to keep existing contents, USER MUST NOT HONOR BEGIN() RETURNING FALSE AND NOT APPEND. |
| ImGuiWindowRefreshFlags_RefreshOnHover = 1 << 1, // [EXPERIMENTAL] Always refresh on hover |
| ImGuiWindowRefreshFlags_RefreshOnFocus = 1 << 2, // [EXPERIMENTAL] Always refresh on focus |
| // Refresh policy/frequency, Load Balancing etc. |
| }; |
| |
| enum ImGuiNextWindowDataFlags_ |
| { |
| ImGuiNextWindowDataFlags_None = 0, |
| ImGuiNextWindowDataFlags_HasPos = 1 << 0, |
| ImGuiNextWindowDataFlags_HasSize = 1 << 1, |
| ImGuiNextWindowDataFlags_HasContentSize = 1 << 2, |
| ImGuiNextWindowDataFlags_HasCollapsed = 1 << 3, |
| ImGuiNextWindowDataFlags_HasSizeConstraint = 1 << 4, |
| ImGuiNextWindowDataFlags_HasFocus = 1 << 5, |
| ImGuiNextWindowDataFlags_HasBgAlpha = 1 << 6, |
| ImGuiNextWindowDataFlags_HasScroll = 1 << 7, |
| ImGuiNextWindowDataFlags_HasChildFlags = 1 << 8, |
| ImGuiNextWindowDataFlags_HasRefreshPolicy = 1 << 9, |
| }; |
| |
| // Storage for SetNexWindow** functions |
| struct ImGuiNextWindowData |
| { |
| ImGuiNextWindowDataFlags Flags; |
| ImGuiCond PosCond; |
| ImGuiCond SizeCond; |
| ImGuiCond CollapsedCond; |
| ImVec2 PosVal; |
| ImVec2 PosPivotVal; |
| ImVec2 SizeVal; |
| ImVec2 ContentSizeVal; |
| ImVec2 ScrollVal; |
| ImGuiChildFlags ChildFlags; |
| bool CollapsedVal; |
| ImRect SizeConstraintRect; |
| ImGuiSizeCallback SizeCallback; |
| void* SizeCallbackUserData; |
| float BgAlphaVal; // Override background alpha |
| ImVec2 MenuBarOffsetMinVal; // (Always on) This is not exposed publicly, so we don't clear it and it doesn't have a corresponding flag (could we? for consistency?) |
| ImGuiWindowRefreshFlags RefreshFlagsVal; |
| |
| ImGuiNextWindowData() { memset(this, 0, sizeof(*this)); } |
| inline void ClearFlags() { Flags = ImGuiNextWindowDataFlags_None; } |
| }; |
| |
| enum ImGuiNextItemDataFlags_ |
| { |
| ImGuiNextItemDataFlags_None = 0, |
| ImGuiNextItemDataFlags_HasWidth = 1 << 0, |
| ImGuiNextItemDataFlags_HasOpen = 1 << 1, |
| ImGuiNextItemDataFlags_HasShortcut = 1 << 2, |
| ImGuiNextItemDataFlags_HasRefVal = 1 << 3, |
| ImGuiNextItemDataFlags_HasStorageID = 1 << 4, |
| }; |
| |
| struct ImGuiNextItemData |
| { |
| ImGuiNextItemDataFlags HasFlags; // Called HasFlags instead of Flags to avoid mistaking this |
| ImGuiItemFlags ItemFlags; // Currently only tested/used for ImGuiItemFlags_AllowOverlap and ImGuiItemFlags_HasSelectionUserData. |
| // Non-flags members are NOT cleared by ItemAdd() meaning they are still valid during NavProcessItem() |
| ImGuiID FocusScopeId; // Set by SetNextItemSelectionUserData() |
| ImGuiSelectionUserData SelectionUserData; // Set by SetNextItemSelectionUserData() (note that NULL/0 is a valid value, we use -1 == ImGuiSelectionUserData_Invalid to mark invalid values) |
| float Width; // Set by SetNextItemWidth() |
| ImGuiKeyChord Shortcut; // Set by SetNextItemShortcut() |
| ImGuiInputFlags ShortcutFlags; // Set by SetNextItemShortcut() |
| bool OpenVal; // Set by SetNextItemOpen() |
| ImU8 OpenCond; // Set by SetNextItemOpen() |
| ImGuiDataTypeStorage RefVal; // Not exposed yet, for ImGuiInputTextFlags_ParseEmptyAsRefVal |
| ImGuiID StorageId; // Set by SetNextItemStorageID() |
| |
| ImGuiNextItemData() { memset(this, 0, sizeof(*this)); SelectionUserData = -1; } |
| inline void ClearFlags() { HasFlags = ImGuiNextItemDataFlags_None; ItemFlags = ImGuiItemFlags_None; } // Also cleared manually by ItemAdd()! |
| }; |
| |
| // Status storage for the last submitted item |
| struct ImGuiLastItemData |
| { |
| ImGuiID ID; |
| ImGuiItemFlags ItemFlags; // See ImGuiItemFlags_ |
| ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_ |
| ImRect Rect; // Full rectangle |
| ImRect NavRect; // Navigation scoring rectangle (not displayed) |
| // Rarely used fields are not explicitly cleared, only valid when the corresponding ImGuiItemStatusFlags ar set. |
| ImRect DisplayRect; // Display rectangle. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasDisplayRect) is set. |
| ImRect ClipRect; // Clip rectangle at the time of submitting item. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasClipRect) is set.. |
| ImGuiKeyChord Shortcut; // Shortcut at the time of submitting item. ONLY VALID IF (StatusFlags & ImGuiItemStatusFlags_HasShortcut) is set.. |
| |
| ImGuiLastItemData() { memset(this, 0, sizeof(*this)); } |
| }; |
| |
| // Store data emitted by TreeNode() for usage by TreePop() |
| // - To implement ImGuiTreeNodeFlags_NavLeftJumpsBackHere: store the minimum amount of data |
| // which we can't infer in TreePop(), to perform the equivalent of NavApplyItemToResult(). |
| // Only stored when the node is a potential candidate for landing on a Left arrow jump. |
| struct ImGuiTreeNodeStackData |
| { |
| ImGuiID ID; |
| ImGuiTreeNodeFlags TreeFlags; |
| ImGuiItemFlags ItemFlags; // Used for nav landing |
| ImRect NavRect; // Used for nav landing |
| }; |
| |
| // sizeof() = 20 |
| struct IMGUI_API ImGuiErrorRecoveryState |
| { |
| short SizeOfWindowStack; |
| short SizeOfIDStack; |
| short SizeOfTreeStack; |
| short SizeOfColorStack; |
| short SizeOfStyleVarStack; |
| short SizeOfFontStack; |
| short SizeOfFocusScopeStack; |
| short SizeOfGroupStack; |
| short SizeOfItemFlagsStack; |
| short SizeOfBeginPopupStack; |
| short SizeOfDisabledStack; |
| |
| ImGuiErrorRecoveryState() { memset(this, 0, sizeof(*this)); } |
| }; |
| |
| // Data saved for each window pushed into the stack |
| struct ImGuiWindowStackData |
| { |
| ImGuiWindow* Window; |
| ImGuiLastItemData ParentLastItemDataBackup; |
| ImGuiErrorRecoveryState StackSizesInBegin; // Store size of various stacks for asserting |
| bool DisabledOverrideReenable; // Non-child window override disabled flag |
| }; |
| |
| struct ImGuiShrinkWidthItem |
| { |
| int Index; |
| float Width; |
| float InitialWidth; |
| }; |
| |
| struct ImGuiPtrOrIndex |
| { |
| void* Ptr; // Either field can be set, not both. e.g. Dock node tab bars are loose while BeginTabBar() ones are in a pool. |
| int Index; // Usually index in a main pool. |
| |
| ImGuiPtrOrIndex(void* ptr) { Ptr = ptr; Index = -1; } |
| ImGuiPtrOrIndex(int index) { Ptr = NULL; Index = index; } |
| }; |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Popup support |
| //----------------------------------------------------------------------------- |
| |
| enum ImGuiPopupPositionPolicy |
| { |
| ImGuiPopupPositionPolicy_Default, |
| ImGuiPopupPositionPolicy_ComboBox, |
| ImGuiPopupPositionPolicy_Tooltip, |
| }; |
| |
| // Storage for popup stacks (g.OpenPopupStack and g.BeginPopupStack) |
| struct ImGuiPopupData |
| { |
| ImGuiID PopupId; // Set on OpenPopup() |
| ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup() |
| ImGuiWindow* RestoreNavWindow;// Set on OpenPopup(), a NavWindow that will be restored on popup close |
| int ParentNavLayer; // Resolved on BeginPopup(). Actually a ImGuiNavLayer type (declared down below), initialized to -1 which is not part of an enum, but serves well-enough as "not any of layers" value |
| int OpenFrameCount; // Set on OpenPopup() |
| ImGuiID OpenParentId; // Set on OpenPopup(), we need this to differentiate multiple menu sets from each others (e.g. inside menu bar vs loose menu items) |
| ImVec2 OpenPopupPos; // Set on OpenPopup(), preferred popup position (typically == OpenMousePos when using mouse) |
| ImVec2 OpenMousePos; // Set on OpenPopup(), copy of mouse position at the time of opening popup |
| |
| ImGuiPopupData() { memset(this, 0, sizeof(*this)); ParentNavLayer = OpenFrameCount = -1; } |
| }; |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Inputs support |
| //----------------------------------------------------------------------------- |
| |
| // Bit array for named keys |
| typedef ImBitArray<ImGuiKey_NamedKey_COUNT, -ImGuiKey_NamedKey_BEGIN> ImBitArrayForNamedKeys; |
| |
| // [Internal] Key ranges |
| #define ImGuiKey_LegacyNativeKey_BEGIN 0 |
| #define ImGuiKey_LegacyNativeKey_END 512 |
| #define ImGuiKey_Keyboard_BEGIN (ImGuiKey_NamedKey_BEGIN) |
| #define ImGuiKey_Keyboard_END (ImGuiKey_GamepadStart) |
| #define ImGuiKey_Gamepad_BEGIN (ImGuiKey_GamepadStart) |
| #define ImGuiKey_Gamepad_END (ImGuiKey_GamepadRStickDown + 1) |
| #define ImGuiKey_Mouse_BEGIN (ImGuiKey_MouseLeft) |
| #define ImGuiKey_Mouse_END (ImGuiKey_MouseWheelY + 1) |
| #define ImGuiKey_Aliases_BEGIN (ImGuiKey_Mouse_BEGIN) |
| #define ImGuiKey_Aliases_END (ImGuiKey_Mouse_END) |
| |
| // [Internal] Named shortcuts for Navigation |
| #define ImGuiKey_NavKeyboardTweakSlow ImGuiMod_Ctrl |
| #define ImGuiKey_NavKeyboardTweakFast ImGuiMod_Shift |
| #define ImGuiKey_NavGamepadTweakSlow ImGuiKey_GamepadL1 |
| #define ImGuiKey_NavGamepadTweakFast ImGuiKey_GamepadR1 |
| #define ImGuiKey_NavGamepadActivate (g.IO.ConfigNavSwapGamepadButtons ? ImGuiKey_GamepadFaceRight : ImGuiKey_GamepadFaceDown) |
| #define ImGuiKey_NavGamepadCancel (g.IO.ConfigNavSwapGamepadButtons ? ImGuiKey_GamepadFaceDown : ImGuiKey_GamepadFaceRight) |
| #define ImGuiKey_NavGamepadMenu ImGuiKey_GamepadFaceLeft |
| #define ImGuiKey_NavGamepadInput ImGuiKey_GamepadFaceUp |
| |
| enum ImGuiInputEventType |
| { |
| ImGuiInputEventType_None = 0, |
| ImGuiInputEventType_MousePos, |
| ImGuiInputEventType_MouseWheel, |
| ImGuiInputEventType_MouseButton, |
| ImGuiInputEventType_Key, |
| ImGuiInputEventType_Text, |
| ImGuiInputEventType_Focus, |
| ImGuiInputEventType_COUNT |
| }; |
| |
| enum ImGuiInputSource |
| { |
| ImGuiInputSource_None = 0, |
| ImGuiInputSource_Mouse, // Note: may be Mouse or TouchScreen or Pen. See io.MouseSource to distinguish them. |
| ImGuiInputSource_Keyboard, |
| ImGuiInputSource_Gamepad, |
| ImGuiInputSource_COUNT |
| }; |
| |
| // FIXME: Structures in the union below need to be declared as anonymous unions appears to be an extension? |
| // Using ImVec2() would fail on Clang 'union member 'MousePos' has a non-trivial default constructor' |
| struct ImGuiInputEventMousePos { float PosX, PosY; ImGuiMouseSource MouseSource; }; |
| struct ImGuiInputEventMouseWheel { float WheelX, WheelY; ImGuiMouseSource MouseSource; }; |
| struct ImGuiInputEventMouseButton { int Button; bool Down; ImGuiMouseSource MouseSource; }; |
| struct ImGuiInputEventKey { ImGuiKey Key; bool Down; float AnalogValue; }; |
| struct ImGuiInputEventText { unsigned int Char; }; |
| struct ImGuiInputEventAppFocused { bool Focused; }; |
| |
| struct ImGuiInputEvent |
| { |
| ImGuiInputEventType Type; |
| ImGuiInputSource Source; |
| ImU32 EventId; // Unique, sequential increasing integer to identify an event (if you need to correlate them to other data). |
| union |
| { |
| ImGuiInputEventMousePos MousePos; // if Type == ImGuiInputEventType_MousePos |
| ImGuiInputEventMouseWheel MouseWheel; // if Type == ImGuiInputEventType_MouseWheel |
| ImGuiInputEventMouseButton MouseButton; // if Type == ImGuiInputEventType_MouseButton |
| ImGuiInputEventKey Key; // if Type == ImGuiInputEventType_Key |
| ImGuiInputEventText Text; // if Type == ImGuiInputEventType_Text |
| ImGuiInputEventAppFocused AppFocused; // if Type == ImGuiInputEventType_Focus |
| }; |
| bool AddedByTestEngine; |
| |
| ImGuiInputEvent() { memset(this, 0, sizeof(*this)); } |
| }; |
| |
| // Input function taking an 'ImGuiID owner_id' argument defaults to (ImGuiKeyOwner_Any == 0) aka don't test ownership, which matches legacy behavior. |
| #define ImGuiKeyOwner_Any ((ImGuiID)0) // Accept key that have an owner, UNLESS a call to SetKeyOwner() explicitly used ImGuiInputFlags_LockThisFrame or ImGuiInputFlags_LockUntilRelease. |
| #define ImGuiKeyOwner_NoOwner ((ImGuiID)-1) // Require key to have no owner. |
| //#define ImGuiKeyOwner_None ImGuiKeyOwner_NoOwner // We previously called this 'ImGuiKeyOwner_None' but it was inconsistent with our pattern that _None values == 0 and quite dangerous. Also using _NoOwner makes the IsKeyPressed() calls more explicit. |
| |
| typedef ImS16 ImGuiKeyRoutingIndex; |
| |
| // Routing table entry (sizeof() == 16 bytes) |
| 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) |
| ImGuiID RoutingCurr; |
| ImGuiID RoutingNext; |
| |
| ImGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingCurrScore = RoutingNextScore = 255; 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. |
| // Stored in main context (1 instance) |
| struct ImGuiKeyRoutingTable |
| { |
| ImGuiKeyRoutingIndex Index[ImGuiKey_NamedKey_COUNT]; // Index of first entry in Entries[] |
| ImVector<ImGuiKeyRoutingData> Entries; |
| ImVector<ImGuiKeyRoutingData> EntriesNext; // Double-buffer to avoid reallocation (could use a shared buffer) |
| |
| ImGuiKeyRoutingTable() { Clear(); } |
| void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Index); n++) Index[n] = -1; Entries.clear(); EntriesNext.clear(); } |
| }; |
| |
| // This extends ImGuiKeyData but only for named keys (legacy keys don't support the new features) |
| // Stored in main context (1 per named key). In the future it might be merged into ImGuiKeyData. |
| struct ImGuiKeyOwnerData |
| { |
| ImGuiID OwnerCurr; |
| ImGuiID OwnerNext; |
| bool LockThisFrame; // Reading this key requires explicit owner id (until end of frame). Set by ImGuiInputFlags_LockThisFrame. |
| bool LockUntilRelease; // Reading this key requires explicit owner id (until key is released). Set by ImGuiInputFlags_LockUntilRelease. When this is true LockThisFrame is always true as well. |
| |
| ImGuiKeyOwnerData() { OwnerCurr = OwnerNext = ImGuiKeyOwner_NoOwner; LockThisFrame = LockUntilRelease = false; } |
| }; |
| |
| // Extend ImGuiInputFlags_ |
| // Flags for extended versions of IsKeyPressed(), IsMouseClicked(), Shortcut(), SetKeyOwner(), SetItemKeyOwner() |
| // Don't mistake with ImGuiInputTextFlags! (which is for ImGui::InputText() function) |
| enum ImGuiInputFlagsPrivate_ |
| { |
| // Flags for IsKeyPressed(), IsKeyChordPressed(), IsMouseClicked(), Shortcut() |
| // - Repeat mode: Repeat rate selection |
| ImGuiInputFlags_RepeatRateDefault = 1 << 1, // Repeat rate: Regular (default) |
| ImGuiInputFlags_RepeatRateNavMove = 1 << 2, // Repeat rate: Fast |
| ImGuiInputFlags_RepeatRateNavTweak = 1 << 3, // Repeat rate: Faster |
| // - Repeat mode: Specify when repeating key pressed can be interrupted. |
| // - In theory ImGuiInputFlags_RepeatUntilOtherKeyPress may be a desirable default, but it would break too many behavior so everything is opt-in. |
| ImGuiInputFlags_RepeatUntilRelease = 1 << 4, // Stop repeating when released (default for all functions except Shortcut). This only exists to allow overriding Shortcut() default behavior. |
| ImGuiInputFlags_RepeatUntilKeyModsChange = 1 << 5, // Stop repeating when released OR if keyboard mods are changed (default for Shortcut) |
| ImGuiInputFlags_RepeatUntilKeyModsChangeFromNone = 1 << 6, // Stop repeating when released OR if keyboard mods are leaving the None state. Allows going from Mod+Key to Key by releasing Mod. |
| ImGuiInputFlags_RepeatUntilOtherKeyPress = 1 << 7, // Stop repeating when released OR if any other keyboard key is pressed during the repeat |
| |
| // Flags for SetKeyOwner(), SetItemKeyOwner() |
| // - Locking key away from non-input aware code. Locking is useful to make input-owner-aware code steal keys from non-input-owner-aware code. If all code is input-owner-aware locking would never be necessary. |
| ImGuiInputFlags_LockThisFrame = 1 << 20, // Further accesses to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared at end of frame. |
| ImGuiInputFlags_LockUntilRelease = 1 << 21, // Further accesses to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared when the key is released or at end of each frame if key is released. |
| |
| // - Condition for SetItemKeyOwner() |
| ImGuiInputFlags_CondHovered = 1 << 22, // Only set if item is hovered (default to both) |
| ImGuiInputFlags_CondActive = 1 << 23, // Only set if item is active (default to both) |
| ImGuiInputFlags_CondDefault_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive, |
| |
| // [Internal] Mask of which function support which flags |
| ImGuiInputFlags_RepeatRateMask_ = ImGuiInputFlags_RepeatRateDefault | ImGuiInputFlags_RepeatRateNavMove | ImGuiInputFlags_RepeatRateNavTweak, |
| ImGuiInputFlags_RepeatUntilMask_ = ImGuiInputFlags_RepeatUntilRelease | ImGuiInputFlags_RepeatUntilKeyModsChange | ImGuiInputFlags_RepeatUntilKeyModsChangeFromNone | ImGuiInputFlags_RepeatUntilOtherKeyPress, |
| ImGuiInputFlags_RepeatMask_ = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_ | ImGuiInputFlags_RepeatUntilMask_, |
| ImGuiInputFlags_CondMask_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive, |
| ImGuiInputFlags_RouteTypeMask_ = ImGuiInputFlags_RouteActive | ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteAlways, |
| ImGuiInputFlags_RouteOptionsMask_ = ImGuiInputFlags_RouteOverFocused | ImGuiInputFlags_RouteOverActive | ImGuiInputFlags_RouteUnlessBgFocused | ImGuiInputFlags_RouteFromRootWindow, |
| ImGuiInputFlags_SupportedByIsKeyPressed = ImGuiInputFlags_RepeatMask_, |
| ImGuiInputFlags_SupportedByIsMouseClicked = ImGuiInputFlags_Repeat, |
| ImGuiInputFlags_SupportedByShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteTypeMask_ | ImGuiInputFlags_RouteOptionsMask_, |
| ImGuiInputFlags_SupportedBySetNextItemShortcut = ImGuiInputFlags_RepeatMask_ | ImGuiInputFlags_RouteTypeMask_ | ImGuiInputFlags_RouteOptionsMask_ | ImGuiInputFlags_Tooltip, |
| ImGuiInputFlags_SupportedBySetKeyOwner = ImGuiInputFlags_LockThisFrame | ImGuiInputFlags_LockUntilRelease, |
| ImGuiInputFlags_SupportedBySetItemKeyOwner = ImGuiInputFlags_SupportedBySetKeyOwner | ImGuiInputFlags_CondMask_, |
| }; |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Clipper support |
| //----------------------------------------------------------------------------- |
| |
| // Note that Max is exclusive, so perhaps should be using a Begin/End convention. |
| struct ImGuiListClipperRange |
| { |
| int Min; |
| int Max; |
| bool PosToIndexConvert; // Begin/End are absolute position (will be converted to indices later) |
| ImS8 PosToIndexOffsetMin; // Add to Min after converting to indices |
| ImS8 PosToIndexOffsetMax; // Add to Min after converting to indices |
| |
| static ImGuiListClipperRange FromIndices(int min, int max) { ImGuiListClipperRange r = { min, max, false, 0, 0 }; return r; } |
| static ImGuiListClipperRange FromPositions(float y1, float y2, int off_min, int off_max) { ImGuiListClipperRange r = { (int)y1, (int)y2, true, (ImS8)off_min, (ImS8)off_max }; return r; } |
| }; |
| |
| // Temporary clipper data, buffers shared/reused between instances |
| struct ImGuiListClipperData |
| { |
| ImGuiListClipper* ListClipper; |
| float LossynessOffset; |
| int StepNo; |
| int ItemsFrozen; |
| ImVector<ImGuiListClipperRange> Ranges; |
| |
| ImGuiListClipperData() { memset(this, 0, sizeof(*this)); } |
| void Reset(ImGuiListClipper* clipper) { ListClipper = clipper; StepNo = ItemsFrozen = 0; Ranges.resize(0); } |
| }; |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Navigation support |
| //----------------------------------------------------------------------------- |
| |
| enum ImGuiActivateFlags_ |
| { |
| ImGuiActivateFlags_None = 0, |
| ImGuiActivateFlags_PreferInput = 1 << 0, // Favor activation that requires keyboard text input (e.g. for Slider/Drag). Default for Enter key. |
| ImGuiActivateFlags_PreferTweak = 1 << 1, // Favor activation for tweaking with arrows or gamepad (e.g. for Slider/Drag). Default for Space key and if keyboard is not used. |
| ImGuiActivateFlags_TryToPreserveState = 1 << 2, // Request widget to preserve state if it can (e.g. InputText will try to preserve cursor/selection) |
| ImGuiActivateFlags_FromTabbing = 1 << 3, // Activation requested by a tabbing request |
| ImGuiActivateFlags_FromShortcut = 1 << 4, // Activation requested by an item shortcut via SetNextItemShortcut() function. |
| }; |
| |
| // Early work-in-progress API for ScrollToItem() |
| enum ImGuiScrollFlags_ |
| { |
| ImGuiScrollFlags_None = 0, |
| ImGuiScrollFlags_KeepVisibleEdgeX = 1 << 0, // If item is not visible: scroll as little as possible on X axis to bring item back into view [default for X axis] |
| ImGuiScrollFlags_KeepVisibleEdgeY = 1 << 1, // If item is not visible: scroll as little as possible on Y axis to bring item back into view [default for Y axis for windows that are already visible] |
| ImGuiScrollFlags_KeepVisibleCenterX = 1 << 2, // If item is not visible: scroll to make the item centered on X axis [rarely used] |
| ImGuiScrollFlags_KeepVisibleCenterY = 1 << 3, // If item is not visible: scroll to make the item centered on Y axis |
| ImGuiScrollFlags_AlwaysCenterX = 1 << 4, // Always center the result item on X axis [rarely used] |
| ImGuiScrollFlags_AlwaysCenterY = 1 << 5, // Always center the result item on Y axis [default for Y axis for appearing window) |
| ImGuiScrollFlags_NoScrollParent = 1 << 6, // Disable forwarding scrolling to parent window if required to keep item/rect visible (only scroll window the function was applied to). |
| ImGuiScrollFlags_MaskX_ = ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleCenterX | ImGuiScrollFlags_AlwaysCenterX, |
| ImGuiScrollFlags_MaskY_ = ImGuiScrollFlags_KeepVisibleEdgeY | ImGuiScrollFlags_KeepVisibleCenterY | ImGuiScrollFlags_AlwaysCenterY, |
| }; |
| |
| enum ImGuiNavRenderCursorFlags_ |
| { |
| ImGuiNavRenderCursorFlags_None = 0, |
| ImGuiNavRenderCursorFlags_Compact = 1 << 1, // Compact highlight, no padding/distance from focused item |
| ImGuiNavRenderCursorFlags_AlwaysDraw = 1 << 2, // Draw rectangular highlight if (g.NavId == id) even when g.NavCursorVisible == false, aka even when using the mouse. |
| ImGuiNavRenderCursorFlags_NoRounding = 1 << 3, |
| #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS |
| ImGuiNavHighlightFlags_None = ImGuiNavRenderCursorFlags_None, // Renamed in 1.91.4 |
| ImGuiNavHighlightFlags_Compact = ImGuiNavRenderCursorFlags_Compact, // Renamed in 1.91.4 |
| ImGuiNavHighlightFlags_AlwaysDraw = ImGuiNavRenderCursorFlags_AlwaysDraw, // Renamed in 1.91.4 |
| ImGuiNavHighlightFlags_NoRounding = ImGuiNavRenderCursorFlags_NoRounding, // Renamed in 1.91.4 |
| #endif |
| }; |
| |
| enum ImGuiNavMoveFlags_ |
| { |
| ImGuiNavMoveFlags_None = 0, |
| ImGuiNavMoveFlags_LoopX = 1 << 0, // On failed request, restart from opposite side |
| ImGuiNavMoveFlags_LoopY = 1 << 1, |
| ImGuiNavMoveFlags_WrapX = 1 << 2, // On failed request, request from opposite side one line down (when NavDir==right) or one line up (when NavDir==left) |
| ImGuiNavMoveFlags_WrapY = 1 << 3, // This is not super useful but provided for completeness |
| 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_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) |
| ImGuiNavMoveFlags_IsTabbing = 1 << 10, // == Focus + Activate if item is Inputable + DontChangeNavHighlight |
| ImGuiNavMoveFlags_IsPageMove = 1 << 11, // Identify a PageDown/PageUp request. |
| ImGuiNavMoveFlags_Activate = 1 << 12, // Activate/select target item. |
| ImGuiNavMoveFlags_NoSelect = 1 << 13, // Don't trigger selection by not setting g.NavJustMovedTo |
| ImGuiNavMoveFlags_NoSetNavCursorVisible = 1 << 14, // Do not alter the nav cursor visible state |
| ImGuiNavMoveFlags_NoClearActiveId = 1 << 15, // (Experimental) Do not clear active id when applying move result |
| }; |
| |
| enum ImGuiNavLayer |
| { |
| ImGuiNavLayer_Main = 0, // Main scrolling layer |
| ImGuiNavLayer_Menu = 1, // Menu layer (access with Alt) |
| ImGuiNavLayer_COUNT |
| }; |
| |
| // Storage for navigation query/results |
| struct ImGuiNavItemData |
| { |
| ImGuiWindow* Window; // Init,Move // Best candidate window (result->ItemWindow->RootWindowForNav == request->Window) |
| ImGuiID ID; // Init,Move // Best candidate item ID |
| ImGuiID FocusScopeId; // Init,Move // Best candidate focus scope ID |
| ImRect RectRel; // Init,Move // Best candidate bounding box in window relative space |
| ImGuiItemFlags ItemFlags; // ????,Move // Best candidate item flags |
| float DistBox; // Move // Best candidate box distance to current NavId |
| float DistCenter; // Move // Best candidate center distance to current NavId |
| float DistAxial; // Move // Best candidate axial distance to current NavId |
| ImGuiSelectionUserData SelectionUserData;//I+Mov // Best candidate SetNextItemSelectionUserData() value. Valid if (ItemFlags & ImGuiItemFlags_HasSelectionUserData) |
| |
| ImGuiNavItemData() { Clear(); } |
| void Clear() { Window = NULL; ID = FocusScopeId = 0; ItemFlags = 0; SelectionUserData = -1; DistBox = DistCenter = DistAxial = FLT_MAX; } |
| }; |
| |
| // Storage for PushFocusScope(), g.FocusScopeStack[], g.NavFocusRoute[] |
| struct ImGuiFocusScopeData |
| { |
| ImGuiID ID; |
| ImGuiID WindowID; |
| }; |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Typing-select support |
| //----------------------------------------------------------------------------- |
| |
| // Flags for GetTypingSelectRequest() |
| enum ImGuiTypingSelectFlags_ |
| { |
| ImGuiTypingSelectFlags_None = 0, |
| ImGuiTypingSelectFlags_AllowBackspace = 1 << 0, // Backspace to delete character inputs. If using: ensure GetTypingSelectRequest() is not called more than once per frame (filter by e.g. focus state) |
| ImGuiTypingSelectFlags_AllowSingleCharMode = 1 << 1, // Allow "single char" search mode which is activated when pressing the same character multiple times. |
| }; |
| |
| // Returned by GetTypingSelectRequest(), designed to eventually be public. |
| struct IMGUI_API ImGuiTypingSelectRequest |
| { |
| ImGuiTypingSelectFlags Flags; // Flags passed to GetTypingSelectRequest() |
| int SearchBufferLen; |
| const char* SearchBuffer; // Search buffer contents (use full string. unless SingleCharMode is set, in which case use SingleCharSize). |
| bool SelectRequest; // Set when buffer was modified this frame, requesting a selection. |
| bool SingleCharMode; // Notify when buffer contains same character repeated, to implement special mode. In this situation it preferred to not display any on-screen search indication. |
| ImS8 SingleCharSize; // Length in bytes of first letter codepoint (1 for ascii, 2-4 for UTF-8). If (SearchBufferLen==RepeatCharSize) only 1 letter has been input. |
| }; |
| |
| // Storage for GetTypingSelectRequest() |
| struct IMGUI_API ImGuiTypingSelectState |
| { |
| ImGuiTypingSelectRequest Request; // User-facing data |
| char SearchBuffer[64]; // Search buffer: no need to make dynamic as this search is very transient. |
| ImGuiID FocusScope; |
| int LastRequestFrame = 0; |
| float LastRequestTime = 0.0f; |
| bool SingleCharModeLock = false; // After a certain single char repeat count we lock into SingleCharMode. Two benefits: 1) buffer never fill, 2) we can provide an immediate SingleChar mode without timer elapsing. |
| |
| ImGuiTypingSelectState() { memset(this, 0, sizeof(*this)); } |
| void Clear() { SearchBuffer[0] = 0; SingleCharModeLock = false; } // We preserve remaining data for easier debugging |
| }; |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Columns support |
| //----------------------------------------------------------------------------- |
| |
| // Flags for internal's BeginColumns(). This is an obsolete API. Prefer using BeginTable() nowadays! |
| enum ImGuiOldColumnFlags_ |
| { |
| ImGuiOldColumnFlags_None = 0, |
| ImGuiOldColumnFlags_NoBorder = 1 << 0, // Disable column dividers |
| ImGuiOldColumnFlags_NoResize = 1 << 1, // Disable resizing columns when clicking on the dividers |
| ImGuiOldColumnFlags_NoPreserveWidths = 1 << 2, // Disable column width preservation when adjusting columns |
| ImGuiOldColumnFlags_NoForceWithinWindow = 1 << 3, // Disable forcing columns to fit within window |
| ImGuiOldColumnFlags_GrowParentContentsSize = 1 << 4, // Restore pre-1.51 behavior of extending the parent window contents size but _without affecting the columns width at all_. Will eventually remove. |
| |
| // Obsolete names (will be removed) |
| #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS |
| //ImGuiColumnsFlags_None = ImGuiOldColumnFlags_None, |
| //ImGuiColumnsFlags_NoBorder = ImGuiOldColumnFlags_NoBorder, |
| //ImGuiColumnsFlags_NoResize = ImGuiOldColumnFlags_NoResize, |
| //ImGuiColumnsFlags_NoPreserveWidths = ImGuiOldColumnFlags_NoPreserveWidths, |
| //ImGuiColumnsFlags_NoForceWithinWindow = ImGuiOldColumnFlags_NoForceWithinWindow, |
| //ImGuiColumnsFlags_GrowParentContentsSize = ImGuiOldColumnFlags_GrowParentContentsSize, |
| #endif |
| }; |
| |
| struct ImGuiOldColumnData |
| { |
| float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) |
| float OffsetNormBeforeResize; |
| ImGuiOldColumnFlags Flags; // Not exposed |
| ImRect ClipRect; |
| |
| ImGuiOldColumnData() { memset(this, 0, sizeof(*this)); } |
| }; |
| |
| struct ImGuiOldColumns |
| { |
| ImGuiID ID; |
| ImGuiOldColumnFlags Flags; |
| bool IsFirstFrame; |
| bool IsBeingResized; |
| int Current; |
| int Count; |
| float OffMinX, OffMaxX; // Offsets from HostWorkRect.Min.x |
| float LineMinY, LineMaxY; |
| float HostCursorPosY; // Backup of CursorPos at the time of BeginColumns() |
| float HostCursorMaxPosX; // Backup of CursorMaxPos at the time of BeginColumns() |
| ImRect HostInitialClipRect; // Backup of ClipRect at the time of BeginColumns() |
| ImRect HostBackupClipRect; // Backup of ClipRect during PushColumnsBackground()/PopColumnsBackground() |
| ImRect HostBackupParentWorkRect;//Backup of WorkRect at the time of BeginColumns() |
| ImVector<ImGuiOldColumnData> Columns; |
| ImDrawListSplitter Splitter; |
| |
| ImGuiOldColumns() { memset(this, 0, sizeof(*this)); } |
| }; |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Box-select support |
| //----------------------------------------------------------------------------- |
| |
| struct ImGuiBoxSelectState |
| { |
| // Active box-selection data (persistent, 1 active at a time) |
| ImGuiID ID; |
| bool IsActive; |
| bool IsStarting; |
| bool IsStartedFromVoid; // Starting click was not from an item. |
| bool IsStartedSetNavIdOnce; |
| bool RequestClear; |
| ImGuiKeyChord KeyMods : 16; // Latched key-mods for box-select logic. |
| ImVec2 StartPosRel; // Start position in window-contents relative space (to support scrolling) |
| ImVec2 EndPosRel; // End position in window-contents relative space |
| ImVec2 ScrollAccum; // Scrolling accumulator (to behave at high-frame spaces) |
| ImGuiWindow* Window; |
| |
| // Temporary/Transient data |
| bool UnclipMode; // (Temp/Transient, here in hot area). Set/cleared by the BeginMultiSelect()/EndMultiSelect() owning active box-select. |
| ImRect UnclipRect; // Rectangle where ItemAdd() clipping may be temporarily disabled. Need support by multi-select supporting widgets. |
| ImRect BoxSelectRectPrev; // Selection rectangle in absolute coordinates (derived every frame from BoxSelectStartPosRel and MousePos) |
| ImRect BoxSelectRectCurr; |
| |
| ImGuiBoxSelectState() { memset(this, 0, sizeof(*this)); } |
| }; |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Multi-select support |
| //----------------------------------------------------------------------------- |
| |
| // We always assume that -1 is an invalid value (which works for indices and pointers) |
| #define ImGuiSelectionUserData_Invalid ((ImGuiSelectionUserData)-1) |
| |
| // Temporary storage for multi-select |
| struct IMGUI_API ImGuiMultiSelectTempData |
| { |
| ImGuiMultiSelectIO IO; // MUST BE FIRST FIELD. Requests are set and returned by BeginMultiSelect()/EndMultiSelect() + written to by user during the loop. |
| ImGuiMultiSelectState* Storage; |
| ImGuiID FocusScopeId; // Copied from g.CurrentFocusScopeId (unless another selection scope was pushed manually) |
| ImGuiMultiSelectFlags Flags; |
| ImVec2 ScopeRectMin; |
| ImVec2 BackupCursorMaxPos; |
| ImGuiSelectionUserData LastSubmittedItem; // Copy of last submitted item data, used to merge output ranges. |
| ImGuiID BoxSelectId; |
| ImGuiKeyChord KeyMods; |
| ImS8 LoopRequestSetAll; // -1: no operation, 0: clear all, 1: select all. |
| bool IsEndIO; // Set when switching IO from BeginMultiSelect() to EndMultiSelect() state. |
| bool IsFocused; // Set if currently focusing the selection scope (any item of the selection). May be used if you have custom shortcut associated to selection. |
| bool IsKeyboardSetRange; // Set by BeginMultiSelect() when using Shift+Navigation. Because scrolling may be affected we can't afford a frame of lag with Shift+Navigation. |
| bool NavIdPassedBy; |
| bool RangeSrcPassedBy; // Set by the item that matches RangeSrcItem. |
| bool RangeDstPassedBy; // Set by the item that matches NavJustMovedToId when IsSetRange is set. |
| |
| ImGuiMultiSelectTempData() { Clear(); } |
| void Clear() { size_t io_sz = sizeof(IO); ClearIO(); memset((void*)(&IO + 1), 0, sizeof(*this) - io_sz); } // Zero-clear except IO as we preserve IO.Requests[] buffer allocation. |
| void ClearIO() { IO.Requests.resize(0); IO.RangeSrcItem = IO.NavIdItem = ImGuiSelectionUserData_Invalid; IO.NavIdSelected = IO.RangeSrcReset = false; } |
| }; |
| |
| // Persistent storage for multi-select (as long as selection is alive) |
| struct IMGUI_API ImGuiMultiSelectState |
| { |
| ImGuiWindow* Window; |
| ImGuiID ID; |
| int LastFrameActive; // Last used frame-count, for GC. |
| int LastSelectionSize; // Set by BeginMultiSelect() based on optional info provided by user. May be -1 if unknown. |
| ImS8 RangeSelected; // -1 (don't have) or true/false |
| ImS8 NavIdSelected; // -1 (don't have) or true/false |
| ImGuiSelectionUserData RangeSrcItem; // |
| ImGuiSelectionUserData NavIdItem; // SetNextItemSelectionUserData() value for NavId (if part of submitted items) |
| |
| ImGuiMultiSelectState() { Window = NULL; ID = 0; LastFrameActive = LastSelectionSize = 0; RangeSelected = NavIdSelected = -1; RangeSrcItem = NavIdItem = ImGuiSelectionUserData_Invalid; } |
| }; |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Docking support |
| //----------------------------------------------------------------------------- |
| |
| #ifdef IMGUI_HAS_DOCK |
| // <this is filled in 'docking' branch> |
| #endif // #ifdef IMGUI_HAS_DOCK |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Viewport support |
| //----------------------------------------------------------------------------- |
| |
| // ImGuiViewport Private/Internals fields (cardinal sin: we are using inheritance!) |
| // Every instance of ImGuiViewport is in fact a ImGuiViewportP. |
| struct ImGuiViewportP : public ImGuiViewport |
| { |
| int BgFgDrawListsLastFrame[2]; // Last frame number the background (0) and foreground (1) draw lists were used |
| ImDrawList* BgFgDrawLists[2]; // Convenience background (0) and foreground (1) draw lists. We use them to draw software mouser cursor when io.MouseDrawCursor is set and to draw most debug overlays. |
| ImDrawData DrawDataP; |
| ImDrawDataBuilder DrawDataBuilder; // Temporary data while building final ImDrawData |
| |
| // Per-viewport work area |
| // - Insets are >= 0.0f values, distance from viewport corners to work area. |
| // - BeginMainMenuBar() and DockspaceOverViewport() tend to use work area to avoid stepping over existing contents. |
| // - Generally 'safeAreaInsets' in iOS land, 'DisplayCutout' in Android land. |
| ImVec2 WorkInsetMin; // Work Area inset locked for the frame. GetWorkRect() always fits within GetMainRect(). |
| ImVec2 WorkInsetMax; // " |
| ImVec2 BuildWorkInsetMin; // Work Area inset accumulator for current frame, to become next frame's WorkInset |
| ImVec2 BuildWorkInsetMax; // " |
| |
| ImGuiViewportP() { BgFgDrawListsLastFrame[0] = BgFgDrawListsLastFrame[1] = -1; BgFgDrawLists[0] = BgFgDrawLists[1] = NULL; } |
| ~ImGuiViewportP() { if (BgFgDrawLists[0]) IM_DELETE(BgFgDrawLists[0]); if (BgFgDrawLists[1]) IM_DELETE(BgFgDrawLists[1]); } |
| |
| // Calculate work rect pos/size given a set of offset (we have 1 pair of offset for rect locked from last frame data, and 1 pair for currently building rect) |
| ImVec2 CalcWorkRectPos(const ImVec2& inset_min) const { return ImVec2(Pos.x + inset_min.x, Pos.y + inset_min.y); } |
| ImVec2 CalcWorkRectSize(const ImVec2& inset_min, const ImVec2& inset_max) const { return ImVec2(ImMax(0.0f, Size.x - inset_min.x - inset_max.x), ImMax(0.0f, Size.y - inset_min.y - inset_max.y)); } |
| void UpdateWorkRect() { WorkPos = CalcWorkRectPos(WorkInsetMin); WorkSize = CalcWorkRectSize(WorkInsetMin, WorkInsetMax); } // Update public fields |
| |
| // Helpers to retrieve ImRect (we don't need to store BuildWorkRect as every access tend to change it, hence the code asymmetry) |
| ImRect GetMainRect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); } |
| ImRect GetWorkRect() const { return ImRect(WorkPos.x, WorkPos.y, WorkPos.x + WorkSize.x, WorkPos.y + WorkSize.y); } |
| ImRect GetBuildWorkRect() const { ImVec2 pos = CalcWorkRectPos(BuildWorkInsetMin); ImVec2 size = CalcWorkRectSize(BuildWorkInsetMin, BuildWorkInsetMax); return ImRect(pos.x, pos.y, pos.x + size.x, pos.y + size.y); } |
| }; |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Settings support |
| //----------------------------------------------------------------------------- |
| |
| // Windows data saved in imgui.ini file |
| // Because we never destroy or rename ImGuiWindowSettings, we can store the names in a separate buffer easily. |
| // (this is designed to be stored in a ImChunkStream buffer, with the variable-length Name following our structure) |
| struct ImGuiWindowSettings |
| { |
| ImGuiID ID; |
| ImVec2ih Pos; |
| ImVec2ih Size; |
| bool Collapsed; |
| bool IsChild; |
| bool WantApply; // Set when loaded from .ini data (to enable merging/loading .ini data into an already running context) |
| bool WantDelete; // Set to invalidate/delete the settings entry |
| |
| ImGuiWindowSettings() { memset(this, 0, sizeof(*this)); } |
| char* GetName() { return (char*)(this + 1); } |
| }; |
| |
| struct ImGuiSettingsHandler |
| { |
| const char* TypeName; // Short description stored in .ini file. Disallowed characters: '[' ']' |
| ImGuiID TypeHash; // == ImHashStr(TypeName) |
| void (*ClearAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler); // Clear all settings data |
| void (*ReadInitFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler); // Read: Called before reading (in registration order) |
| void* (*ReadOpenFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, const char* name); // Read: Called when entering into a new ini entry e.g. "[Window][Name]" |
| void (*ReadLineFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, void* entry, const char* line); // Read: Called for every line of text within an ini entry |
| void (*ApplyAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler); // Read: Called after reading (in registration order) |
| void (*WriteAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* out_buf); // Write: Output every entries into 'out_buf' |
| void* UserData; |
| |
| ImGuiSettingsHandler() { memset(this, 0, sizeof(*this)); } |
| }; |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Localization support |
| //----------------------------------------------------------------------------- |
| |
| // This is experimental and not officially supported, it'll probably fall short of features, if/when it does we may backtrack. |
| enum ImGuiLocKey : int |
| { |
| ImGuiLocKey_VersionStr, |
| ImGuiLocKey_TableSizeOne, |
| ImGuiLocKey_TableSizeAllFit, |
| ImGuiLocKey_TableSizeAllDefault, |
| ImGuiLocKey_TableResetOrder, |
| ImGuiLocKey_WindowingMainMenuBar, |
| ImGuiLocKey_WindowingPopup, |
| ImGuiLocKey_WindowingUntitled, |
| ImGuiLocKey_OpenLink_s, |
| ImGuiLocKey_CopyLink, |
| ImGuiLocKey_COUNT |
| }; |
| |
| struct ImGuiLocEntry |
| { |
| ImGuiLocKey Key; |
| const char* Text; |
| }; |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Error handling, State recovery support |
| //----------------------------------------------------------------------------- |
| |
| // Macros used by Recoverable Error handling |
| // - Only dispatch error if _EXPR: evaluate as assert (similar to an assert macro). |
| // - The message will always be a string literal, in order to increase likelihood of being display by an assert handler. |
| // - See 'Demo->Configuration->Error Handling' and ImGuiIO definitions for details on error handling. |
| // - Read https://github.com/ocornut/imgui/wiki/Error-Handling for details on error handling. |
| #ifndef IM_ASSERT_USER_ERROR |
| #define IM_ASSERT_USER_ERROR(_EXPR,_MSG) do { if (!(_EXPR) && ImGui::ErrorLog(_MSG)) { IM_ASSERT((_EXPR) && _MSG); } } while (0) // Recoverable User Error |
| #endif |
| |
| // The error callback is currently not public, as it is expected that only advanced users will rely on it. |
| typedef void (*ImGuiErrorCallback)(ImGuiContext* ctx, void* user_data, const char* msg); // Function signature for g.ErrorCallback |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Metrics, Debug Tools |
| //----------------------------------------------------------------------------- |
| |
| enum ImGuiDebugLogFlags_ |
| { |
| // Event types |
| ImGuiDebugLogFlags_None = 0, |
| ImGuiDebugLogFlags_EventError = 1 << 0, // Error submitted by IM_ASSERT_USER_ERROR() |
| ImGuiDebugLogFlags_EventActiveId = 1 << 1, |
| ImGuiDebugLogFlags_EventFocus = 1 << 2, |
| ImGuiDebugLogFlags_EventPopup = 1 << 3, |
| ImGuiDebugLogFlags_EventNav = 1 << 4, |
| ImGuiDebugLogFlags_EventClipper = 1 << 5, |
| ImGuiDebugLogFlags_EventSelection = 1 << 6, |
| ImGuiDebugLogFlags_EventIO = 1 << 7, |
| ImGuiDebugLogFlags_EventInputRouting = 1 << 8, |
| ImGuiDebugLogFlags_EventDocking = 1 << 9, // Unused in this branch |
| ImGuiDebugLogFlags_EventViewport = 1 << 10, // Unused in this branch |
| |
| ImGuiDebugLogFlags_EventMask_ = ImGuiDebugLogFlags_EventError | ImGuiDebugLogFlags_EventActiveId | ImGuiDebugLogFlags_EventFocus | ImGuiDebugLogFlags_EventPopup | ImGuiDebugLogFlags_EventNav | ImGuiDebugLogFlags_EventClipper | ImGuiDebugLogFlags_EventSelection | ImGuiDebugLogFlags_EventIO | ImGuiDebugLogFlags_EventInputRouting | ImGuiDebugLogFlags_EventDocking | ImGuiDebugLogFlags_EventViewport, |
| ImGuiDebugLogFlags_OutputToTTY = 1 << 20, // Also send output to TTY |
| ImGuiDebugLogFlags_OutputToTestEngine = 1 << 21, // Also send output to Test Engine |
| }; |
| |
| struct ImGuiDebugAllocEntry |
| { |
| int FrameCount; |
| ImS16 AllocCount; |
| ImS16 FreeCount; |
| }; |
| |
| struct ImGuiDebugAllocInfo |
| { |
| int TotalAllocCount; // Number of call to MemAlloc(). |
| int TotalFreeCount; |
| ImS16 LastEntriesIdx; // Current index in buffer |
| ImGuiDebugAllocEntry LastEntriesBuf[6]; // Track last 6 frames that had allocations |
| |
| ImGuiDebugAllocInfo() { memset(this, 0, sizeof(*this)); } |
| }; |
| |
| struct ImGuiMetricsConfig |
| { |
| bool ShowDebugLog = false; |
| bool ShowIDStackTool = false; |
| bool ShowWindowsRects = false; |
| bool ShowWindowsBeginOrder = false; |
| bool ShowTablesRects = false; |
| bool ShowDrawCmdMesh = true; |
| bool ShowDrawCmdBoundingBoxes = true; |
| bool ShowTextEncodingViewer = false; |
| bool ShowAtlasTintedWithTextColor = false; |
| int ShowWindowsRectsType = -1; |
| int ShowTablesRectsType = -1; |
| int HighlightMonitorIdx = -1; |
| ImGuiID HighlightViewportID = 0; |
| }; |
| |
| struct ImGuiStackLevelInfo |
| { |
| ImGuiID ID; |
| ImS8 QueryFrameCount; // >= 1: Query in progress |
| bool QuerySuccess; // Obtained result from DebugHookIdInfo() |
| ImGuiDataType DataType : 8; |
| char Desc[57]; // Arbitrarily sized buffer to hold a result (FIXME: could replace Results[] with a chunk stream?) FIXME: Now that we added CTRL+C this should be fixed. |
| |
| ImGuiStackLevelInfo() { 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 QueryId; // ID to query details for |
| ImVector<ImGuiStackLevelInfo> Results; |
| bool CopyToClipboardOnCtrlC; |
| float CopyToClipboardLastTime; |
| |
| ImGuiIDStackTool() { memset(this, 0, sizeof(*this)); CopyToClipboardLastTime = -FLT_MAX; } |
| }; |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Generic context hooks |
| //----------------------------------------------------------------------------- |
| |
| typedef void (*ImGuiContextHookCallback)(ImGuiContext* ctx, ImGuiContextHook* hook); |
| enum ImGuiContextHookType { ImGuiContextHookType_NewFramePre, ImGuiContextHookType_NewFramePost, ImGuiContextHookType_EndFramePre, ImGuiContextHookType_EndFramePost, ImGuiContextHookType_RenderPre, ImGuiContextHookType_RenderPost, ImGuiContextHookType_Shutdown, ImGuiContextHookType_PendingRemoval_ }; |
| |
| struct ImGuiContextHook |
| { |
| ImGuiID HookId; // A unique ID assigned by AddContextHook() |
| ImGuiContextHookType Type; |
| ImGuiID Owner; |
| ImGuiContextHookCallback Callback; |
| void* UserData; |
| |
| ImGuiContextHook() { memset(this, 0, sizeof(*this)); } |
| }; |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] ImGuiContext (main Dear ImGui context) |
| //----------------------------------------------------------------------------- |
| |
| struct ImGuiContext |
| { |
| bool Initialized; |
| bool FontAtlasOwnedByContext; // IO.Fonts-> is owned by the ImGuiContext and will be destructed along with it. |
| ImGuiIO IO; |
| ImGuiPlatformIO PlatformIO; |
| ImGuiStyle Style; |
| ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() |
| float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window. |
| float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height. |
| float FontScale; // == FontSize / Font->FontSize |
| float CurrentDpiScale; // Current window/viewport DpiScale |
| ImDrawListSharedData DrawListSharedData; |
| double Time; |
| int FrameCount; |
| int FrameCountEnded; |
| int FrameCountRendered; |
| 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 WithinEndChild; // Set within EndChild() |
| 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. |
| ImVector<ImGuiInputEvent> InputEventsTrail; // Past input events processed in NewFrame(). This is to allow domain-specific application to access e.g mouse/pen trail. |
| ImGuiMouseSource InputEventsNextMouseSource; |
| ImU32 InputEventsNextEventId; |
| |
| // Windows state |
| ImVector<ImGuiWindow*> Windows; // Windows, sorted in display order, back to front |
| ImVector<ImGuiWindow*> WindowsFocusOrder; // Root windows, sorted in focus order, back to front. |
| ImVector<ImGuiWindow*> WindowsTempSortBuffer; // Temporary buffer used in EndFrame() to reorder windows so parents are kept before their child |
| ImVector<ImGuiWindowStackData> CurrentWindowStack; |
| ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow* |
| int WindowsActiveCount; // Number of unique windows submitted by frame |
| ImVec2 WindowsHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == ImMax(style.TouchExtraPadding, WINDOWS_HOVER_PADDING). |
| ImGuiID DebugBreakInWindow; // Set to break in Begin() call. |
| ImGuiWindow* CurrentWindow; // Window being drawn into |
| ImGuiWindow* HoveredWindow; // Window the mouse is hovering. Will typically catch mouse inputs. |
| ImGuiWindow* HoveredWindowUnderMovingWindow; // Hovered window ignoring MovingWindow. Only set if MovingWindow is set. |
| ImGuiWindow* HoveredWindowBeforeClear; // Window the mouse is hovering. Filled even with _NoMouse. This is currently useful for multi-context compositors. |
| ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actual window that is moved is generally MovingWindow->RootWindow. |
| ImGuiWindow* WheelingWindow; // Track the window we started mouse-wheeling on. Until a timer elapse or mouse has moved, generally keep scrolling the same window even if during the course of scrolling the mouse ends up hovering a child window. |
| ImVec2 WheelingWindowRefMousePos; |
| int WheelingWindowStartFrame; // This may be set one frame before WheelingWindow is != NULL |
| int WheelingWindowScrolledFrame; |
| float WheelingWindowReleaseTimer; |
| ImVec2 WheelingWindowWheelRemainder; |
| ImVec2 WheelingAxisAvg; |
| |
| // Item/widgets state and tracking information |
| ImGuiID DebugDrawIdConflicts; // Set when we detect multiple items with the same identifier |
| ImGuiID DebugHookIdInfo; // Will call core hooks: DebugHookIdInfo() from GetID functions, used by ID Stack Tool [next HoveredId/ActiveId to not pull in an extra cache-line] |
| ImGuiID HoveredId; // Hovered widget, filled during the frame |
| ImGuiID HoveredIdPreviousFrame; |
| int HoveredIdPreviousFrameItemCount; // Count numbers of items using the same ID as last frame's hovered id |
| float HoveredIdTimer; // Measure contiguous hovering time |
| float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active |
| bool HoveredIdAllowOverlap; |
| bool HoveredIdIsDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0. |
| bool ItemUnclipByLog; // Disable ItemAdd() clipping, essentially a memory-locality friendly copy of LogEnabled |
| ImGuiID ActiveId; // Active widget |
| ImGuiID ActiveIdIsAlive; // Active widget has been seen this frame (we can't use a bool as the ActiveId may change within the frame) |
| float ActiveIdTimer; |
| bool ActiveIdIsJustActivated; // Set at the time of activation for one frame |
| bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always) |
| bool ActiveIdNoClearOnFocusLoss; // Disable losing active id if the active id window gets unfocused. |
| bool ActiveIdHasBeenPressedBefore; // Track whether the active id led to a press (this is to allow changing between PressOnClick and PressOnRelease without pressing twice). Used by range_select branch. |
| bool ActiveIdHasBeenEditedBefore; // Was the value associated to the widget Edited over the course of the Active state. |
| bool ActiveIdHasBeenEditedThisFrame; |
| bool ActiveIdFromShortcut; |
| 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 |
| ImGuiID ActiveIdPreviousFrame; |
| bool ActiveIdPreviousFrameIsAlive; |
| bool ActiveIdPreviousFrameHasBeenEditedBefore; |
| ImGuiWindow* ActiveIdPreviousFrameWindow; |
| ImGuiID LastActiveId; // Store the last non-zero ActiveId, useful for animation. |
| float LastActiveIdTimer; // Store the last non-zero ActiveId timer since the beginning of activation, useful for animation. |
| |
| // Key/Input Ownership + Shortcut Routing system |
| // - The idea is that instead of "eating" a given key, we can link to an owner. |
| // - Input query can then read input by specifying ImGuiKeyOwner_Any (== 0), ImGuiKeyOwner_NoOwner (== -1) or a custom ID. |
| // - Routing is requested ahead of time for a given chord (Key + Mods) and granted in NewFrame(). |
| double LastKeyModsChangeTime; // Record the last time key mods changed (affect repeat delay when using shortcut logic) |
| double LastKeyModsChangeFromNoneTime; // Record the last time key mods changed away from being 0 (affect repeat delay when using shortcut logic) |
| double LastKeyboardKeyPressTime; // Record the last time a keyboard key (ignore mouse/gamepad ones) was pressed. |
| ImBitArrayForNamedKeys KeysMayBeCharInput; // Lookup to tell if a key can emit char input, see IsKeyChordPotentiallyCharInput(). sizeof() = 20 bytes |
| ImGuiKeyOwnerData KeysOwnerData[ImGuiKey_NamedKey_COUNT]; |
| ImGuiKeyRoutingTable KeysRoutingTable; |
| ImU32 ActiveIdUsingNavDirMask; // Active widget will want to read those nav move requests (e.g. can activate a button and move away from it) |
| bool ActiveIdUsingAllKeyboardKeys; // Active widget will want to read all keyboard keys inputs. (this is a shortcut for not taking ownership of 100+ keys, frequently used by drag operations) |
| ImGuiKeyChord DebugBreakInShortcutRouting; // Set to break in SetShortcutRouting()/Shortcut() calls. |
| //ImU32 ActiveIdUsingNavInputMask; // [OBSOLETE] Since (IMGUI_VERSION_NUM >= 18804) : 'g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel);' becomes --> 'SetKeyOwner(ImGuiKey_Escape, g.ActiveId) and/or SetKeyOwner(ImGuiKey_NavGamepadCancel, g.ActiveId);' |
| |
| // Next window/item data |
| ImGuiID CurrentFocusScopeId; // Value for currently appending items == g.FocusScopeStack.back(). Not to be mistaken with g.NavFocusScopeId. |
| ImGuiItemFlags CurrentItemFlags; // Value for currently appending items == g.ItemFlagsStack.back() |
| ImGuiID DebugLocateId; // Storage for DebugLocateItemOnHover() feature: this is read by ItemAdd() so we keep it in a hot/cached location |
| ImGuiNextItemData NextItemData; // Storage for SetNextItem** functions |
| ImGuiLastItemData LastItemData; // Storage for last submitted item (setup by ItemAdd) |
| ImGuiNextWindowData NextWindowData; // Storage for SetNextWindow** functions |
| bool DebugShowGroupRects; |
| |
| // Shared stacks |
| ImGuiCol DebugFlashStyleColorIdx; // (Keep close to ColorStack to share cache line) |
| ImVector<ImGuiColorMod> ColorStack; // Stack for PushStyleColor()/PopStyleColor() - inherited by Begin() |
| ImVector<ImGuiStyleMod> StyleVarStack; // Stack for PushStyleVar()/PopStyleVar() - inherited by Begin() |
| ImVector<ImFont*> FontStack; // Stack for PushFont()/PopFont() - inherited by Begin() |
| ImVector<ImGuiFocusScopeData> FocusScopeStack; // Stack for PushFocusScope()/PopFocusScope() - inherited by BeginChild(), pushed into by Begin() |
| ImVector<ImGuiItemFlags> ItemFlagsStack; // Stack for PushItemFlag()/PopItemFlag() - inherited by Begin() |
| ImVector<ImGuiGroupData> GroupStack; // Stack for BeginGroup()/EndGroup() - not inherited by Begin() |
| ImVector<ImGuiPopupData> OpenPopupStack; // Which popups are open (persistent) |
| ImVector<ImGuiPopupData> BeginPopupStack; // Which level of BeginPopup() we are in (reset every frame) |
| ImVector<ImGuiTreeNodeStackData>TreeNodeStack; // Stack for TreeNode() |
| |
| // Viewports |
| ImVector<ImGuiViewportP*> Viewports; // Active viewports (Size==1 in 'master' branch). Each viewports hold their copy of ImDrawData. |
| |
| // Keyboard/Gamepad Navigation |
| bool NavCursorVisible; // Nav focus cursor/rectangle is visible? We hide it after a mouse click. We show it after a nav move. |
| bool NavHighlightItemUnderNav; // Disable mouse hovering highlight. Highlight navigation focused item instead of mouse hovered item. |
| //bool NavDisableHighlight; // Old name for !g.NavCursorVisible before 1.91.4 (2024/10/18). OPPOSITE VALUE (g.NavDisableHighlight == !g.NavCursorVisible) |
| //bool NavDisableMouseHover; // Old name for g.NavHighlightItemUnderNav before 1.91.1 (2024/10/18) this was called When user starts using keyboard/gamepad, we hide mouse hovering highlight until mouse is touched again. |
| bool NavMousePosDirty; // When set we will update mouse position if io.ConfigNavMoveSetMousePos is set (not enabled by default) |
| bool NavIdIsAlive; // Nav widget has been seen this frame ~~ NavRectRel is valid |
| ImGuiID NavId; // Focused item for navigation |
| ImGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusedWindow' |
| ImGuiID NavFocusScopeId; // Focused focus scope (e.g. selection code often wants to "clear other items" when landing on an item of the same scope) |
| ImGuiNavLayer NavLayer; // Focused layer (main scrolling layer, or menu/title bar layer) |
| ImGuiID NavActivateId; // ~~ (g.ActiveId == 0) && (IsKeyPressed(ImGuiKey_Space) || IsKeyDown(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_NavGamepadActivate)) ? NavId : 0, also set when calling ActivateItem() |
| ImGuiID NavActivateDownId; // ~~ IsKeyDown(ImGuiKey_Space) || IsKeyDown(ImGuiKey_Enter) || IsKeyDown(ImGuiKey_NavGamepadActivate) ? NavId : 0 |
| ImGuiID NavActivatePressedId; // ~~ IsKeyPressed(ImGuiKey_Space) || IsKeyPressed(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_NavGamepadActivate) ? NavId : 0 (no repeat) |
| ImGuiActivateFlags NavActivateFlags; |
| ImVector<ImGuiFocusScopeData> NavFocusRoute; // Reversed copy focus scope stack for NavId (should contains NavFocusScopeId). This essentially follow the window->ParentWindowForFocusRoute chain. |
| ImGuiID NavHighlightActivatedId; |
| float NavHighlightActivatedTimer; |
| ImGuiID NavNextActivateId; // Set by ActivateItem(), queued until next frame. |
| ImGuiActivateFlags NavNextActivateFlags; |
| ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS CAN ONLY BE ImGuiInputSource_Keyboard or ImGuiInputSource_Mouse |
| 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; |
| |
| // Navigation: Init & Move Requests |
| bool NavAnyRequest; // ~~ NavMoveRequest || NavInitRequest this is to perform early out in ItemAdd() |
| bool NavInitRequest; // Init request for appearing window to select first item |
| bool NavInitRequestFromMove; |
| ImGuiNavItemData NavInitResult; // Init request result (first item of the window, or one for which SetItemDefaultFocus() was called) |
| bool NavMoveSubmitted; // Move request submitted, will process result on next NewFrame() |
| bool NavMoveScoringItems; // Move request submitted, still scoring incoming items |
| bool NavMoveForwardToNextFrame; |
| ImGuiNavMoveFlags NavMoveFlags; |
| ImGuiScrollFlags NavMoveScrollFlags; |
| ImGuiKeyChord NavMoveKeyMods; |
| ImGuiDir NavMoveDir; // Direction of the move request (left/right/up/down) |
| ImGuiDir NavMoveDirForDebug; |
| ImGuiDir NavMoveClipDir; // FIXME-NAV: Describe the purpose of this better. Might want to rename? |
| ImRect NavScoringRect; // Rectangle used for scoring, in screen space. Based of window->NavRectRel[], modified for directional navigation scoring. |
| ImRect NavScoringNoClipRect; // Some nav operations (such as PageUp/PageDown) enforce a region which clipper will attempt to always keep submitted |
| int NavScoringDebugCount; // Metrics for debugging |
| int NavTabbingDir; // Generally -1 or +1, 0 when tabbing without a nav id |
| int NavTabbingCounter; // >0 when counting items for tabbing |
| ImGuiNavItemData NavMoveResultLocal; // Best move request candidate within NavWindow |
| ImGuiNavItemData NavMoveResultLocalVisible; // Best move request candidate within NavWindow that are mostly visible (when using ImGuiNavMoveFlags_AlsoScoreVisibleSet flag) |
| ImGuiNavItemData NavMoveResultOther; // Best move request candidate within NavWindow's flattened hierarchy (when using ImGuiWindowFlags_NavFlattened flag) |
| ImGuiNavItemData NavTabbingResultFirst; // First tabbing request candidate within NavWindow and flattened hierarchy |
| |
| // Navigation: record of last move request |
| ImGuiID NavJustMovedFromFocusScopeId; // Just navigated from this focus scope id (result of a successfully MoveRequest). |
| ImGuiID NavJustMovedToId; // Just navigated to this id (result of a successfully MoveRequest). |
| ImGuiID NavJustMovedToFocusScopeId; // Just navigated to this focus scope id (result of a successfully MoveRequest). |
| ImGuiKeyChord NavJustMovedToKeyMods; |
| 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) |
| 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* 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 |
| float NavWindowingTimer; |
| float NavWindowingHighlightAlpha; |
| bool NavWindowingToggleLayer; |
| ImGuiKey NavWindowingToggleKey; |
| ImVec2 NavWindowingAccumDeltaPos; |
| ImVec2 NavWindowingAccumDeltaSize; |
| |
| // Render |
| 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; |
| bool DragDropWithinSource; // Set when within a BeginDragDropXXX/EndDragDropXXX block for a drag source. |
| bool DragDropWithinTarget; // Set when within a BeginDragDropXXX/EndDragDropXXX block for a drag target. |
| ImGuiDragDropFlags DragDropSourceFlags; |
| int DragDropSourceFrameCount; |
| int DragDropMouseButton; |
| ImGuiPayload DragDropPayload; |
| 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; |
| 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) |
| int DragDropAcceptFrameCount; // Last time a target expressed a desire to accept the source |
| ImGuiID DragDropHoldJustPressedId; // Set when holding a payload just made ButtonBehavior() return a press. |
| ImVector<unsigned char> DragDropPayloadBufHeap; // We don't expose the ImVector<> directly, ImGuiPayload only holds pointer+size |
| unsigned char DragDropPayloadBufLocal[16]; // Local buffer for small payloads |
| |
| // Clipper |
| int ClipperTempDataStacked; |
| ImVector<ImGuiListClipperData> ClipperTempData; |
| |
| // Tables |
| ImGuiTable* CurrentTable; |
| ImGuiID DebugBreakInTable; // Set to break in BeginTable() call. |
| int TablesTempDataStacked; // Temporary table data size (because we leave previous instances undestructed, we generally don't use TablesTempData.Size) |
| ImVector<ImGuiTableTempData> TablesTempData; // Temporary table data (buffers reused/shared across instances, support nesting) |
| ImPool<ImGuiTable> Tables; // Persistent table data |
| ImVector<float> TablesLastTimeActive; // Last used timestamp of each tables (SOA, for efficient GC) |
| ImVector<ImDrawChannel> |