| // dear imgui, v1.90.0 |
| // (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] Widgets support: flags, enums, data structures |
| // [SECTION] Inputs support |
| // [SECTION] Clipper support |
| // [SECTION] Navigation support |
| // [SECTION] Typing-select support |
| // [SECTION] Columns support |
| // [SECTION] Multi-select support |
| // [SECTION] Docking support |
| // [SECTION] Viewport support |
| // [SECTION] Settings support |
| // [SECTION] Localization 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' |
| #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 |
| #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 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 avoid style variables from an enum) |
| struct ImGuiDataTypeInfo; // Type information associated to a ImGuiDataType enum |
| struct ImGuiDockContext; // Docking system context |
| struct ImGuiDockRequest; // Docking system dock/undock queued request |
| struct ImGuiDockNode; // Docking system node (hold a list of Windows OR two child dock nodes) |
| struct ImGuiDockNodeSettings; // Storage for a dock node in .ini file (we preserve those even if the associated dock node isn't active during the session) |
| 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 ImGuiNavItemData; // Result of a gamepad/keyboard directional navigation move query result |
| struct ImGuiNavTreeNodeData; // Temporary storage for last TreeNode() being a Left arrow landing candidate. |
| 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 ImGuiStackSizes; // Storage of stack sizes for debugging/asserting |
| 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 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 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 ImGuiDataAuthority; // -> enum ImGuiDataAuthority_ // Enum: for storing the source authority (dock node vs window) of a field |
| 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 ImGuiInputFlags; // -> enum ImGuiInputFlags_ // Flags: for IsKeyPressed(), IsMouseClicked(), SetKeyOwner(), SetItemKeyOwner() etc. |
| typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag(), g.LastItemData.InFlags |
| typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for g.LastItemData.StatusFlags |
| typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns() |
| typedef int ImGuiNavHighlightFlags; // -> enum ImGuiNavHighlightFlags_ // Flags: for RenderNavHighlight() |
| 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 void (*ImGuiErrorLogCallback)(void* user_data, const char* fmt, ...); |
| |
| //----------------------------------------------------------------------------- |
| // [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] STB libraries includes |
| //------------------------------------------------------------------------- |
| |
| namespace ImStb |
| { |
| |
| #undef STB_TEXTEDIT_STRING |
| #undef STB_TEXTEDIT_CHARTYPE |
| #define STB_TEXTEDIT_STRING ImGuiInputTextState |
| #define STB_TEXTEDIT_CHARTYPE ImWchar |
| #define STB_TEXTEDIT_GETWIDTH_NEWLINE (-1.0f) |
| #define STB_TEXTEDIT_UNDOSTATECOUNT 99 |
| #define STB_TEXTEDIT_UNDOCHARCOUNT 999 |
| #include "imstb_textedit.h" |
| |
| } // namespace ImStb |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Macros |
| //----------------------------------------------------------------------------- |
| |
| // Internal Drag and Drop payload types. String starting with '_' are reserved for Dear ImGui. |
| #define IMGUI_PAYLOAD_TYPE_WINDOW "_IMWINDOW" // Payload == ImGuiWindow* |
| |
| // 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_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_DOCKING(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventDocking) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0) |
| #define IMGUI_DEBUG_LOG_VIEWPORT(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventViewport) 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 |
| |
| // Error handling |
| // Down the line in some frameworks/languages we would like to have a way to redirect those to the programmer and recover from more faults. |
| #ifndef IM_ASSERT_USER_ERROR |
| #define IM_ASSERT_USER_ERROR(_EXP,_MSG) IM_ASSERT((_EXP) && _MSG) // Recoverable User Error |
| #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("int $0x03") |
| #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 |
| //----------------------------------------------------------------------------- |
| |
| // 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 ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line (ImWchar string) |
| IM_MSVC_RUNTIME_CHECKS_OFF |
| static inline char ImToUpper(char c) { return (c >= 'a' && c <= 'z') ? c &= ~32 : c; } |
| static inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; } |
| static inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; } |
| 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. |
| |
| // 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, 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 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; } |
| |
| // 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); } |
| #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS |
| int GetSize() { return GetMapSize(); } // For ImPlot: should use GetMapSize() from (IMGUI_VERSION_NUM >= 18304) |
| #endif |
| }; |
| |
| // 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); |
| }; |
| |
| //----------------------------------------------------------------------------- |
| // [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 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] Widgets support: flags, enums, data structures |
| //----------------------------------------------------------------------------- |
| |
| // Flags used by upcoming items |
| // - input: PushItemFlag() manipulates g.CurrentItemFlags, ItemAdd() calls may add extra flags. |
| // - output: stored in g.LastItemData.InFlags |
| // Current window shared by all windows. |
| // This is going to be exposed in imgui.h when stabilized enough. |
| enum ImGuiItemFlags_ |
| { |
| // Controlled by user |
| ImGuiItemFlags_None = 0, |
| ImGuiItemFlags_NoTabStop = 1 << 0, // false // Disable keyboard tabbing. This is a "lighter" version of ImGuiItemFlags_NoNav. |
| ImGuiItemFlags_ButtonRepeat = 1 << 1, // false // Button() will return true multiple times based on io.KeyRepeatDelay and io.KeyRepeatRate settings. |
| ImGuiItemFlags_Disabled = 1 << 2, // false // Disable interactions but doesn't affect visuals. See BeginDisabled()/EndDisabled(). See github.com/ocornut/imgui/issues/211 |
| ImGuiItemFlags_NoNav = 1 << 3, // false // Disable any form of focusing (keyboard/gamepad directional navigation and SetKeyboardFocusHere() calls) |
| ImGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false // Disable item being a candidate for default focus (e.g. used by title bar items) |
| ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // Disable MenuItem/Selectable() automatically closing their popup window |
| ImGuiItemFlags_MixedValue = 1 << 6, // 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_ReadOnly = 1 << 7, // false // [ALPHA] Allow hovering interactions but underlying value is not changed. |
| ImGuiItemFlags_NoWindowHoverableCheck = 1 << 8, // false // Disable hoverable check in ItemHoverable() |
| ImGuiItemFlags_AllowOverlap = 1 << 9, // false // Allow being overlapped by another widget. Not-hovered to Hovered transition deferred by a frame. |
| |
| // Controlled by widget code |
| ImGuiItemFlags_Inputable = 1 << 10, // 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 << 11, // false // Set by SetNextItemSelectionUserData() |
| }; |
| |
| // 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_FocusedByTabbing = 1 << 8, // Set when the Focusable item just got focused by Tabbing (FIXME: to be removed soon) |
| ImGuiItemStatusFlags_Visible = 1 << 9, // [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()). |
| |
| // 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_DockHierarchy | 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_NoMarkEdited = 1 << 27, // For internal use by functions using InputText() before reformatting data |
| ImGuiInputTextFlags_MergedItem = 1 << 28, // For internal use by TempInputText(), will skip calling ItemAdd(). Require bounding-box to strictly match. |
| }; |
| |
| // 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 // [UNUSED] |
| //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_NoKeyModifiers = 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 everytime an item uses ImGuiItemFlags_NoNav, but because legacy specs don't requires LastItemData to be set ButtonBehavior(), we can't poll g.LastItemData.InFlags) |
| 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 << 20, |
| ImGuiTreeNodeFlags_UpsideDownArrow = 1 << 21,// (FIXME-WIP) Turn Down arrow into an Up arrow, but reversed trees (#6517) |
| }; |
| |
| 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, |
| }; |
| |
| enum ImGuiPopupPositionPolicy |
| { |
| ImGuiPopupPositionPolicy_Default, |
| ImGuiPopupPositionPolicy_ComboBox, |
| ImGuiPopupPositionPolicy_Tooltip, |
| }; |
| |
| 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 ImGuiDataTypeTempStorage |
| { |
| ImU8 Data[8]; // Can 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, |
| }; |
| |
| // 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(); } |
| }; |
| // 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). |
| ImGuiID ID; // widget id owning the text state |
| int CurLenW, CurLenA; // we need to maintain our buffer length in both UTF-8 and wchar format. UTF-8 length is valid even if TextA is not. |
| ImVector<ImWchar> TextW; // edit buffer, we need to persist but can't guarantee the persistence of the user-provided buffer. so we copy into own buffer. |
| ImVector<char> TextA; // temporary UTF8 buffer for callbacks and other operations. this is not updated in every code-path! size=capacity. |
| ImVector<char> InitialTextA; // backup of end-user buffer at the time of focus (in UTF-8, unaltered) |
| bool TextAIsValid; // temporary UTF8 buffer is not initially valid before we make the widget active (until then we pull the data from user argument) |
| int BufCapacityA; // end-user buffer capacity |
| float ScrollX; // horizontal scrolling/offset |
| ImStb::STB_TexteditState Stb; // state for stb_textedit.h |
| 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. |
| |
| ImGuiInputTextState() { memset(this, 0, sizeof(*this)); } |
| void ClearText() { CurLenW = CurLenA = 0; TextW[0] = 0; TextA[0] = 0; CursorClamp(); } |
| void ClearFreeMemory() { TextW.clear(); TextA.clear(); InitialTextA.clear(); } |
| int GetUndoAvailCount() const { return Stb.undostate.undo_point; } |
| int GetRedoAvailCount() const { return STB_TEXTEDIT_UNDOSTATECOUNT - Stb.undostate.redo_point; } |
| void OnKeyPressed(int key); // Cannot be inline because we call in code in stb_textedit.h implementation |
| |
| // Cursor & Selection |
| void CursorAnimReset() { CursorAnim = -0.30f; } // After a user-input the cursor stays on for a while without blinking |
| void CursorClamp() { Stb.cursor = ImMin(Stb.cursor, CurLenW); Stb.select_start = ImMin(Stb.select_start, CurLenW); Stb.select_end = ImMin(Stb.select_end, CurLenW); } |
| bool HasSelection() const { return Stb.select_start != Stb.select_end; } |
| void ClearSelection() { Stb.select_start = Stb.select_end = Stb.cursor; } |
| int GetCursorPos() const { return Stb.cursor; } |
| int GetSelectionStart() const { return Stb.select_start; } |
| int GetSelectionEnd() const { return Stb.select_end; } |
| void SelectAll() { Stb.select_start = 0; Stb.cursor = Stb.select_end = CurLenW; Stb.has_preferred_x = 0; } |
| }; |
| |
| // Storage for current popup stack |
| struct ImGuiPopupData |
| { |
| ImGuiID PopupId; // Set on OpenPopup() |
| ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup() |
| ImGuiWindow* BackupNavWindow;// 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; } |
| }; |
| |
| 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_HasViewport = 1 << 9, |
| ImGuiNextWindowDataFlags_HasDock = 1 << 10, |
| ImGuiNextWindowDataFlags_HasWindowClass = 1 << 11, |
| }; |
| |
| // Storage for SetNexWindow** functions |
| struct ImGuiNextWindowData |
| { |
| ImGuiNextWindowDataFlags Flags; |
| ImGuiCond PosCond; |
| ImGuiCond SizeCond; |
| ImGuiCond CollapsedCond; |
| ImGuiCond DockCond; |
| ImVec2 PosVal; |
| ImVec2 PosPivotVal; |
| ImVec2 SizeVal; |
| ImVec2 ContentSizeVal; |
| ImVec2 ScrollVal; |
| ImGuiChildFlags ChildFlags; |
| bool PosUndock; |
| bool CollapsedVal; |
| ImRect SizeConstraintRect; |
| ImGuiSizeCallback SizeCallback; |
| void* SizeCallbackUserData; |
| float BgAlphaVal; // Override background alpha |
| ImGuiID ViewportId; |
| ImGuiID DockId; |
| ImGuiWindowClass WindowClass; |
| 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?) |
| |
| ImGuiNextWindowData() { memset(this, 0, sizeof(*this)); } |
| inline void ClearFlags() { Flags = ImGuiNextWindowDataFlags_None; } |
| }; |
| |
| // Multi-Selection item index or identifier when using SetNextItemSelectionUserData()/BeginMultiSelect() |
| // (Most users are likely to use this store an item INDEX but this may be used to store a POINTER as well.) |
| typedef ImS64 ImGuiSelectionUserData; |
| |
| enum ImGuiNextItemDataFlags_ |
| { |
| ImGuiNextItemDataFlags_None = 0, |
| ImGuiNextItemDataFlags_HasWidth = 1 << 0, |
| ImGuiNextItemDataFlags_HasOpen = 1 << 1, |
| }; |
| |
| struct ImGuiNextItemData |
| { |
| ImGuiNextItemDataFlags Flags; |
| ImGuiItemFlags ItemFlags; // Currently only tested/used for ImGuiItemFlags_AllowOverlap. |
| // Non-flags members are NOT cleared by ItemAdd() meaning they are still valid during NavProcessItem() |
| float Width; // Set by SetNextItemWidth() |
| ImGuiSelectionUserData SelectionUserData; // Set by SetNextItemSelectionUserData() (note that NULL/0 is a valid value, we use -1 == ImGuiSelectionUserData_Invalid to mark invalid values) |
| ImGuiCond OpenCond; |
| bool OpenVal; // Set by SetNextItemOpen() |
| |
| ImGuiNextItemData() { memset(this, 0, sizeof(*this)); SelectionUserData = -1; } |
| inline void ClearFlags() { Flags = ImGuiNextItemDataFlags_None; ItemFlags = ImGuiItemFlags_None; } // Also cleared manually by ItemAdd()! |
| }; |
| |
| // Status storage for the last submitted item |
| struct ImGuiLastItemData |
| { |
| ImGuiID ID; |
| ImGuiItemFlags InFlags; // See ImGuiItemFlags_ |
| ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_ |
| ImRect Rect; // Full rectangle |
| ImRect NavRect; // Navigation scoring rectangle (not displayed) |
| ImRect DisplayRect; // Display rectangle (only if ImGuiItemStatusFlags_HasDisplayRect is set) |
| |
| ImGuiLastItemData() { memset(this, 0, sizeof(*this)); } |
| }; |
| |
| // Store data emitted by TreeNode() for usage by TreePop() to implement ImGuiTreeNodeFlags_NavLeftJumpsBackHere. |
| // This is the minimum amount of data that we need to perform the equivalent of NavApplyItemToResult() and which we can't infer in TreePop() |
| // Only stored when the node is a potential candidate for landing on a Left arrow jump. |
| struct ImGuiNavTreeNodeData |
| { |
| ImGuiID ID; |
| ImGuiItemFlags InFlags; |
| ImRect NavRect; |
| }; |
| |
| struct IMGUI_API ImGuiStackSizes |
| { |
| short SizeOfIDStack; |
| short SizeOfColorStack; |
| short SizeOfStyleVarStack; |
| short SizeOfFontStack; |
| short SizeOfFocusScopeStack; |
| short SizeOfGroupStack; |
| short SizeOfItemFlagsStack; |
| short SizeOfBeginPopupStack; |
| short SizeOfDisabledStack; |
| |
| ImGuiStackSizes() { memset(this, 0, sizeof(*this)); } |
| void SetToContextState(ImGuiContext* ctx); |
| void CompareWithContextState(ImGuiContext* ctx); |
| }; |
| |
| // Data saved for each window pushed into the stack |
| struct ImGuiWindowStackData |
| { |
| ImGuiWindow* Window; |
| ImGuiLastItemData ParentLastItemDataBackup; |
| ImGuiStackSizes StackSizesOnBegin; // Store size of various stacks for asserting |
| }; |
| |
| 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] 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 ImGuiKey_GamepadFaceDown |
| #define ImGuiKey_NavGamepadCancel ImGuiKey_GamepadFaceRight |
| #define ImGuiKey_NavGamepadMenu ImGuiKey_GamepadFaceLeft |
| #define ImGuiKey_NavGamepadInput ImGuiKey_GamepadFaceUp |
| |
| enum ImGuiInputEventType |
| { |
| ImGuiInputEventType_None = 0, |
| ImGuiInputEventType_MousePos, |
| ImGuiInputEventType_MouseWheel, |
| ImGuiInputEventType_MouseButton, |
| ImGuiInputEventType_MouseViewport, |
| 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_Clipboard, // Currently only used by InputText() |
| 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 ImGuiInputEventMouseViewport { ImGuiID HoveredViewportID; }; |
| 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 |
| ImGuiInputEventMouseViewport MouseViewport; // if Type == ImGuiInputEventType_MouseViewport |
| 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_None ((ImGuiID)-1) // Require key to have no owner. |
| |
| 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. ImGuiMod_Shortcut is already translated to Ctrl/Super. |
| ImU8 RoutingNextScore; // Lower is better (0: perfect score) |
| ImGuiID RoutingCurr; |
| ImGuiID RoutingNext; |
| |
| ImGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingNextScore = 255; RoutingCurr = RoutingNext = ImGuiKeyOwner_None; } |
| }; |
| |
| // 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_None; LockThisFrame = LockUntilRelease = false; } |
| }; |
| |
| // Flags for extended versions of IsKeyPressed(), IsMouseClicked(), Shortcut(), SetKeyOwner(), SetItemKeyOwner() |
| // Don't mistake with ImGuiInputTextFlags! (for ImGui::InputText() function) |
| enum ImGuiInputFlags_ |
| { |
| // Flags for IsKeyPressed(), IsMouseClicked(), Shortcut() |
| ImGuiInputFlags_None = 0, |
| ImGuiInputFlags_Repeat = 1 << 0, // Return true on successive repeats. Default for legacy IsKeyPressed(). NOT Default for legacy IsMouseClicked(). MUST BE == 1. |
| ImGuiInputFlags_RepeatRateDefault = 1 << 1, // Repeat rate: Regular (default) |
| ImGuiInputFlags_RepeatRateNavMove = 1 << 2, // Repeat rate: Fast |
| ImGuiInputFlags_RepeatRateNavTweak = 1 << 3, // Repeat rate: Faster |
| ImGuiInputFlags_RepeatRateMask_ = ImGuiInputFlags_RepeatRateDefault | ImGuiInputFlags_RepeatRateNavMove | ImGuiInputFlags_RepeatRateNavTweak, |
| |
| // Flags for SetItemKeyOwner() |
| ImGuiInputFlags_CondHovered = 1 << 4, // Only set if item is hovered (default to both) |
| ImGuiInputFlags_CondActive = 1 << 5, // Only set if item is active (default to both) |
| ImGuiInputFlags_CondDefault_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive, |
| ImGuiInputFlags_CondMask_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive, |
| |
| // Flags for SetKeyOwner(), SetItemKeyOwner() |
| ImGuiInputFlags_LockThisFrame = 1 << 6, // Access to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared at end of frame. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code. |
| ImGuiInputFlags_LockUntilRelease = 1 << 7, // Access 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. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code. |
| |
| // Routing policies for Shortcut() + low-level SetShortcutRouting() |
| // - The general idea is that several callers register interest in a shortcut, and only one owner gets it. |
| // - When a policy (other than _RouteAlways) is set, Shortcut() will register itself with SetShortcutRouting(), |
| // allowing the system to decide where to route the input among other route-aware calls. |
| // - Shortcut() uses ImGuiInputFlags_RouteFocused by default: meaning that a simple Shortcut() poll |
| // will register a route and only succeed when parent window is in the focus stack and if no-one |
| // with a higher priority is claiming the shortcut. |
| // - Using ImGuiInputFlags_RouteAlways is roughly equivalent to doing e.g. IsKeyPressed(key) + testing mods. |
| // - Priorities: GlobalHigh > Focused (when owner is active item) > Global > Focused (when focused window) > GlobalLow. |
| // - Can select only 1 policy among all available. |
| ImGuiInputFlags_RouteFocused = 1 << 8, // (Default) Register focused route: Accept inputs if window is in focus stack. Deep-most focused window takes inputs. ActiveId takes inputs over deep-most focused window. |
| ImGuiInputFlags_RouteGlobalLow = 1 << 9, // Register route globally (lowest priority: unless a focused window or active item registered the route) -> recommended Global priority. |
| ImGuiInputFlags_RouteGlobal = 1 << 10, // Register route globally (medium priority: unless an active item registered the route, e.g. CTRL+A registered by InputText). |
| ImGuiInputFlags_RouteGlobalHigh = 1 << 11, // Register route globally (highest priority: unlikely you need to use that: will interfere with every active items) |
| ImGuiInputFlags_RouteMask_ = ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteGlobalLow | ImGuiInputFlags_RouteGlobalHigh, // _Always not part of this! |
| ImGuiInputFlags_RouteAlways = 1 << 12, // Do not register route, poll keys directly. |
| ImGuiInputFlags_RouteUnlessBgFocused= 1 << 13, // Global routes will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications. |
| ImGuiInputFlags_RouteExtraMask_ = ImGuiInputFlags_RouteAlways | ImGuiInputFlags_RouteUnlessBgFocused, |
| |
| // [Internal] Mask of which function support which flags |
| ImGuiInputFlags_SupportedByIsKeyPressed = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_, |
| ImGuiInputFlags_SupportedByShortcut = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_ | ImGuiInputFlags_RouteMask_ | ImGuiInputFlags_RouteExtraMask_, |
| 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) |
| }; |
| |
| // 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 ImGuiNavHighlightFlags_ |
| { |
| ImGuiNavHighlightFlags_None = 0, |
| ImGuiNavHighlightFlags_TypeDefault = 1 << 0, |
| ImGuiNavHighlightFlags_TypeThin = 1 << 1, |
| ImGuiNavHighlightFlags_AlwaysDraw = 1 << 2, // Draw rectangular highlight if (g.NavId == id) _even_ when using the mouse. |
| ImGuiNavHighlightFlags_NoRounding = 1 << 3, |
| }; |
| |
| 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_NoSetNavHighlight = 1 << 14, // Do not alter the visible state of keyboard vs mouse nav highlight |
| }; |
| |
| enum ImGuiNavLayer |
| { |
| ImGuiNavLayer_Main = 0, // Main scrolling layer |
| ImGuiNavLayer_Menu = 1, // Menu layer (access with Alt) |
| ImGuiNavLayer_COUNT |
| }; |
| |
| 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 InFlags; // ????,Move // Best candidate item flags |
| ImGuiSelectionUserData SelectionUserData;//I+Mov // Best candidate SetNextItemSelectionData() value. |
| 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 |
| |
| ImGuiNavItemData() { Clear(); } |
| void Clear() { Window = NULL; ID = FocusScopeId = 0; InFlags = 0; SelectionUserData = -1; DistBox = DistCenter = DistAxial = FLT_MAX; } |
| }; |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Typing-select support |
| //----------------------------------------------------------------------------- |
| |
| // Flags for GetTypingSelectRequest() |
| enum ImGuiTypingSelectFlags_ |
| { |
| ImGuiTypingSelectFlags_None = 0, |
| ImGuiTypingSelectFlags_AllowBackspace = 1 << 0, // Backspace to delete character inputs. If using: ensure GetTypingSelectRequest() is not called more than once per frame (filter by e.g. focus state) |
| 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(). Prefix 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, // (WIP) 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] Multi-select support |
| //----------------------------------------------------------------------------- |
| |
| // We always assume that -1 is an invalid value (which works for indices and pointers) |
| #define ImGuiSelectionUserData_Invalid ((ImGuiSelectionUserData)-1) |
| |
| #ifdef IMGUI_HAS_MULTI_SELECT |
| // <this is filled in 'range_select' branch> |
| #endif // #ifdef IMGUI_HAS_MULTI_SELECT |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Docking support |
| //----------------------------------------------------------------------------- |
| |
| #define DOCKING_HOST_DRAW_CHANNEL_BG 0 // Dock host: background fill |
| #define DOCKING_HOST_DRAW_CHANNEL_FG 1 // Dock host: decorations and contents |
| |
| #ifdef IMGUI_HAS_DOCK |
| |
| // Extend ImGuiDockNodeFlags_ |
| enum ImGuiDockNodeFlagsPrivate_ |
| { |
| // [Internal] |
| ImGuiDockNodeFlags_DockSpace = 1 << 10, // Saved // A dockspace is a node that occupy space within an existing user window. Otherwise the node is floating and create its own window. |
| ImGuiDockNodeFlags_CentralNode = 1 << 11, // Saved // The central node has 2 main properties: stay visible when empty, only use "remaining" spaces from its neighbor. |
| ImGuiDockNodeFlags_NoTabBar = 1 << 12, // Saved // Tab bar is completely unavailable. No triangle in the corner to enable it back. |
| ImGuiDockNodeFlags_HiddenTabBar = 1 << 13, // Saved // Tab bar is hidden, with a triangle in the corner to show it again (NB: actual tab-bar instance may be destroyed as this is only used for single-window tab bar) |
| ImGuiDockNodeFlags_NoWindowMenuButton = 1 << 14, // Saved // Disable window/docking menu (that one that appears instead of the collapse button) |
| ImGuiDockNodeFlags_NoCloseButton = 1 << 15, // Saved // Disable close button |
| ImGuiDockNodeFlags_NoResizeX = 1 << 16, // // |
| ImGuiDockNodeFlags_NoResizeY = 1 << 17, // // |
| // Disable docking/undocking actions in this dockspace or individual node (existing docked nodes will be preserved) |
| // Those are not exposed in public because the desirable sharing/inheriting/copy-flag-on-split behaviors are quite difficult to design and understand. |
| // The two public flags ImGuiDockNodeFlags_NoDockingOverCentralNode/ImGuiDockNodeFlags_NoDockingSplit don't have those issues. |
| ImGuiDockNodeFlags_NoDockingSplitOther = 1 << 19, // // Disable this node from splitting other windows/nodes. |
| ImGuiDockNodeFlags_NoDockingOverMe = 1 << 20, // // Disable other windows/nodes from being docked over this node. |
| ImGuiDockNodeFlags_NoDockingOverOther = 1 << 21, // // Disable this node from being docked over another window or non-empty node. |
| ImGuiDockNodeFlags_NoDockingOverEmpty = 1 << 22, // // Disable this node from being docked over an empty node (e.g. DockSpace with no other windows) |
| ImGuiDockNodeFlags_NoDocking = ImGuiDockNodeFlags_NoDockingOverMe | ImGuiDockNodeFlags_NoDockingOverOther | ImGuiDockNodeFlags_NoDockingOverEmpty | ImGuiDockNodeFlags_NoDockingSplit | ImGuiDockNodeFlags_NoDockingSplitOther, |
| // Masks |
| ImGuiDockNodeFlags_SharedFlagsInheritMask_ = ~0, |
| ImGuiDockNodeFlags_NoResizeFlagsMask_ = ImGuiDockNodeFlags_NoResize | ImGuiDockNodeFlags_NoResizeX | ImGuiDockNodeFlags_NoResizeY, |
| // When splitting, those local flags are moved to the inheriting child, never duplicated |
| ImGuiDockNodeFlags_LocalFlagsTransferMask_ = ImGuiDockNodeFlags_NoDockingSplit | ImGuiDockNodeFlags_NoResizeFlagsMask_ | ImGuiDockNodeFlags_AutoHideTabBar | ImGuiDockNodeFlags_CentralNode | ImGuiDockNodeFlags_NoTabBar | ImGuiDockNodeFlags_HiddenTabBar | ImGuiDockNodeFlags_NoWindowMenuButton | ImGuiDockNodeFlags_NoCloseButton, |
| ImGuiDockNodeFlags_SavedFlagsMask_ = ImGuiDockNodeFlags_NoResizeFlagsMask_ | ImGuiDockNodeFlags_DockSpace | ImGuiDockNodeFlags_CentralNode | ImGuiDockNodeFlags_NoTabBar | ImGuiDockNodeFlags_HiddenTabBar | ImGuiDockNodeFlags_NoWindowMenuButton | ImGuiDockNodeFlags_NoCloseButton, |
| }; |
| |
| // Store the source authority (dock node vs window) of a field |
| enum ImGuiDataAuthority_ |
| { |
| ImGuiDataAuthority_Auto, |
| ImGuiDataAuthority_DockNode, |
| ImGuiDataAuthority_Window, |
| }; |
| |
| enum ImGuiDockNodeState |
| { |
| ImGuiDockNodeState_Unknown, |
| ImGuiDockNodeState_HostWindowHiddenBecauseSingleWindow, |
| ImGuiDockNodeState_HostWindowHiddenBecauseWindowsAreResizing, |
| ImGuiDockNodeState_HostWindowVisible, |
| }; |
| |
| // sizeof() 156~192 |
| struct IMGUI_API ImGuiDockNode |
| { |
| ImGuiID ID; |
| ImGuiDockNodeFlags SharedFlags; // (Write) Flags shared by all nodes of a same dockspace hierarchy (inherited from the root node) |
| ImGuiDockNodeFlags LocalFlags; // (Write) Flags specific to this node |
| ImGuiDockNodeFlags LocalFlagsInWindows; // (Write) Flags specific to this node, applied from windows |
| ImGuiDockNodeFlags MergedFlags; // (Read) Effective flags (== SharedFlags | LocalFlagsInNode | LocalFlagsInWindows) |
| ImGuiDockNodeState State; |
| ImGuiDockNode* ParentNode; |
| ImGuiDockNode* ChildNodes[2]; // [Split node only] Child nodes (left/right or top/bottom). Consider switching to an array. |
| ImVector<ImGuiWindow*> Windows; // Note: unordered list! Iterate TabBar->Tabs for user-order. |
| ImGuiTabBar* TabBar; |
| ImVec2 Pos; // Current position |
| ImVec2 Size; // Current size |
| ImVec2 SizeRef; // [Split node only] Last explicitly written-to size (overridden when using a splitter affecting the node), used to calculate Size. |
| ImGuiAxis SplitAxis; // [Split node only] Split axis (X or Y) |
| ImGuiWindowClass WindowClass; // [Root node only] |
| ImU32 LastBgColor; |
| |
| ImGuiWindow* HostWindow; |
| ImGuiWindow* VisibleWindow; // Generally point to window which is ID is == SelectedTabID, but when CTRL+Tabbing this can be a different window. |
| ImGuiDockNode* CentralNode; // [Root node only] Pointer to central node. |
| ImGuiDockNode* OnlyNodeWithWindows; // [Root node only] Set when there is a single visible node within the hierarchy. |
| int CountNodeWithWindows; // [Root node only] |
| int LastFrameAlive; // Last frame number the node was updated or kept alive explicitly with DockSpace() + ImGuiDockNodeFlags_KeepAliveOnly |
| int LastFrameActive; // Last frame number the node was updated. |
| int LastFrameFocused; // Last frame number the node was focused. |
| ImGuiID LastFocusedNodeId; // [Root node only] Which of our child docking node (any ancestor in the hierarchy) was last focused. |
| ImGuiID SelectedTabId; // [Leaf node only] Which of our tab/window is selected. |
| ImGuiID WantCloseTabId; // [Leaf node only] Set when closing a specific tab/window. |
| ImGuiID RefViewportId; // Reference viewport ID from visible window when HostWindow == NULL. |
| ImGuiDataAuthority AuthorityForPos :3; |
| ImGuiDataAuthority AuthorityForSize :3; |
| ImGuiDataAuthority AuthorityForViewport :3; |
| bool IsVisible :1; // Set to false when the node is hidden (usually disabled as it has no active window) |
| bool IsFocused :1; |
| bool IsBgDrawnThisFrame :1; |
| bool HasCloseButton :1; // Provide space for a close button (if any of the docked window has one). Note that button may be hidden on window without one. |
| bool HasWindowMenuButton :1; |
| bool HasCentralNodeChild :1; |
| bool WantCloseAll :1; // Set when closing all tabs at once. |
| bool WantLockSizeOnce :1; |
| bool WantMouseMove :1; // After a node extraction we need to transition toward moving the newly created host window |
| bool WantHiddenTabBarUpdate :1; |
| bool WantHiddenTabBarToggle :1; |
| |
| ImGuiDockNode(ImGuiID id); |
| ~ImGuiDockNode(); |
| bool IsRootNode() const { return ParentNode == NULL; } |
| bool IsDockSpace() const { return (MergedFlags & ImGuiDockNodeFlags_DockSpace) != 0; } |
| bool IsFloatingNode() const { return ParentNode == NULL && (MergedFlags & ImGuiDockNodeFlags_DockSpace) == 0; } |
| bool IsCentralNode() const { return (MergedFlags & ImGuiDockNodeFlags_CentralNode) != 0; } |
| bool IsHiddenTabBar() const { return (MergedFlags & ImGuiDockNodeFlags_HiddenTabBar) != 0; } // Hidden tab bar can be shown back by clicking the small triangle |
| bool IsNoTabBar() const { return (MergedFlags & ImGuiDockNodeFlags_NoTabBar) != 0; } // Never show a tab bar |
| bool IsSplitNode() const { return ChildNodes[0] != NULL; } |
| bool IsLeafNode() const { return ChildNodes[0] == NULL; } |
| bool IsEmpty() const { return ChildNodes[0] == NULL && Windows.Size == 0; } |
| ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); } |
| |
| void SetLocalFlags(ImGuiDockNodeFlags flags) { LocalFlags = flags; UpdateMergedFlags(); } |
| void UpdateMergedFlags() { MergedFlags = SharedFlags | LocalFlags | LocalFlagsInWindows; } |
| }; |
| |
| // List of colors that are stored at the time of Begin() into Docked Windows. |
| // We currently store the packed colors in a simple array window->DockStyle.Colors[]. |
| // A better solution may involve appending into a log of colors in ImGuiContext + store offsets into those arrays in ImGuiWindow, |
| // but it would be more complex as we'd need to double-buffer both as e.g. drop target may refer to window from last frame. |
| enum ImGuiWindowDockStyleCol |
| { |
| ImGuiWindowDockStyleCol_Text, |
| ImGuiWindowDockStyleCol_Tab, |
| ImGuiWindowDockStyleCol_TabHovered, |
| ImGuiWindowDockStyleCol_TabActive, |
| ImGuiWindowDockStyleCol_TabUnfocused, |
| ImGuiWindowDockStyleCol_TabUnfocusedActive, |
| ImGuiWindowDockStyleCol_COUNT |
| }; |
| |
| struct ImGuiWindowDockStyle |
| { |
| ImU32 Colors[ImGuiWindowDockStyleCol_COUNT]; |
| }; |
| |
| struct ImGuiDockContext |
| { |
| ImGuiStorage Nodes; // Map ID -> ImGuiDockNode*: Active nodes |
| ImVector<ImGuiDockRequest> Requests; |
| ImVector<ImGuiDockNodeSettings> NodesSettings; |
| bool WantFullRebuild; |
| ImGuiDockContext() { memset(this, 0, sizeof(*this)); } |
| }; |
| |
| #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 |
| { |
| ImGuiWindow* Window; // Set when the viewport is owned by a window (and ImGuiViewportFlags_CanHostOtherWindows is NOT set) |
| int Idx; |
| int LastFrameActive; // Last frame number this viewport was activated by a window |
| int LastFocusedStampCount; // Last stamp number from when a window hosted by this viewport was focused (by comparing this value between two viewport we have an implicit viewport z-order we use as fallback) |
| ImGuiID LastNameHash; |
| ImVec2 LastPos; |
| float Alpha; // Window opacity (when dragging dockable windows/viewports we make them transparent) |
| float LastAlpha; |
| bool LastFocusedHadNavWindow;// Instead of maintaining a LastFocusedWindow (which may harder to correctly maintain), we merely store weither NavWindow != NULL last time the viewport was focused. |
| short PlatformMonitor; |
| 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 |
| ImVec2 LastPlatformPos; |
| ImVec2 LastPlatformSize; |
| ImVec2 LastRendererSize; |
| ImVec2 WorkOffsetMin; // Work Area: Offset from Pos to top-left corner of Work Area. Generally (0,0) or (0,+main_menu_bar_height). Work Area is Full Area but without menu-bars/status-bars (so WorkArea always fit inside Pos/Size!) |
| ImVec2 WorkOffsetMax; // Work Area: Offset from Pos+Size to bottom-right corner of Work Area. Generally (0,0) or (0,-status_bar_height). |
| ImVec2 BuildWorkOffsetMin; // Work Area: Offset being built during current frame. Generally >= 0.0f. |
| ImVec2 BuildWorkOffsetMax; // Work Area: Offset being built during current frame. Generally <= 0.0f. |
| |
| ImGuiViewportP() { Window = NULL; Idx = -1; LastFrameActive = BgFgDrawListsLastFrame[0] = BgFgDrawListsLastFrame[1] = LastFocusedStampCount = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; LastFocusedHadNavWindow = false; PlatformMonitor = -1; BgFgDrawLists[0] = BgFgDrawLists[1] = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); } |
| ~ImGuiViewportP() { if (BgFgDrawLists[0]) IM_DELETE(BgFgDrawLists[0]); if (BgFgDrawLists[1]) IM_DELETE(BgFgDrawLists[1]); } |
| void ClearRequestFlags() { PlatformRequestClose = PlatformRequestMove = PlatformRequestResize = false; } |
| |
| // 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& off_min) const { return ImVec2(Pos.x + off_min.x, Pos.y + off_min.y); } |
| ImVec2 CalcWorkRectSize(const ImVec2& off_min, const ImVec2& off_max) const { return ImVec2(ImMax(0.0f, Size.x - off_min.x + off_max.x), ImMax(0.0f, Size.y - off_min.y + off_max.y)); } |
| void UpdateWorkRect() { WorkPos = CalcWorkRectPos(WorkOffsetMin); WorkSize = CalcWorkRectSize(WorkOffsetMin, WorkOffsetMax); } // 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(BuildWorkOffsetMin); ImVec2 size = CalcWorkRectSize(BuildWorkOffsetMin, BuildWorkOffsetMax); 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; // NB: Settings position are stored RELATIVE to the viewport! Whereas runtime ones are absolute positions. |
| ImVec2ih Size; |
| ImVec2ih ViewportPos; |
| ImGuiID ViewportId; |
| ImGuiID DockId; // ID of last known DockNode (even if the DockNode is invisible because it has only 1 active window), or 0 if none. |
| ImGuiID ClassId; // ID of window class if specified |
| short DockOrder; // Order of the last time the window was visible within its DockNode. This is used to reorder windows that are reappearing on the same frame. Same value between windows that were active and windows that were none are possible. |
| 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)); DockOrder = -1; } |
| 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_DockingHideTabBar, |
| ImGuiLocKey_DockingHoldShiftToDock, |
| ImGuiLocKey_DockingDragToUndockOrMoveNode, |
| ImGuiLocKey_COUNT |
| }; |
| |
| struct ImGuiLocEntry |
| { |
| ImGuiLocKey Key; |
| const char* Text; |
| }; |
| |
| |
| //----------------------------------------------------------------------------- |
| // [SECTION] Metrics, Debug Tools |
| //----------------------------------------------------------------------------- |
| |
| enum ImGuiDebugLogFlags_ |
| { |
| // Event types |
| ImGuiDebugLogFlags_None = 0, |
| ImGuiDebugLogFlags_EventActiveId = 1 << 0, |
| ImGuiDebugLogFlags_EventFocus = 1 << 1, |
| ImGuiDebugLogFlags_EventPopup = 1 << 2, |
| ImGuiDebugLogFlags_EventNav = 1 << 3, |
| ImGuiDebugLogFlags_EventClipper = 1 << 4, |
| ImGuiDebugLogFlags_EventSelection = 1 << 5, |
| ImGuiDebugLogFlags_EventIO = 1 << 6, |
| ImGuiDebugLogFlags_EventDocking = 1 << 7, |
| ImGuiDebugLogFlags_EventViewport = 1 << 8, |
| ImGuiDebugLogFlags_EventMask_ = ImGuiDebugLogFlags_EventActiveId | ImGuiDebugLogFlags_EventFocus | ImGuiDebugLogFlags_EventPopup | ImGuiDebugLogFlags_EventNav | ImGuiDebugLogFlags_EventClipper | ImGuiDebugLogFlags_EventSelection | ImGuiDebugLogFlags_EventIO | ImGuiDebugLogFlags_EventDocking | ImGuiDebugLogFlags_EventViewport, |
| ImGuiDebugLogFlags_OutputToTTY = 1 << 10, // Also send output to TTY |
| ImGuiDebugLogFlags_OutputToTestEngine = 1 << 11,// 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 ShowAtlasTintedWithTextColor = false; |
| bool ShowDockingNodes = false; |
| int ShowWindowsRectsType = -1; |
| int ShowTablesRectsType = -1; |
| }; |
| |
| 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; |
| ImGuiConfigFlags ConfigFlagsCurrFrame; // = g.IO.ConfigFlags at the time of NewFrame() |
| ImGuiConfigFlags ConfigFlagsLastFrame; |
| 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. |
| ImDrawListSharedData DrawListSharedData; |
| double Time; |
| int FrameCount; |
| int FrameCountEnded; |
| int FrameCountPlatformEnded; |
| 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 |
| |
| // 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) |
| 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* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actual window that is moved is generally MovingWindow->RootWindowDockTree. |
| 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 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; |
| bool HoveredIdAllowOverlap; |
| bool HoveredIdDisabled; // 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. |
| float HoveredIdTimer; // Measure contiguous hovering time |
| float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active |
| 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; |
| 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 |
| int ActiveIdMouseButton; |
| 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. |
| |
| // [EXPERIMENTAL] 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_None (== -1) or a custom ID. |
| // - Routing is requested ahead of time for a given chord (Key + Mods) and granted in NewFrame(). |
| 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. (FIXME: This is a shortcut for not taking ownership of 100+ keys but perhaps best to not have the inconsistency) |
| #ifndef IMGUI_DISABLE_OBSOLETE_KEYIO |
| ImU32 ActiveIdUsingNavInputMask; // If you used this. Since (IMGUI_VERSION_NUM >= 18804) : 'g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel);' becomes 'SetKeyOwner(ImGuiKey_Escape, g.ActiveId) and/or SetKeyOwner(ImGuiKey_NavGamepadCancel, g.ActiveId);' |
| #endif |
| |
| // Next window/item data |
| ImGuiID CurrentFocusScopeId; // == g.FocusScopeStack.back() |
| ImGuiItemFlags CurrentItemFlags; // == 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 |
| 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<ImGuiID> 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<ImGuiNavTreeNodeData> NavTreeNodeStack; // Stack for TreeNode() when a NavLeft requested is emitted. |
| |
| int BeginMenuCount; |
| |
| // Viewports |
| ImVector<ImGuiViewportP*> Viewports; // Active viewports (always 1+, and generally 1 unless multi-viewports are enabled). Each viewports hold their copy of ImDrawData. |
| float CurrentDpiScale; // == CurrentViewport->DpiScale |
| ImGuiViewportP* CurrentViewport; // We track changes of viewport (happening in Begin) so we can call Platform_OnChangedViewport() |
| ImGuiViewportP* MouseViewport; |
| ImGuiViewportP* MouseLastHoveredViewport; // Last known viewport that was hovered by mouse (even if we are not hovering any viewport any more) + honoring the _NoInputs flag. |
| ImGuiID PlatformLastFocusedViewportId; |
| ImGuiPlatformMonitor FallbackMonitor; // Virtual monitor used as fallback if backend doesn't provide monitor information. |
| int ViewportCreatedCount; // Unique sequential creation counter (mostly for testing/debugging) |
| int PlatformWindowsCreatedCount; // Unique sequential creation counter (mostly for testing/debugging) |
| int ViewportFocusedStampCount; // Every time the front-most window changes, we stamp its viewport with an incrementing counter |
| |
| // Gamepad/keyboard Navigation |
| ImGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusedWindow' |
| ImGuiID NavId; // Focused item for navigation |
| ImGuiID NavFocusScopeId; // Identify a selection scope (selection code often wants to "clear other items" when landing on an item of the selection set) |
| 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; |
| 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; |
| 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 |
| ImGuiNavLayer NavLayer; // Layer we are navigating on. For now the system is hard-coded for 0=main contents and 1=menu/title bar, may expose layers later. |
| 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. |
| bool NavIdIsAlive; // Nav widget has been seen this frame ~~ NavRectRel is valid |
| bool NavMousePosDirty; // When set we will update mouse position if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) if set (NB: this not enabled by default) |
| bool NavDisableHighlight; // When user starts using mouse, we hide gamepad/keyboard highlight (NB: but they are still available, which is why NavDisableHighlight isn't always != NavDisableMouseHover) |
| bool NavDisableMouseHover; // When user starts using gamepad/keyboard, we hide mouse hovering highlight until mouse is touched again. |
| |
| // 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: Windowing (CTRL+TAB for list, or Menu button + keys or directional pads to move/resize) |
| ImGuiKeyChord ConfigNavWindowingKeyNext; // = ImGuiMod_Ctrl | ImGuiKey_Tab, for reconfiguration (see #4828) |
| ImGuiKeyChord ConfigNavWindowingKeyPrev; // = ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Tab |
| ImGuiWindow* Nav
|