axmol/extensions/ImGuiEXT/imgui/imgui_internal.h

4465 lines
216 KiB
C++

// 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 <stdio.h> // FILE*, sscanf
# include <stdlib.h> // NULL, malloc, free, qsort, atoi, atof
# include <math.h> // sqrtf, fabsf, fmodf, powf, floorf, ceilf, cosf, sinf
# include <limits.h> // INT_MIN, INT_MAX
// Enable SSE intrinsics if available
# if (defined __SSE__ || defined __x86_64__ || defined _M_X64) && !defined(IMGUI_DISABLE_SSE)
# define IMGUI_ENABLE_SSE
# include <immintrin.h>
# endif
// Visual Studio warnings
# ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable : 4251) // class 'xxx' needs to have dll-interface to be used by clients of struct
// 'xxx' // when IMGUI_API is set to__declspec(dllexport)
# pragma warning(disable : 26812) // The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).
// [MSVC Static Analyzer)
# pragma warning(disable : 26495) // [Static Analyzer] Variable 'XXX' is uninitialized. Always initialize a
// member variable (type.6).
# if defined(_MSC_VER) && _MSC_VER >= 1922 // MSVC 2019 16.2 or later
# pragma warning(disable : 5054) // operator '|': deprecated between enumerations of different types
# endif
# endif
// Clang/GCC warnings with -Weverything
# if defined(__clang__)
# pragma clang diagnostic push
# if __has_warning("-Wunknown-warning-option")
# pragma clang diagnostic ignored "-Wunknown-warning-option" // warning: unknown warning group 'xxx'
# endif
# pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
# pragma clang diagnostic ignored \
"-Wfloat-equal" // warning: comparing floating point with == or != is unsafe // storing and comparing
// against same constants ok, for 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 <typename T>
static inline T ImMin(T lhs, T rhs)
{
return lhs < rhs ? lhs : rhs;
}
template <typename T>
static inline T ImMax(T lhs, T rhs)
{
return lhs >= rhs ? lhs : rhs;
}
template <typename T>
static inline T ImClamp(T v, T mn, T mx)
{
return (v < mn) ? mn : (v > mx) ? mx : v;
}
template <typename T>
static inline T ImLerp(T a, T b, float t)
{
return (T)(a + (b - a) * t);
}
template <typename T>
static inline void ImSwap(T& a, T& b)
{
T tmp = a;
a = b;
b = tmp;
}
template <typename T>
static inline T ImAddClampOverflow(T a, T b, T mn, T mx)
{
if (b < 0 && (a < mn - b))
return mn;
if (b > 0 && (a > mx - b))
return mx;
return a + b;
}
template <typename T>
static inline T ImSubClampOverflow(T a, T b, T mn, T mx)
{
if (b > 0 && (a < mn + b))
return mn;
if (b < 0 && (a > mx + b))
return mx;
return a - b;
}
// - Misc maths helpers
static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs)
{
return ImVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y);
}
static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs)
{
return ImVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y);
}
static inline ImVec2 ImClamp(const ImVec2& v, const ImVec2& mn, ImVec2 mx)
{
return ImVec2((v.x < mn.x) ? mn.x : (v.x > mx.x) ? mx.x : v.x, (v.y < mn.y) ? mn.y : (v.y > mx.y) ? mx.y : v.y);
}
static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t)
{
return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t);
}
static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t)
{
return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y);
}
static inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t)
{
return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t);
}
static inline float ImSaturate(float f)
{
return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f;
}
static inline float ImLengthSqr(const ImVec2& lhs)
{
return (lhs.x * lhs.x) + (lhs.y * lhs.y);
}
static inline float ImLengthSqr(const ImVec4& lhs)
{
return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w);
}
static inline float ImInvLength(const ImVec2& lhs, float fail_value)
{
float d = (lhs.x * lhs.x) + (lhs.y * lhs.y);
if (d > 0.0f)
return ImRsqrt(d);
return fail_value;
}
static inline float 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 <int BITCOUNT>
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<ImU32> Storage;
void Create(int sz)
{
Storage.resize((sz + 31) >> 5);
memset(Storage.Data, 0, (size_t)Storage.Size * sizeof(Storage.Data[0]));
}
void Clear() { Storage.clear(); }
bool TestBit(int n) const
{
IM_ASSERT(n < (Storage.Size << 5));
return 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 <typename T>
struct ImSpan
{
T* Data;
T* DataEnd;
// Constructors, destructor
inline ImSpan() { Data = DataEnd = NULL; }
inline ImSpan(T* data, int size)
{
Data = data;
DataEnd = data + size;
}
inline ImSpan(T* data, T* data_end)
{
Data = data;
DataEnd = data_end;
}
inline void set(T* data, int size)
{
Data = data;
DataEnd = data + size;
}
inline void set(T* data, T* data_end)
{
Data = data;
DataEnd = data_end;
}
inline int size() const { return (int)(ptrdiff_t)(DataEnd - Data); }
inline int size_in_bytes() const { return (int)(ptrdiff_t)(DataEnd - Data) * (int)sizeof(T); }
inline T& operator[](int i)
{
T* p = Data + i;
IM_ASSERT(p >= Data && p < DataEnd);
return *p;
}
inline const T& operator[](int i) const
{
const T* p = Data + i;
IM_ASSERT(p >= Data && p < DataEnd);
return *p;
}
inline T* begin() { return Data; }
inline const T* begin() const { return Data; }
inline T* end() { return DataEnd; }
inline const T* end() const { return DataEnd; }
// Utilities
inline int index_from_ptr(const T* it) const
{
IM_ASSERT(it >= Data && it < DataEnd);
const ptrdiff_t off = it - Data;
return (int)off;
}
};
// Helper: ImSpanAllocator<>
// Facilitate storing multiple chunks into a single large block (the "arena")
// - Usage: call Reserve() N times, allocate GetArenaSizeInBytes() worth, pass it to SetArenaBasePtr(), call GetSpan() N
// times to retrieve the aligned ranges.
template <int CHUNKS>
struct ImSpanAllocator
{
char* BasePtr;
int CurrOff;
int CurrIdx;
int Offsets[CHUNKS];
int Sizes[CHUNKS];
ImSpanAllocator() { memset(this, 0, sizeof(*this)); }
inline void Reserve(int n, size_t sz, int a = 4)
{
IM_ASSERT(n == CurrIdx && n < CHUNKS);
CurrOff = IM_MEMALIGN(CurrOff, a);
Offsets[n] = CurrOff;
Sizes[n] = (int)sz;
CurrIdx++;
CurrOff += (int)sz;
}
inline int GetArenaSizeInBytes() { return CurrOff; }
inline void SetArenaBasePtr(void* base_ptr) { BasePtr = (char*)base_ptr; }
inline void* GetSpanPtrBegin(int n)
{
IM_ASSERT(n >= 0 && n < CHUNKS && CurrIdx == CHUNKS);
return (void*)(BasePtr + Offsets[n]);
}
inline void* GetSpanPtrEnd(int n)
{
IM_ASSERT(n >= 0 && n < CHUNKS && CurrIdx == CHUNKS);
return (void*)(BasePtr + Offsets[n] + Sizes[n]);
}
template <typename T>
inline void GetSpan(int n, ImSpan<T>* span)
{
span->set((T*)GetSpanPtrBegin(n), (T*)GetSpanPtrEnd(n));
}
};
// Helper: ImPool<>
// Basic keyed storage for contiguous instances, slow/amortized insertion, O(1) indexable, O(Log N) queries by ID over a
// dense/hot buffer, Honor constructor/destructor. Add/remove invalidate all pointers. Indexes have the same lifetime as
// the associated object.
typedef int ImPoolIdx;
template <typename T>
struct IMGUI_API ImPool
{
ImVector<T> Buf; // Contiguous data
ImGuiStorage Map; // ID->Index
ImPoolIdx FreeIdx; // Next free idx to use
ImPoolIdx AliveCount; // Number of active/alive items (for display purpose)
ImPool() { FreeIdx = AliveCount = 0; }
~ImPool() { Clear(); }
T* GetByKey(ImGuiID key)
{
int idx = Map.GetInt(key, -1);
return (idx != -1) ? &Buf[idx] : NULL;
}
T* GetByIndex(ImPoolIdx n) { return &Buf[n]; }
ImPoolIdx GetIndex(const T* p) const
{
IM_ASSERT(p >= Buf.Data && p < Buf.Data + Buf.Size);
return (ImPoolIdx)(p - Buf.Data);
}
T* GetOrAddByKey(ImGuiID key)
{
int* p_idx = Map.GetIntRef(key, -1);
if (*p_idx != -1)
return &Buf[*p_idx];
*p_idx = FreeIdx;
return Add();
}
bool Contains(const T* p) const { return (p >= Buf.Data && p < Buf.Data + Buf.Size); }
void Clear()
{
for (int n = 0; n < Map.Data.Size; n++)
{
int idx = Map.Data[n].val_i;
if (idx != -1)
Buf[idx].~T();
}
Map.Clear();
Buf.clear();
FreeIdx = AliveCount = 0;
}
T* Add()
{
int idx = FreeIdx;
if (idx == Buf.Size)
{
Buf.resize(Buf.Size + 1);
FreeIdx++;
}
else
{
FreeIdx = *(int*)&Buf[idx];
}
IM_PLACEMENT_NEW(&Buf[idx]) T();
AliveCount++;
return &Buf[idx];
}
void Remove(ImGuiID key, const T* p) { Remove(key, GetIndex(p)); }
void Remove(ImGuiID key, ImPoolIdx idx)
{
Buf[idx].~T();
*(int*)&Buf[idx] = FreeIdx;
FreeIdx = idx;
Map.SetInt(key, -1);
AliveCount--;
}
void Reserve(int capacity)
{
Buf.reserve(capacity);
Map.Data.reserve(capacity);
}
// To iterate a ImPool: for (int n = 0; n < pool.GetMapSize(); n++) if (T* t = pool.TryGetMapData(n)) { ... }
// Can be avoided if you know .Remove() has never been called on the pool, or AliveCount == GetMapSize()
int GetAliveCount() const { return AliveCount; } // Number of active/alive items in the pool (for display purpose)
int GetBufSize() const { return Buf.Size; }
int GetMapSize() const
{
return Map.Data.Size;
} // It is the map we need iterate to find valid items, since we don't have "alive" storage anywhere
T* TryGetMapData(ImPoolIdx n)
{
int idx = Map.Data[n].val_i;
if (idx == -1)
return NULL;
return GetByIndex(idx);
}
# ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
int GetSize() { return GetMapSize(); } // For ImPlot: should use GetMapSize() from (IMGUI_VERSION_NUM >= 18304)
# endif
};
// Helper: ImChunkStream<>
// Build and iterate a contiguous stream of variable-sized structures.
// This is used by Settings to store persistent data while reducing allocation count.
// We store the chunk size first, and align the final size on 4 bytes boundaries.
// The tedious/zealous amount of casting is to avoid -Wcast-align warnings.
template <typename T>
struct IMGUI_API ImChunkStream
{
ImVector<char> Buf;
void clear() { Buf.clear(); }
bool empty() const { return Buf.Size == 0; }
int size() const { return Buf.Size; }
T* alloc_chunk(size_t sz)
{
size_t HDR_SZ = 4;
sz = IM_MEMALIGN(HDR_SZ + sz, 4u);
int off = Buf.Size;
Buf.resize(off + (int)sz);
((int*)(void*)(Buf.Data + off))[0] = (int)sz;
return (T*)(void*)(Buf.Data + off + (int)HDR_SZ);
}
T* begin()
{
size_t HDR_SZ = 4;
if (!Buf.Data)
return NULL;
return (T*)(void*)(Buf.Data + HDR_SZ);
}
T* next_chunk(T* p)
{
size_t HDR_SZ = 4;
IM_ASSERT(p >= begin() && p < end());
p = (T*)(void*)((char*)(void*)p + chunk_size(p));
if (p == (T*)(void*)((char*)end() + HDR_SZ))
return (T*)0;
IM_ASSERT(p < end());
return p;
}
int chunk_size(const T* p) { return ((const int*)p)[-1]; }
T* end() { return (T*)(void*)(Buf.Data + Buf.Size); }
int offset_from_ptr(const T* p)
{
IM_ASSERT(p >= begin() && p < end());
const ptrdiff_t off = (const char*)p - Buf.Data;
return (int)off;
}
T* ptr_from_offset(int off)
{
IM_ASSERT(off >= 4 && off < Buf.Size);
return (T*)(void*)(Buf.Data + off);
}
void swap(ImChunkStream<T>& rhs) { rhs.Buf.swap(Buf); }
};
//-----------------------------------------------------------------------------
// [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<ImDrawList*> 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<ImWchar> TextW; // edit buffer, we need to persist but can't guarantee the persistence of the
// user-provided buffer. so we copy into own buffer.
ImVector<char> TextA; // temporary UTF8 buffer for callbacks and other operations. this is not updated in every
// code-path! size=capacity.
ImVector<char> InitialTextA; // backup of end-user buffer at the time of focus (in UTF-8, unaltered)
bool TextAIsValid; // temporary UTF8 buffer is not initially valid before we make the widget active (until then we
// pull the data from user argument)
int BufCapacityA; // end-user buffer capacity
float ScrollX; // horizontal scrolling/offset
ImStb::STB_TexteditState Stb; // state for stb_textedit.h
float CursorAnim; // timer for cursor blink, reset on every user action so the cursor reappears immediately
bool CursorFollow; // set when we want scrolling to follow the current cursor position (not always!)
bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection
bool Edited; // edited this frame
ImGuiInputTextFlags Flags; // copy of InputText() flags
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<ImGuiOldColumnData> Columns;
ImDrawListSplitter Splitter;
ImGuiOldColumns() { memset(this, 0, sizeof(*this)); }
};
//-----------------------------------------------------------------------------
// [SECTION] Multi-select support
//-----------------------------------------------------------------------------
# ifdef IMGUI_HAS_MULTI_SELECT
// <this is filled in 'range_select' branch>
# 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<ImGuiWindow*> Windows; // Note: unordered list! Iterate TabBar->Tabs for user-order.
ImGuiTabBar* TabBar;
ImVec2 Pos; // Current position
ImVec2 Size; // Current size
ImVec2 SizeRef; // [Split node only] Last explicitly written-to size (overridden when using a splitter affecting
// the node), used to calculate Size.
ImGuiAxis SplitAxis; // [Split node only] Split axis (X or Y)
ImGuiWindowClass WindowClass; // [Root node only]
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<ImGuiDockRequest> Requests;
ImVector<ImGuiDockNodeSettings> NodesSettings;
bool WantFullRebuild;
ImGuiDockContext() { memset(this, 0, sizeof(*this)); }
};
# endif // #ifdef IMGUI_HAS_DOCK
//-----------------------------------------------------------------------------
// [SECTION] Viewport support
//-----------------------------------------------------------------------------
// ImGuiViewport Private/Internals fields (cardinal sin: we are using inheritance!)
// Every instance of ImGuiViewport is in fact a ImGuiViewportP.
struct ImGuiViewportP : public ImGuiViewport
{
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<ImGuiWindow*> Windows; // Windows, sorted in display order, back to front
ImVector<ImGuiWindow*> WindowsFocusOrder; // Root windows, sorted in focus order, back to front.
ImVector<ImGuiWindow*> WindowsTempSortBuffer; // Temporary buffer used in EndFrame() to reorder windows so parents
// are kept before their child
ImVector<ImGuiWindowStackData> CurrentWindowStack;
ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow*
int WindowsActiveCount; // Number of unique windows submitted by frame
ImVec2 WindowsHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window
// == ImMax(style.TouchExtraPadding, WINDOWS_HOVER_PADDING)
ImGuiWindow* CurrentWindow; // Window being drawn into
ImGuiWindow* HoveredWindow; // Window the mouse is hovering. Will typically catch mouse inputs.
ImGuiWindow*
HoveredWindowUnderMovingWindow; // Hovered window ignoring MovingWindow. Only set if MovingWindow is set.
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<ImGuiColorMod> ColorStack; // Stack for PushStyleColor()/PopStyleColor() - inherited by Begin()
ImVector<ImGuiStyleMod> StyleVarStack; // Stack for PushStyleVar()/PopStyleVar() - inherited by Begin()
ImVector<ImFont*> FontStack; // Stack for PushFont()/PopFont() - inherited by Begin()
ImVector<ImGuiID>
FocusScopeStack; // Stack for PushFocusScope()/PopFocusScope() - not inherited by Begin(), unless child window
ImVector<ImGuiItemFlags> ItemFlagsStack; // Stack for PushItemFlag()/PopItemFlag() - inherited by Begin()
ImVector<ImGuiGroupData> GroupStack; // Stack for BeginGroup()/EndGroup() - not inherited by Begin()
ImVector<ImGuiPopupData> OpenPopupStack; // Which popups are open (persistent)
ImVector<ImGuiPopupData> BeginPopupStack; // Which level of BeginPopup() we are in (reset every frame)
// Viewports
ImVector<ImGuiViewportP*> Viewports; // Active viewports (always 1+, and generally 1 unless multi-viewports are
// enabled). Each viewports hold their copy of ImDrawData.
float CurrentDpiScale; // == CurrentViewport->DpiScale
ImGuiViewportP* CurrentViewport; // We track changes of viewport (happening in Begin) so we can call
// Platform_OnChangedViewport()
ImGuiViewportP* MouseViewport;
ImGuiViewportP* MouseLastHoveredViewport; // Last known viewport that was hovered by mouse (even if we are not
// hovering any viewport any more) + honoring the _NoInputs flag.
ImGuiID PlatformLastFocusedViewportId;
ImGuiPlatformMonitor
FallbackMonitor; // Virtual monitor used as fallback if backend doesn't provide monitor information.
int 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<unsigned char>
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<ImGuiTable> Tables;
ImVector<ImGuiTableTempData> TablesTempDataStack;
ImVector<float> TablesLastTimeActive; // Last used timestamp of each tables (SOA, for efficient GC)
ImVector<ImDrawChannel> DrawChannelsTempMergeBuffer;
// Tab bars
ImGuiTabBar* CurrentTabBar;
ImPool<ImGuiTabBar> TabBars;
ImVector<ImGuiPtrOrIndex> CurrentTabBarStack;
ImVector<ImGuiShrinkWidthItem> 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<char> ClipboardHandlerData; // If no custom clipboard handler is defined
ImVector<ImGuiID> 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<ImGuiSettingsHandler> SettingsHandlers; // List of .ini settings handlers
ImChunkStream<ImGuiWindowSettings> SettingsWindows; // ImGuiWindow .ini settings entries
ImChunkStream<ImGuiTableSettings> SettingsTables; // ImGuiTable .ini settings entries
ImVector<ImGuiContextHook> 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<ImGuiWindow*> 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<float> ItemWidthStack; // Store item widths to restore (attention: .back() is not == ItemWidth)
ImVector<float> 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<ImGuiID> 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<ImGuiOldColumns> 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<ImGuiTabItem> 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<ImGuiTableColumn> Columns; // Point within RawData[]
ImSpan<ImGuiTableColumnIdx> DisplayOrderToIndex; // Point within RawData[]. Store display order of columns (when
// not reordered, the values are 0...Count-1)
ImSpan<ImGuiTableCellData> 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<ImGuiTableColumnSortSpecs> 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<const char*>* in_window_remap_pairs);
IMGUI_API void DockBuilderCopyNode(ImGuiID src_node_id, ImGuiID dst_node_id, ImVector<ImGuiID>* 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<float, float>(const char* format, ImGuiDataType data_type, float v); "
template <typename T, typename SIGNED_T, typename FLOAT_T>
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 <typename T, typename SIGNED_T, typename FLOAT_T>
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 <typename T, typename SIGNED_T, typename FLOAT_T>
IMGUI_API bool DragBehaviorT(ImGuiDataType data_type,
T* v,
float v_speed,
T v_min,
T v_max,
const char* format,
ImGuiSliderFlags flags);
template <typename T, typename SIGNED_T, typename FLOAT_T>
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 <typename T, typename SIGNED_T>
IMGUI_API T RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v);
template <typename T>
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<ImGuiWindow*>* 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