// dear imgui, v1.84 // (internal structures/api) // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward // compatibility! Set: // #define IMGUI_DEFINE_MATH_OPERATORS // To implement maths operators for ImVec2 (disabled by default to not collide with using IM_VEC2_CLASS_EXTRA along with // your own math types+operators) /* 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] Columns support // [SECTION] Multi-select support // [SECTION] Docking support // [SECTION] Viewport support // [SECTION] Settings support // [SECTION] Metrics, Debug // [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 // FILE*, sscanf # include // NULL, malloc, free, qsort, atoi, atof # include // sqrtf, fabsf, fmodf, powf, floorf, ceilf, cosf, sinf # include // INT_MIN, INT_MAX // Enable SSE intrinsics if available # if (defined __SSE__ || defined __x86_64__ || defined _M_X64) && !defined(IMGUI_DISABLE_SSE) # define IMGUI_ENABLE_SSE # include # 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 ImFloorSigned() # 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 # 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 // Helper macros # if defined(__clang__) # define IM_NORETURN __attribute__((noreturn)) # else # define IM_NORETURN # 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 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 ImGuiLastItemData; // Status storage for last submitted items struct ImGuiMenuColumns; // Simple column measurement, currently used for MenuItem() only struct ImGuiNavItemData; // Result of a gamepad/keyboard directional navigation move query result struct ImGuiMetricsConfig; // Storage for ShowMetricsWindow() and DebugNodeXXX() functions struct ImGuiNextWindowData; // Storage for SetNextWindow** functions struct ImGuiNextItemData; // Storage for SetNextItem** functions struct ImGuiOldColumnData; // Storage data for a single column for legacy Columns() api struct ImGuiOldColumns; // Storage data for a columns set for legacy Columns() api struct ImGuiPopupData; // Storage for current popup stack struct ImGuiSettingsHandler; // Storage for one type registered in the .ini file struct 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 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 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) // Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum // lists. 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 typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag() typedef int ImGuiItemAddFlags; // -> enum ImGuiItemAddFlags_ // Flags: for ItemAdd() typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for DC.LastItemStatusFlags typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns() typedef int ImGuiNavHighlightFlags; // -> enum ImGuiNavHighlightFlags_ // Flags: for RenderNavHighlight() typedef int ImGuiNavDirSourceFlags; // -> enum ImGuiNavDirSourceFlags_ // Flags: for GetNavInputAmount2d() 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 ImGuiSeparatorFlags; // -> enum ImGuiSeparatorFlags_ // Flags: for SeparatorEx() typedef int ImGuiTextFlags; // -> enum ImGuiTextFlags_ // Flags: for TextEx() typedef int ImGuiTooltipFlags; // -> enum ImGuiTooltipFlags_ // Flags: for BeginTooltipEx() 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 Logging # ifndef IMGUI_DEBUG_LOG # define IMGUI_DEBUG_LOG(_FMT, ...) printf("[%05d] " _FMT, GImGui->FrameCount, __VA_ARGS__) # endif // Debug Logging for selected systems. Remove the '((void)0) //' to enable. //#define IMGUI_DEBUG_LOG_POPUP IMGUI_DEBUG_LOG // Enable log //#define IMGUI_DEBUG_LOG_NAV IMGUI_DEBUG_LOG // Enable log //#define IMGUI_DEBUG_LOG_VIEWPORT IMGUI_DEBUG_LOG // Enable log //#define IMGUI_DEBUG_LOG_DOCKING IMGUI_DEBUG_LOG // Enable log # define IMGUI_DEBUG_LOG_POPUP(...) ((void)0) // Disable log # define IMGUI_DEBUG_LOG_NAV(...) ((void)0) // Disable log # define IMGUI_DEBUG_LOG_VIEWPORT(...) ((void)0) // Disable log # define IMGUI_DEBUG_LOG_DOCKING(...) ((void)0) // Disable log // Static Asserts # if (__cplusplus >= 201100) || (defined(_MSVC_LANG) && _MSVC_LANG >= 201100) # define IM_STATIC_ASSERT(_COND) static_assert(_COND, "") # else # define IM_STATIC_ASSERT(_COND) typedef char static_assertion_##__line__[(_COND) ? 1 : -1] # endif // "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 # define IM_TABSIZE (4) # 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_FLOOR(_VAL) ((float)(int)(_VAL)) // ImFloor() is not inlined in MSVC debug builds # define IM_ROUND(_VAL) ((float)(int)((_VAL) + 0.5f)) // // 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->Tools->Item Picker' to break into the call-stack of a specific item. # ifndef IM_DEBUG_BREAK # if defined(__clang__) # define IM_DEBUG_BREAK() __builtin_debugtrap() # elif defined(_MSC_VER) # define IM_DEBUG_BREAK() __debugbreak() # 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 //----------------------------------------------------------------------------- // [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, 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<> //----------------------------------------------------------------------------- // Helpers: Hashing IMGUI_API ImGuiID ImHashData(const void* data, size_t data_size, ImU32 seed = 0); IMGUI_API ImGuiID ImHashStr(const char* data, size_t data_size = 0, ImU32 seed = 0); # ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS static inline ImGuiID ImHash(const void* data, int size, ImU32 seed = 0) { return size ? ImHashData(data, (size_t)size, seed) : ImHashStr((const char*)data, 0, seed); } // [moved to ImHashStr/ImHashData in 1.68] # endif // Helpers: Sorting # define ImQsort qsort // 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, Formatting IMGUI_API int ImStricmp(const char* str1, const char* str2); IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count); IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); IMGUI_API char* ImStrdup(const char* str); IMGUI_API char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* str); IMGUI_API const char* ImStrchrRange(const char* str_begin, const char* str_end, char c); IMGUI_API int ImStrlenW(const ImWchar* str); IMGUI_API const char* ImStreolRange(const char* str, const char* str_end); // End end-of-line IMGUI_API const ImWchar* ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end); IMGUI_API void ImStrTrimBlanks(char* str); IMGUI_API const char* ImStrSkipBlank(const char* str); IMGUI_API 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 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 int ImParseFormatPrecision(const char* format, int default_value); static inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; } static inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; } // 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 // Helpers: ImVec2/ImVec4 operators // We are keeping those disabled by default so they don't leak in user space, to allow user enabling implicit cast // operators between ImVec2 and their own types (using IM_VEC2_CLASS_EXTRA etc.) We unfortunately don't have a unary- // operator for ImVec2 because this would needs to be defined inside the class itself. # ifdef IMGUI_DEFINE_MATH_OPERATORS IM_MSVC_RUNTIME_CHECKS_OFF static inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x * rhs, lhs.y * rhs); } static inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x / rhs, lhs.y / rhs); } static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x + rhs.x, lhs.y + rhs.y); } static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x - rhs.x, lhs.y - rhs.y); } static inline ImVec2 operator*(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } static inline ImVec2 operator/(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x / rhs.x, lhs.y / rhs.y); } static inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; } static inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; } static inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; } static inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; } static inline ImVec2& operator*=(ImVec2& lhs, const ImVec2& rhs) { lhs.x *= rhs.x; lhs.y *= rhs.y; return lhs; } static inline ImVec2& operator/=(ImVec2& lhs, const ImVec2& rhs) { lhs.x /= rhs.x; lhs.y /= rhs.y; return lhs; } static inline ImVec4 operator+(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w); } static inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w); } static inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w); } IM_MSVC_RUNTIME_CHECKS_RESTORE # endif // 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 ImFloorStd(X) floorf(X) // We use our own, see ImFloor() and ImFloorSigned() # 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 static inline T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; } template static inline T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; } template static inline T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } template static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * t); } template static inline void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; } template 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 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 ImFloor(float f) { return (float)(int)(f); } static inline float ImFloorSigned(float f) { return (float)((f >= 0 || (int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf() static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(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); } 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; } IMGUI_API ImGuiDir ImGetDirQuadrantFromDelta(float dx, float dy); // 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; ImVec1() { x = 0.0f; } ImVec1(float _x) { x = _x; } }; // Helper: ImVec2ih (2D vector, half-size integer, for long-term packed storage) struct ImVec2ih { short x, y; ImVec2ih() { x = y = 0; } ImVec2ih(short _x, short _y) { x = _x; y = _y; } 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 ImRect() : Min(0.0f, 0.0f), Max(0.0f, 0.0f) {} ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {} ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {} 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 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_FLOOR(Min.x); Min.y = IM_FLOOR(Min.y); Max.x = IM_FLOOR(Max.x); Max.y = IM_FLOOR(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); } }; IM_MSVC_RUNTIME_CHECKS_RESTORE // Helper: ImBitArray 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; } } // Helper: ImBitArray class (wrapper over ImBitArray functions) // Store 1-bit per value. template struct IMGUI_API 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 { IM_ASSERT(n < BITCOUNT); return ImBitArrayTestBit(Storage, n); } void SetBit(int n) { IM_ASSERT(n < BITCOUNT); ImBitArraySetBit(Storage, n); } void ClearBit(int n) { IM_ASSERT(n < BITCOUNT); ImBitArrayClearBit(Storage, n); } void SetBitRange(int n, int n2) { ImBitArraySetBitRange(Storage, n, n2); } // Works on range [n..n2) }; // Helper: ImBitVector // Store 1-bit per value. struct IMGUI_API ImBitVector { ImVector 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 ImBitArrayTestBit(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); } }; // Helper: ImSpan<> // Pointing to a span of data we don't own. template 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 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 inline void GetSpan(int n, ImSpan* 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 struct IMGUI_API ImPool { ImVector 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 struct IMGUI_API ImChunkStream { ImVector 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& rhs) { rhs.Buf.swap(Buf); } }; //----------------------------------------------------------------------------- // [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] 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 Layers[2]; // Global layers for: regular, tooltip void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].resize(0); } void ClearFreeMemory() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].clear(); } int GetDrawListCount() const { int count = 0; for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) count += Layers[n].Size; return count; } IMGUI_API void FlattenIntoSingleLayer(); }; //----------------------------------------------------------------------------- // [SECTION] Widgets support: flags, enums, data structures //----------------------------------------------------------------------------- // Transient per-window flags, reset at the beginning of the frame. For child window, inherited from parent on first // Begin(). This is going to be exposed in imgui.h when stabilized enough. enum ImGuiItemFlags_ { ImGuiItemFlags_None = 0, ImGuiItemFlags_NoTabStop = 1 << 0, // false // Disable keyboard tabbing (FIXME: should merge with _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 keyboard/gamepad directional navigation (FIXME: should merge with _NoTabStop) 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. }; // Flags for ItemAdd() // FIXME-NAV: _Focusable is _ALMOST_ what you would expect to be called '_TabStop' but because SetKeyboardFocusHere() // works on items with no TabStop we distinguish Focusable from TabStop. enum ImGuiItemAddFlags_ { ImGuiItemAddFlags_None = 0, ImGuiItemAddFlags_Focusable = 1 << 0 // FIXME-NAV: In current/legacy scheme, Focusable+TabStop support are opt-in by widgets. We will // transition it toward being opt-out, so this flag is expected to eventually disappear. }; // Storage for LastItem data 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, // window->DC.LastItemDisplayRect 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_FocusedByCode = 1 << 8, // Set when the Focusable item just got focused from code. ImGuiItemStatusFlags_FocusedByTabbing = 1 << 9, // Set when the Focusable item just got focused by Tabbing. ImGuiItemStatusFlags_Focused = ImGuiItemStatusFlags_FocusedByCode | ImGuiItemStatusFlags_FocusedByTabbing # ifdef IMGUI_ENABLE_TEST_ENGINE , // [imgui_tests only] ImGuiItemStatusFlags_Openable = 1 << 20, // ImGuiItemStatusFlags_Opened = 1 << 21, // ImGuiItemStatusFlags_Checkable = 1 << 22, // ImGuiItemStatusFlags_Checked = 1 << 23 // # endif }; // 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_AllowItemOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null // before being usable, use along with SetItemAllowOverlap() 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 ImGuiButtonFlags_NoHoveredOnFocus = 1 << 19, // don't report as hovered when nav focus is on this item 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 }; // 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_DrawHoveredWhenHeld = 1 << 25, // Always show active when held, even is not hovered. This // concept could probably be renamed/formalized somehow. ImGuiSelectableFlags_SetNavIdOnHover = 1 << 26, // Set Nav/Focus ID on mouse hover (used by MenuItem) ImGuiSelectableFlags_NoPadWithHalfSpacing = 1 << 27 // Disable padding each side with ItemSpacing * 0.5f }; // Extend ImGuiTreeNodeFlags_ enum ImGuiTreeNodeFlagsPrivate_ { ImGuiTreeNodeFlags_ClipLabelForTrailingButton = 1 << 20 }; 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 }; enum ImGuiTextFlags_ { ImGuiTextFlags_None = 0, ImGuiTextFlags_NoWidthForLargeClippedText = 1 << 0 }; enum ImGuiTooltipFlags_ { ImGuiTooltipFlags_None = 0, ImGuiTooltipFlags_OverridePreviousTooltip = 1 << 0 // Override will 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 ImGuiInputSource { ImGuiInputSource_None = 0, ImGuiInputSource_Mouse, ImGuiInputSource_Keyboard, ImGuiInputSource_Gamepad, ImGuiInputSource_Nav, // Stored in g.ActiveIdSource only ImGuiInputSource_Clipboard, // Currently only used by InputText() ImGuiInputSource_COUNT }; // FIXME-NAV: Clarify/expose various repeat delay/rate enum ImGuiInputReadMode { ImGuiInputReadMode_Down, ImGuiInputReadMode_Pressed, ImGuiInputReadMode_Released, ImGuiInputReadMode_Repeat, ImGuiInputReadMode_RepeatSlow, ImGuiInputReadMode_RepeatFast }; 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 ImGuiNavDirSourceFlags_ { ImGuiNavDirSourceFlags_None = 0, ImGuiNavDirSourceFlags_Keyboard = 1 << 0, ImGuiNavDirSourceFlags_PadDPad = 1 << 1, ImGuiNavDirSourceFlags_PadLStick = 1 << 2 }; 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 for provided for completeness 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 NavMoveResultLocalVisibleSet that only // comprise elements that are already fully visible. ImGuiNavMoveFlags_ScrollToEdge = 1 << 6 }; enum ImGuiNavForward { ImGuiNavForward_None, ImGuiNavForward_ForwardQueued, ImGuiNavForward_ForwardActive }; enum ImGuiNavLayer { ImGuiNavLayer_Main = 0, // Main scrolling layer ImGuiNavLayer_Menu = 1, // Menu layer (access with Alt/ImGuiNavInput_Menu) ImGuiNavLayer_COUNT }; enum ImGuiPopupPositionPolicy { ImGuiPopupPositionPolicy_Default, ImGuiPopupPositionPolicy_ComboBox, ImGuiPopupPositionPolicy_Tooltip }; 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; ImVec1 BackupIndent; ImVec1 BackupGroupOffset; ImVec2 BackupCurrLineSize; float BackupCurrLineTextBaseOffset; ImGuiID BackupActiveIdIsAlive; bool BackupActiveIdPreviousFrameIsAlive; bool BackupHoveredIdIsAlive; 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 state of the currently focused/edited text input box // For a given item ID, access with ImGui::GetInputTextState() struct IMGUI_API ImGuiInputTextState { 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 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 TextA; // temporary UTF8 buffer for callbacks and other operations. this is not updated in every // code-path! size=capacity. ImVector 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 ImGuiInputTextCallback UserCallback; // " void* UserCallbackData; // " 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* SourceWindow; // Set on OpenPopup() copy of NavWindow at the time of opening the popup 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)); OpenFrameCount = -1; } }; 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 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; RectRel = ImRect(); DistBox = DistCenter = DistAxial = FLT_MAX; } }; 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_HasViewport = 1 << 8, ImGuiNextWindowDataFlags_HasDock = 1 << 9, ImGuiNextWindowDataFlags_HasWindowClass = 1 << 10 }; // 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; 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; } }; enum ImGuiNextItemDataFlags_ { ImGuiNextItemDataFlags_None = 0, ImGuiNextItemDataFlags_HasWidth = 1 << 0, ImGuiNextItemDataFlags_HasOpen = 1 << 1 }; struct ImGuiNextItemData { ImGuiNextItemDataFlags Flags; float Width; // Set by SetNextItemWidth() ImGuiID FocusScopeId; // Set by SetNextItemMultiSelectData() (!= 0 signify value has been set, so it's an alternate // version of HasSelectionData, we don't use Flags for this because they are cleared too // early. This is mostly used for debugging) ImGuiCond OpenCond; bool OpenVal; // Set by SetNextItemOpen() ImGuiNextItemData() { memset(this, 0, sizeof(*this)); } inline void ClearFlags() { Flags = ImGuiNextItemDataFlags_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; ImRect DisplayRect; ImGuiLastItemData() { memset(this, 0, sizeof(*this)); } }; // Data saved for each window pushed into the stack struct ImGuiWindowStackData { ImGuiWindow* Window; ImGuiLastItemData ParentLastItemDataBackup; }; struct ImGuiShrinkWidthItem { int Index; float Width; }; 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] 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 Columns; ImDrawListSplitter Splitter; ImGuiOldColumns() { memset(this, 0, sizeof(*this)); } }; //----------------------------------------------------------------------------- // [SECTION] Multi-select support //----------------------------------------------------------------------------- # ifdef IMGUI_HAS_MULTI_SELECT // # endif // #ifdef IMGUI_HAS_MULTI_SELECT //----------------------------------------------------------------------------- // [SECTION] Docking support //----------------------------------------------------------------------------- # ifdef IMGUI_HAS_DOCK // Extend ImGuiDockNodeFlags_ enum ImGuiDockNodeFlagsPrivate_ { // [Internal] ImGuiDockNodeFlags_DockSpace = 1 << 10, // Local, 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, // Local, Saved // The central node has 2 main properties: stay visible // when empty, only use "remaining" spaces from its neighbor. ImGuiDockNodeFlags_NoTabBar = 1 << 12, // Local, Saved // Tab bar is completely unavailable. No triangle in the corner to enable it back. ImGuiDockNodeFlags_HiddenTabBar = 1 << 13, // Local, 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, // Local, Saved // Disable window/docking menu (that one that appears instead of the collapse button) ImGuiDockNodeFlags_NoCloseButton = 1 << 15, // Local, Saved // ImGuiDockNodeFlags_NoDocking = 1 << 16, // Local, Saved // Disable any form of docking in this dockspace or individual node. (On a whole // dockspace, this pretty much defeat the purpose of using a dockspace at all). Note: when turned on, // existing docked nodes will be preserved. ImGuiDockNodeFlags_NoDockingSplitMe = 1 << 17, // [EXPERIMENTAL] Prevent another window/node from splitting this node. ImGuiDockNodeFlags_NoDockingSplitOther = 1 << 18, // [EXPERIMENTAL] Prevent this node from splitting another window/node. ImGuiDockNodeFlags_NoDockingOverMe = 1 << 19, // [EXPERIMENTAL] Prevent another window/node to be docked over this node. ImGuiDockNodeFlags_NoDockingOverOther = 1 << 20, // [EXPERIMENTAL] Prevent this node to be docked over another window or non-empty node. ImGuiDockNodeFlags_NoDockingOverEmpty = 1 << 21, // [EXPERIMENTAL] Prevent this node to be docked over an empty // node (e.g. DockSpace with no other windows) ImGuiDockNodeFlags_NoResizeX = 1 << 22, // [EXPERIMENTAL] ImGuiDockNodeFlags_NoResizeY = 1 << 23, // [EXPERIMENTAL] ImGuiDockNodeFlags_SharedFlagsInheritMask_ = ~0, ImGuiDockNodeFlags_NoResizeFlagsMask_ = ImGuiDockNodeFlags_NoResize | ImGuiDockNodeFlags_NoResizeX | ImGuiDockNodeFlags_NoResizeY, ImGuiDockNodeFlags_LocalFlagsMask_ = ImGuiDockNodeFlags_NoSplit | ImGuiDockNodeFlags_NoResizeFlagsMask_ | ImGuiDockNodeFlags_AutoHideTabBar | ImGuiDockNodeFlags_DockSpace | ImGuiDockNodeFlags_CentralNode | ImGuiDockNodeFlags_NoTabBar | ImGuiDockNodeFlags_HiddenTabBar | ImGuiDockNodeFlags_NoWindowMenuButton | ImGuiDockNodeFlags_NoCloseButton | ImGuiDockNodeFlags_NoDocking, ImGuiDockNodeFlags_LocalFlagsTransferMask_ = ImGuiDockNodeFlags_LocalFlagsMask_ & ~ImGuiDockNodeFlags_DockSpace, // When splitting those flags are moved to // the inheriting child, never duplicated ImGuiDockNodeFlags_SavedFlagsMask_ = ImGuiDockNodeFlags_NoResizeFlagsMask_ | ImGuiDockNodeFlags_DockSpace | ImGuiDockNodeFlags_CentralNode | ImGuiDockNodeFlags_NoTabBar | ImGuiDockNodeFlags_HiddenTabBar | ImGuiDockNodeFlags_NoWindowMenuButton | ImGuiDockNodeFlags_NoCloseButton | ImGuiDockNodeFlags_NoDocking }; // 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 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] 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 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. 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 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 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; bool MarkedForPosSizeWrite : 1; // Update by DockNodeTreeUpdatePosSize() write-filtering 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 Requests; ImVector 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 { int Idx; int LastFrameActive; // Last frame number this viewport was activated by a window int LastFrontMostStampCount; // Last stamp number from when a window hosted by this viewport was made front-most // (by comparing this value between two viewport we have an implicit viewport z-order ImGuiID LastNameHash; ImVec2 LastPos; float Alpha; // Window opacity (when dragging dockable windows/viewports we make them transparent) float LastAlpha; short PlatformMonitor; bool PlatformWindowCreated; ImGuiWindow* Window; // Set when the viewport is owned by a window (and ImGuiViewportFlags_CanHostOtherWindows is NOT set) int DrawListsLastFrame[2]; // Last frame number the background (0) and foreground (1) draw lists were used ImDrawList* DrawLists[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; 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() { Idx = -1; LastFrameActive = DrawListsLastFrame[0] = DrawListsLastFrame[1] = LastFrontMostStampCount = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; PlatformMonitor = -1; PlatformWindowCreated = false; Window = NULL; DrawLists[0] = DrawLists[1] = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); } ~ImGuiViewportP() { if (DrawLists[0]) IM_DELETE(DrawLists[0]); if (DrawLists[1]) IM_DELETE(DrawLists[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 WantApply; // Set when loaded from .ini data (to enable merging/loading .ini data into an already running // context) 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] Metrics, Debug //----------------------------------------------------------------------------- struct ImGuiMetricsConfig { bool ShowWindowsRects; bool ShowWindowsBeginOrder; bool ShowTablesRects; bool ShowDrawCmdMesh; bool ShowDrawCmdBoundingBoxes; bool ShowDockingNodes; int ShowWindowsRectsType; int ShowTablesRectsType; ImGuiMetricsConfig() { ShowWindowsRects = false; ShowWindowsBeginOrder = false; ShowTablesRects = false; ShowDrawCmdMesh = true; ShowDrawCmdBoundingBoxes = true; ShowDockingNodes = false; ShowWindowsRectsType = -1; ShowTablesRectsType = -1; } }; struct IMGUI_API ImGuiStackSizes { short SizeOfIDStack; short SizeOfColorStack; short SizeOfStyleVarStack; short SizeOfFontStack; short SizeOfFocusScopeStack; short SizeOfGroupStack; short SizeOfBeginPopupStack; ImGuiStackSizes() { memset(this, 0, sizeof(*this)); } void SetToCurrentState(); void CompareWithCurrentState(); }; //----------------------------------------------------------------------------- // [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 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() ImGuiID TestEngineHookIdInfo; // Will call test engine hooks: ImGuiTestEngineHook_IdInfo() from GetID() void* TestEngine; // Test engine user data // Windows state ImVector Windows; // Windows, sorted in display order, back to front ImVector WindowsFocusOrder; // Root windows, sorted in focus order, back to front. ImVector WindowsTempSortBuffer; // Temporary buffer used in EndFrame() to reorder windows so parents // are kept before their child ImVector 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. ImGuiDockNode* HoveredDockNode; // Hovered dock node. 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; float WheelingWindowTimer; // Item/widgets state and tracking information ImGuiID HoveredId; // Hovered widget, filled during the frame ImGuiID HoveredIdPreviousFrame; bool HoveredIdAllowOverlap; bool HoveredIdUsingMouseWheel; // Hovered widget will use mouse wheel. Blocks scrolling the underlying window. bool HoveredIdPreviousFrameUsingMouseWheel; 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; bool ActiveIdUsingMouseWheel; // Active widget will want to read mouse wheel. Blocks scrolling the underlying // window. ImU32 ActiveIdUsingNavDirMask; // Active widget will want to read those nav move requests (e.g. can activate a // button and move away from it) ImU32 ActiveIdUsingNavInputMask; // Active widget will want to read those nav inputs. ImU64 ActiveIdUsingKeyInputMask; // Active widget will want to read those key inputs. When we grow the ImGuiKey // enum we'll need to either to order the enum to make useful keys come first, // either redesign this into e.g. a small array. ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by // ButtonBehavior) ImGuiWindow* ActiveIdWindow; ImGuiInputSource ActiveIdSource; // Activating with mouse or nav (gamepad/keyboard) 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. // Next window/item data ImGuiItemFlags CurrentItemFlags; // == g.ItemFlagsStack.back() ImGuiNextItemData NextItemData; // Storage for SetNextItem** functions ImGuiLastItemData LastItemData; // Storage for last submitted item (setup by ItemAdd) ImGuiNextWindowData NextWindowData; // Storage for SetNextWindow** functions // Shared stacks ImVector ColorStack; // Stack for PushStyleColor()/PopStyleColor() - inherited by Begin() ImVector StyleVarStack; // Stack for PushStyleVar()/PopStyleVar() - inherited by Begin() ImVector FontStack; // Stack for PushFont()/PopFont() - inherited by Begin() ImVector FocusScopeStack; // Stack for PushFocusScope()/PopFocusScope() - not inherited by Begin(), unless child window ImVector ItemFlagsStack; // Stack for PushItemFlag()/PopItemFlag() - inherited by Begin() ImVector GroupStack; // Stack for BeginGroup()/EndGroup() - not inherited by Begin() ImVector OpenPopupStack; // Which popups are open (persistent) ImVector BeginPopupStack; // Which level of BeginPopup() we are in (reset every frame) // Viewports ImVector 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 ViewportFrontMostStampCount; // 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 'FocusWindow' 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) && IsNavInputPressed(ImGuiNavInput_Activate) ? NavId : 0, also set // when calling ActivateItem() ImGuiID NavActivateDownId; // ~~ IsNavInputDown(ImGuiNavInput_Activate) ? NavId : 0 ImGuiID NavActivatePressedId; // ~~ IsNavInputPressed(ImGuiNavInput_Activate) ? NavId : 0 ImGuiID NavInputId; // ~~ IsNavInputPressed(ImGuiNavInput_Input) ? NavId : 0 ImGuiID NavJustTabbedId; // Just tabbed to this id. 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). ImGuiKeyModFlags NavJustMovedToKeyMods; ImGuiID NavNextActivateId; // Set by ActivateItem(), queued until next frame. ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS WILL ONLY BE None or NavGamepad or NavKeyboard. ImRect NavScoringRect; // Rectangle used for scoring, in screen space. Based of window->NavRectRel[], modified for // directional navigation scoring. int NavScoringCount; // Metrics for debugging 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. int NavIdTabCounter; // == NavWindow->DC.FocusIdxTabCounter at time of NavId processing 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. bool NavAnyRequest; // ~~ NavMoveRequest || NavInitRequest bool NavInitRequest; // Init request for appearing window to select first item bool NavInitRequestFromMove; ImGuiID NavInitResultId; // Init request result (first item of the window, or one for which SetItemDefaultFocus() // was called) ImRect NavInitResultRectRel; // Init request result rectangle (relative to parent window) bool NavMoveRequest; // Move request for this frame ImGuiNavMoveFlags NavMoveRequestFlags; ImGuiNavForward NavMoveRequestForward; // None / ForwardQueued / ForwardActive (this is used to navigate sibling // parent menus from a child menu) ImGuiKeyModFlags NavMoveRequestKeyMods; ImGuiDir NavMoveDir, NavMoveDirLast; // Direction of the move request (left/right/up/down), direction of the previous move request ImGuiDir NavMoveClipDir; // FIXME-NAV: Describe the purpose of this better. Might want to rename? ImGuiNavItemData NavMoveResultLocal; // Best move request candidate within NavWindow ImGuiNavItemData NavMoveResultLocalVisibleSet; // 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) ImGuiWindow* NavWrapRequestWindow; // Window which requested trying nav wrap-around. ImGuiNavMoveFlags NavWrapRequestFlags; // Wrap-around operation flags. // Navigation: Windowing (CTRL+TAB for list, or Menu button + keys or directional pads to move/resize) ImGuiWindow* NavWindowingTarget; // Target window when doing CTRL+Tab (or Pad Menu + FocusPrev/Next), this window // is temporarily displayed top-most! ImGuiWindow* NavWindowingTargetAnim; // Record of last valid NavWindowingTarget until DimBgRatio and // NavWindowingHighlightAlpha becomes 0.0f, so the fade-out can stay on it. ImGuiWindow* NavWindowingListWindow; // Internal window actually listing the CTRL+Tab contents float NavWindowingTimer; float NavWindowingHighlightAlpha; bool NavWindowingToggleLayer; // Legacy Focus/Tabbing system (older than Nav, active even if Nav is disabled, misnamed. FIXME-NAV: This needs a // redesign!) ImGuiWindow* TabFocusRequestCurrWindow; // ImGuiWindow* TabFocusRequestNextWindow; // int TabFocusRequestCurrCounterRegular; // Any item being requested for focus, stored as an index (we on layout to // be stable between the frame pressing TAB and the next frame, semi-ouch) int TabFocusRequestCurrCounterTabStop; // Tab item being requested for focus, stored as an index int TabFocusRequestNextCounterRegular; // Stored for next frame int TabFocusRequestNextCounterTabStop; // " bool TabFocusPressed; // Set in NewFrame() when user pressed Tab // Render float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list) ImGuiMouseCursor MouseCursor; // Drag and Drop bool DragDropActive; bool DragDropWithinSource; // Set when within a BeginDragDropXXX/EndDragDropXXX block for a drag source. bool DragDropWithinTarget; // Set when within a BeginDragDropXXX/EndDragDropXXX block for a drag target. ImGuiDragDropFlags DragDropSourceFlags; int DragDropSourceFrameCount; int DragDropMouseButton; ImGuiPayload DragDropPayload; ImRect DragDropTargetRect; // Store rectangle of current target candidate (we favor small targets when overlapping) ImGuiID DragDropTargetId; ImGuiDragDropFlags DragDropAcceptFlags; float DragDropAcceptIdCurrRectSurface; // Target item surface (we resolve overlapping targets by prioritizing the // smaller surface) ImGuiID DragDropAcceptIdCurr; // Target item id (set at the time of accepting the payload) ImGuiID DragDropAcceptIdPrev; // Target item id from previous frame (we need to store this to allow for overlapping // drag and drop targets) int DragDropAcceptFrameCount; // Last time a target expressed a desire to accept the source ImGuiID DragDropHoldJustPressedId; // Set when holding a payload just made ButtonBehavior() return a press. ImVector DragDropPayloadBufHeap; // We don't expose the ImVector<> directly, ImGuiPayload only holds pointer+size unsigned char DragDropPayloadBufLocal[16]; // Local buffer for small payloads // Table ImGuiTable* CurrentTable; int CurrentTableStackIdx; ImPool Tables; ImVector TablesTempDataStack; ImVector TablesLastTimeActive; // Last used timestamp of each tables (SOA, for efficient GC) ImVector DrawChannelsTempMergeBuffer; // Tab bars ImGuiTabBar* CurrentTabBar; ImPool TabBars; ImVector CurrentTabBarStack; ImVector ShrinkWidthBuffer; // Widget state ImVec2 LastValidMousePos; ImGuiInputTextState InputTextState; ImFont InputTextPasswordFont; ImGuiID TempInputId; // Temporary text input when CTRL+clicking on a slider, etc. ImGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets float ColorEditLastHue; // Backup of last Hue associated to LastColor[3], so we can restore Hue in lossy RGB<>HSV // round trips float ColorEditLastSat; // Backup of last Saturation associated to LastColor[3], so we can restore Saturation in // lossy RGB<>HSV round trips float ColorEditLastColor[3]; ImVec4 ColorPickerRef; // Initial/reference color at the time of opening the color picker. ImGuiComboPreviewData ComboPreviewData; float SliderCurrentAccum; // Accumulated slider delta when using navigation controls. bool SliderCurrentAccumDirty; // Has the accumulated slider delta changed since last time we tried to apply it? bool DragCurrentAccumDirty; float DragCurrentAccum; // Accumulator for dragging modification. Always high-precision, not rounded by end-user // precision settings float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio float DisabledAlphaBackup; // Backup for style.Alpha for BeginDisabled() float ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent // space. Use storage? int TooltipOverrideCount; float TooltipSlowDelay; // Time before slow tooltips appears (FIXME: This is temporary until we merge in tooltip // timer+priority work) ImVector ClipboardHandlerData; // If no custom clipboard handler is defined ImVector MenusIdSubmittedThisFrame; // A list of menu IDs that were rendered at least once // Platform support ImVec2 PlatformImePos; // Cursor position request & last passed to the OS Input Method Editor ImVec2 PlatformImeLastPos; ImGuiViewportP* PlatformImePosViewport; char PlatformLocaleDecimalPoint; // '.' or *localeconv()->decimal_point // Extensions // FIXME: We could provide an API to register one slot in an array held in ImGuiContext? ImGuiDockContext DockContext; // Settings bool SettingsLoaded; float SettingsDirtyTimer; // Save .ini Settings to memory when time reaches zero ImGuiTextBuffer SettingsIniData; // In memory .ini settings ImVector SettingsHandlers; // List of .ini settings handlers ImChunkStream SettingsWindows; // ImGuiWindow .ini settings entries ImChunkStream SettingsTables; // ImGuiTable .ini settings entries ImVector Hooks; // Hooks for extensions (e.g. test engine) ImGuiID HookIdNext; // Next available HookId // Capture/Logging bool LogEnabled; // Currently capturing ImGuiLogType LogType; // Capture target ImFileHandle LogFile; // If != NULL log to stdout/ file ImGuiTextBuffer LogBuffer; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static // constructor doesn't call heap allocators. const char* LogNextPrefix; const char* LogNextSuffix; float LogLinePosY; bool LogLineFirstItem; int LogDepthRef; int LogDepthToExpand; int LogDepthToExpandDefault; // Default/stored value for LogDepthMaxExpand if not specified in the LogXXX function // call. // Debug Tools bool DebugItemPickerActive; // Item picker is active (started with DebugStartItemPicker()) ImGuiID DebugItemPickerBreakId; // Will call IM_DEBUG_BREAK() when encountering this id ImGuiMetricsConfig DebugMetricsConfig; // Misc float FramerateSecPerFrame[120]; // Calculate estimate of framerate for user over the last 2 seconds. int FramerateSecPerFrameIdx; int FramerateSecPerFrameCount; float FramerateSecPerFrameAccum; int WantCaptureMouseNextFrame; // Explicit capture via CaptureKeyboardFromApp()/CaptureMouseFromApp() sets those // flags int WantCaptureKeyboardNextFrame; int WantTextInputNextFrame; char TempBuffer[1024 * 3 + 1]; // Temporary text buffer ImGuiContext(ImFontAtlas* shared_font_atlas) { Initialized = false; ConfigFlagsCurrFrame = ConfigFlagsLastFrame = ImGuiConfigFlags_None; FontAtlasOwnedByContext = shared_font_atlas ? false : true; Font = NULL; FontSize = FontBaseSize = 0.0f; IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)(); Time = 0.0f; FrameCount = 0; FrameCountEnded = FrameCountPlatformEnded = FrameCountRendered = -1; WithinFrameScope = WithinFrameScopeWithImplicitWindow = WithinEndChild = false; GcCompactAll = false; TestEngineHookItems = false; TestEngineHookIdInfo = 0; TestEngine = NULL; WindowsActiveCount = 0; CurrentWindow = NULL; HoveredWindow = NULL; HoveredWindowUnderMovingWindow = NULL; HoveredDockNode = NULL; MovingWindow = NULL; WheelingWindow = NULL; WheelingWindowTimer = 0.0f; HoveredId = HoveredIdPreviousFrame = 0; HoveredIdAllowOverlap = false; HoveredIdUsingMouseWheel = HoveredIdPreviousFrameUsingMouseWheel = false; HoveredIdDisabled = false; HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f; ActiveId = 0; ActiveIdIsAlive = 0; ActiveIdTimer = 0.0f; ActiveIdIsJustActivated = false; ActiveIdAllowOverlap = false; ActiveIdNoClearOnFocusLoss = false; ActiveIdHasBeenPressedBefore = false; ActiveIdHasBeenEditedBefore = false; ActiveIdHasBeenEditedThisFrame = false; ActiveIdUsingMouseWheel = false; ActiveIdUsingNavDirMask = 0x00; ActiveIdUsingNavInputMask = 0x00; ActiveIdUsingKeyInputMask = 0x00; ActiveIdClickOffset = ImVec2(-1, -1); ActiveIdWindow = NULL; ActiveIdSource = ImGuiInputSource_None; ActiveIdMouseButton = -1; ActiveIdPreviousFrame = 0; ActiveIdPreviousFrameIsAlive = false; ActiveIdPreviousFrameHasBeenEditedBefore = false; ActiveIdPreviousFrameWindow = NULL; LastActiveId = 0; LastActiveIdTimer = 0.0f; CurrentItemFlags = ImGuiItemFlags_None; CurrentDpiScale = 0.0f; CurrentViewport = NULL; MouseViewport = MouseLastHoveredViewport = NULL; PlatformLastFocusedViewportId = 0; ViewportFrontMostStampCount = 0; NavWindow = NULL; NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = NavInputId = 0; NavJustTabbedId = NavJustMovedToId = NavJustMovedToFocusScopeId = NavNextActivateId = 0; NavJustMovedToKeyMods = ImGuiKeyModFlags_None; NavInputSource = ImGuiInputSource_None; NavScoringRect = ImRect(); NavScoringCount = 0; NavLayer = ImGuiNavLayer_Main; NavIdTabCounter = INT_MAX; NavIdIsAlive = false; NavMousePosDirty = false; NavDisableHighlight = true; NavDisableMouseHover = false; NavAnyRequest = false; NavInitRequest = false; NavInitRequestFromMove = false; NavInitResultId = 0; NavMoveRequest = false; NavMoveRequestFlags = ImGuiNavMoveFlags_None; NavMoveRequestForward = ImGuiNavForward_None; NavMoveRequestKeyMods = ImGuiKeyModFlags_None; NavMoveDir = NavMoveDirLast = NavMoveClipDir = ImGuiDir_None; NavWrapRequestWindow = NULL; NavWrapRequestFlags = ImGuiNavMoveFlags_None; NavWindowingTarget = NavWindowingTargetAnim = NavWindowingListWindow = NULL; NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f; NavWindowingToggleLayer = false; TabFocusRequestCurrWindow = TabFocusRequestNextWindow = NULL; TabFocusRequestCurrCounterRegular = TabFocusRequestCurrCounterTabStop = INT_MAX; TabFocusRequestNextCounterRegular = TabFocusRequestNextCounterTabStop = INT_MAX; TabFocusPressed = false; DimBgRatio = 0.0f; MouseCursor = ImGuiMouseCursor_Arrow; DragDropActive = DragDropWithinSource = DragDropWithinTarget = false; DragDropSourceFlags = ImGuiDragDropFlags_None; DragDropSourceFrameCount = -1; DragDropMouseButton = -1; DragDropTargetId = 0; DragDropAcceptFlags = ImGuiDragDropFlags_None; DragDropAcceptIdCurrRectSurface = 0.0f; DragDropAcceptIdPrev = DragDropAcceptIdCurr = 0; DragDropAcceptFrameCount = -1; DragDropHoldJustPressedId = 0; memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal)); CurrentTable = NULL; CurrentTableStackIdx = -1; CurrentTabBar = NULL; LastValidMousePos = ImVec2(0.0f, 0.0f); TempInputId = 0; ColorEditOptions = ImGuiColorEditFlags_DefaultOptions_; ColorEditLastHue = ColorEditLastSat = 0.0f; ColorEditLastColor[0] = ColorEditLastColor[1] = ColorEditLastColor[2] = FLT_MAX; SliderCurrentAccum = 0.0f; SliderCurrentAccumDirty = false; DragCurrentAccumDirty = false; DragCurrentAccum = 0.0f; DragSpeedDefaultRatio = 1.0f / 100.0f; DisabledAlphaBackup = 0.0f; ScrollbarClickDeltaToGrabCenter = 0.0f; TooltipOverrideCount = 0; TooltipSlowDelay = 0.50f; PlatformImePos = PlatformImeLastPos = ImVec2(FLT_MAX, FLT_MAX); PlatformImePosViewport = 0; PlatformLocaleDecimalPoint = '.'; SettingsLoaded = false; SettingsDirtyTimer = 0.0f; HookIdNext = 0; LogEnabled = false; LogType = ImGuiLogType_None; LogNextPrefix = LogNextSuffix = NULL; LogFile = NULL; LogLinePosY = FLT_MAX; LogLineFirstItem = false; LogDepthRef = 0; LogDepthToExpand = LogDepthToExpandDefault = 2; DebugItemPickerActive = false; DebugItemPickerBreakId = 0; memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame)); FramerateSecPerFrameIdx = FramerateSecPerFrameCount = 0; FramerateSecPerFrameAccum = 0.0f; WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = WantTextInputNextFrame = -1; memset(TempBuffer, 0, sizeof(TempBuffer)); } }; //----------------------------------------------------------------------------- // [SECTION] ImGuiWindowTempData, ImGuiWindow //----------------------------------------------------------------------------- // Transient per-window data, reset at the beginning of the frame. This used to be called ImGuiDrawContext, hence the DC // variable name in ImGuiWindow. (That's theory, in practice the delimitation between ImGuiWindow and // ImGuiWindowTempData is quite tenuous and could be reconsidered..) (This doesn't need a constructor because we // zero-clear it as part of ImGuiWindow and all frame-temporary data are setup on Begin) struct IMGUI_API ImGuiWindowTempData { // Layout ImVec2 CursorPos; // Current emitting position, in absolute coordinates. ImVec2 CursorPosPrevLine; ImVec2 CursorStartPos; // Initial position after Begin(), generally ~ window position + WindowPadding. ImVec2 CursorMaxPos; // Used to implicitly calculate ContentSize at the beginning of next frame, for scrolling // range and auto-resize. Always growing during the frame. ImVec2 IdealMaxPos; // Used to implicitly calculate ContentSizeIdeal at the beginning of next frame, for // auto-resize only. Always growing during the frame. ImVec2 CurrLineSize; ImVec2 PrevLineSize; float CurrLineTextBaseOffset; // Baseline offset (0.0f by default on a new line, generally == style.FramePadding.y // when a framed item has been added). float PrevLineTextBaseOffset; ImVec1 Indent; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.) ImVec1 ColumnsOffset; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be // a stack to allow use cases like Tree->Column->Tree. Need revamp columns API. ImVec1 GroupOffset; // Keyboard/Gamepad navigation ImGuiNavLayer NavLayerCurrent; // Current layer, 0..31 (we currently only use 0..1) short NavLayersActiveMask; // Which layers have been written to (result from previous frame) short NavLayersActiveMaskNext; // Which layers have been written to (accumulator for current frame) ImGuiID NavFocusScopeIdCurrent; // Current focus scope ID while appending bool NavHideHighlightOneFrame; bool NavHasScroll; // Set when scrolling can be used (ScrollMax > 0.0f) // Miscellaneous bool MenuBarAppending; // FIXME: Remove this ImVec2 MenuBarOffset; // MenuBarOffset.x is sort of equivalent of a per-layer CursorPos.x, saved/restored as we // switch to the menu bar. The only situation when MenuBarOffset.y is > 0 if when // (SafeAreaPadding.y > FramePadding.y), often used on TVs. ImGuiMenuColumns MenuColumns; // Simplified columns storage for menu items measurement int TreeDepth; // Current tree depth. ImU32 TreeJumpToParentOnPopMask; // Store a copy of !g.NavIdIsAlive for TreeDepth 0..31.. Could be turned into a // ImU64 if necessary. ImVector ChildWindows; ImGuiStorage* StateStorage; // Current persistent per-window storage (store e.g. tree node open/close state) ImGuiOldColumns* CurrentColumns; // Current columns set int CurrentTableIdx; // Current table index (into g.Tables) ImGuiLayoutType LayoutType; ImGuiLayoutType ParentLayoutType; // Layout type of parent window at the time of Begin() int FocusCounterRegular; // (Legacy Focus/Tabbing system) Sequential counter, start at -1 and increase as assigned // via FocusableItemRegister() (FIXME-NAV: Needs redesign) int FocusCounterTabStop; // (Legacy Focus/Tabbing system) Same, but only count widgets which you can Tab through. // Local parameters stacks // We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The // vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using // those settings. float ItemWidth; // Current item width (>0.0: width in pixels, <0.0: align xx pixels to the right of window). float TextWrapPos; // Current text wrap pos. ImVector ItemWidthStack; // Store item widths to restore (attention: .back() is not == ItemWidth) ImVector TextWrapPosStack; // Store text wrap pos to restore (attention: .back() is not == TextWrapPos) ImGuiStackSizes StackSizesOnBegin; // Store size of various stacks for asserting }; // Storage for one window struct IMGUI_API ImGuiWindow { char* Name; // Window name, owned by the window. ImGuiID ID; // == ImHashStr(Name) ImGuiWindowFlags Flags, FlagsPreviousFrame; // See enum ImGuiWindowFlags_ ImGuiWindowClass WindowClass; // Advanced users only. Set with SetNextWindowClass() ImGuiViewportP* Viewport; // Always set in Begin(), only inactive windows may have a NULL value here ImGuiID ViewportId; // We backup the viewport id (since the viewport may disappear or never be created if the // window is inactive) ImVec2 ViewportPos; // We backup the viewport position (since the viewport may disappear or never be created if the // window is inactive) int ViewportAllowPlatformMonitorExtend; // Reset to -1 every frame (index is guaranteed to be valid between // NewFrame..EndFrame), only used in the Appearing frame of a tooltip/popup // to enforce clamping to a given monitor ImVec2 Pos; // Position (always rounded-up to nearest pixel) ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) ImVec2 SizeFull; // Size when non collapsed ImVec2 ContentSize; // Size of contents/scrollable client area (calculated from the extents reach of the cursor) // from previous frame. Does not include window decoration or window padding. ImVec2 ContentSizeIdeal; ImVec2 ContentSizeExplicit; // Size of contents/scrollable client area explicitly request by the user via // SetNextWindowContentSize(). ImVec2 WindowPadding; // Window padding at the time of Begin(). float WindowRounding; // Window rounding at the time of Begin(). May be clamped lower to avoid rendering artifacts // with title bar, menu bar etc. float WindowBorderSize; // Window border size at the time of Begin(). int NameBufLen; // Size of buffer storing Name. May be larger than strlen(Name)! ImGuiID MoveId; // == window->GetID("#MOVE") ImGuiID ChildId; // ID of corresponding item in parent window (for navigation to return from child window to parent // window) ImVec2 Scroll; ImVec2 ScrollMax; ImVec2 ScrollTarget; // target scroll position. stored as cursor position with scrolling canceled out, so the // highest point is always 0.0f. (FLT_MAX for no change) ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target // position is centered ImVec2 ScrollTargetEdgeSnapDist; // 0.0f = no snapping, >0.0f snapping threshold ImVec2 ScrollbarSizes; // Size taken by each scrollbars on their smaller axis. Pay attention! ScrollbarSizes.x == // width of the vertical scrollbar, ScrollbarSizes.y = height of the horizontal scrollbar. bool ScrollbarX, ScrollbarY; // Are scrollbars visible? bool ViewportOwned; bool Active; // Set to true on Begin(), unless Collapsed bool WasActive; bool WriteAccessed; // Set to true when any widget access the current window bool Collapsed; // Set when collapsing window to become only title-bar bool WantCollapseToggle; bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed) bool Appearing; // Set during the frame where the window is appearing (or re-appearing) bool Hidden; // Do not display (== HiddenFrames*** > 0) bool IsFallbackWindow; // Set on the "Debug##Default" window. bool HasCloseButton; // Set when the window has a close button (p_open != NULL) signed char ResizeBorderHeld; // Current border being held for resize (-1: none, otherwise 0-3) short BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple // Begin/End pairs) short BeginOrderWithinParent; // Begin() order within immediate parent window, if we are a child window. Otherwise 0. short BeginOrderWithinContext; // Begin() order within entire imgui context. This is mostly used for debugging // submission order related issues. short FocusOrder; // Order within WindowsFocusOrder[], altered when windows are focused. ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID // for recycling) ImS8 AutoFitFramesX, AutoFitFramesY; ImS8 AutoFitChildAxises; bool AutoFitOnlyGrows; ImGuiDir AutoPosLastDirection; ImS8 HiddenFramesCanSkipItems; // Hide the window for N frames ImS8 HiddenFramesCannotSkipItems; // Hide the window for N frames while allowing items to be submitted so we can // measure their size ImS8 HiddenFramesForRenderOnly; // Hide the window until frame N at Render() time only ImS8 DisableInputsFrames; // Disable window interactions for N frames ImGuiCond SetWindowPosAllowFlags : 8; // store acceptable condition flags for SetNextWindowPos() use. ImGuiCond SetWindowSizeAllowFlags : 8; // store acceptable condition flags for SetNextWindowSize() use. ImGuiCond SetWindowCollapsedAllowFlags : 8; // store acceptable condition flags for SetNextWindowCollapsed() use. ImGuiCond SetWindowDockAllowFlags : 8; // store acceptable condition flags for SetNextWindowDock() use. ImVec2 SetWindowPosVal; // store window position when using a non-zero Pivot (position set needs to be processed // when we know the window size) ImVec2 SetWindowPosPivot; // store window pivot for positioning. ImVec2(0, 0) when positioning from top-left // corner; ImVec2(0.5f, 0.5f) for centering; ImVec2(1, 1) for bottom right. ImVector IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack. (In theory // this should be in the TempData structure) ImGuiWindowTempData DC; // Temporary per-window data, reset at the beginning of the frame. This used to be called // ImGuiDrawContext, hence the "DC" variable name. // The best way to understand what those rectangles are is to use the 'Metrics->Tools->Show Windows Rectangles' // viewer. The main 'OuterRect', omitted as a field, is window->Rect(). ImRect OuterRectClipped; // == Window->Rect() just after setup in Begin(). == window->Rect() for root window. ImRect InnerRect; // Inner rectangle (omit title bar, menu bar, scroll bar) ImRect InnerClipRect; // == InnerRect shrunk by WindowPadding*0.5f on each side, clipped within viewport or parent // clip rect. ImRect WorkRect; // Initially covers the whole scrolling region. Reduced by containers e.g columns/tables when // active. Shrunk by WindowPadding*1.0f on each side. This is meant to replace ContentRegionRect // over time (from 1.71+ onward). ImRect ParentWorkRect; // Backup of WorkRect before entering a container such as columns/tables. Used by e.g. // SpanAllColumns functions to easily access. Stacked containers are responsible for // maintaining this. // FIXME-WORKRECT: Could be a stack? ImRect ClipRect; // Current clipping/scissoring rectangle, evolve as we are using PushClipRect(), etc. == // DrawList->clip_rect_stack.back(). ImRect ContentRegionRect; // FIXME: This is currently confusing/misleading. It is essentially WorkRect but not // handling of scrolling. We currently rely on it as right/bottom aligned sizing // operation need some size to rely on. ImVec2ih HitTestHoleSize; // Define an optional rectangular hole where mouse will pass-through the window. ImVec2ih HitTestHoleOffset; int LastFrameActive; // Last frame number the window was Active. int LastFrameJustFocused; // Last frame number the window was made Focused. float LastTimeActive; // Last timestamp the window was Active (using float as we don't need high precision there) float ItemWidthDefault; ImGuiStorage StateStorage; ImVector ColumnsStorage; float FontWindowScale; // User scale multiplier per-window, via SetWindowFontScale() float FontDpiScale; int SettingsOffset; // Offset into SettingsWindows[] (offsets are always valid as we only grow the array from the // back) ImDrawList* DrawList; // == &DrawListInst (for backward compatibility reason with code using imgui_internal.h we // keep this a pointer) ImDrawList DrawListInst; ImGuiWindow* ParentWindow; // If we are a child _or_ popup window, this is pointing to our parent. Otherwise NULL. ImGuiWindow* RootWindow; // Point to ourself or first ancestor that is not a child window. Doesn't cross through dock nodes. // We use this so IsWindowFocused() can behave consistently regardless of docking state. ImGuiWindow* RootWindowDockTree; // Point to ourself or first ancestor that is not a child window. Cross through dock nodes. ImGuiWindow* RootWindowForTitleBarHighlight; // Point to ourself or first ancestor which will display TitleBgActive // color when this window is active. ImGuiWindow* RootWindowForNav; // Point to ourself or first ancestor which doesn't have the NavFlattened flag. ImGuiWindow* NavLastChildNavWindow; // When going to the menu bar, we remember the child window we came from. (This // could probably be made implicit if we kept g.Windows sorted by last focused // including child window.) ImGuiID NavLastIds[ImGuiNavLayer_COUNT]; // Last known NavId for this window, per layer (0/1) ImRect NavRectRel[ImGuiNavLayer_COUNT]; // Reference rectangle, in window relative space int MemoryDrawListIdxCapacity; // Backup of last idx/vtx count, so when waking up the window we can preallocate and // avoid iterative alloc/copy int MemoryDrawListVtxCapacity; bool MemoryCompacted; // Set when window extraneous data have been garbage collected // Docking bool DockIsActive : 1; // When docking artifacts are actually visible. When this is set, DockNode is guaranteed to // be != NULL. ~~ (DockNode != NULL) && (DockNode->Windows.Size > 1). bool DockNodeIsVisible : 1; bool DockTabIsVisible : 1; // Is our window visible this frame? ~~ is the corresponding tab selected? bool DockTabWantClose : 1; 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. ImGuiWindowDockStyle DockStyle; ImGuiDockNode* DockNode; // Which node are we docked into. Important: Prefer testing DockIsActive in many cases as // this will still be set when the dock node is hidden. ImGuiDockNode* DockNodeAsHost; // Which node are we owning (for parent windows) ImGuiID DockId; // Backup of last valid DockNode->ID, so single window remember their dock node id even when they // are not bound any more ImGuiItemStatusFlags DockTabItemStatusFlags; ImRect DockTabItemRect; public: ImGuiWindow(ImGuiContext* context, const char* name); ~ImGuiWindow(); ImGuiID GetID(const char* str, const char* str_end = NULL); ImGuiID GetID(const void* ptr); ImGuiID GetID(int n); ImGuiID GetIDNoKeepAlive(const char* str, const char* str_end = NULL); ImGuiID GetIDNoKeepAlive(const void* ptr); ImGuiID GetIDNoKeepAlive(int n); ImGuiID GetIDFromRectangle(const ImRect& r_abs); // We don't use g.FontSize because the window may be != g.CurrentWidow. ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); } float CalcFontSize() const { ImGuiContext& g = *GImGui; float scale = g.FontBaseSize * FontWindowScale * FontDpiScale; if (ParentWindow) scale *= ParentWindow->FontWindowScale; return scale; } float TitleBarHeight() const { ImGuiContext& g = *GImGui; return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + g.Style.FramePadding.y * 2.0f; } ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight())); } float MenuBarHeight() const { ImGuiContext& g = *GImGui; return (Flags & ImGuiWindowFlags_MenuBar) ? DC.MenuBarOffset.y + CalcFontSize() + g.Style.FramePadding.y * 2.0f : 0.0f; } ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight(); return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight()); } }; //----------------------------------------------------------------------------- // [SECTION] Tab bar, Tab item support //----------------------------------------------------------------------------- // Extend ImGuiTabBarFlags_ enum ImGuiTabBarFlagsPrivate_ { ImGuiTabBarFlags_DockNode = 1 << 20, // Part of a dock node [we don't use this in the master branch but it // facilitate branch syncing to keep this around] ImGuiTabBarFlags_IsFocused = 1 << 21, ImGuiTabBarFlags_SaveSettings = 1 << 22 // FIXME: Settings are handled by the docking system, this only request the // tab bar to mark settings dirty when reordering tabs }; // Extend ImGuiTabItemFlags_ enum ImGuiTabItemFlagsPrivate_ { ImGuiTabItemFlags_SectionMask_ = ImGuiTabItemFlags_Leading | ImGuiTabItemFlags_Trailing, ImGuiTabItemFlags_NoCloseButton = 1 << 20, // Track whether p_open was set or not (we'll need this info on the next // frame to recompute ContentWidth during layout) ImGuiTabItemFlags_Button = 1 << 21, // Used by TabItemButton, change the tab item behavior to mimic a button ImGuiTabItemFlags_Unsorted = 1 << 22, // [Docking] Trailing tabs with the _Unsorted flag will be sorted based on // the DockOrder of their Window. ImGuiTabItemFlags_Preview = 1 << 23 // [Docking] Display tab shape for docking preview (height is adjusted slightly // to compensate for the yet missing tab bar) }; // Storage for one active tab item (sizeof() 48 bytes) struct ImGuiTabItem { ImGuiID ID; ImGuiTabItemFlags Flags; ImGuiWindow* Window; // When TabItem is part of a DockNode's TabBar, we hold on to a window. int LastFrameVisible; int LastFrameSelected; // This allows us to infer an ordered list of the last activated tabs with little // maintenance float Offset; // Position relative to beginning of tab float Width; // Width currently displayed float ContentWidth; // Width of label, stored during BeginTabItem() call ImS32 NameOffset; // When Window==NULL, offset to name within parent ImGuiTabBar::TabsNames ImS16 BeginOrder; // BeginTabItem() order, used to re-order tabs after toggling ImGuiTabBarFlags_Reorderable ImS16 IndexDuringLayout; // Index only used during TabBarLayout() bool WantClose; // Marked as closed by SetTabItemClosed() ImGuiTabItem() { memset(this, 0, sizeof(*this)); LastFrameVisible = LastFrameSelected = -1; NameOffset = -1; BeginOrder = IndexDuringLayout = -1; } }; // Storage for a tab bar (sizeof() 152 bytes) struct IMGUI_API ImGuiTabBar { ImVector Tabs; ImGuiTabBarFlags Flags; ImGuiID ID; // Zero for tab-bars used by docking ImGuiID SelectedTabId; // Selected tab/window ImGuiID NextSelectedTabId; // Next selected tab/window. Will also trigger a scrolling animation ImGuiID VisibleTabId; // Can occasionally be != SelectedTabId (e.g. when previewing contents for CTRL+TAB preview) int CurrFrameVisible; int PrevFrameVisible; ImRect BarRect; float CurrTabsContentsHeight; float PrevTabsContentsHeight; // Record the height of contents submitted below the tab bar float WidthAllTabs; // Actual width of all tabs (locked during layout) float WidthAllTabsIdeal; // Ideal width if all tabs were visible and not clipped float ScrollingAnim; float ScrollingTarget; float ScrollingTargetDistToVisibility; float ScrollingSpeed; float ScrollingRectMinX; float ScrollingRectMaxX; ImGuiID ReorderRequestTabId; ImS16 ReorderRequestOffset; ImS8 BeginCount; bool WantLayout; bool VisibleTabWasSubmitted; bool TabsAddedNew; // Set to true when a new tab item or button has been added to the tab bar during last frame ImS16 TabsActiveCount; // Number of tabs submitted this frame. ImS16 LastTabItemIdx; // Index of last BeginTabItem() tab for use by EndTabItem() float ItemSpacingY; ImVec2 FramePadding; // style.FramePadding locked at the time of BeginTabBar() ImVec2 BackupCursorPos; ImGuiTextBuffer TabsNames; // For non-docking tab bar we re-append names in a contiguous buffer. ImGuiTabBar(); int GetTabOrder(const ImGuiTabItem* tab) const { return Tabs.index_from_ptr(tab); } const char* GetTabName(const ImGuiTabItem* tab) const { if (tab->Window) return tab->Window->Name; IM_ASSERT(tab->NameOffset != -1 && tab->NameOffset < TabsNames.Buf.Size); return TabsNames.Buf.Data + tab->NameOffset; } }; //----------------------------------------------------------------------------- // [SECTION] Table support //----------------------------------------------------------------------------- # define IM_COL32_DISABLE IM_COL32(0, 0, 0, 1) // Special sentinel code which cannot be used as a regular color. # define IMGUI_TABLE_MAX_COLUMNS \ 64 // sizeof(ImU64) * 8. This is solely because we frequently encode columns set in a ImU64. # define IMGUI_TABLE_MAX_DRAW_CHANNELS (4 + 64 * 2) // See TableSetupDrawChannels() // Our current column maximum is 64 but we may raise that in the future. typedef ImS8 ImGuiTableColumnIdx; typedef ImU8 ImGuiTableDrawChannelIdx; // [Internal] sizeof() ~ 104 // We use the terminology "Enabled" to refer to a column that is not Hidden by user/api. // We use the terminology "Clipped" to refer to a column that is out of sight because of scrolling/clipping. // This is in contrast with some user-facing api such as IsItemVisible() / IsRectVisible() which use "Visible" to mean // "not clipped". struct ImGuiTableColumn { ImGuiTableColumnFlags Flags; // Flags after some patching (not directly same as provided by user). See ImGuiTableColumnFlags_ float WidthGiven; // Final/actual width visible == (MaxX - MinX), locked in TableUpdateLayout(). May be > // WidthRequest to honor minimum width, may be < WidthRequest to honor shrinking columns down in // tight space. float MinX; // Absolute positions float MaxX; float WidthRequest; // Master width absolute value when !(Flags & _WidthStretch). When Stretch this is derived // every frame from StretchWeight in TableUpdateLayout() float WidthAuto; // Automatic width float StretchWeight; // Master width weight when (Flags & _WidthStretch). Often around ~1.0f initially. float InitStretchWeightOrWidth; // Value passed to TableSetupColumn(). For Width it is a content width (_without // padding_). ImRect ClipRect; // Clipping rectangle for the column ImGuiID UserID; // Optional, value passed to TableSetupColumn() float WorkMinX; // Contents region min ~(MinX + CellPaddingX + CellSpacingX1) == cursor start position when // entering column float WorkMaxX; // Contents region max ~(MaxX - CellPaddingX - CellSpacingX2) float ItemWidth; // Current item width for the column, preserved across rows float ContentMaxXFrozen; // Contents maximum position for frozen rows (apart from headers), from which we can infer // content width. float ContentMaxXUnfrozen; float ContentMaxXHeadersUsed; // Contents maximum position for headers rows (regardless of freezing). TableHeader() // automatically softclip itself + report ideal desired size, to avoid creating // extraneous draw calls float ContentMaxXHeadersIdeal; ImS16 NameOffset; // Offset into parent ColumnsNames[] ImGuiTableColumnIdx DisplayOrder; // Index within Table's IndexToDisplayOrder[] (column may be reordered by users) ImGuiTableColumnIdx IndexWithinEnabledSet; // Index within enabled/visible set (<= IndexToDisplayOrder) ImGuiTableColumnIdx PrevEnabledColumn; // Index of prev enabled/visible column within Columns[], -1 if first enabled/visible column ImGuiTableColumnIdx NextEnabledColumn; // Index of next enabled/visible column within Columns[], -1 if last enabled/visible column ImGuiTableColumnIdx SortOrder; // Index of this column within sort specs, -1 if not sorting on this column, 0 for // single-sort, may be >0 on multi-sort ImGuiTableDrawChannelIdx DrawChannelCurrent; // Index within DrawSplitter.Channels[] ImGuiTableDrawChannelIdx DrawChannelFrozen; // Draw channels for frozen rows (often headers) ImGuiTableDrawChannelIdx DrawChannelUnfrozen; // Draw channels for unfrozen rows bool IsEnabled; // IsUserEnabled && (Flags & ImGuiTableColumnFlags_Disabled) == 0 bool IsUserEnabled; // Is the column not marked Hidden by the user? (unrelated to being off view, e.g. clipped by // scrolling). bool IsUserEnabledNextFrame; bool IsVisibleX; // Is actually in view (e.g. overlapping the host window clipping rectangle, not scrolled). bool IsVisibleY; bool IsRequestOutput; // Return value for TableSetColumnIndex() / TableNextColumn(): whether we request user to // output contents or not. bool IsSkipItems; // Do we want item submissions to this column to be completely ignored (no layout will happen). bool IsPreserveWidthAuto; ImS8 NavLayerCurrent; // ImGuiNavLayer in 1 byte ImU8 AutoFitQueue; // Queue of 8 values for the next 8 frames to request auto-fit ImU8 CannotSkipItemsQueue; // Queue of 8 values for the next 8 frames to disable Clipped/SkipItem ImU8 SortDirection : 2; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending ImU8 SortDirectionsAvailCount : 2; // Number of available sort directions (0 to 3) ImU8 SortDirectionsAvailMask : 4; // Mask of available sort directions (1-bit each) ImU8 SortDirectionsAvailList; // Ordered of available sort directions (2-bits each) ImGuiTableColumn() { memset(this, 0, sizeof(*this)); StretchWeight = WidthRequest = -1.0f; NameOffset = -1; DisplayOrder = IndexWithinEnabledSet = -1; PrevEnabledColumn = NextEnabledColumn = -1; SortOrder = -1; SortDirection = ImGuiSortDirection_None; DrawChannelCurrent = DrawChannelFrozen = DrawChannelUnfrozen = (ImU8)-1; } }; // Transient cell data stored per row. // sizeof() ~ 6 struct ImGuiTableCellData { ImU32 BgColor; // Actual color ImGuiTableColumnIdx Column; // Column number }; // FIXME-TABLE: more transient data could be stored in a per-stacked table structure: DrawSplitter, SortSpecs, incoming // RowData struct ImGuiTable { ImGuiID ID; ImGuiTableFlags Flags; void* RawData; // Single allocation to hold Columns[], DisplayOrderToIndex[] and RowCellData[] ImGuiTableTempData* TempData; // Transient data while table is active. Point within g.CurrentTableStack[] ImSpan Columns; // Point within RawData[] ImSpan DisplayOrderToIndex; // Point within RawData[]. Store display order of columns (when // not reordered, the values are 0...Count-1) ImSpan RowCellData; // Point within RawData[]. Store cells background requests for current row. ImU64 EnabledMaskByDisplayOrder; // Column DisplayOrder -> IsEnabled map ImU64 EnabledMaskByIndex; // Column Index -> IsEnabled map (== not hidden by user/api) in a format adequate for // iterating column without touching cold data ImU64 VisibleMaskByIndex; // Column Index -> IsVisibleX|IsVisibleY map (== not hidden by user/api && not hidden by // scrolling/cliprect) ImU64 RequestOutputMaskByIndex; // Column Index -> IsVisible || AutoFit (== expect user to submit items) ImGuiTableFlags SettingsLoadedFlags; // Which data were loaded from the .ini file (e.g. when order is not altered // we won't save order) int SettingsOffset; // Offset in g.SettingsTables int LastFrameActive; int ColumnsCount; // Number of columns declared in BeginTable() int CurrentRow; int CurrentColumn; ImS16 InstanceCurrent; // Count of BeginTable() calls with same ID in the same frame (generally 0). This is a // little bit similar to BeginCount for a window, but multiple table with same ID look are // multiple tables, they are just synched. ImS16 InstanceInteracted; // Mark which instance (generally 0) of the same ID is being interacted with float RowPosY1; float RowPosY2; float RowMinHeight; // Height submitted to TableNextRow() float RowTextBaseline; float RowIndentOffsetX; ImGuiTableRowFlags RowFlags : 16; // Current row flags, see ImGuiTableRowFlags_ ImGuiTableRowFlags LastRowFlags : 16; int RowBgColorCounter; // Counter for alternating background colors (can be fast-forwarded by e.g clipper), not // same as CurrentRow because header rows typically don't increase this. ImU32 RowBgColor[2]; // Background color override for current row. ImU32 BorderColorStrong; ImU32 BorderColorLight; float BorderX1; float BorderX2; float HostIndentX; float MinColumnWidth; float OuterPaddingX; float CellPaddingX; // Padding from each borders float CellPaddingY; float CellSpacingX1; // Spacing between non-bordered cells float CellSpacingX2; float LastOuterHeight; // Outer height from last frame float LastFirstRowHeight; // Height of first row from last frame float InnerWidth; // User value passed to BeginTable(), see comments at the top of BeginTable() for details. float ColumnsGivenWidth; // Sum of current column width float ColumnsAutoFitWidth; // Sum of ideal column width in order nothing to be clipped, used for auto-fitting and // content width submission in outer window float ResizedColumnNextWidth; float ResizeLockMinContentsX2; // Lock minimum contents width while resizing down in order to not create feedback // loops. But we allow growing the table. float RefScale; // Reference scale to be able to rescale columns on font/dpi changes. ImRect OuterRect; // Note: for non-scrolling table, OuterRect.Max.y is often FLT_MAX until EndTable(), unless a // height has been specified in BeginTable(). ImRect InnerRect; // InnerRect but without decoration. As with OuterRect, for non-scrolling tables, InnerRect.Max.y is ImRect WorkRect; ImRect InnerClipRect; ImRect BgClipRect; // We use this to cpu-clip cell background color fill ImRect Bg0ClipRectForDrawCmd; // Actual ImDrawCmd clip rect for BG0/1 channel. This tends to be == // OuterWindow->ClipRect at BeginTable() because output in BG0/BG1 is cpu-clipped ImRect Bg2ClipRectForDrawCmd; // Actual ImDrawCmd clip rect for BG2 channel. This tends to be a correct, tight-fit, // because output to BG2 are done by widgets relying on regular ClipRect. ImRect HostClipRect; // This is used to check if we can eventually merge our columns draw calls into the current // draw call of the current window. ImRect HostBackupInnerClipRect; // Backup of InnerWindow->ClipRect during PushTableBackground()/PopTableBackground() ImGuiWindow* OuterWindow; // Parent window for the table ImGuiWindow* InnerWindow; // Window holding the table data (== OuterWindow or a child window) ImGuiTextBuffer ColumnsNames; // Contiguous buffer holding columns names ImDrawListSplitter* DrawSplitter; // Shortcut to TempData->DrawSplitter while in table. Isolate draw commands per // columns to avoid switching clip rect constantly ImGuiTableColumnSortSpecs SortSpecsSingle; ImVector SortSpecsMulti; // FIXME-OPT: Using a small-vector pattern would be good. ImGuiTableSortSpecs SortSpecs; // Public facing sorts specs, this is what we return in TableGetSortSpecs() ImGuiTableColumnIdx SortSpecsCount; ImGuiTableColumnIdx ColumnsEnabledCount; // Number of enabled columns (<= ColumnsCount) ImGuiTableColumnIdx ColumnsEnabledFixedCount; // Number of enabled columns (<= ColumnsCount) ImGuiTableColumnIdx DeclColumnsCount; // Count calls to TableSetupColumn() ImGuiTableColumnIdx HoveredColumnBody; // Index of column whose visible region is being hovered. Important: == // ColumnsCount when hovering empty region after the right-most column! ImGuiTableColumnIdx HoveredColumnBorder; // Index of column whose right-border is being hovered (for resizing). ImGuiTableColumnIdx AutoFitSingleColumn; // Index of single column requesting auto-fit. ImGuiTableColumnIdx ResizedColumn; // Index of column being resized. Reset when InstanceCurrent==0. ImGuiTableColumnIdx LastResizedColumn; // Index of column being resized from previous frame. ImGuiTableColumnIdx HeldHeaderColumn; // Index of column header being held. ImGuiTableColumnIdx ReorderColumn; // Index of column being reordered. (not cleared) ImGuiTableColumnIdx ReorderColumnDir; // -1 or +1 ImGuiTableColumnIdx LeftMostEnabledColumn; // Index of left-most non-hidden column. ImGuiTableColumnIdx RightMostEnabledColumn; // Index of right-most non-hidden column. ImGuiTableColumnIdx LeftMostStretchedColumn; // Index of left-most stretched column. ImGuiTableColumnIdx RightMostStretchedColumn; // Index of right-most stretched column. ImGuiTableColumnIdx ContextPopupColumn; // Column right-clicked on, of -1 if opening context menu from a neutral/empty spot ImGuiTableColumnIdx FreezeRowsRequest; // Requested frozen rows count ImGuiTableColumnIdx FreezeRowsCount; // Actual frozen row count (== FreezeRowsRequest, or == 0 when no scrolling offset) ImGuiTableColumnIdx FreezeColumnsRequest; // Requested frozen columns count ImGuiTableColumnIdx FreezeColumnsCount; // Actual frozen columns count (== FreezeColumnsRequest, or == 0 when no scrolling offset) ImGuiTableColumnIdx RowCellDataCurrent; // Index of current RowCellData[] entry in current row ImGuiTableDrawChannelIdx DummyDrawChannel; // Redirect non-visible columns here. ImGuiTableDrawChannelIdx Bg2DrawChannelCurrent; // For Selectable() and other widgets drawing across columns after // the freezing line. Index within DrawSplitter.Channels[] ImGuiTableDrawChannelIdx Bg2DrawChannelUnfrozen; bool IsLayoutLocked; // Set by TableUpdateLayout() which is called when beginning the first row. bool IsInsideRow; // Set when inside TableBeginRow()/TableEndRow(). bool IsInitializing; bool IsSortSpecsDirty; bool IsUsingHeaders; // Set when the first row had the ImGuiTableRowFlags_Headers flag. bool IsContextPopupOpen; // Set when default context menu is open (also see: ContextPopupColumn, // InstanceInteracted). bool IsSettingsRequestLoad; bool IsSettingsDirty; // Set when table settings have changed and needs to be reported into ImGuiTableSetttings // data. bool IsDefaultDisplayOrder; // Set when display order is unchanged from default (DisplayOrder contains 0...Count-1) bool IsResetAllRequest; bool IsResetDisplayOrderRequest; bool IsUnfrozenRows; // Set when we got past the frozen row. bool IsDefaultSizingPolicy; // Set if user didn't explicitly set a sizing policy in BeginTable() bool MemoryCompacted; bool HostSkipItems; // Backup of InnerWindow->SkipItem at the end of BeginTable(), because we will overwrite // InnerWindow->SkipItem on a per-column basis IMGUI_API ImGuiTable() { memset(this, 0, sizeof(*this)); LastFrameActive = -1; } IMGUI_API ~ImGuiTable() { IM_FREE(RawData); } }; // Transient data that are only needed between BeginTable() and EndTable(), those buffers are shared (1 per level of // stacked table). // - Accessing those requires chasing an extra pointer so for very frequently used data we leave them in the main table // structure. // - We also leave out of this structure data that tend to be particularly useful for debugging/metrics. struct ImGuiTableTempData { int TableIndex; // Index in g.Tables.Buf[] pool float LastTimeActive; // Last timestamp this structure was used ImVec2 UserOuterSize; // outer_size.x passed to BeginTable() ImDrawListSplitter DrawSplitter; ImRect HostBackupWorkRect; // Backup of InnerWindow->WorkRect at the end of BeginTable() ImRect HostBackupParentWorkRect; // Backup of InnerWindow->ParentWorkRect at the end of BeginTable() ImVec2 HostBackupPrevLineSize; // Backup of InnerWindow->DC.PrevLineSize at the end of BeginTable() ImVec2 HostBackupCurrLineSize; // Backup of InnerWindow->DC.CurrLineSize at the end of BeginTable() ImVec2 HostBackupCursorMaxPos; // Backup of InnerWindow->DC.CursorMaxPos at the end of BeginTable() ImVec1 HostBackupColumnsOffset; // Backup of OuterWindow->DC.ColumnsOffset at the end of BeginTable() float HostBackupItemWidth; // Backup of OuterWindow->DC.ItemWidth at the end of BeginTable() int HostBackupItemWidthStackSize; // Backup of OuterWindow->DC.ItemWidthStack.Size at the end of BeginTable() IMGUI_API ImGuiTableTempData() { memset(this, 0, sizeof(*this)); LastTimeActive = -1.0f; } }; // sizeof() ~ 12 struct ImGuiTableColumnSettings { float WidthOrWeight; ImGuiID UserID; ImGuiTableColumnIdx Index; ImGuiTableColumnIdx DisplayOrder; ImGuiTableColumnIdx SortOrder; ImU8 SortDirection : 2; ImU8 IsEnabled : 1; // "Visible" in ini file ImU8 IsStretch : 1; ImGuiTableColumnSettings() { WidthOrWeight = 0.0f; UserID = 0; Index = -1; DisplayOrder = SortOrder = -1; SortDirection = ImGuiSortDirection_None; IsEnabled = 1; IsStretch = 0; } }; // This is designed to be stored in a single ImChunkStream (1 header followed by N ImGuiTableColumnSettings, etc.) struct ImGuiTableSettings { ImGuiID ID; // Set to 0 to invalidate/delete the setting ImGuiTableFlags SaveFlags; // Indicate data we want to save using the Resizable/Reorderable/Sortable/Hideable flags // (could be using its own flags..) float RefScale; // Reference scale to be able to rescale columns on font/dpi changes. ImGuiTableColumnIdx ColumnsCount; ImGuiTableColumnIdx ColumnsCountMax; // Maximum number of columns this settings instance can store, we can recycle // a settings instance with lower number of columns but not higher bool WantApply; // Set when loaded from .ini data (to enable merging/loading .ini data into an already running // context) ImGuiTableSettings() { memset(this, 0, sizeof(*this)); } ImGuiTableColumnSettings* GetColumnSettings() { return (ImGuiTableColumnSettings*)(this + 1); } }; //----------------------------------------------------------------------------- // [SECTION] ImGui internal API // No guarantee of forward compatibility here! //----------------------------------------------------------------------------- namespace ImGui { // Windows // We should always have a CurrentWindow in the stack (there is an implicit "Debug" window) // If this ever crash because g.CurrentWindow is NULL it means that either // - ImGui::NewFrame() has never been called, which is illegal. // - You are calling ImGui functions after ImGui::EndFrame()/ImGui::Render() and before the next ImGui::NewFrame(), // which is also illegal. inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; } inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->WriteAccessed = true; return g.CurrentWindow; } IMGUI_API ImGuiWindow* FindWindowByID(ImGuiID id); IMGUI_API ImGuiWindow* FindWindowByName(const char* name); IMGUI_API void UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window); IMGUI_API ImVec2 CalcWindowNextAutoFitSize(ImGuiWindow* window); IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent); IMGUI_API bool IsWindowAbove(ImGuiWindow* potential_above, ImGuiWindow* potential_below); IMGUI_API bool IsWindowNavFocusable(ImGuiWindow* window); IMGUI_API void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond = 0); IMGUI_API void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond = 0); IMGUI_API void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond = 0); IMGUI_API void SetWindowHitTestHole(ImGuiWindow* window, const ImVec2& pos, const ImVec2& size); // Windows: Display Order and Focus Order IMGUI_API void FocusWindow(ImGuiWindow* window); IMGUI_API void FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window); IMGUI_API void BringWindowToFocusFront(ImGuiWindow* window); IMGUI_API void BringWindowToDisplayFront(ImGuiWindow* window); IMGUI_API void BringWindowToDisplayBack(ImGuiWindow* window); // Fonts, drawing IMGUI_API void SetCurrentFont(ImFont* font); inline ImFont* GetDefaultFont() { ImGuiContext& g = *GImGui; return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; } inline ImDrawList* GetForegroundDrawList(ImGuiWindow* window) { return GetForegroundDrawList(window->Viewport); } // Init IMGUI_API void Initialize(ImGuiContext* context); IMGUI_API void Shutdown(ImGuiContext* context); // Since 1.60 this is a _private_ function. You can call // DestroyContext() to destroy the context created by CreateContext(). // NewFrame IMGUI_API void UpdateHoveredWindowAndCaptureFlags(); IMGUI_API void StartMouseMovingWindow(ImGuiWindow* window); IMGUI_API void StartMouseMovingWindowOrNode(ImGuiWindow* window, ImGuiDockNode* node, bool undock_floating_node); IMGUI_API void UpdateMouseMovingWindowNewFrame(); IMGUI_API void UpdateMouseMovingWindowEndFrame(); // Generic context hooks IMGUI_API ImGuiID AddContextHook(ImGuiContext* context, const ImGuiContextHook* hook); IMGUI_API void RemoveContextHook(ImGuiContext* context, ImGuiID hook_to_remove); IMGUI_API void CallContextHooks(ImGuiContext* context, ImGuiContextHookType type); // Viewports IMGUI_API void TranslateWindowsInViewport(ImGuiViewportP* viewport, const ImVec2& old_pos, const ImVec2& new_pos); IMGUI_API void ScaleWindowsInViewport(ImGuiViewportP* viewport, float scale); IMGUI_API void DestroyPlatformWindow(ImGuiViewportP* viewport); IMGUI_API void SetCurrentViewport(ImGuiWindow* window, ImGuiViewportP* viewport); IMGUI_API const ImGuiPlatformMonitor* GetViewportPlatformMonitor(ImGuiViewport* viewport); // Settings IMGUI_API void MarkIniSettingsDirty(); IMGUI_API void MarkIniSettingsDirty(ImGuiWindow* window); IMGUI_API void ClearIniSettings(); IMGUI_API ImGuiWindowSettings* CreateNewWindowSettings(const char* name); IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id); IMGUI_API ImGuiWindowSettings* FindOrCreateWindowSettings(const char* name); IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name); // Scrolling IMGUI_API void SetNextWindowScroll(const ImVec2& scroll); // Use -1.0f on one axis to leave as-is IMGUI_API void SetScrollX(ImGuiWindow* window, float scroll_x); IMGUI_API void SetScrollY(ImGuiWindow* window, float scroll_y); IMGUI_API void SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x_ratio); IMGUI_API void SetScrollFromPosY(ImGuiWindow* window, float local_y, float center_y_ratio); IMGUI_API ImVec2 ScrollToBringRectIntoView(ImGuiWindow* window, const ImRect& item_rect); // Basic Accessors inline ImGuiID GetItemID() { ImGuiContext& g = *GImGui; return g.LastItemData.ID; } // Get ID of last item (~~ often same ImGui::GetID(label) beforehand) inline ImGuiItemStatusFlags GetItemStatusFlags() { ImGuiContext& g = *GImGui; return g.LastItemData.StatusFlags; } inline ImGuiItemFlags GetItemFlags() { ImGuiContext& g = *GImGui; return g.LastItemData.InFlags; } inline ImGuiID GetActiveID() { ImGuiContext& g = *GImGui; return g.ActiveId; } inline ImGuiID GetFocusID() { ImGuiContext& g = *GImGui; return g.NavId; } IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window); IMGUI_API void SetFocusID(ImGuiID id, ImGuiWindow* window); IMGUI_API void ClearActiveID(); IMGUI_API ImGuiID GetHoveredID(); IMGUI_API void SetHoveredID(ImGuiID id); IMGUI_API void KeepAliveID(ImGuiID id); IMGUI_API void MarkItemEdited( ImGuiID id); // Mark data associated to given item as "edited", used by IsItemDeactivatedAfterEdit() function. IMGUI_API void PushOverrideID( ImGuiID id); // Push given value as-is at the top of the ID stack (whereas PushID combines old and new hashes) IMGUI_API ImGuiID GetIDWithSeed(const char* str_id_begin, const char* str_id_end, ImGuiID seed); // Basic Helpers for widget code IMGUI_API void ItemSize(const ImVec2& size, float text_baseline_y = -1.0f); IMGUI_API void ItemSize(const ImRect& bb, float text_baseline_y = -1.0f); IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL, ImGuiItemAddFlags flags = 0); IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id); IMGUI_API void ItemFocusable(ImGuiWindow* window, ImGuiID id); IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged); IMGUI_API void SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags status_flags, const ImRect& item_rect); IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_w, float default_h); IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); IMGUI_API void PushMultiItemsWidths(int components, float width_full); IMGUI_API bool IsItemToggledSelection(); // Was the last item selection toggled? (after Selectable(), TreeNode() etc. // We only returns toggle _event_ in order to handle clipping correctly) IMGUI_API ImVec2 GetContentRegionMaxAbs(); IMGUI_API void ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_excess); // Parameter stacks IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); IMGUI_API void PopItemFlag(); # ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS // If you have old/custom copy-and-pasted widgets that used FocusableItemRegister(): // (Old) IMGUI_VERSION_NUM < 18209: using 'ItemAdd(....)' and 'bool focused = // FocusableItemRegister(...)' (New) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)' and // 'bool focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_Focused) != 0' // Widget code are simplified as there's no need to call FocusableItemUnregister() while managing the transition from // regular widget to TempInputText() inline bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id) { IM_ASSERT(0); IM_UNUSED(window); IM_UNUSED(id); return false; } // -> pass ImGuiItemAddFlags_Focusable flag to ItemAdd() inline IM_NORETURN void FocusableItemUnregister(ImGuiWindow* window) { IM_ASSERT(0); IM_UNUSED(window); } // -> unnecessary: TempInputText() uses ImGuiInputTextFlags_MergedItem # endif // Logging/Capture IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now // stay under the radar by using the old name. IMGUI_API void LogToBuffer(int auto_open_depth = -1); // Start logging/capturing to internal buffer IMGUI_API void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL); IMGUI_API void LogSetNextTextDecoration(const char* prefix, const char* suffix); // Popups, Modals, Tooltips IMGUI_API bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags); IMGUI_API void OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags = ImGuiPopupFlags_None); IMGUI_API void ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup); IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup); IMGUI_API bool IsPopupOpen(ImGuiID id, ImGuiPopupFlags popup_flags); IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, ImGuiTooltipFlags tooltip_flags); IMGUI_API ImRect GetPopupAllowedExtentRect(ImGuiWindow* window); IMGUI_API ImGuiWindow* GetTopMostPopupModal(); IMGUI_API ImVec2 FindBestWindowPosForPopup(ImGuiWindow* window); IMGUI_API ImVec2 FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy); IMGUI_API bool BeginViewportSideBar(const char* name, ImGuiViewport* viewport, ImGuiDir dir, float size, ImGuiWindowFlags window_flags); // Menus IMGUI_API bool MenuItemEx(const char* label, const char* icon, const char* shortcut = NULL, bool selected = false, bool enabled = true); // Combos IMGUI_API bool BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags flags); IMGUI_API bool BeginComboPreview(); IMGUI_API void EndComboPreview(); // Gamepad/Keyboard Navigation IMGUI_API void NavInitWindow(ImGuiWindow* window, bool force_reinit); IMGUI_API bool NavMoveRequestButNoResultYet(); IMGUI_API void NavMoveRequestCancel(); IMGUI_API void NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, const ImRect& bb_rel, ImGuiNavMoveFlags move_flags); IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags); IMGUI_API float GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode); IMGUI_API ImVec2 GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f); IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate); IMGUI_API void ActivateItem( ImGuiID id); // Remotely activate a button, checkbox, tree node etc. given its unique ID. activation is queued and // processed on the next frame when the item is encountered again. IMGUI_API void SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel); // Focus Scope (WIP) // This is generally used to identify a selection set (multiple of which may be in the same window), as selection // patterns generally need to react (e.g. clear selection) when landing on an item of the set. IMGUI_API void PushFocusScope(ImGuiID id); IMGUI_API void PopFocusScope(); inline ImGuiID GetFocusedFocusScope() { ImGuiContext& g = *GImGui; return g.NavFocusScopeId; } // Focus scope which is actually active inline ImGuiID GetFocusScope() { ImGuiContext& g = *GImGui; return g.CurrentWindow->DC.NavFocusScopeIdCurrent; } // Focus scope we are outputting into, set by PushFocusScope() // Inputs // FIXME: Eventually we should aim to move e.g. IsActiveIdUsingKey() into IsKeyXXX functions. IMGUI_API void SetItemUsingMouseWheel(); IMGUI_API void SetActiveIdUsingNavAndKeys(); inline bool IsActiveIdUsingNavDir(ImGuiDir dir) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavDirMask & (1 << dir)) != 0; } inline bool IsActiveIdUsingNavInput(ImGuiNavInput input) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavInputMask & (1 << input)) != 0; } inline bool IsActiveIdUsingKey(ImGuiKey key) { ImGuiContext& g = *GImGui; IM_ASSERT(key < 64); return (g.ActiveIdUsingKeyInputMask & ((ImU64)1 << key)) != 0; } IMGUI_API bool IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold = -1.0f); inline bool IsKeyPressedMap(ImGuiKey key, bool repeat = true) { ImGuiContext& g = *GImGui; const int key_index = g.IO.KeyMap[key]; return (key_index >= 0) ? IsKeyPressed(key_index, repeat) : false; } inline bool IsNavInputDown(ImGuiNavInput n) { ImGuiContext& g = *GImGui; return g.IO.NavInputs[n] > 0.0f; } inline bool IsNavInputTest(ImGuiNavInput n, ImGuiInputReadMode rm) { return (GetNavInputAmount(n, rm) > 0.0f); } IMGUI_API ImGuiKeyModFlags GetMergedKeyModFlags(); // Docking // (some functions are only declared in imgui.cpp, see Docking section) IMGUI_API void DockContextInitialize(ImGuiContext* ctx); IMGUI_API void DockContextShutdown(ImGuiContext* ctx); IMGUI_API void DockContextClearNodes(ImGuiContext* ctx, ImGuiID root_id, bool clear_settings_refs); // Use root_id==0 to clear all IMGUI_API void DockContextRebuildNodes(ImGuiContext* ctx); IMGUI_API void DockContextNewFrameUpdateUndocking(ImGuiContext* ctx); IMGUI_API void DockContextNewFrameUpdateDocking(ImGuiContext* ctx); IMGUI_API ImGuiID DockContextGenNodeID(ImGuiContext* ctx); IMGUI_API void DockContextQueueDock(ImGuiContext* ctx, ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, float split_ratio, bool split_outer); IMGUI_API void DockContextQueueUndockWindow(ImGuiContext* ctx, ImGuiWindow* window); IMGUI_API void DockContextQueueUndockNode(ImGuiContext* ctx, ImGuiDockNode* node); IMGUI_API bool DockContextCalcDropPosForDocking(ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload, ImGuiDir split_dir, bool split_outer, ImVec2* out_pos); IMGUI_API bool DockNodeBeginAmendTabBar(ImGuiDockNode* node); IMGUI_API void DockNodeEndAmendTabBar(); inline ImGuiDockNode* DockNodeGetRootNode(ImGuiDockNode* node) { while (node->ParentNode) node = node->ParentNode; return node; } inline int DockNodeGetDepth(const ImGuiDockNode* node) { int depth = 0; while (node->ParentNode) { node = node->ParentNode; depth++; } return depth; } inline ImGuiID DockNodeGetWindowMenuButtonId(const ImGuiDockNode* node) { return ImHashStr("#COLLAPSE", 0, node->ID); } inline ImGuiDockNode* GetWindowDockNode() { ImGuiContext& g = *GImGui; return g.CurrentWindow->DockNode; } IMGUI_API bool GetWindowAlwaysWantOwnTabBar(ImGuiWindow* window); IMGUI_API void BeginDocked(ImGuiWindow* window, bool* p_open); IMGUI_API void BeginDockableDragDropSource(ImGuiWindow* window); IMGUI_API void BeginDockableDragDropTarget(ImGuiWindow* window); IMGUI_API void SetWindowDock(ImGuiWindow* window, ImGuiID dock_id, ImGuiCond cond); // Docking - Builder function needs to be generally called before the node is used/submitted. // - The DockBuilderXXX functions are designed to _eventually_ become a public API, but it is too early to expose it and // guarantee stability. // - Do not hold on ImGuiDockNode* pointers! They may be invalidated by any split/merge/remove operation and every // frame. // - To create a DockSpace() node, make sure to set the ImGuiDockNodeFlags_DockSpace flag when calling // DockBuilderAddNode(). // You can create dockspace nodes (attached to a window) _or_ floating nodes (carry its own window) with this API. // - DockBuilderSplitNode() create 2 child nodes within 1 node. The initial node becomes a parent node. // - If you intend to split the node immediately after creation using DockBuilderSplitNode(), make sure // to call DockBuilderSetNodeSize() beforehand. If you don't, the resulting split sizes may not be reliable. // - Call DockBuilderFinish() after you are done. IMGUI_API void DockBuilderDockWindow(const char* window_name, ImGuiID node_id); IMGUI_API ImGuiDockNode* DockBuilderGetNode(ImGuiID node_id); inline ImGuiDockNode* DockBuilderGetCentralNode(ImGuiID node_id) { ImGuiDockNode* node = DockBuilderGetNode(node_id); if (!node) return NULL; return DockNodeGetRootNode(node)->CentralNode; } IMGUI_API ImGuiID DockBuilderAddNode(ImGuiID node_id = 0, ImGuiDockNodeFlags flags = 0); IMGUI_API void DockBuilderRemoveNode(ImGuiID node_id); // Remove node and all its child, undock all windows IMGUI_API void DockBuilderRemoveNodeDockedWindows(ImGuiID node_id, bool clear_settings_refs = true); IMGUI_API void DockBuilderRemoveNodeChildNodes( ImGuiID node_id); // Remove all split/hierarchy. All remaining docked windows will be re-docked to the remaining // root node (node_id). IMGUI_API void DockBuilderSetNodePos(ImGuiID node_id, ImVec2 pos); IMGUI_API void DockBuilderSetNodeSize(ImGuiID node_id, ImVec2 size); IMGUI_API ImGuiID DockBuilderSplitNode(ImGuiID node_id, ImGuiDir split_dir, float size_ratio_for_node_at_dir, ImGuiID* out_id_at_dir, ImGuiID* out_id_at_opposite_dir); // Create 2 child nodes in this parent node. IMGUI_API void DockBuilderCopyDockSpace(ImGuiID src_dockspace_id, ImGuiID dst_dockspace_id, ImVector* in_window_remap_pairs); IMGUI_API void DockBuilderCopyNode(ImGuiID src_node_id, ImGuiID dst_node_id, ImVector* out_node_remap_pairs); IMGUI_API void DockBuilderCopyWindowSettings(const char* src_name, const char* dst_name); IMGUI_API void DockBuilderFinish(ImGuiID node_id); // Drag and Drop IMGUI_API bool BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id); IMGUI_API void ClearDragDrop(); IMGUI_API bool IsDragDropPayloadBeingAccepted(); // Internal Columns API (this is not exposed because we will encourage transitioning to the Tables API) IMGUI_API void SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect); IMGUI_API void BeginColumns( const char* str_id, int count, ImGuiOldColumnFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). IMGUI_API void EndColumns(); // close columns IMGUI_API void PushColumnClipRect(int column_index); IMGUI_API void PushColumnsBackground(); IMGUI_API void PopColumnsBackground(); IMGUI_API ImGuiID GetColumnsID(const char* str_id, int count); IMGUI_API ImGuiOldColumns* FindOrCreateColumns(ImGuiWindow* window, ImGuiID id); IMGUI_API float GetColumnOffsetFromNorm(const ImGuiOldColumns* columns, float offset_norm); IMGUI_API float GetColumnNormFromOffset(const ImGuiOldColumns* columns, float offset); // Tables: Candidates for public API IMGUI_API void TableOpenContextMenu(int column_n = -1); IMGUI_API void TableSetColumnWidth(int column_n, float width); IMGUI_API void TableSetColumnSortDirection(int column_n, ImGuiSortDirection sort_direction, bool append_to_sort_specs); IMGUI_API int TableGetHoveredColumn(); // May use (TableGetColumnFlags() & ImGuiTableColumnFlags_IsHovered) instead. // Return hovered column. return -1 when table is not hovered. return // columns_count if the unused space at the right of visible columns is hovered. IMGUI_API float TableGetHeaderRowHeight(); IMGUI_API void TablePushBackgroundChannel(); IMGUI_API void TablePopBackgroundChannel(); // Tables: Internals inline ImGuiTable* GetCurrentTable() { ImGuiContext& g = *GImGui; return g.CurrentTable; } IMGUI_API ImGuiTable* TableFindByID(ImGuiID id); IMGUI_API bool BeginTableEx(const char* name, ImGuiID id, int columns_count, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0, 0), float inner_width = 0.0f); IMGUI_API void TableBeginInitMemory(ImGuiTable* table, int columns_count); IMGUI_API void TableBeginApplyRequests(ImGuiTable* table); IMGUI_API void TableSetupDrawChannels(ImGuiTable* table); IMGUI_API void TableUpdateLayout(ImGuiTable* table); IMGUI_API void TableUpdateBorders(ImGuiTable* table); IMGUI_API void TableUpdateColumnsWeightFromWidth(ImGuiTable* table); IMGUI_API void TableDrawBorders(ImGuiTable* table); IMGUI_API void TableDrawContextMenu(ImGuiTable* table); IMGUI_API void TableMergeDrawChannels(ImGuiTable* table); IMGUI_API void TableSortSpecsSanitize(ImGuiTable* table); IMGUI_API void TableSortSpecsBuild(ImGuiTable* table); IMGUI_API ImGuiSortDirection TableGetColumnNextSortDirection(ImGuiTableColumn* column); IMGUI_API void TableFixColumnSortDirection(ImGuiTable* table, ImGuiTableColumn* column); IMGUI_API float TableGetColumnWidthAuto(ImGuiTable* table, ImGuiTableColumn* column); IMGUI_API void TableBeginRow(ImGuiTable* table); IMGUI_API void TableEndRow(ImGuiTable* table); IMGUI_API void TableBeginCell(ImGuiTable* table, int column_n); IMGUI_API void TableEndCell(ImGuiTable* table); IMGUI_API ImRect TableGetCellBgRect(const ImGuiTable* table, int column_n); IMGUI_API const char* TableGetColumnName(const ImGuiTable* table, int column_n); IMGUI_API ImGuiID TableGetColumnResizeID(const ImGuiTable* table, int column_n, int instance_no = 0); IMGUI_API float TableGetMaxColumnWidth(const ImGuiTable* table, int column_n); IMGUI_API void TableSetColumnWidthAutoSingle(ImGuiTable* table, int column_n); IMGUI_API void TableSetColumnWidthAutoAll(ImGuiTable* table); IMGUI_API void TableRemove(ImGuiTable* table); IMGUI_API void TableGcCompactTransientBuffers(ImGuiTable* table); IMGUI_API void TableGcCompactTransientBuffers(ImGuiTableTempData* table); IMGUI_API void TableGcCompactSettings(); // Tables: Settings IMGUI_API void TableLoadSettings(ImGuiTable* table); IMGUI_API void TableSaveSettings(ImGuiTable* table); IMGUI_API void TableResetSettings(ImGuiTable* table); IMGUI_API ImGuiTableSettings* TableGetBoundSettings(ImGuiTable* table); IMGUI_API void TableSettingsInstallHandler(ImGuiContext* context); IMGUI_API ImGuiTableSettings* TableSettingsCreate(ImGuiID id, int columns_count); IMGUI_API ImGuiTableSettings* TableSettingsFindByID(ImGuiID id); // Tab Bars IMGUI_API bool BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags, ImGuiDockNode* dock_node); IMGUI_API ImGuiTabItem* TabBarFindTabByID(ImGuiTabBar* tab_bar, ImGuiID tab_id); IMGUI_API ImGuiTabItem* TabBarFindMostRecentlySelectedTabForActiveWindow(ImGuiTabBar* tab_bar); IMGUI_API void TabBarAddTab(ImGuiTabBar* tab_bar, ImGuiTabItemFlags tab_flags, ImGuiWindow* window); IMGUI_API void TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id); IMGUI_API void TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab); IMGUI_API void TabBarQueueReorder(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, int offset); IMGUI_API void TabBarQueueReorderFromMousePos(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, ImVec2 mouse_pos); IMGUI_API bool TabBarProcessReorder(ImGuiTabBar* tab_bar); IMGUI_API bool TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags, ImGuiWindow* docked_window); IMGUI_API ImVec2 TabItemCalcSize(const char* label, bool has_close_button); IMGUI_API void TabItemBackground(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImU32 col); IMGUI_API void TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb, ImGuiTabItemFlags flags, ImVec2 frame_padding, const char* label, ImGuiID tab_id, ImGuiID close_button_id, bool is_contents_visible, bool* out_just_closed, bool* out_text_clipped); // Render helpers // AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. THOSE FUNCTIONS ARE A MESS. THEIR SIGNATURE AND // BEHAVIOR WILL CHANGE, THEY NEED TO BE REFACTORED INTO SOMETHING DECENT. NB: All position are in absolute pixels // coordinates (we are never using window coordinates internally) IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width); IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0, 0), const ImRect* clip_rect = NULL); IMGUI_API void RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0, 0), const ImRect* clip_rect = NULL); IMGUI_API void RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float clip_max_x, float ellipsis_max_x, const char* text, const char* text_end, const ImVec2* text_size_if_known); IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f); IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, ImDrawFlags flags = 0); IMGUI_API void RenderNavHighlight( const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags = ImGuiNavHighlightFlags_TypeDefault); // Navigation highlight IMGUI_API const char* FindRenderedTextEnd( const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text. // Render helpers (those functions don't access any ImGui state!) IMGUI_API void RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImU32 col, ImGuiDir dir, float scale = 1.0f); IMGUI_API void RenderBullet(ImDrawList* draw_list, ImVec2 pos, ImU32 col); IMGUI_API void RenderCheckMark(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float sz); IMGUI_API void RenderMouseCursor(ImDrawList* draw_list, ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow); IMGUI_API void RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col); IMGUI_API void RenderArrowDockMenu(ImDrawList* draw_list, ImVec2 p_min, float sz, ImU32 col); IMGUI_API void RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding); IMGUI_API void RenderRectFilledWithHole(ImDrawList* draw_list, ImRect outer, ImRect inner, ImU32 col, float rounding); # ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS // [1.71: 2019/06/07: Updating prototypes of some of the internal functions. Leaving those for reference for a short // while] inline void RenderArrow(ImVec2 pos, ImGuiDir dir, float scale = 1.0f) { ImGuiWindow* window = GetCurrentWindow(); RenderArrow(window->DrawList, pos, GetColorU32(ImGuiCol_Text), dir, scale); } inline void RenderBullet(ImVec2 pos) { ImGuiWindow* window = GetCurrentWindow(); RenderBullet(window->DrawList, pos, GetColorU32(ImGuiCol_Text)); } # endif // Widgets IMGUI_API void TextEx(const char* text, const char* text_end = NULL, ImGuiTextFlags flags = 0); IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0); IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos); IMGUI_API bool CollapseButton(ImGuiID id, const ImVec2& pos, ImGuiDockNode* dock_node); IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags = 0); IMGUI_API void Scrollbar(ImGuiAxis axis); IMGUI_API bool ScrollbarEx(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* p_scroll_v, float avail_v, float contents_v, ImDrawFlags flags); IMGUI_API bool ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec2& padding, const ImVec4& bg_col, const ImVec4& tint_col); IMGUI_API ImRect GetWindowScrollbarRect(ImGuiWindow* window, ImGuiAxis axis); IMGUI_API ImGuiID GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis); IMGUI_API ImGuiID GetWindowResizeCornerID(ImGuiWindow* window, int n); // 0..3: corners IMGUI_API ImGuiID GetWindowResizeBorderID(ImGuiWindow* window, ImGuiDir dir); IMGUI_API void SeparatorEx(ImGuiSeparatorFlags flags); IMGUI_API bool CheckboxFlags(const char* label, ImS64* flags, ImS64 flags_value); IMGUI_API bool CheckboxFlags(const char* label, ImU64* flags, ImU64 flags_value); // Widgets low-level behaviors IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0); IMGUI_API bool DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags); IMGUI_API bool SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, void* p_v, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb); IMGUI_API bool SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f, float hover_visibility_delay = 0.0f); IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL); IMGUI_API bool TreeNodeBehaviorIsOpen( ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextItemOpen() data, if any. May return true when logging IMGUI_API void TreePushOverrideID(ImGuiID id); // Template functions are instantiated in imgui_widgets.cpp for a finite number of types. // To use them externally (for custom widget) you may need an "extern template" statement in your code in order to link // to existing instances and silence Clang warnings (see #2036). e.g. " extern template IMGUI_API float // RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, float v); " template IMGUI_API float ScaleRatioFromValueT(ImGuiDataType data_type, T v, T v_min, T v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_size); template IMGUI_API T ScaleValueFromRatioT(ImGuiDataType data_type, float t, T v_min, T v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_size); template IMGUI_API bool DragBehaviorT(ImGuiDataType data_type, T* v, float v_speed, T v_min, T v_max, const char* format, ImGuiSliderFlags flags); template IMGUI_API bool SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_type, T* v, T v_min, T v_max, const char* format, ImGuiSliderFlags flags, ImRect* out_grab_bb); template IMGUI_API T RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v); template IMGUI_API bool CheckboxFlagsT(const char* label, T* flags, T flags_value); // Data type helpers IMGUI_API const ImGuiDataTypeInfo* DataTypeGetInfo(ImGuiDataType data_type); IMGUI_API int DataTypeFormatString(char* buf, int buf_size, ImGuiDataType data_type, const void* p_data, const char* format); IMGUI_API void DataTypeApplyOp(ImGuiDataType data_type, int op, void* output, const void* arg_1, const void* arg_2); IMGUI_API bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* p_data, const char* format); IMGUI_API int DataTypeCompare(ImGuiDataType data_type, const void* arg_1, const void* arg_2); IMGUI_API bool DataTypeClamp(ImGuiDataType data_type, void* p_data, const void* p_min, const void* p_max); // InputText IMGUI_API bool InputTextEx(const char* label, const char* hint, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback = NULL, void* user_data = NULL); IMGUI_API bool TempInputText(const ImRect& bb, ImGuiID id, const char* label, char* buf, int buf_size, ImGuiInputTextFlags flags); IMGUI_API bool TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImGuiDataType data_type, void* p_data, const char* format, const void* p_clamp_min = NULL, const void* p_clamp_max = NULL); inline bool TempInputIsActive(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.ActiveId == id && g.TempInputId == id); } inline ImGuiInputTextState* GetInputTextState(ImGuiID id) { ImGuiContext& g = *GImGui; return (g.InputTextState.ID == id) ? &g.InputTextState : NULL; } // Get input text state if active // Color IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags); IMGUI_API void ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags); IMGUI_API void ColorPickerOptionsPopup(const float* ref_col, ImGuiColorEditFlags flags); // Plot IMGUI_API int PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 frame_size); // Shade functions (write over already created vertices) IMGUI_API void ShadeVertsLinearColorGradientKeepAlpha(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1); IMGUI_API void ShadeVertsLinearUV(ImDrawList* draw_list, int vert_start_idx, int vert_end_idx, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, bool clamp); // Garbage collection IMGUI_API void GcCompactTransientMiscBuffers(); IMGUI_API void GcCompactTransientWindowBuffers(ImGuiWindow* window); IMGUI_API void GcAwakeTransientWindowBuffers(ImGuiWindow* window); // Debug Tools IMGUI_API void ErrorCheckEndFrameRecover(ImGuiErrorLogCallback log_callback, void* user_data = NULL); inline void DebugDrawItemRect(ImU32 col = IM_COL32(255, 0, 0, 255)) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; GetForegroundDrawList(window)->AddRect(g.LastItemData.Rect.Min, g.LastItemData.Rect.Max, col); } inline void DebugStartItemPicker() { ImGuiContext& g = *GImGui; g.DebugItemPickerActive = true; } IMGUI_API void ShowFontAtlas(ImFontAtlas* atlas); IMGUI_API void DebugNodeColumns(ImGuiOldColumns* columns); IMGUI_API void DebugNodeDockNode(ImGuiDockNode* node, const char* label); IMGUI_API void DebugNodeDrawList(ImGuiWindow* window, ImGuiViewportP* viewport, const ImDrawList* draw_list, const char* label); IMGUI_API void DebugNodeDrawCmdShowMeshAndBoundingBox(ImDrawList* out_draw_list, const ImDrawList* draw_list, const ImDrawCmd* draw_cmd, bool show_mesh, bool show_aabb); IMGUI_API void DebugNodeFont(ImFont* font); IMGUI_API void DebugNodeStorage(ImGuiStorage* storage, const char* label); IMGUI_API void DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label); IMGUI_API void DebugNodeTable(ImGuiTable* table); IMGUI_API void DebugNodeTableSettings(ImGuiTableSettings* settings); IMGUI_API void DebugNodeWindow(ImGuiWindow* window, const char* label); IMGUI_API void DebugNodeWindowSettings(ImGuiWindowSettings* settings); IMGUI_API void DebugNodeWindowsList(ImVector* windows, const char* label); IMGUI_API void DebugNodeViewport(ImGuiViewportP* viewport); IMGUI_API void DebugRenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewport, const ImRect& bb); } // namespace ImGui //----------------------------------------------------------------------------- // [SECTION] ImFontAtlas internal API //----------------------------------------------------------------------------- // This structure is likely to evolve as we add support for incremental atlas updates struct ImFontBuilderIO { bool (*FontBuilder_Build)(ImFontAtlas* atlas); }; // Helper for font builder IMGUI_API const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype(); IMGUI_API void ImFontAtlasBuildInit(ImFontAtlas* atlas); IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent); IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* stbrp_context_opaque); IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas); IMGUI_API void ImFontAtlasBuildRender8bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value); IMGUI_API void ImFontAtlasBuildRender32bppRectFromString(ImFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned int in_marker_pixel_value); IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor); IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride); //----------------------------------------------------------------------------- // [SECTION] Test Engine specific hooks (imgui_test_engine) //----------------------------------------------------------------------------- # ifdef IMGUI_ENABLE_TEST_ENGINE extern void ImGuiTestEngineHook_ItemAdd(ImGuiContext* ctx, const ImRect& bb, ImGuiID id); extern void ImGuiTestEngineHook_ItemInfo(ImGuiContext* ctx, ImGuiID id, const char* label, ImGuiItemStatusFlags flags); extern void ImGuiTestEngineHook_IdInfo(ImGuiContext* ctx, ImGuiDataType data_type, ImGuiID id, const void* data_id); extern void ImGuiTestEngineHook_IdInfo(ImGuiContext* ctx, ImGuiDataType data_type, ImGuiID id, const void* data_id, const void* data_id_end); extern void ImGuiTestEngineHook_Log(ImGuiContext* ctx, const char* fmt, ...); # define IMGUI_TEST_ENGINE_ITEM_ADD(_BB, _ID) \ if (g.TestEngineHookItems) \ ImGuiTestEngineHook_ItemAdd(&g, _BB, _ID) // Register item bounding box # define IMGUI_TEST_ENGINE_ITEM_INFO(_ID, _LABEL, _FLAGS) \ if (g.TestEngineHookItems) \ ImGuiTestEngineHook_ItemInfo(&g, _ID, _LABEL, _FLAGS) // Register item label and status flags (optional) # define IMGUI_TEST_ENGINE_LOG(_FMT, ...) \ if (g.TestEngineHookItems) \ ImGuiTestEngineHook_Log(&g, _FMT, __VA_ARGS__) // Custom log entry from user land into test log # define IMGUI_TEST_ENGINE_ID_INFO(_ID, _TYPE, _DATA) \ if (g.TestEngineHookIdInfo == _ID) \ ImGuiTestEngineHook_IdInfo(&g, _TYPE, _ID, (const void*)(_DATA)); # define IMGUI_TEST_ENGINE_ID_INFO2(_ID, _TYPE, _DATA, _DATA2) \ if (g.TestEngineHookIdInfo == _ID) \ ImGuiTestEngineHook_IdInfo(&g, _TYPE, _ID, (const void*)(_DATA), (const void*)(_DATA2)); # else # define IMGUI_TEST_ENGINE_ITEM_INFO(_ID, _LABEL, _FLAGS) ((void)0) # endif //----------------------------------------------------------------------------- # if defined(__clang__) # pragma clang diagnostic pop # elif defined(__GNUC__) # pragma GCC diagnostic pop # endif # ifdef _MSC_VER # pragma warning(pop) # endif #endif // #ifndef IMGUI_DISABLE