axmol/extensions/ImGui/imgui/imgui_internal.h

3550 lines
256 KiB
C
Raw Normal View History

2023-08-31 18:14:26 +08:00
// dear imgui, v1.89.3 WIP
2020-09-04 17:19:51 +08:00
// (internal structures/api)
2023-08-31 18:14:26 +08:00
// 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)
2020-09-04 17:19:51 +08:00
/*
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
2022-02-08 12:43:16 +08:00
// [SECTION] Inputs support
// [SECTION] Clipper support
// [SECTION] Navigation support
2020-09-04 17:19:51 +08:00
// [SECTION] Columns support
// [SECTION] Multi-select support
// [SECTION] Docking support
// [SECTION] Viewport support
2021-06-15 22:30:54 +08:00
// [SECTION] Settings support
2023-01-24 17:20:31 +08:00
// [SECTION] Localization support
2022-02-08 12:43:16 +08:00
// [SECTION] Metrics, Debug tools
2021-06-15 22:30:54 +08:00
// [SECTION] Generic context hooks
2020-09-04 17:19:51 +08:00
// [SECTION] ImGuiContext (main imgui context)
// [SECTION] ImGuiWindowTempData, ImGuiWindow
// [SECTION] Tab bar, Tab item support
// [SECTION] Table support
2021-06-15 22:30:54 +08:00
// [SECTION] ImGui internal API
// [SECTION] ImFontAtlas internal API
// [SECTION] Test Engine specific hooks (imgui_test_engine)
2020-09-04 17:19:51 +08:00
*/
#pragma once
#ifndef IMGUI_DISABLE
//-----------------------------------------------------------------------------
// [SECTION] Header mess
//-----------------------------------------------------------------------------
2022-02-08 12:43:16 +08:00
#ifndef IMGUI_VERSION
#include "imgui.h"
#endif
2020-09-04 17:19:51 +08:00
2022-02-08 12:43:16 +08:00
#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
2020-09-04 17:19:51 +08:00
2021-06-15 22:30:54 +08:00
// Enable SSE intrinsics if available
2023-01-24 17:20:31 +08:00
#if (defined __SSE__ || defined __x86_64__ || defined _M_X64 || (defined(_M_IX86_FP) && (_M_IX86_FP >= 1))) && !defined(IMGUI_DISABLE_SSE)
2022-02-08 12:43:16 +08:00
#define IMGUI_ENABLE_SSE
#include <immintrin.h>
#endif
2021-06-15 22:30:54 +08:00
2020-09-04 17:19:51 +08:00
// Visual Studio warnings
2022-02-08 12:43:16 +08:00
#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
2020-09-04 17:19:51 +08:00
// Clang/GCC warnings with -Weverything
2022-02-08 12:43:16 +08:00
#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
#pragma clang diagnostic ignored "-Wmissing-noreturn" // warning: function 'xxx' could be declared with attribute 'noreturn'
#elif defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
#pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
#endif
2021-08-23 17:49:38 +08:00
2020-09-04 17:19:51 +08:00
// Legacy defines
2022-02-08 12:43:16 +08:00
#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
2020-09-04 17:19:51 +08:00
2021-06-15 22:30:54 +08:00
// 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.
2022-02-08 12:43:16 +08:00
#ifndef IMGUI_ENABLE_FREETYPE
#define IMGUI_ENABLE_STB_TRUETYPE
#endif
2021-06-15 22:30:54 +08:00
2020-09-04 17:19:51 +08:00
//-----------------------------------------------------------------------------
// [SECTION] Forward declarations
//-----------------------------------------------------------------------------
2022-02-08 12:43:16 +08:00
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
2023-01-24 17:20:31 +08:00
struct ImGuiLocEntry; // A localization entry.
2022-02-08 12:43:16 +08:00
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 ImGuiTableInstanceData; // Storage for one instance of a same table
2022-02-08 12:43:16 +08:00
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)
2023-01-24 17:20:31 +08:00
// Enumerations
2022-02-08 12:43:16 +08:00
// Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists.
2023-01-24 17:20:31 +08:00
enum ImGuiLocKey : int; // -> enum ImGuiLocKey // Enum: a localization entry for translation.
2022-02-08 12:43:16 +08:00
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
2023-01-24 17:20:31 +08:00
// Flags
2022-02-08 12:43:16 +08:00
typedef int ImGuiActivateFlags; // -> enum ImGuiActivateFlags_ // Flags: for navigation/focus function (will be for ActivateItem() later)
typedef int ImGuiDebugLogFlags; // -> enum ImGuiDebugLogFlags_ // Flags: for ShowDebugLogWindow(), g.DebugLogFlags
2023-01-24 17:20:31 +08:00
typedef int ImGuiInputFlags; // -> enum ImGuiInputFlags_ // Flags: for IsKeyPressed(), IsMouseClicked(), SetKeyOwner(), SetItemKeyOwner() etc.
typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag(), g.LastItemData.InFlags
typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for g.LastItemData.StatusFlags
2022-02-08 12:43:16 +08:00
typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns()
typedef int ImGuiNavHighlightFlags; // -> enum ImGuiNavHighlightFlags_ // Flags: for RenderNavHighlight()
typedef int ImGuiNavMoveFlags; // -> enum ImGuiNavMoveFlags_ // Flags: for navigation requests
typedef int ImGuiNextItemDataFlags; // -> enum ImGuiNextItemDataFlags_ // Flags: for SetNextItemXXX() functions
typedef int ImGuiNextWindowDataFlags; // -> enum ImGuiNextWindowDataFlags_// Flags: for SetNextWindowXXX() functions
typedef int ImGuiScrollFlags; // -> enum ImGuiScrollFlags_ // Flags: for ScrollToItem() and navigation requests
typedef int ImGuiSeparatorFlags; // -> enum ImGuiSeparatorFlags_ // Flags: for SeparatorEx()
typedef int ImGuiTextFlags; // -> enum ImGuiTextFlags_ // Flags: for TextEx()
typedef int ImGuiTooltipFlags; // -> enum ImGuiTooltipFlags_ // Flags: for BeginTooltipEx()
2020-09-04 17:19:51 +08:00
2021-06-15 22:30:54 +08:00
typedef void (*ImGuiErrorLogCallback)(void* user_data, const char* fmt, ...);
2020-09-04 17:19:51 +08:00
//-----------------------------------------------------------------------------
// [SECTION] Context pointer
// See implementation of this variable in imgui.cpp for comments and details.
//-----------------------------------------------------------------------------
2022-02-08 12:43:16 +08:00
#ifndef GImGui
2020-09-04 17:19:51 +08:00
extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
2022-02-08 12:43:16 +08:00
#endif
2020-09-04 17:19:51 +08:00
//-------------------------------------------------------------------------
// [SECTION] STB libraries includes
//-------------------------------------------------------------------------
namespace ImStb
{
2022-02-08 12:43:16 +08:00
#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"
2020-09-04 17:19:51 +08:00
2022-02-08 12:43:16 +08:00
} // namespace ImStb
2020-09-04 17:19:51 +08:00
//-----------------------------------------------------------------------------
// [SECTION] Macros
//-----------------------------------------------------------------------------
// Internal Drag and Drop payload types. String starting with '_' are reserved for Dear ImGui.
2022-02-08 12:43:16 +08:00
#define IMGUI_PAYLOAD_TYPE_WINDOW "_IMWINDOW" // Payload == ImGuiWindow*
2020-09-04 17:19:51 +08:00
// Debug Printing Into TTY
// (since IMGUI_VERSION_NUM >= 18729: IMGUI_DEBUG_LOG was reworked into IMGUI_DEBUG_PRINTF (and removed framecount from it). If you were using a #define IMGUI_DEBUG_LOG please rename)
#ifndef IMGUI_DEBUG_PRINTF
#ifndef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS
#define IMGUI_DEBUG_PRINTF(_FMT,...) printf(_FMT, __VA_ARGS__)
#else
2023-01-24 17:20:31 +08:00
#define IMGUI_DEBUG_PRINTF(_FMT,...) ((void)0)
#endif
2022-02-08 12:43:16 +08:00
#endif
2020-09-04 17:19:51 +08:00
// Debug Logging for ShowDebugLogWindow(). This is designed for relatively rare events so please don't spam.
2023-01-24 17:20:31 +08:00
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
#define IMGUI_DEBUG_LOG(...) ImGui::DebugLog(__VA_ARGS__)
#else
#define IMGUI_DEBUG_LOG(...) ((void)0)
#endif
#define IMGUI_DEBUG_LOG_ACTIVEID(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventActiveId) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
#define IMGUI_DEBUG_LOG_FOCUS(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventFocus) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
#define IMGUI_DEBUG_LOG_POPUP(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventPopup) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
#define IMGUI_DEBUG_LOG_NAV(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventNav) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
2023-01-24 17:20:31 +08:00
#define IMGUI_DEBUG_LOG_CLIPPER(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventClipper) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
#define IMGUI_DEBUG_LOG_IO(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventIO) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
#define IMGUI_DEBUG_LOG_DOCKING(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventDocking) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
#define IMGUI_DEBUG_LOG_VIEWPORT(...) do { if (g.DebugLogFlags & ImGuiDebugLogFlags_EventViewport) IMGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
2020-09-04 17:19:51 +08:00
// Static Asserts
2022-02-08 12:43:16 +08:00
#define IM_STATIC_ASSERT(_COND) static_assert(_COND, "")
// "Paranoid" Debug Asserts are meant to only be enabled during specific debugging/work, otherwise would slow down the code too much.
// We currently don't have many of those so the effect is currently negligible, but onward intent to add more aggressive ones in the code.
2020-09-04 17:19:51 +08:00
//#define IMGUI_DEBUG_PARANOID
2022-02-08 12:43:16 +08:00
#ifdef IMGUI_DEBUG_PARANOID
#define IM_ASSERT_PARANOID(_EXPR) IM_ASSERT(_EXPR)
#else
#define IM_ASSERT_PARANOID(_EXPR)
#endif
2020-09-04 17:19:51 +08:00
// Error handling
2022-02-08 12:43:16 +08:00
// 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
2020-09-04 17:19:51 +08:00
// Misc Macros
2022-02-08 12:43:16 +08:00
#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
2023-01-24 17:20:31 +08:00
#ifndef IM_TABSIZE // Until we move this to runtime and/or add proper tab support, at least allow users to compile-time override
2022-02-08 12:43:16 +08:00
#define IM_TABSIZE (4)
2023-01-24 17:20:31 +08:00
#endif
#define IM_MEMALIGN(_OFF,_ALIGN) (((_OFF) + ((_ALIGN) - 1)) & ~((_ALIGN) - 1)) // Memory align e.g. IM_ALIGN(0,4)=0, IM_ALIGN(1,4)=4, IM_ALIGN(4,4)=4, IM_ALIGN(5,4)=8
2022-02-08 12:43:16 +08:00
#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
2020-09-04 17:19:51 +08:00
2021-06-15 22:30:54 +08:00
// Warnings
2022-02-08 12:43:16 +08:00
#if defined(_MSC_VER) && !defined(__clang__)
#define IM_MSVC_WARNING_SUPPRESS(XXXX) __pragma(warning(suppress: XXXX))
#else
#define IM_MSVC_WARNING_SUPPRESS(XXXX)
#endif
2021-06-15 22:30:54 +08:00
2020-09-04 17:19:51 +08:00
// Debug Tools
2022-02-08 12:43:16 +08:00
// Use 'Metrics/Debugger->Tools->Item Picker' to break into the call-stack of a specific item.
// This will call IM_DEBUG_BREAK() which you may redefine yourself. See https://github.com/scottt/debugbreak for more reference.
#ifndef IM_DEBUG_BREAK
#if defined (_MSC_VER)
#define IM_DEBUG_BREAK() __debugbreak()
#elif defined(__clang__)
#define IM_DEBUG_BREAK() __builtin_debugtrap()
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
#define IM_DEBUG_BREAK() __asm__ volatile("int $0x03")
#elif defined(__GNUC__) && defined(__thumb__)
#define IM_DEBUG_BREAK() __asm__ volatile(".inst 0xde01")
#elif defined(__GNUC__) && defined(__arm__) && !defined(__thumb__)
#define IM_DEBUG_BREAK() __asm__ volatile(".inst 0xe7f001f0");
#else
#define IM_DEBUG_BREAK() IM_ASSERT(0) // It is expected that you define IM_DEBUG_BREAK() into something that will break nicely in a debugger!
#endif
#endif // #ifndef IM_DEBUG_BREAK
2020-09-04 17:19:51 +08:00
//-----------------------------------------------------------------------------
// [SECTION] Generic helpers
// Note that the ImXXX helpers functions are lower-level than ImGui functions.
// ImGui functions or the ImGui context are never called/used from other ImXXX functions.
//-----------------------------------------------------------------------------
// - Helpers: Hashing
// - Helpers: Sorting
// - Helpers: Bit manipulation
// - Helpers: String
// - Helpers: Formatting
2020-09-04 17:19:51 +08:00
// - Helpers: UTF-8 <> wchar conversions
// - Helpers: ImVec2/ImVec4 operators
// - Helpers: Maths
// - Helpers: Geometry
// - Helper: ImVec1
// - Helper: ImVec2ih
// - Helper: ImRect
// - Helper: ImBitArray
// - Helper: ImBitVector
2021-06-15 22:30:54 +08:00
// - Helper: ImSpan<>, ImSpanAllocator<>
2020-09-04 17:19:51 +08:00
// - Helper: ImPool<>
// - Helper: ImChunkStream<>
2023-01-24 17:20:31 +08:00
// - Helper: ImGuiTextIndex
2020-09-04 17:19:51 +08:00
//-----------------------------------------------------------------------------
// Helpers: Hashing
2023-08-31 18:14:26 +08:00
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);
2020-09-04 17:19:51 +08:00
// Helpers: Sorting
2022-02-08 12:43:16 +08:00
#ifndef ImQsort
static inline void ImQsort(void* base, size_t count, size_t size_of_element, int(IMGUI_CDECL *compare_func)(void const*, void const*)) { if (count > 1) qsort(base, count, size_of_element, compare_func); }
#endif
2020-09-04 17:19:51 +08:00
// Helpers: Color Blending
2022-02-08 12:43:16 +08:00
IMGUI_API ImU32 ImAlphaBlendColors(ImU32 col_a, ImU32 col_b);
2020-09-04 17:19:51 +08:00
// Helpers: Bit manipulation
2022-02-08 12:43:16 +08:00
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; }
2020-09-04 17:19:51 +08:00
// Helpers: String
2022-02-08 12:43:16 +08:00
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);
2023-01-24 17:20:31 +08:00
IM_MSVC_RUNTIME_CHECKS_OFF
static inline char ImToUpper(char c) { return (c >= 'a' && c <= 'z') ? c &= ~32 : c; }
static inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; }
static inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; }
2023-01-24 17:20:31 +08:00
IM_MSVC_RUNTIME_CHECKS_RESTORE
// Helpers: Formatting
2022-02-08 12:43:16 +08:00
IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) IM_FMTARGS(3);
IMGUI_API int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) IM_FMTLIST(3);
IMGUI_API void ImFormatStringToTempBuffer(const char** out_buf, const char** out_buf_end, const char* fmt, ...) IM_FMTARGS(3);
IMGUI_API void ImFormatStringToTempBufferV(const char** out_buf, const char** out_buf_end, const char* fmt, va_list args) IM_FMTLIST(3);
2022-02-08 12:43:16 +08:00
IMGUI_API const char* ImParseFormatFindStart(const char* format);
IMGUI_API const char* ImParseFormatFindEnd(const char* format);
IMGUI_API const char* ImParseFormatTrimDecorations(const char* format, char* buf, size_t buf_size);
IMGUI_API void ImParseFormatSanitizeForPrinting(const char* fmt_in, char* fmt_out, size_t fmt_out_size);
IMGUI_API const char* ImParseFormatSanitizeForScanning(const char* fmt_in, char* fmt_out, size_t fmt_out_size);
2022-02-08 12:43:16 +08:00
IMGUI_API int ImParseFormatPrecision(const char* format, int default_value);
2020-09-04 17:19:51 +08:00
// Helpers: UTF-8 <> wchar conversions
2022-02-08 12:43:16 +08:00
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
2020-09-04 17:19:51 +08:00
2023-08-31 18:14:26 +08:00
// 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
2020-09-04 17:19:51 +08:00
// Helpers: File System
2022-02-08 12:43:16 +08:00
#ifdef IMGUI_DISABLE_FILE_FUNCTIONS
#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS
2020-09-04 17:19:51 +08:00
typedef void* ImFileHandle;
2022-02-08 12:43:16 +08:00
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
2020-09-04 17:19:51 +08:00
typedef FILE* ImFileHandle;
2022-02-08 12:43:16 +08:00
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);
2020-09-04 17:19:51 +08:00
// Helpers: Maths
2021-06-15 22:30:54 +08:00
IM_MSVC_RUNTIME_CHECKS_OFF
2020-09-04 17:19:51 +08:00
// - Wrapper for standard libs functions. (Note that imgui_demo.cpp does _not_ use them to keep the code easy to copy)
2022-02-08 12:43:16 +08:00
#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)
2021-06-15 22:30:54 +08:00
//#define ImFloorStd(X) floorf(X) // We use our own, see ImFloor() and ImFloorSigned()
2022-02-08 12:43:16 +08:00
#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; }
2020-09-04 17:19:51 +08:00
// - Misc maths helpers
2022-02-08 12:43:16 +08:00
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 || (float)(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 ImVec2 ImFloorSigned(const ImVec2& v) { return ImVec2(ImFloorSigned(v.x), ImFloorSigned(v.y)); }
static inline int ImModPositive(int a, int b) { return (a + b) % b; }
static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }
static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; }
static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
static inline bool ImIsFloatAboveGuaranteedIntegerPrecision(float f) { return f <= -16777216 || f >= 16777216; }
2023-01-24 17:20:31 +08:00
static inline float ImExponentialMovingAverage(float avg, float sample, int n) { avg -= avg / n; avg += sample / n; return avg; }
2021-06-15 22:30:54 +08:00
IM_MSVC_RUNTIME_CHECKS_RESTORE
2020-09-04 17:19:51 +08:00
// Helpers: Geometry
2022-02-08 12:43:16 +08:00
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; }
2023-08-31 18:14:26 +08:00
IMGUI_API ImGuiDir ImGetDirQuadrantFromDelta(float dx, float dy);
2020-09-04 17:19:51 +08:00
// Helper: ImVec1 (1D vector)
2022-02-08 12:43:16 +08:00
// (this odd construct is used to facilitate the transition between 1D and 2D, and the maintenance of some branches/patches)
2021-06-15 22:30:54 +08:00
IM_MSVC_RUNTIME_CHECKS_OFF
2020-09-04 17:19:51 +08:00
struct ImVec1
{
2022-02-08 12:43:16 +08:00
float x;
constexpr ImVec1() : x(0.0f) { }
constexpr ImVec1(float _x) : x(_x) { }
2020-09-04 17:19:51 +08:00
};
// Helper: ImVec2ih (2D vector, half-size integer, for long-term packed storage)
struct ImVec2ih
{
2022-02-08 12:43:16 +08:00
short x, y;
constexpr ImVec2ih() : x(0), y(0) {}
constexpr ImVec2ih(short _x, short _y) : x(_x), y(_y) {}
constexpr explicit ImVec2ih(const ImVec2& rhs) : x((short)rhs.x), y((short)rhs.y) {}
2020-09-04 17:19:51 +08:00
};
// Helper: ImRect (2D axis aligned bounding-box)
// NB: we can't rely on ImVec2 math operators being available here!
struct IMGUI_API ImRect
{
2022-02-08 12:43:16 +08:00
ImVec2 Min; // Upper-left
ImVec2 Max; // Lower-right
constexpr ImRect() : Min(0.0f, 0.0f), Max(0.0f, 0.0f) {}
constexpr ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {}
constexpr ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {}
constexpr ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {}
2022-02-08 12:43:16 +08:00
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); }
2020-09-04 17:19:51 +08:00
};
// Helper: ImBitArray
2023-01-24 17:20:31 +08:00
#define IM_BITARRAY_TESTBIT(_ARRAY, _N) ((_ARRAY[(_N) >> 5] & ((ImU32)1 << ((_N) & 31))) != 0) // Macro version of ImBitArrayTestBit(): ensure args have side-effect or are costly!
#define IM_BITARRAY_CLEARBIT(_ARRAY, _N) ((_ARRAY[(_N) >> 5] &= ~((ImU32)1 << ((_N) & 31)))) // Macro version of ImBitArrayClearBit(): ensure args have side-effect or are costly!
inline size_t ImBitArrayGetStorageSizeInBytes(int bitcount) { return (size_t)((bitcount + 31) >> 5) << 2; }
inline void ImBitArrayClearAllBits(ImU32* arr, int bitcount){ memset(arr, 0, ImBitArrayGetStorageSizeInBytes(bitcount)); }
2022-02-08 12:43:16 +08:00
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)
2020-09-04 17:19:51 +08:00
{
2021-06-15 22:30:54 +08:00
n2--;
2020-09-04 17:19:51 +08:00
while (n <= n2)
{
2022-02-08 12:43:16 +08:00
int a_mod = (n & 31);
int b_mod = (n2 > (n | 31) ? 31 : (n2 & 31)) + 1;
2020-09-04 17:19:51 +08:00
ImU32 mask = (ImU32)(((ImU64)1 << b_mod) - 1) & ~(ImU32)(((ImU64)1 << a_mod) - 1);
arr[n >> 5] |= mask;
n = (n + 32) & ~31;
}
}
2023-01-24 17:20:31 +08:00
typedef ImU32* ImBitArrayPtr; // Name for use in structs
2021-06-15 22:30:54 +08:00
// Helper: ImBitArray class (wrapper over ImBitArray functions)
// Store 1-bit per value.
2022-02-08 12:43:16 +08:00
template<int BITCOUNT, int OFFSET = 0>
struct ImBitArray
2021-06-15 22:30:54 +08:00
{
2022-02-08 12:43:16 +08:00
ImU32 Storage[(BITCOUNT + 31) >> 5];
ImBitArray() { ClearAllBits(); }
void ClearAllBits() { memset(Storage, 0, sizeof(Storage)); }
void SetAllBits() { memset(Storage, 255, sizeof(Storage)); }
2023-01-24 17:20:31 +08:00
bool TestBit(int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return IM_BITARRAY_TESTBIT(Storage, n); }
void SetBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArraySetBit(Storage, n); }
void ClearBit(int n) { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); ImBitArrayClearBit(Storage, n); }
void SetBitRange(int n, int n2) { n += OFFSET; n2 += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT && n2 > n && n2 <= BITCOUNT); ImBitArraySetBitRange(Storage, n, n2); } // Works on range [n..n2)
2023-01-24 17:20:31 +08:00
bool operator[](int n) const { n += OFFSET; IM_ASSERT(n >= 0 && n < BITCOUNT); return IM_BITARRAY_TESTBIT(Storage, n); }
2021-06-15 22:30:54 +08:00
};
2020-09-04 17:19:51 +08:00
// Helper: ImBitVector
// Store 1-bit per value.
struct IMGUI_API ImBitVector
{
ImVector<ImU32> Storage;
2022-02-08 12:43:16 +08:00
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(); }
2023-01-24 17:20:31 +08:00
bool TestBit(int n) const { IM_ASSERT(n < (Storage.Size << 5)); return IM_BITARRAY_TESTBIT(Storage.Data, n); }
2022-02-08 12:43:16 +08:00
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); }
2020-09-04 17:19:51 +08:00
};
2023-01-24 17:20:31 +08:00
IM_MSVC_RUNTIME_CHECKS_RESTORE
2020-09-04 17:19:51 +08:00
2021-06-15 22:30:54 +08:00
// Helper: ImSpan<>
// Pointing to a span of data we don't own.
2022-02-08 12:43:16 +08:00
template<typename T>
2021-06-15 22:30:54 +08:00
struct ImSpan
{
2022-02-08 12:43:16 +08:00
T* Data;
T* DataEnd;
2021-06-15 22:30:54 +08:00
// Constructors, destructor
2022-02-08 12:43:16 +08:00
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; }
2021-06-15 22:30:54 +08:00
// Utilities
2022-02-08 12:43:16 +08:00
inline int index_from_ptr(const T* it) const { IM_ASSERT(it >= Data && it < DataEnd); const ptrdiff_t off = it - Data; return (int)off; }
2021-06-15 22:30:54 +08:00
};
// Helper: ImSpanAllocator<>
// Facilitate storing multiple chunks into a single large block (the "arena")
2022-02-08 12:43:16 +08:00
// - Usage: call Reserve() N times, allocate GetArenaSizeInBytes() worth, pass it to SetArenaBasePtr(), call GetSpan() N times to retrieve the aligned ranges.
template<int CHUNKS>
2021-06-15 22:30:54 +08:00
struct ImSpanAllocator
{
2022-02-08 12:43:16 +08:00
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)); }
2021-06-15 22:30:54 +08:00
};
2020-09-04 17:19:51 +08:00
// Helper: ImPool<>
2022-02-08 12:43:16 +08:00
// 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.
2020-09-04 17:19:51 +08:00
typedef int ImPoolIdx;
2022-02-08 12:43:16 +08:00
template<typename T>
struct ImPool
{
ImVector<T> Buf; // Contiguous data
ImGuiStorage Map; // ID->Index
ImPoolIdx FreeIdx; // Next free idx to use
ImPoolIdx AliveCount; // Number of active/alive items (for display purpose)
ImPool() { FreeIdx = AliveCount = 0; }
~ImPool() { Clear(); }
T* GetByKey(ImGuiID key) { int idx = Map.GetInt(key, -1); return (idx != -1) ? &Buf[idx] : NULL; }
T* GetByIndex(ImPoolIdx n) { return &Buf[n]; }
ImPoolIdx GetIndex(const T* p) const { IM_ASSERT(p >= Buf.Data && p < Buf.Data + Buf.Size); return (ImPoolIdx)(p - Buf.Data); }
T* GetOrAddByKey(ImGuiID key) { int* p_idx = Map.GetIntRef(key, -1); if (*p_idx != -1) return &Buf[*p_idx]; *p_idx = FreeIdx; return Add(); }
bool Contains(const T* p) const { return (p >= Buf.Data && p < Buf.Data + Buf.Size); }
void Clear() { for (int n = 0; n < Map.Data.Size; n++) { int idx = Map.Data[n].val_i; if (idx != -1) Buf[idx].~T(); } Map.Clear(); Buf.clear(); FreeIdx = AliveCount = 0; }
T* Add() { int idx = FreeIdx; if (idx == Buf.Size) { Buf.resize(Buf.Size + 1); FreeIdx++; } else { FreeIdx = *(int*)&Buf[idx]; } IM_PLACEMENT_NEW(&Buf[idx]) T(); AliveCount++; return &Buf[idx]; }
void Remove(ImGuiID key, const T* p) { Remove(key, GetIndex(p)); }
void Remove(ImGuiID key, ImPoolIdx idx) { Buf[idx].~T(); *(int*)&Buf[idx] = FreeIdx; FreeIdx = idx; Map.SetInt(key, -1); AliveCount--; }
void Reserve(int capacity) { Buf.reserve(capacity); Map.Data.reserve(capacity); }
2021-06-15 22:30:54 +08:00
// 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()
2022-02-08 12:43:16 +08:00
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
2020-09-04 17:19:51 +08:00
};
// 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.
2021-06-15 22:30:54 +08:00
// We store the chunk size first, and align the final size on 4 bytes boundaries.
2020-09-04 17:19:51 +08:00
// The tedious/zealous amount of casting is to avoid -Wcast-align warnings.
2022-02-08 12:43:16 +08:00
template<typename T>
struct ImChunkStream
2020-09-04 17:19:51 +08:00
{
2022-02-08 12:43:16 +08:00
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); }
2021-06-15 22:30:54 +08:00
2020-09-04 17:19:51 +08:00
};
2023-01-24 17:20:31 +08:00
// Helper: ImGuiTextIndex<>
// Maintain a line index for a text buffer. This is a strong candidate to be moved into the public API.
struct ImGuiTextIndex
{
ImVector<int> LineOffsets;
int EndOffset = 0; // Because we don't own text buffer we need to maintain EndOffset (may bake in LineOffsets?)
void clear() { LineOffsets.clear(); EndOffset = 0; }
int size() { return LineOffsets.Size; }
const char* get_line_begin(const char* base, int n) { return base + LineOffsets[n]; }
const char* get_line_end(const char* base, int n) { return base + (n + 1 < LineOffsets.Size ? (LineOffsets[n + 1] - 1) : EndOffset); }
void append(const char* base, int old_size, int new_size);
};
2020-09-04 17:19:51 +08:00
//-----------------------------------------------------------------------------
// [SECTION] ImDrawList support
//-----------------------------------------------------------------------------
// ImDrawList: Helper function to calculate a circle's segment count given its radius and a "maximum error" value.
2022-02-08 12:43:16 +08:00
// 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:
2021-06-15 22:30:54 +08:00
// 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.)
2022-02-08 12:43:16 +08:00
#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)
2020-09-04 17:19:51 +08:00
2021-06-15 22:30:54 +08:00
// Raw equation from IM_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC rewritten for 'r' and 'error'.
2022-02-08 12:43:16 +08:00
#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))
2021-06-15 22:30:54 +08:00
// ImDrawList: Lookup table size for adaptive arc drawing, cover full circle.
2022-02-08 12:43:16 +08:00
#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.
2020-09-04 17:19:51 +08:00
// Data shared between all ImDrawList instances
2022-02-08 12:43:16 +08:00
// 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.
2020-09-04 17:19:51 +08:00
struct IMGUI_API ImDrawListSharedData
{
2022-02-08 12:43:16 +08:00
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)
2020-09-04 17:19:51 +08:00
2023-01-24 17:20:31 +08:00
// [Internal] Temp write buffer
ImVector<ImVec2> TempBuffer;
2020-09-04 17:19:51 +08:00
// [Internal] Lookup tables
2022-02-08 12:43:16 +08:00
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
2020-09-04 17:19:51 +08:00
ImDrawListSharedData();
2021-06-15 22:30:54 +08:00
void SetCircleTessellationMaxError(float max_error);
2020-09-04 17:19:51 +08:00
};
struct ImDrawDataBuilder
{
2023-08-31 18:14:26 +08:00
ImVector<ImDrawList*> Layers[2]; // Global layers for: regular, tooltip
2020-09-04 17:19:51 +08:00
2023-08-31 18:14:26 +08:00
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();
2020-09-04 17:19:51 +08:00
};
//-----------------------------------------------------------------------------
// [SECTION] Widgets support: flags, enums, data structures
//-----------------------------------------------------------------------------
2023-01-24 17:20:31 +08:00
// Flags used by upcoming items
// - input: PushItemFlag() manipulates g.CurrentItemFlags, ItemAdd() calls may add extra flags.
// - output: stored in g.LastItemData.InFlags
// Current window shared by all windows.
2022-02-08 12:43:16 +08:00
// This is going to be exposed in imgui.h when stabilized enough.
2020-09-04 17:19:51 +08:00
enum ImGuiItemFlags_
{
2023-01-24 17:20:31 +08:00
// Controlled by user
2022-02-08 12:43:16 +08:00
ImGuiItemFlags_None = 0,
2023-08-31 18:14:26 +08:00
ImGuiItemFlags_NoTabStop = 1 << 0, // false // Disable keyboard tabbing (FIXME: should merge with _NoNav)
2022-02-08 12:43:16 +08:00
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
2023-08-31 18:14:26 +08:00
ImGuiItemFlags_NoNav = 1 << 3, // false // Disable keyboard/gamepad directional navigation (FIXME: should merge with _NoTabStop)
2022-02-08 12:43:16 +08:00
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.
2023-01-24 17:20:31 +08:00
ImGuiItemFlags_NoWindowHoverableCheck = 1 << 8, // false // Disable hoverable check in ItemHoverable()
// Controlled by widget code
ImGuiItemFlags_Inputable = 1 << 10, // false // [WIP] Auto-activate input mode when tab focused. Currently only used and supported by a few items before it becomes a generic feature.
2020-09-04 17:19:51 +08:00
};
2023-01-24 17:20:31 +08:00
// Status flags for an already submitted item
// - output: stored in g.LastItemData.StatusFlags
2020-09-04 17:19:51 +08:00
enum ImGuiItemStatusFlags_
{
2022-02-08 12:43:16 +08:00
ImGuiItemStatusFlags_None = 0,
ImGuiItemStatusFlags_HoveredRect = 1 << 0, // Mouse position is within item rectangle (does NOT mean that the window is in correct z-order and can be hovered!, this is only one part of the most-common IsItemHovered test)
ImGuiItemStatusFlags_HasDisplayRect = 1 << 1, // g.LastItemData.DisplayRect is valid
ImGuiItemStatusFlags_Edited = 1 << 2, // Value exposed by item was edited in the current frame (should match the bool return value of most widgets)
ImGuiItemStatusFlags_ToggledSelection = 1 << 3, // Set when Selectable(), TreeNode() reports toggling a selection. We can't report "Selected", only state changes, in order to easily handle clipping with less issues.
ImGuiItemStatusFlags_ToggledOpen = 1 << 4, // Set when TreeNode() reports toggling their open state.
ImGuiItemStatusFlags_HasDeactivated = 1 << 5, // Set if the widget/group is able to provide data for the ImGuiItemStatusFlags_Deactivated flag.
ImGuiItemStatusFlags_Deactivated = 1 << 6, // Only valid if ImGuiItemStatusFlags_HasDeactivated is set.
ImGuiItemStatusFlags_HoveredWindow = 1 << 7, // Override the HoveredWindow test to allow cross-window hover testing.
2023-01-24 17:20:31 +08:00
ImGuiItemStatusFlags_FocusedByTabbing = 1 << 8, // Set when the Focusable item just got focused by Tabbing (FIXME: to be removed soon)
ImGuiItemStatusFlags_Visible = 1 << 9, // [WIP] Set when item is overlapping the current clipping rectangle (Used internally. Please don't use yet: API/system will change as we refactor Itemadd()).
2022-02-08 12:43:16 +08:00
#ifdef IMGUI_ENABLE_TEST_ENGINE
ImGuiItemStatusFlags_Openable = 1 << 20, // Item is an openable (e.g. TreeNode)
2023-08-31 18:14:26 +08:00
ImGuiItemStatusFlags_Opened = 1 << 21, //
ImGuiItemStatusFlags_Checkable = 1 << 22, // Item is a checkable (e.g. CheckBox, MenuItem)
2023-08-31 18:14:26 +08:00
ImGuiItemStatusFlags_Checked = 1 << 23, //
2022-02-08 12:43:16 +08:00
#endif
2020-09-04 17:19:51 +08:00
};
2021-06-15 22:30:54 +08:00
// Extend ImGuiInputTextFlags_
enum ImGuiInputTextFlagsPrivate_
{
// [Internal]
2022-02-08 12:43:16 +08:00
ImGuiInputTextFlags_Multiline = 1 << 26, // For internal use by InputTextMultiline()
ImGuiInputTextFlags_NoMarkEdited = 1 << 27, // For internal use by functions using InputText() before reformatting data
2023-01-24 17:20:31 +08:00
ImGuiInputTextFlags_MergedItem = 1 << 28, // For internal use by TempInputText(), will skip calling ItemAdd(). Require bounding-box to strictly match.
2021-06-15 22:30:54 +08:00
};
2020-09-04 17:19:51 +08:00
// Extend ImGuiButtonFlags_
enum ImGuiButtonFlagsPrivate_
{
2022-02-08 12:43:16 +08:00
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
2023-08-31 18:14:26 +08:00
ImGuiButtonFlags_AllowItemOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable, use along with SetItemAllowOverlap()
2022-02-08 12:43:16 +08:00
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)
2023-01-24 17:20:31 +08:00
ImGuiButtonFlags_NoNavFocus = 1 << 18, // don't override navigation focus when activated (FIXME: this is essentially used everytime an item uses ImGuiItemFlags_NoNav, but because legacy specs don't requires LastItemData to be set ButtonBehavior(), we can't poll g.LastItemData.InFlags)
2022-02-08 12:43:16 +08:00
ImGuiButtonFlags_NoHoveredOnFocus = 1 << 19, // don't report as hovered when nav focus is on this item
2023-01-24 17:20:31 +08:00
ImGuiButtonFlags_NoSetKeyOwner = 1 << 20, // don't set key/input owner on the initial click (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!)
ImGuiButtonFlags_NoTestKeyOwner = 1 << 21, // don't test key/input owner when polling the key (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!)
2022-02-08 12:43:16 +08:00
ImGuiButtonFlags_PressedOnMask_ = ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClickReleaseAnywhere | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick | ImGuiButtonFlags_PressedOnDragDropHold,
2023-01-24 17:20:31 +08:00
ImGuiButtonFlags_PressedOnDefault_ = ImGuiButtonFlags_PressedOnClickRelease,
2020-09-04 17:19:51 +08:00
};
2021-08-23 17:49:38 +08:00
// Extend ImGuiComboFlags_
enum ImGuiComboFlagsPrivate_
{
2023-01-24 17:20:31 +08:00
ImGuiComboFlags_CustomPreview = 1 << 20, // enable BeginComboPreview()
2021-08-23 17:49:38 +08:00
};
2020-09-04 17:19:51 +08:00
// Extend ImGuiSliderFlags_
enum ImGuiSliderFlagsPrivate_
{
2022-02-08 12:43:16 +08:00
ImGuiSliderFlags_Vertical = 1 << 20, // Should this slider be orientated vertically?
2023-01-24 17:20:31 +08:00
ImGuiSliderFlags_ReadOnly = 1 << 21,
2020-09-04 17:19:51 +08:00
};
// Extend ImGuiSelectableFlags_
enum ImGuiSelectableFlagsPrivate_
{
// NB: need to be in sync with last value of ImGuiSelectableFlags_
2022-02-08 12:43:16 +08:00
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)
2023-01-24 17:20:31 +08:00
ImGuiSelectableFlags_SetNavIdOnHover = 1 << 25, // Set Nav/Focus ID on mouse hover (used by MenuItem)
ImGuiSelectableFlags_NoPadWithHalfSpacing = 1 << 26, // Disable padding each side with ItemSpacing * 0.5f
ImGuiSelectableFlags_NoSetKeyOwner = 1 << 27, // Don't set key/input owner on the initial click (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!)
2020-09-04 17:19:51 +08:00
};
// Extend ImGuiTreeNodeFlags_
enum ImGuiTreeNodeFlagsPrivate_
{
2023-01-24 17:20:31 +08:00
ImGuiTreeNodeFlags_ClipLabelForTrailingButton = 1 << 20,
2020-09-04 17:19:51 +08:00
};
enum ImGuiSeparatorFlags_
{
2023-01-24 17:20:31 +08:00
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,
2023-08-31 18:14:26 +08:00
ImGuiSeparatorFlags_SpanAllColumns = 1 << 2,
2020-09-04 17:19:51 +08:00
};
enum ImGuiTextFlags_
{
2023-01-24 17:20:31 +08:00
ImGuiTextFlags_None = 0,
ImGuiTextFlags_NoWidthForLargeClippedText = 1 << 0,
2020-09-04 17:19:51 +08:00
};
enum ImGuiTooltipFlags_
{
2023-01-24 17:20:31 +08:00
ImGuiTooltipFlags_None = 0,
2023-08-31 18:14:26 +08:00
ImGuiTooltipFlags_OverridePreviousTooltip = 1 << 0, // Override will clear/ignore previously submitted tooltip (defaults to append)
2020-09-04 17:19:51 +08:00
};
// 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,
2022-02-08 12:43:16 +08:00
ImGuiLayoutType_Vertical = 1
2020-09-04 17:19:51 +08:00
};
enum ImGuiLogType
{
ImGuiLogType_None = 0,
ImGuiLogType_TTY,
ImGuiLogType_File,
2022-02-08 12:43:16 +08:00
ImGuiLogType_Buffer,
2023-01-24 17:20:31 +08:00
ImGuiLogType_Clipboard,
2020-09-04 17:19:51 +08:00
};
2022-02-08 12:43:16 +08:00
// X/Y enums are fixed to 0/1 so they may be used to index ImVec2
enum ImGuiAxis
2020-09-04 17:19:51 +08:00
{
2022-02-08 12:43:16 +08:00
ImGuiAxis_None = -1,
ImGuiAxis_X = 0,
ImGuiAxis_Y = 1
2020-09-04 17:19:51 +08:00
};
2022-02-08 12:43:16 +08:00
enum ImGuiPlotType
2020-09-04 17:19:51 +08:00
{
2022-02-08 12:43:16 +08:00
ImGuiPlotType_Lines,
2023-01-24 17:20:31 +08:00
ImGuiPlotType_Histogram,
2020-09-04 17:19:51 +08:00
};
enum ImGuiPopupPositionPolicy
{
ImGuiPopupPositionPolicy_Default,
2021-06-15 22:30:54 +08:00
ImGuiPopupPositionPolicy_ComboBox,
2023-01-24 17:20:31 +08:00
ImGuiPopupPositionPolicy_Tooltip,
2020-09-04 17:19:51 +08:00
};
struct ImGuiDataTypeTempStorage
{
2022-02-08 12:43:16 +08:00
ImU8 Data[8]; // Can fit any data up to ImGuiDataType_COUNT
2020-09-04 17:19:51 +08:00
};
// Type information associated to one ImGuiDataType. Retrieve with DataTypeGetInfo().
struct ImGuiDataTypeInfo
{
2022-02-08 12:43:16 +08:00
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
2020-09-04 17:19:51 +08:00
};
// Extend ImGuiDataType_
enum ImGuiDataTypePrivate_
{
ImGuiDataType_String = ImGuiDataType_COUNT + 1,
ImGuiDataType_Pointer,
2023-01-24 17:20:31 +08:00
ImGuiDataType_ID,
2020-09-04 17:19:51 +08:00
};
// Stacked color modifier, backup of modified data so we can restore it
struct ImGuiColorMod
{
ImGuiCol Col;
ImVec4 BackupValue;
2020-09-04 17:19:51 +08:00
};
// Stacked style modifier, backup of modified data so we can restore it. Data type inferred from the variable.
struct ImGuiStyleMod
{
2022-02-08 12:43:16 +08:00
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; }
2020-09-04 17:19:51 +08:00
};
2021-08-23 17:49:38 +08:00
// Storage data for BeginComboPreview()/EndComboPreview()
struct IMGUI_API ImGuiComboPreviewData
{
2022-02-08 12:43:16 +08:00
ImRect PreviewRect;
ImVec2 BackupCursorPos;
ImVec2 BackupCursorMaxPos;
ImVec2 BackupCursorPosPrevLine;
float BackupPrevLineTextBaseOffset;
2021-08-23 17:49:38 +08:00
ImGuiLayoutType BackupLayout;
ImGuiComboPreviewData() { memset(this, 0, sizeof(*this)); }
};
2020-09-04 17:19:51 +08:00
// Stacked storage data for BeginGroup()/EndGroup()
2021-06-15 22:30:54 +08:00
struct IMGUI_API ImGuiGroupData
2020-09-04 17:19:51 +08:00
{
2022-02-08 12:43:16 +08:00
ImGuiID WindowID;
ImVec2 BackupCursorPos;
ImVec2 BackupCursorMaxPos;
ImVec1 BackupIndent;
ImVec1 BackupGroupOffset;
ImVec2 BackupCurrLineSize;
float BackupCurrLineTextBaseOffset;
ImGuiID BackupActiveIdIsAlive;
bool BackupActiveIdPreviousFrameIsAlive;
bool BackupHoveredIdIsAlive;
bool EmitItem;
2020-09-04 17:19:51 +08:00
};
2022-02-08 12:43:16 +08:00
// Simple column measurement, currently used for MenuItem() only.. This is very short-sighted/throw-away code and NOT a generic helper.
2020-09-04 17:19:51 +08:00
struct IMGUI_API ImGuiMenuColumns
{
2022-02-08 12:43:16 +08:00
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)
2020-09-04 17:19:51 +08:00
2021-06-15 22:30:54 +08:00
ImGuiMenuColumns() { memset(this, 0, sizeof(*this)); }
2022-02-08 12:43:16 +08:00
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);
2020-09-04 17:19:51 +08:00
};
// Internal state of the currently focused/edited text input box
// For a given item ID, access with ImGui::GetInputTextState()
struct IMGUI_API ImGuiInputTextState
{
2023-08-31 18:14:26 +08:00
ImGuiContext* Ctx; // parent dear imgui context
2022-02-08 12:43:16 +08:00
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
2023-01-24 17:20:31 +08:00
ImGuiInputTextFlags Flags; // copy of InputText() flags. may be used to check if e.g. ImGuiInputTextFlags_Password is set.
2022-02-08 12:43:16 +08:00
2023-08-31 18:14:26 +08:00
ImGuiInputTextState(ImGuiContext* ctx) { memset(this, 0, sizeof(*this)); Ctx = ctx;}
2022-02-08 12:43:16 +08:00
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
2020-09-04 17:19:51 +08:00
// Cursor & Selection
2022-02-08 12:43:16 +08:00
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; }
2020-09-04 17:19:51 +08:00
};
// Storage for current popup stack
struct ImGuiPopupData
{
2022-02-08 12:43:16 +08:00
ImGuiID PopupId; // Set on OpenPopup()
ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup()
2023-01-24 17:20:31 +08:00
ImGuiWindow* BackupNavWindow;// Set on OpenPopup(), a NavWindow that will be restored on popup close
int ParentNavLayer; // Resolved on BeginPopup(). Actually a ImGuiNavLayer type (declared down below), initialized to -1 which is not part of an enum, but serves well-enough as "not any of layers" value
2022-02-08 12:43:16 +08:00
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
2020-09-04 17:19:51 +08:00
ImGuiPopupData() { memset(this, 0, sizeof(*this)); ParentNavLayer = OpenFrameCount = -1; }
2020-09-04 17:19:51 +08:00
};
enum ImGuiNextWindowDataFlags_
{
2022-02-08 12:43:16 +08:00
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,
2023-01-24 17:20:31 +08:00
ImGuiNextWindowDataFlags_HasWindowClass = 1 << 10,
2020-09-04 17:19:51 +08:00
};
// Storage for SetNexWindow** functions
struct ImGuiNextWindowData
{
2022-02-08 12:43:16 +08:00
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; }
2020-09-04 17:19:51 +08:00
};
enum ImGuiNextItemDataFlags_
{
ImGuiNextItemDataFlags_None = 0,
ImGuiNextItemDataFlags_HasWidth = 1 << 0,
2023-01-24 17:20:31 +08:00
ImGuiNextItemDataFlags_HasOpen = 1 << 1,
2020-09-04 17:19:51 +08:00
};
struct ImGuiNextItemData
{
2022-02-08 12:43:16 +08:00
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)); }
2023-08-31 18:14:26 +08:00
inline void ClearFlags() { Flags = ImGuiNextItemDataFlags_None; } // Also cleared manually by ItemAdd()!
2020-09-04 17:19:51 +08:00
};
2021-08-23 17:49:38 +08:00
// Status storage for the last submitted item
struct ImGuiLastItemData
{
2022-02-08 12:43:16 +08:00
ImGuiID ID;
ImGuiItemFlags InFlags; // See ImGuiItemFlags_
ImGuiItemStatusFlags StatusFlags; // See ImGuiItemStatusFlags_
ImRect Rect; // Full rectangle
ImRect NavRect; // Navigation scoring rectangle (not displayed)
ImRect DisplayRect; // Display rectangle (only if ImGuiItemStatusFlags_HasDisplayRect is set)
ImGuiLastItemData() { memset(this, 0, sizeof(*this)); }
};
struct IMGUI_API ImGuiStackSizes
{
short SizeOfIDStack;
short SizeOfColorStack;
short SizeOfStyleVarStack;
short SizeOfFontStack;
short SizeOfFocusScopeStack;
short SizeOfGroupStack;
short SizeOfItemFlagsStack;
short SizeOfBeginPopupStack;
short SizeOfDisabledStack;
2021-08-23 17:49:38 +08:00
2022-02-08 12:43:16 +08:00
ImGuiStackSizes() { memset(this, 0, sizeof(*this)); }
2023-08-31 18:14:26 +08:00
void SetToCurrentState();
void CompareWithCurrentState();
2021-08-23 17:49:38 +08:00
};
// Data saved for each window pushed into the stack
struct ImGuiWindowStackData
{
2022-02-08 12:43:16 +08:00
ImGuiWindow* Window;
ImGuiLastItemData ParentLastItemDataBackup;
ImGuiStackSizes StackSizesOnBegin; // Store size of various stacks for asserting
2021-08-23 17:49:38 +08:00
};
2020-09-04 17:19:51 +08:00
struct ImGuiShrinkWidthItem
{
2022-02-08 12:43:16 +08:00
int Index;
float Width;
float InitialWidth;
2020-09-04 17:19:51 +08:00
};
struct ImGuiPtrOrIndex
{
2022-02-08 12:43:16 +08:00
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.
2020-09-04 17:19:51 +08:00
2022-02-08 12:43:16 +08:00
ImGuiPtrOrIndex(void* ptr) { Ptr = ptr; Index = -1; }
ImGuiPtrOrIndex(int index) { Ptr = NULL; Index = index; }
};
//-----------------------------------------------------------------------------
// [SECTION] Inputs support
//-----------------------------------------------------------------------------
typedef ImBitArray<ImGuiKey_NamedKey_COUNT, -ImGuiKey_NamedKey_BEGIN> ImBitArrayForNamedKeys;
2023-01-24 17:20:31 +08:00
// [Internal] Key ranges
#define ImGuiKey_LegacyNativeKey_BEGIN 0
#define ImGuiKey_LegacyNativeKey_END 512
#define ImGuiKey_Keyboard_BEGIN (ImGuiKey_NamedKey_BEGIN)
#define ImGuiKey_Keyboard_END (ImGuiKey_GamepadStart)
#define ImGuiKey_Gamepad_BEGIN (ImGuiKey_GamepadStart)
#define ImGuiKey_Gamepad_END (ImGuiKey_GamepadRStickDown + 1)
#define ImGuiKey_Mouse_BEGIN (ImGuiKey_MouseLeft)
#define ImGuiKey_Mouse_END (ImGuiKey_MouseWheelY + 1)
#define ImGuiKey_Aliases_BEGIN (ImGuiKey_Mouse_BEGIN)
#define ImGuiKey_Aliases_END (ImGuiKey_Mouse_END)
// [Internal] Named shortcuts for Navigation
#define ImGuiKey_NavKeyboardTweakSlow ImGuiMod_Ctrl
#define ImGuiKey_NavKeyboardTweakFast ImGuiMod_Shift
#define ImGuiKey_NavGamepadTweakSlow ImGuiKey_GamepadL1
#define ImGuiKey_NavGamepadTweakFast ImGuiKey_GamepadR1
#define ImGuiKey_NavGamepadActivate ImGuiKey_GamepadFaceDown
#define ImGuiKey_NavGamepadCancel ImGuiKey_GamepadFaceRight
#define ImGuiKey_NavGamepadMenu ImGuiKey_GamepadFaceLeft
#define ImGuiKey_NavGamepadInput ImGuiKey_GamepadFaceUp
2022-02-08 12:43:16 +08:00
enum ImGuiInputEventType
{
ImGuiInputEventType_None = 0,
ImGuiInputEventType_MousePos,
ImGuiInputEventType_MouseWheel,
ImGuiInputEventType_MouseButton,
ImGuiInputEventType_MouseViewport,
ImGuiInputEventType_Key,
ImGuiInputEventType_Text,
2022-02-08 12:43:16 +08:00
ImGuiInputEventType_Focus,
ImGuiInputEventType_COUNT
};
enum ImGuiInputSource
{
ImGuiInputSource_None = 0,
2023-08-31 18:14:26 +08:00
ImGuiInputSource_Mouse,
2022-02-08 12:43:16 +08:00
ImGuiInputSource_Keyboard,
ImGuiInputSource_Gamepad,
ImGuiInputSource_Clipboard, // Currently only used by InputText()
2023-08-31 18:14:26 +08:00
ImGuiInputSource_Nav, // Stored in g.ActiveIdSource only
2022-02-08 12:43:16 +08:00
ImGuiInputSource_COUNT
};
// FIXME: Structures in the union below need to be declared as anonymous unions appears to be an extension?
// Using ImVec2() would fail on Clang 'union member 'MousePos' has a non-trivial default constructor'
2023-08-31 18:14:26 +08:00
struct ImGuiInputEventMousePos { float PosX, PosY; };
struct ImGuiInputEventMouseWheel { float WheelX, WheelY; };
struct ImGuiInputEventMouseButton { int Button; bool Down; };
2022-02-08 12:43:16 +08:00
struct ImGuiInputEventMouseViewport { ImGuiID HoveredViewportID; };
struct ImGuiInputEventKey { ImGuiKey Key; bool Down; float AnalogValue; };
struct ImGuiInputEventText { unsigned int Char; };
struct ImGuiInputEventAppFocused { bool Focused; };
struct ImGuiInputEvent
{
ImGuiInputEventType Type;
ImGuiInputSource Source;
union
2021-12-25 10:04:45 +08:00
{
2022-02-08 12:43:16 +08:00
ImGuiInputEventMousePos MousePos; // if Type == ImGuiInputEventType_MousePos
ImGuiInputEventMouseWheel MouseWheel; // if Type == ImGuiInputEventType_MouseWheel
ImGuiInputEventMouseButton MouseButton; // if Type == ImGuiInputEventType_MouseButton
ImGuiInputEventMouseViewport MouseViewport; // if Type == ImGuiInputEventType_MouseViewport
ImGuiInputEventKey Key; // if Type == ImGuiInputEventType_Key
ImGuiInputEventText Text; // if Type == ImGuiInputEventType_Text
ImGuiInputEventAppFocused AppFocused; // if Type == ImGuiInputEventType_Focus
};
bool AddedByTestEngine;
ImGuiInputEvent() { memset(this, 0, sizeof(*this)); }
};
2023-01-24 17:20:31 +08:00
// Input function taking an 'ImGuiID owner_id' argument defaults to (ImGuiKeyOwner_Any == 0) aka don't test ownership, which matches legacy behavior.
#define ImGuiKeyOwner_Any ((ImGuiID)0) // Accept key that have an owner, UNLESS a call to SetKeyOwner() explicitly used ImGuiInputFlags_LockThisFrame or ImGuiInputFlags_LockUntilRelease.
#define ImGuiKeyOwner_None ((ImGuiID)-1) // Require key to have no owner.
typedef ImS16 ImGuiKeyRoutingIndex;
// Routing table entry (sizeof() == 16 bytes)
struct ImGuiKeyRoutingData
{
ImGuiKeyRoutingIndex NextEntryIndex;
ImU16 Mods; // Technically we'd only need 4-bits but for simplify we store ImGuiMod_ values which need 16-bits. ImGuiMod_Shortcut is already translated to Ctrl/Super.
ImU8 RoutingNextScore; // Lower is better (0: perfect score)
ImGuiID RoutingCurr;
ImGuiID RoutingNext;
ImGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingNextScore = 255; RoutingCurr = RoutingNext = ImGuiKeyOwner_None; }
};
// Routing table: maintain a desired owner for each possible key-chord (key + mods), and setup owner in NewFrame() when mods are matching.
// Stored in main context (1 instance)
struct ImGuiKeyRoutingTable
{
ImGuiKeyRoutingIndex Index[ImGuiKey_NamedKey_COUNT]; // Index of first entry in Entries[]
ImVector<ImGuiKeyRoutingData> Entries;
ImVector<ImGuiKeyRoutingData> EntriesNext; // Double-buffer to avoid reallocation (could use a shared buffer)
ImGuiKeyRoutingTable() { Clear(); }
void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Index); n++) Index[n] = -1; Entries.clear(); EntriesNext.clear(); }
};
// This extends ImGuiKeyData but only for named keys (legacy keys don't support the new features)
// Stored in main context (1 per named key). In the future it might be merged into ImGuiKeyData.
struct ImGuiKeyOwnerData
2022-02-08 12:43:16 +08:00
{
2023-01-24 17:20:31 +08:00
ImGuiID OwnerCurr;
ImGuiID OwnerNext;
bool LockThisFrame; // Reading this key requires explicit owner id (until end of frame). Set by ImGuiInputFlags_LockThisFrame.
bool LockUntilRelease; // Reading this key requires explicit owner id (until key is released). Set by ImGuiInputFlags_LockUntilRelease. When this is true LockThisFrame is always true as well.
ImGuiKeyOwnerData() { OwnerCurr = OwnerNext = ImGuiKeyOwner_None; LockThisFrame = LockUntilRelease = false; }
};
// Flags for extended versions of IsKeyPressed(), IsMouseClicked(), Shortcut(), SetKeyOwner(), SetItemKeyOwner()
// Don't mistake with ImGuiInputTextFlags! (for ImGui::InputText() function)
enum ImGuiInputFlags_
{
// Flags for IsKeyPressed(), IsMouseClicked(), Shortcut()
ImGuiInputFlags_None = 0,
ImGuiInputFlags_Repeat = 1 << 0, // Return true on successive repeats. Default for legacy IsKeyPressed(). NOT Default for legacy IsMouseClicked(). MUST BE == 1.
ImGuiInputFlags_RepeatRateDefault = 1 << 1, // Repeat rate: Regular (default)
ImGuiInputFlags_RepeatRateNavMove = 1 << 2, // Repeat rate: Fast
ImGuiInputFlags_RepeatRateNavTweak = 1 << 3, // Repeat rate: Faster
ImGuiInputFlags_RepeatRateMask_ = ImGuiInputFlags_RepeatRateDefault | ImGuiInputFlags_RepeatRateNavMove | ImGuiInputFlags_RepeatRateNavTweak,
// Flags for SetItemKeyOwner()
ImGuiInputFlags_CondHovered = 1 << 4, // Only set if item is hovered (default to both)
ImGuiInputFlags_CondActive = 1 << 5, // Only set if item is active (default to both)
ImGuiInputFlags_CondDefault_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive,
ImGuiInputFlags_CondMask_ = ImGuiInputFlags_CondHovered | ImGuiInputFlags_CondActive,
// Flags for SetKeyOwner(), SetItemKeyOwner()
ImGuiInputFlags_LockThisFrame = 1 << 6, // Access to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared at end of frame. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code.
ImGuiInputFlags_LockUntilRelease = 1 << 7, // Access to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared when the key is released or at end of each frame if key is released. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code.
// Routing policies for Shortcut() + low-level SetShortcutRouting()
// - The general idea is that several callers register interest in a shortcut, and only one owner gets it.
// - When a policy (other than _RouteAlways) is set, Shortcut() will register itself with SetShortcutRouting(),
// allowing the system to decide where to route the input among other route-aware calls.
// - Shortcut() uses ImGuiInputFlags_RouteFocused by default: meaning that a simple Shortcut() poll
// will register a route and only succeed when parent window is in the focus stack and if no-one
// with a higher priority is claiming the shortcut.
// - Using ImGuiInputFlags_RouteAlways is roughly equivalent to doing e.g. IsKeyPressed(key) + testing mods.
// - Priorities: GlobalHigh > Focused (when owner is active item) > Global > Focused (when focused window) > GlobalLow.
// - Can select only 1 policy among all available.
ImGuiInputFlags_RouteFocused = 1 << 8, // (Default) Register focused route: Accept inputs if window is in focus stack. Deep-most focused window takes inputs. ActiveId takes inputs over deep-most focused window.
ImGuiInputFlags_RouteGlobalLow = 1 << 9, // Register route globally (lowest priority: unless a focused window or active item registered the route) -> recommended Global priority.
ImGuiInputFlags_RouteGlobal = 1 << 10, // Register route globally (medium priority: unless an active item registered the route, e.g. CTRL+A registered by InputText).
ImGuiInputFlags_RouteGlobalHigh = 1 << 11, // Register route globally (highest priority: unlikely you need to use that: will interfere with every active items)
ImGuiInputFlags_RouteMask_ = ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteGlobalLow | ImGuiInputFlags_RouteGlobalHigh, // _Always not part of this!
ImGuiInputFlags_RouteAlways = 1 << 12, // Do not register route, poll keys directly.
ImGuiInputFlags_RouteUnlessBgFocused= 1 << 13, // Global routes will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications.
ImGuiInputFlags_RouteExtraMask_ = ImGuiInputFlags_RouteAlways | ImGuiInputFlags_RouteUnlessBgFocused,
// [Internal] Mask of which function support which flags
ImGuiInputFlags_SupportedByIsKeyPressed = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_,
ImGuiInputFlags_SupportedByShortcut = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_ | ImGuiInputFlags_RouteMask_ | ImGuiInputFlags_RouteExtraMask_,
ImGuiInputFlags_SupportedBySetKeyOwner = ImGuiInputFlags_LockThisFrame | ImGuiInputFlags_LockUntilRelease,
ImGuiInputFlags_SupportedBySetItemKeyOwner = ImGuiInputFlags_SupportedBySetKeyOwner | ImGuiInputFlags_CondMask_,
2022-02-08 12:43:16 +08:00
};
//-----------------------------------------------------------------------------
// [SECTION] Clipper support
//-----------------------------------------------------------------------------
struct ImGuiListClipperRange
{
int Min;
int Max;
bool PosToIndexConvert; // Begin/End are absolute position (will be converted to indices later)
ImS8 PosToIndexOffsetMin; // Add to Min after converting to indices
ImS8 PosToIndexOffsetMax; // Add to Min after converting to indices
static ImGuiListClipperRange FromIndices(int min, int max) { ImGuiListClipperRange r = { min, max, false, 0, 0 }; return r; }
static ImGuiListClipperRange FromPositions(float y1, float y2, int off_min, int off_max) { ImGuiListClipperRange r = { (int)y1, (int)y2, true, (ImS8)off_min, (ImS8)off_max }; return r; }
};
// Temporary clipper data, buffers shared/reused between instances
struct ImGuiListClipperData
{
ImGuiListClipper* ListClipper;
float LossynessOffset;
int StepNo;
int ItemsFrozen;
ImVector<ImGuiListClipperRange> Ranges;
ImGuiListClipperData() { memset(this, 0, sizeof(*this)); }
void Reset(ImGuiListClipper* clipper) { ListClipper = clipper; StepNo = ItemsFrozen = 0; Ranges.resize(0); }
};
//-----------------------------------------------------------------------------
// [SECTION] Navigation support
//-----------------------------------------------------------------------------
enum ImGuiActivateFlags_
{
ImGuiActivateFlags_None = 0,
2023-08-31 18:14:26 +08:00
ImGuiActivateFlags_PreferInput = 1 << 0, // Favor activation that requires keyboard text input (e.g. for Slider/Drag). Default if keyboard is available.
ImGuiActivateFlags_PreferTweak = 1 << 1, // Favor activation for tweaking with arrows or gamepad (e.g. for Slider/Drag). Default if keyboard is not available.
2023-01-24 17:20:31 +08:00
ImGuiActivateFlags_TryToPreserveState = 1 << 2, // Request widget to preserve state if it can (e.g. InputText will try to preserve cursor/selection)
2022-02-08 12:43:16 +08:00
};
// Early work-in-progress API for ScrollToItem()
enum ImGuiScrollFlags_
{
ImGuiScrollFlags_None = 0,
ImGuiScrollFlags_KeepVisibleEdgeX = 1 << 0, // If item is not visible: scroll as little as possible on X axis to bring item back into view [default for X axis]
ImGuiScrollFlags_KeepVisibleEdgeY = 1 << 1, // If item is not visible: scroll as little as possible on Y axis to bring item back into view [default for Y axis for windows that are already visible]
ImGuiScrollFlags_KeepVisibleCenterX = 1 << 2, // If item is not visible: scroll to make the item centered on X axis [rarely used]
ImGuiScrollFlags_KeepVisibleCenterY = 1 << 3, // If item is not visible: scroll to make the item centered on Y axis
ImGuiScrollFlags_AlwaysCenterX = 1 << 4, // Always center the result item on X axis [rarely used]
ImGuiScrollFlags_AlwaysCenterY = 1 << 5, // Always center the result item on Y axis [default for Y axis for appearing window)
ImGuiScrollFlags_NoScrollParent = 1 << 6, // Disable forwarding scrolling to parent window if required to keep item/rect visible (only scroll window the function was applied to).
ImGuiScrollFlags_MaskX_ = ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleCenterX | ImGuiScrollFlags_AlwaysCenterX,
2023-01-24 17:20:31 +08:00
ImGuiScrollFlags_MaskY_ = ImGuiScrollFlags_KeepVisibleEdgeY | ImGuiScrollFlags_KeepVisibleCenterY | ImGuiScrollFlags_AlwaysCenterY,
2022-02-08 12:43:16 +08:00
};
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.
2023-01-24 17:20:31 +08:00
ImGuiNavHighlightFlags_NoRounding = 1 << 3,
2022-02-08 12:43:16 +08:00
};
enum ImGuiNavMoveFlags_
{
ImGuiNavMoveFlags_None = 0,
ImGuiNavMoveFlags_LoopX = 1 << 0, // On failed request, restart from opposite side
ImGuiNavMoveFlags_LoopY = 1 << 1,
ImGuiNavMoveFlags_WrapX = 1 << 2, // On failed request, request from opposite side one line down (when NavDir==right) or one line up (when NavDir==left)
ImGuiNavMoveFlags_WrapY = 1 << 3, // This is not super useful but provided for completeness
ImGuiNavMoveFlags_AllowCurrentNavId = 1 << 4, // Allow scoring and considering the current NavId as a move target candidate. This is used when the move source is offset (e.g. pressing PageDown actually needs to send a Up move request, if we are pressing PageDown from the bottom-most item we need to stay in place)
ImGuiNavMoveFlags_AlsoScoreVisibleSet = 1 << 5, // Store alternate result in NavMoveResultLocalVisible that only comprise elements that are already fully visible (used by PageUp/PageDown)
ImGuiNavMoveFlags_ScrollToEdgeY = 1 << 6, // Force scrolling to min/max (used by Home/End) // FIXME-NAV: Aim to remove or reword, probably unnecessary
ImGuiNavMoveFlags_Forwarded = 1 << 7,
ImGuiNavMoveFlags_DebugNoResult = 1 << 8, // Dummy scoring for debug purpose, don't apply result
2023-08-31 18:14:26 +08:00
ImGuiNavMoveFlags_FocusApi = 1 << 9,
ImGuiNavMoveFlags_Tabbing = 1 << 10, // == Focus + Activate if item is Inputable + DontChangeNavHighlight
ImGuiNavMoveFlags_Activate = 1 << 11,
ImGuiNavMoveFlags_DontSetNavHighlight = 1 << 12, // Do not alter the visible state of keyboard vs mouse nav highlight
2022-02-08 12:43:16 +08:00
};
enum ImGuiNavLayer
{
ImGuiNavLayer_Main = 0, // Main scrolling layer
2023-01-24 17:20:31 +08:00
ImGuiNavLayer_Menu = 1, // Menu layer (access with Alt)
2022-02-08 12:43:16 +08:00
ImGuiNavLayer_COUNT
};
struct ImGuiNavItemData
{
ImGuiWindow* Window; // Init,Move // Best candidate window (result->ItemWindow->RootWindowForNav == request->Window)
ImGuiID ID; // Init,Move // Best candidate item ID
ImGuiID FocusScopeId; // Init,Move // Best candidate focus scope ID
ImRect RectRel; // Init,Move // Best candidate bounding box in window relative space
ImGuiItemFlags InFlags; // ????,Move // Best candidate item flags
float DistBox; // Move // Best candidate box distance to current NavId
float DistCenter; // Move // Best candidate center distance to current NavId
float DistAxial; // Move // Best candidate axial distance to current NavId
ImGuiNavItemData() { Clear(); }
void Clear() { Window = NULL; ID = FocusScopeId = 0; InFlags = 0; DistBox = DistCenter = DistAxial = FLT_MAX; }
2020-09-04 17:19:51 +08:00
};
//-----------------------------------------------------------------------------
// [SECTION] Columns support
//-----------------------------------------------------------------------------
2021-06-15 22:30:54 +08:00
// Flags for internal's BeginColumns(). Prefix using BeginTable() nowadays!
enum ImGuiOldColumnFlags_
2020-09-04 17:19:51 +08:00
{
2022-02-08 12:43:16 +08:00
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
2023-01-24 17:20:31 +08:00
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.
2022-02-08 12:43:16 +08:00
// Obsolete names (will be removed)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
2023-01-24 17:20:31 +08:00
ImGuiColumnsFlags_None = ImGuiOldColumnFlags_None,
2022-02-08 12:43:16 +08:00
ImGuiColumnsFlags_NoBorder = ImGuiOldColumnFlags_NoBorder,
ImGuiColumnsFlags_NoResize = ImGuiOldColumnFlags_NoResize,
ImGuiColumnsFlags_NoPreserveWidths = ImGuiOldColumnFlags_NoPreserveWidths,
ImGuiColumnsFlags_NoForceWithinWindow = ImGuiOldColumnFlags_NoForceWithinWindow,
2023-01-24 17:20:31 +08:00
ImGuiColumnsFlags_GrowParentContentsSize = ImGuiOldColumnFlags_GrowParentContentsSize,
2022-02-08 12:43:16 +08:00
#endif
2020-09-04 17:19:51 +08:00
};
2021-06-15 22:30:54 +08:00
struct ImGuiOldColumnData
2020-09-04 17:19:51 +08:00
{
2023-01-24 17:20:31 +08:00
float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right)
2022-02-08 12:43:16 +08:00
float OffsetNormBeforeResize;
2023-01-24 17:20:31 +08:00
ImGuiOldColumnFlags Flags; // Not exposed
2022-02-08 12:43:16 +08:00
ImRect ClipRect;
2020-09-04 17:19:51 +08:00
2021-06-15 22:30:54 +08:00
ImGuiOldColumnData() { memset(this, 0, sizeof(*this)); }
2020-09-04 17:19:51 +08:00
};
2021-06-15 22:30:54 +08:00
struct ImGuiOldColumns
2020-09-04 17:19:51 +08:00
{
2022-02-08 12:43:16 +08:00
ImGuiID ID;
2021-06-15 22:30:54 +08:00
ImGuiOldColumnFlags Flags;
2022-02-08 12:43:16 +08:00
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()
2021-06-15 22:30:54 +08:00
ImVector<ImGuiOldColumnData> Columns;
2022-02-08 12:43:16 +08:00
ImDrawListSplitter Splitter;
2020-09-04 17:19:51 +08:00
2022-02-08 12:43:16 +08:00
ImGuiOldColumns() { memset(this, 0, sizeof(*this)); }
2020-09-04 17:19:51 +08:00
};
//-----------------------------------------------------------------------------
// [SECTION] Multi-select support
//-----------------------------------------------------------------------------
2022-02-08 12:43:16 +08:00
#ifdef IMGUI_HAS_MULTI_SELECT
2020-09-04 17:19:51 +08:00
// <this is filled in 'range_select' branch>
2022-02-08 12:43:16 +08:00
#endif // #ifdef IMGUI_HAS_MULTI_SELECT
2020-09-04 17:19:51 +08:00
//-----------------------------------------------------------------------------
// [SECTION] Docking support
//-----------------------------------------------------------------------------
2023-01-24 17:20:31 +08:00
#define DOCKING_HOST_DRAW_CHANNEL_BG 0 // Dock host: background fill
#define DOCKING_HOST_DRAW_CHANNEL_FG 1 // Dock host: decorations and contents
2022-02-08 12:43:16 +08:00
#ifdef IMGUI_HAS_DOCK
2020-09-04 17:19:51 +08:00
// Extend ImGuiDockNodeFlags_
enum ImGuiDockNodeFlagsPrivate_
{
// [Internal]
2022-02-08 12:43:16 +08:00
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
2020-09-04 17:19:51 +08:00
};
// Store the source authority (dock node vs window) of a field
enum ImGuiDataAuthority_
{
ImGuiDataAuthority_Auto,
ImGuiDataAuthority_DockNode,
2023-01-24 17:20:31 +08:00
ImGuiDataAuthority_Window,
2020-09-04 17:19:51 +08:00
};
enum ImGuiDockNodeState
{
ImGuiDockNodeState_Unknown,
ImGuiDockNodeState_HostWindowHiddenBecauseSingleWindow,
ImGuiDockNodeState_HostWindowHiddenBecauseWindowsAreResizing,
2023-01-24 17:20:31 +08:00
ImGuiDockNodeState_HostWindowVisible,
2020-09-04 17:19:51 +08:00
};
2021-08-23 17:49:38 +08:00
// sizeof() 156~192
2021-06-15 22:30:54 +08:00
struct IMGUI_API ImGuiDockNode
2020-09-04 17:19:51 +08:00
{
2022-02-08 12:43:16 +08:00
ImGuiID ID;
ImGuiDockNodeFlags SharedFlags; // (Write) Flags shared by all nodes of a same dockspace hierarchy (inherited from the root node)
ImGuiDockNodeFlags LocalFlags; // (Write) Flags specific to this node
ImGuiDockNodeFlags LocalFlagsInWindows; // (Write) Flags specific to this node, applied from windows
ImGuiDockNodeFlags MergedFlags; // (Read) Effective flags (== SharedFlags | LocalFlagsInNode | LocalFlagsInWindows)
ImGuiDockNodeState State;
ImGuiDockNode* ParentNode;
ImGuiDockNode* ChildNodes[2]; // [Split node only] Child nodes (left/right or top/bottom). Consider switching to an array.
ImVector<ImGuiWindow*> Windows; // Note: unordered list! Iterate TabBar->Tabs for user-order.
ImGuiTabBar* TabBar;
ImVec2 Pos; // Current position
ImVec2 Size; // Current size
ImVec2 SizeRef; // [Split node only] Last explicitly written-to size (overridden when using a splitter affecting the node), used to calculate Size.
ImGuiAxis SplitAxis; // [Split node only] Split axis (X or Y)
ImGuiWindowClass WindowClass; // [Root node only]
ImU32 LastBgColor;
ImGuiWindow* HostWindow;
ImGuiWindow* VisibleWindow; // Generally point to window which is ID is == SelectedTabID, but when CTRL+Tabbing this can be a different window.
ImGuiDockNode* CentralNode; // [Root node only] Pointer to central node.
ImGuiDockNode* OnlyNodeWithWindows; // [Root node only] Set when there is a single visible node within the hierarchy.
int CountNodeWithWindows; // [Root node only]
int LastFrameAlive; // Last frame number the node was updated or kept alive explicitly with DockSpace() + ImGuiDockNodeFlags_KeepAliveOnly
int LastFrameActive; // Last frame number the node was updated.
int LastFrameFocused; // Last frame number the node was focused.
ImGuiID LastFocusedNodeId; // [Root node only] Which of our child docking node (any ancestor in the hierarchy) was last focused.
ImGuiID SelectedTabId; // [Leaf node only] Which of our tab/window is selected.
ImGuiID WantCloseTabId; // [Leaf node only] Set when closing a specific tab/window.
ImGuiDataAuthority AuthorityForPos :3;
ImGuiDataAuthority AuthorityForSize :3;
ImGuiDataAuthority AuthorityForViewport :3;
bool IsVisible :1; // Set to false when the node is hidden (usually disabled as it has no active window)
bool IsFocused :1;
bool IsBgDrawnThisFrame :1;
bool HasCloseButton :1; // Provide space for a close button (if any of the docked window has one). Note that button may be hidden on window without one.
bool HasWindowMenuButton :1;
bool HasCentralNodeChild :1;
bool WantCloseAll :1; // Set when closing all tabs at once.
bool WantLockSizeOnce :1;
bool WantMouseMove :1; // After a node extraction we need to transition toward moving the newly created host window
bool WantHiddenTabBarUpdate :1;
bool WantHiddenTabBarToggle :1;
2020-09-04 17:19:51 +08:00
ImGuiDockNode(ImGuiID id);
~ImGuiDockNode();
2022-02-08 12:43:16 +08:00
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; }
2020-09-04 17:19:51 +08:00
};
2021-06-15 22:30:54 +08:00
// 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[].
2022-02-08 12:43:16 +08:00
// 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.
2021-06-15 22:30:54 +08:00
enum ImGuiWindowDockStyleCol
{
ImGuiWindowDockStyleCol_Text,
ImGuiWindowDockStyleCol_Tab,
ImGuiWindowDockStyleCol_TabHovered,
ImGuiWindowDockStyleCol_TabActive,
ImGuiWindowDockStyleCol_TabUnfocused,
ImGuiWindowDockStyleCol_TabUnfocusedActive,
ImGuiWindowDockStyleCol_COUNT
};
struct ImGuiWindowDockStyle
{
ImU32 Colors[ImGuiWindowDockStyleCol_COUNT];
};
2020-09-04 17:19:51 +08:00
struct ImGuiDockContext
{
2022-02-08 12:43:16 +08:00
ImGuiStorage Nodes; // Map ID -> ImGuiDockNode*: Active nodes
ImVector<ImGuiDockRequest> Requests;
2020-09-04 17:19:51 +08:00
ImVector<ImGuiDockNodeSettings> NodesSettings;
2022-02-08 12:43:16 +08:00
bool WantFullRebuild;
ImGuiDockContext() { memset(this, 0, sizeof(*this)); }
2020-09-04 17:19:51 +08:00
};
2022-02-08 12:43:16 +08:00
#endif // #ifdef IMGUI_HAS_DOCK
2020-09-04 17:19:51 +08:00
//-----------------------------------------------------------------------------
// [SECTION] Viewport support
//-----------------------------------------------------------------------------
// ImGuiViewport Private/Internals fields (cardinal sin: we are using inheritance!)
2021-06-15 22:30:54 +08:00
// Every instance of ImGuiViewport is in fact a ImGuiViewportP.
2020-09-04 17:19:51 +08:00
struct ImGuiViewportP : public ImGuiViewport
{
2022-02-08 12:43:16 +08:00
int Idx;
int LastFrameActive; // Last frame number this viewport was activated by a window
2023-08-31 18:14:26 +08:00
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
2022-02-08 12:43:16 +08:00
ImGuiID LastNameHash;
ImVec2 LastPos;
float Alpha; // Window opacity (when dragging dockable windows/viewports we make them transparent)
float LastAlpha;
short PlatformMonitor;
2023-08-31 18:14:26 +08:00
ImGuiWindow* Window; // Set when the viewport is owned by a window (and ImGuiViewportFlags_CanHostOtherWindows is NOT set)
2022-02-08 12:43:16 +08:00
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;
2023-08-31 18:14:26 +08:00
ImDrawDataBuilder DrawDataBuilder;
2022-02-08 12:43:16 +08:00
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.
2023-08-31 18:14:26 +08:00
ImGuiViewportP() { Idx = -1; LastFrameActive = DrawListsLastFrame[0] = DrawListsLastFrame[1] = LastFrontMostStampCount = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; PlatformMonitor = -1; Window = NULL; DrawLists[0] = DrawLists[1] = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); }
2022-02-08 12:43:16 +08:00
~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); }
2021-06-15 22:30:54 +08:00
};
2020-09-04 17:19:51 +08:00
//-----------------------------------------------------------------------------
// [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
{
2022-02-08 12:43:16 +08:00
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); }
2020-09-04 17:19:51 +08:00
};
struct ImGuiSettingsHandler
{
2022-02-08 12:43:16 +08:00
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;
2020-09-04 17:19:51 +08:00
ImGuiSettingsHandler() { memset(this, 0, sizeof(*this)); }
};
2023-01-24 17:20:31 +08:00
//-----------------------------------------------------------------------------
// [SECTION] Localization support
//-----------------------------------------------------------------------------
// This is experimental and not officially supported, it'll probably fall short of features, if/when it does we may backtrack.
enum ImGuiLocKey : int
{
ImGuiLocKey_TableSizeOne,
ImGuiLocKey_TableSizeAllFit,
ImGuiLocKey_TableSizeAllDefault,
ImGuiLocKey_TableResetOrder,
ImGuiLocKey_WindowingMainMenuBar,
ImGuiLocKey_WindowingPopup,
ImGuiLocKey_WindowingUntitled,
ImGuiLocKey_DockingHideTabBar,
ImGuiLocKey_COUNT
};
struct ImGuiLocEntry
{
ImGuiLocKey Key;
const char* Text;
};
2021-06-15 22:30:54 +08:00
//-----------------------------------------------------------------------------
2022-02-08 12:43:16 +08:00
// [SECTION] Metrics, Debug Tools
2021-06-15 22:30:54 +08:00
//-----------------------------------------------------------------------------
enum ImGuiDebugLogFlags_
{
// Event types
ImGuiDebugLogFlags_None = 0,
ImGuiDebugLogFlags_EventActiveId = 1 << 0,
ImGuiDebugLogFlags_EventFocus = 1 << 1,
ImGuiDebugLogFlags_EventPopup = 1 << 2,
ImGuiDebugLogFlags_EventNav = 1 << 3,
2023-01-24 17:20:31 +08:00
ImGuiDebugLogFlags_EventClipper = 1 << 4,
2023-08-31 18:14:26 +08:00
ImGuiDebugLogFlags_EventIO = 1 << 5,
ImGuiDebugLogFlags_EventDocking = 1 << 6,
ImGuiDebugLogFlags_EventViewport = 1 << 7,
ImGuiDebugLogFlags_EventMask_ = ImGuiDebugLogFlags_EventActiveId | ImGuiDebugLogFlags_EventFocus | ImGuiDebugLogFlags_EventPopup | ImGuiDebugLogFlags_EventNav | ImGuiDebugLogFlags_EventClipper | ImGuiDebugLogFlags_EventIO | ImGuiDebugLogFlags_EventDocking | ImGuiDebugLogFlags_EventViewport,
2023-01-24 17:20:31 +08:00
ImGuiDebugLogFlags_OutputToTTY = 1 << 10, // Also send output to TTY
};
2021-06-15 22:30:54 +08:00
struct ImGuiMetricsConfig
{
2023-08-31 18:14:26 +08:00
bool ShowDebugLog;
bool ShowStackTool;
bool ShowWindowsRects;
bool ShowWindowsBeginOrder;
bool ShowTablesRects;
bool ShowDrawCmdMesh;
bool ShowDrawCmdBoundingBoxes;
bool ShowDockingNodes;
int ShowWindowsRectsType;
int ShowTablesRectsType;
ImGuiMetricsConfig()
{
ShowDebugLog = ShowStackTool = ShowWindowsRects = ShowWindowsBeginOrder = ShowTablesRects = false;
ShowDrawCmdMesh = true;
ShowDrawCmdBoundingBoxes = true;
ShowDockingNodes = false;
ShowWindowsRectsType = ShowTablesRectsType = -1;
}
2021-06-15 22:30:54 +08:00
};
2022-02-08 12:43:16 +08:00
struct ImGuiStackLevelInfo
2021-06-15 22:30:54 +08:00
{
2022-02-08 12:43:16 +08:00
ImGuiID ID;
ImS8 QueryFrameCount; // >= 1: Query in progress
bool QuerySuccess; // Obtained result from DebugHookIdInfo()
ImGuiDataType DataType : 8;
char Desc[57]; // Arbitrarily sized buffer to hold a result (FIXME: could replace Results[] with a chunk stream?) FIXME: Now that we added CTRL+C this should be fixed.
2021-06-15 22:30:54 +08:00
2022-02-08 12:43:16 +08:00
ImGuiStackLevelInfo() { memset(this, 0, sizeof(*this)); }
};
// State for Stack tool queries
struct ImGuiStackTool
{
int LastActiveFrame;
int StackLevel; // -1: query stack and resize Results, >= 0: individual stack level
ImGuiID QueryId; // ID to query details for
ImVector<ImGuiStackLevelInfo> Results;
bool CopyToClipboardOnCtrlC;
float CopyToClipboardLastTime;
2022-02-08 12:43:16 +08:00
ImGuiStackTool() { memset(this, 0, sizeof(*this)); CopyToClipboardLastTime = -FLT_MAX; }
2021-06-15 22:30:54 +08:00
};
//-----------------------------------------------------------------------------
// [SECTION] Generic context hooks
//-----------------------------------------------------------------------------
typedef void (*ImGuiContextHookCallback)(ImGuiContext* ctx, ImGuiContextHook* hook);
2022-02-08 12:43:16 +08:00
enum ImGuiContextHookType { ImGuiContextHookType_NewFramePre, ImGuiContextHookType_NewFramePost, ImGuiContextHookType_EndFramePre, ImGuiContextHookType_EndFramePost, ImGuiContextHookType_RenderPre, ImGuiContextHookType_RenderPost, ImGuiContextHookType_Shutdown, ImGuiContextHookType_PendingRemoval_ };
2021-06-15 22:30:54 +08:00
struct ImGuiContextHook
{
2022-02-08 12:43:16 +08:00
ImGuiID HookId; // A unique ID assigned by AddContextHook()
ImGuiContextHookType Type;
ImGuiID Owner;
ImGuiContextHookCallback Callback;
void* UserData;
2021-06-15 22:30:54 +08:00
2022-02-08 12:43:16 +08:00
ImGuiContextHook() { memset(this, 0, sizeof(*this)); }
2021-06-15 22:30:54 +08:00
};
2020-09-04 17:19:51 +08:00
//-----------------------------------------------------------------------------
// [SECTION] ImGuiContext (main Dear ImGui context)
2020-09-04 17:19:51 +08:00
//-----------------------------------------------------------------------------
struct ImGuiContext
{
2022-02-08 12:43:16 +08:00
bool Initialized;
bool FontAtlasOwnedByContext; // IO.Fonts-> is owned by the ImGuiContext and will be destructed along with it.
ImGuiIO IO;
ImGuiPlatformIO PlatformIO;
2023-08-31 18:14:26 +08:00
ImVector<ImGuiInputEvent> InputEventsQueue; // Input events which will be tricked/written into IO structure.
ImVector<ImGuiInputEvent> InputEventsTrail; // Past input events processed in NewFrame(). This is to allow domain-specific application to access e.g mouse/pen trail.
2022-02-08 12:43:16 +08:00
ImGuiStyle Style;
ImGuiConfigFlags ConfigFlagsCurrFrame; // = g.IO.ConfigFlags at the time of NewFrame()
ImGuiConfigFlags ConfigFlagsLastFrame;
ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back()
float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window.
float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height.
ImDrawListSharedData DrawListSharedData;
double Time;
int FrameCount;
int FrameCountEnded;
int FrameCountPlatformEnded;
int FrameCountRendered;
bool WithinFrameScope; // Set by NewFrame(), cleared by EndFrame()
bool WithinFrameScopeWithImplicitWindow; // Set by NewFrame(), cleared by EndFrame() when the implicit debug window has been pushed
bool WithinEndChild; // Set within EndChild()
bool GcCompactAll; // Request full GC
bool TestEngineHookItems; // Will call test engine hooks: ImGuiTestEngineHook_ItemAdd(), ImGuiTestEngineHook_ItemInfo(), ImGuiTestEngineHook_Log()
void* TestEngine; // Test engine user data
2020-09-04 17:19:51 +08:00
// Windows state
2022-02-08 12:43:16 +08:00
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
2021-08-23 17:49:38 +08:00
ImVector<ImGuiWindowStackData> CurrentWindowStack;
2022-02-08 12:43:16 +08:00
ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow*
int WindowsActiveCount; // Number of unique windows submitted by frame
ImVec2 WindowsHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == ImMax(style.TouchExtraPadding, WINDOWS_HOVER_PADDING)
ImGuiWindow* CurrentWindow; // Window being drawn into
ImGuiWindow* HoveredWindow; // Window the mouse is hovering. Will typically catch mouse inputs.
ImGuiWindow* HoveredWindowUnderMovingWindow; // Hovered window ignoring MovingWindow. Only set if MovingWindow is set.
ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actual window that is moved is generally MovingWindow->RootWindowDockTree.
ImGuiWindow* WheelingWindow; // Track the window we started mouse-wheeling on. Until a timer elapse or mouse has moved, generally keep scrolling the same window even if during the course of scrolling the mouse ends up hovering a child window.
ImVec2 WheelingWindowRefMousePos;
2023-01-24 17:20:31 +08:00
int WheelingWindowStartFrame; // This may be set one frame before WheelingWindow is != NULL
float WheelingWindowReleaseTimer;
ImVec2 WheelingWindowWheelRemainder;
ImVec2 WheelingAxisAvg;
2020-09-04 17:19:51 +08:00
// Item/widgets state and tracking information
2022-02-08 12:43:16 +08:00
ImGuiID DebugHookIdInfo; // Will call core hooks: DebugHookIdInfo() from GetID functions, used by Stack Tool [next HoveredId/ActiveId to not pull in an extra cache-line]
ImGuiID HoveredId; // Hovered widget, filled during the frame
ImGuiID HoveredIdPreviousFrame;
bool HoveredIdAllowOverlap;
bool HoveredIdDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0.
float HoveredIdTimer; // Measure contiguous hovering time
float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active
ImGuiID ActiveId; // Active widget
ImGuiID ActiveIdIsAlive; // Active widget has been seen this frame (we can't use a bool as the ActiveId may change within the frame)
float ActiveIdTimer;
bool ActiveIdIsJustActivated; // Set at the time of activation for one frame
bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always)
bool ActiveIdNoClearOnFocusLoss; // Disable losing active id if the active id window gets unfocused.
bool ActiveIdHasBeenPressedBefore; // Track whether the active id led to a press (this is to allow changing between PressOnClick and PressOnRelease without pressing twice). Used by range_select branch.
bool ActiveIdHasBeenEditedBefore; // Was the value associated to the widget Edited over the course of the Active state.
bool ActiveIdHasBeenEditedThisFrame;
ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior)
ImGuiWindow* ActiveIdWindow;
2023-08-31 18:14:26 +08:00
ImGuiInputSource ActiveIdSource; // Activating with mouse or nav (gamepad/keyboard)
2022-02-08 12:43:16 +08:00
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.
2020-09-04 17:19:51 +08:00
2023-01-24 17:20:31 +08:00
// [EXPERIMENTAL] Key/Input Ownership + Shortcut Routing system
// - The idea is that instead of "eating" a given key, we can link to an owner.
// - Input query can then read input by specifying ImGuiKeyOwner_Any (== 0), ImGuiKeyOwner_None (== -1) or a custom ID.
// - Routing is requested ahead of time for a given chord (Key + Mods) and granted in NewFrame().
ImGuiKeyOwnerData KeysOwnerData[ImGuiKey_NamedKey_COUNT];
ImGuiKeyRoutingTable KeysRoutingTable;
ImU32 ActiveIdUsingNavDirMask; // Active widget will want to read those nav move requests (e.g. can activate a button and move away from it)
2023-01-24 17:20:31 +08:00
bool ActiveIdUsingAllKeyboardKeys; // Active widget will want to read all keyboard keys inputs. (FIXME: This is a shortcut for not taking ownership of 100+ keys but perhaps best to not have the inconsistency)
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
ImU32 ActiveIdUsingNavInputMask; // If you used this. Since (IMGUI_VERSION_NUM >= 18804) : 'g.ActiveIdUsingNavInputMask |= (1 << ImGuiNavInput_Cancel);' becomes 'SetKeyOwner(ImGuiKey_Escape, g.ActiveId) and/or SetKeyOwner(ImGuiKey_NavGamepadCancel, g.ActiveId);'
#endif
2020-09-04 17:19:51 +08:00
// Next window/item data
2023-01-24 17:20:31 +08:00
ImGuiID CurrentFocusScopeId; // == g.FocusScopeStack.back()
ImGuiItemFlags CurrentItemFlags; // == g.ItemFlagsStack.back()
ImGuiID DebugLocateId; // Storage for DebugLocateItemOnHover() feature: this is read by ItemAdd() so we keep it in a hot/cached location
2022-02-08 12:43:16 +08:00
ImGuiNextItemData NextItemData; // Storage for SetNextItem** functions
ImGuiLastItemData LastItemData; // Storage for last submitted item (setup by ItemAdd)
ImGuiNextWindowData NextWindowData; // Storage for SetNextWindow** functions
2020-09-04 17:19:51 +08:00
// Shared stacks
2022-02-08 12:43:16 +08:00
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()
2023-01-24 17:20:31 +08:00
ImVector<ImGuiID> FocusScopeStack; // Stack for PushFocusScope()/PopFocusScope() - inherited by BeginChild(), pushed into by Begin()
2022-02-08 12:43:16 +08:00
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)
int BeginMenuCount;
2020-09-04 17:19:51 +08:00
// Viewports
2022-02-08 12:43:16 +08:00
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.
2023-08-31 18:14:26 +08:00
int ViewportFrontMostStampCount; // Every time the front-most window changes, we stamp its viewport with an incrementing counter
2020-09-04 17:19:51 +08:00
// Gamepad/keyboard Navigation
ImGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusedWindow'
2022-02-08 12:43:16 +08:00
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)
2023-08-31 18:14:26 +08:00
ImGuiID NavActivateId; // ~~ (g.ActiveId == 0) && (IsKeyPressed(ImGuiKey_Space) || IsKeyPressed(ImGuiKey_NavGamepadActivate)) ? NavId : 0, also set when calling ActivateItem()
ImGuiID NavActivateDownId; // ~~ IsKeyDown(ImGuiKey_Space) || IsKeyDown(ImGuiKey_NavGamepadActivate) ? NavId : 0
ImGuiID NavActivatePressedId; // ~~ IsKeyPressed(ImGuiKey_Space) || IsKeyPressed(ImGuiKey_NavGamepadActivate) ? NavId : 0 (no repeat)
ImGuiID NavActivateInputId; // ~~ IsKeyPressed(ImGuiKey_Enter) || IsKeyPressed(ImGuiKey_NavGamepadInput) ? NavId : 0; ImGuiActivateFlags_PreferInput will be set and NavActivateId will be 0.
2022-02-08 12:43:16 +08:00
ImGuiActivateFlags NavActivateFlags;
ImGuiID NavJustMovedToId; // Just navigated to this id (result of a successfully MoveRequest).
ImGuiID NavJustMovedToFocusScopeId; // Just navigated to this focus scope id (result of a successfully MoveRequest).
2023-01-24 17:20:31 +08:00
ImGuiKeyChord NavJustMovedToKeyMods;
2022-02-08 12:43:16 +08:00
ImGuiID NavNextActivateId; // Set by ActivateItem(), queued until next frame.
ImGuiActivateFlags NavNextActivateFlags;
2023-08-31 18:14:26 +08:00
ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS WILL ONLY BE None or NavGamepad or NavKeyboard.
2022-02-08 12:43:16 +08:00
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.
bool NavIdIsAlive; // Nav widget has been seen this frame ~~ NavRectRel is valid
bool NavMousePosDirty; // When set we will update mouse position if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) if set (NB: this not enabled by default)
bool NavDisableHighlight; // When user starts using mouse, we hide gamepad/keyboard highlight (NB: but they are still available, which is why NavDisableHighlight isn't always != NavDisableMouseHover)
bool NavDisableMouseHover; // When user starts using gamepad/keyboard, we hide mouse hovering highlight until mouse is touched again.
// Navigation: Init & Move Requests
bool NavAnyRequest; // ~~ NavMoveRequest || NavInitRequest this is to perform early out in ItemAdd()
bool NavInitRequest; // Init request for appearing window to select first item
bool NavInitRequestFromMove;
2023-08-31 18:14:26 +08:00
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)
2022-02-08 12:43:16 +08:00
bool NavMoveSubmitted; // Move request submitted, will process result on next NewFrame()
bool NavMoveScoringItems; // Move request submitted, still scoring incoming items
bool NavMoveForwardToNextFrame;
ImGuiNavMoveFlags NavMoveFlags;
ImGuiScrollFlags NavMoveScrollFlags;
2023-01-24 17:20:31 +08:00
ImGuiKeyChord NavMoveKeyMods;
2022-02-08 12:43:16 +08:00
ImGuiDir NavMoveDir; // Direction of the move request (left/right/up/down)
ImGuiDir NavMoveDirForDebug;
ImGuiDir NavMoveClipDir; // FIXME-NAV: Describe the purpose of this better. Might want to rename?
ImRect NavScoringRect; // Rectangle used for scoring, in screen space. Based of window->NavRectRel[], modified for directional navigation scoring.
ImRect NavScoringNoClipRect; // Some nav operations (such as PageUp/PageDown) enforce a region which clipper will attempt to always keep submitted
int NavScoringDebugCount; // Metrics for debugging
int NavTabbingDir; // Generally -1 or +1, 0 when tabbing without a nav id
int NavTabbingCounter; // >0 when counting items for tabbing
ImGuiNavItemData NavMoveResultLocal; // Best move request candidate within NavWindow
ImGuiNavItemData NavMoveResultLocalVisible; // Best move request candidate within NavWindow that are mostly visible (when using ImGuiNavMoveFlags_AlsoScoreVisibleSet flag)
ImGuiNavItemData NavMoveResultOther; // Best move request candidate within NavWindow's flattened hierarchy (when using ImGuiWindowFlags_NavFlattened flag)
ImGuiNavItemData NavTabbingResultFirst; // First tabbing request candidate within NavWindow and flattened hierarchy
2020-09-04 17:19:51 +08:00
// Navigation: Windowing (CTRL+TAB for list, or Menu button + keys or directional pads to move/resize)
2023-01-24 17:20:31 +08:00
ImGuiKeyChord ConfigNavWindowingKeyNext; // = ImGuiMod_Ctrl | ImGuiKey_Tab, for reconfiguration (see #4828)
ImGuiKeyChord ConfigNavWindowingKeyPrev; // = ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Tab
2022-02-08 12:43:16 +08:00
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;
2023-01-24 17:20:31 +08:00
ImVec2 NavWindowingAccumDeltaPos;
ImVec2 NavWindowingAccumDeltaSize;
2020-09-04 17:19:51 +08:00
// Render
2022-02-08 12:43:16 +08:00
float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list)
2023-08-31 18:14:26 +08:00
ImGuiMouseCursor MouseCursor;
2020-09-04 17:19:51 +08:00
// Drag and Drop
2022-02-08 12:43:16 +08:00
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
// Clipper
int ClipperTempDataStacked;
ImVector<ImGuiListClipperData> ClipperTempData;
2020-09-04 17:19:51 +08:00
// Tables
2022-02-08 12:43:16 +08:00
ImGuiTable* CurrentTable;
int TablesTempDataStacked; // Temporary table data size (because we leave previous instances undestructed, we generally don't use TablesTempData.Size)
ImVector<ImGuiTableTempData> TablesTempData; // Temporary table data (buffers reused/shared across instances, support nesting)
ImPool<ImGuiTable> Tables; // Persistent table data
ImVector<float> TablesLastTimeActive; // Last used timestamp of each tables (SOA, for efficient GC)
ImVector<ImDrawChannel> DrawChannelsTempMergeBuffer;
2021-06-15 22:30:54 +08:00
2020-09-04 17:19:51 +08:00
// Tab bars
2022-02-08 12:43:16 +08:00
ImGuiTabBar* CurrentTabBar;
ImPool<ImGuiTabBar> TabBars;
ImVector<ImGuiPtrOrIndex> CurrentTabBarStack;
ImVector<ImGuiShrinkWidthItem> ShrinkWidthBuffer;
2020-09-04 17:19:51 +08:00
2023-01-24 17:20:31 +08:00
// Hover Delay system
2023-08-31 18:14:26 +08:00
ImGuiID HoverDelayId;
ImGuiID HoverDelayIdPreviousFrame;
float HoverDelayTimer; // Currently used IsItemHovered(), generally inferred from g.HoveredIdTimer but kept uncleared until clear timer elapse.
float HoverDelayClearTimer; // Currently used IsItemHovered(): grace time before g.TooltipHoverTimer gets cleared.
2023-01-24 17:20:31 +08:00
2020-09-04 17:19:51 +08:00
// Widget state
2023-08-31 18:14:26 +08:00
ImVec2 MouseLastValidPos;
2022-02-08 12:43:16 +08:00
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
2023-08-31 18:14:26 +08:00
float ColorEditLastHue; // Backup of last Hue associated to LastColor, so we can restore Hue in lossy RGB<>HSV round trips
float ColorEditLastSat; // Backup of last Saturation associated to LastColor, so we can restore Saturation in lossy RGB<>HSV round trips
ImU32 ColorEditLastColor; // RGB value with alpha set to 0.
2022-02-08 12:43:16 +08:00
ImVec4 ColorPickerRef; // Initial/reference color at the time of opening the color picker.
ImGuiComboPreviewData ComboPreviewData;
float SliderGrabClickOffset;
2022-02-08 12:43:16 +08:00
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 ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage?
float DisabledAlphaBackup; // Backup for style.Alpha for BeginDisabled()
short DisabledStackSize;
short TooltipOverrideCount;
ImVector<char> ClipboardHandlerData; // If no custom clipboard handler is defined
ImVector<ImGuiID> MenusIdSubmittedThisFrame; // A list of menu IDs that were rendered at least once
2020-09-04 17:19:51 +08:00
// Platform support
2022-02-08 12:43:16 +08:00
ImGuiPlatformImeData PlatformImeData; // Data updated by current frame
ImGuiPlatformImeData PlatformImeDataPrev; // Previous frame data (when changing we will call io.SetPlatformImeDataFn
ImGuiID PlatformImeViewport;
char PlatformLocaleDecimalPoint; // '.' or *localeconv()->decimal_point
2020-09-04 17:19:51 +08:00
// Extensions
// FIXME: We could provide an API to register one slot in an array held in ImGuiContext?
2022-02-08 12:43:16 +08:00
ImGuiDockContext DockContext;
2020-09-04 17:19:51 +08:00
// Settings
2022-02-08 12:43:16 +08:00
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
2020-09-04 17:19:51 +08:00
2023-01-24 17:20:31 +08:00
// Localization
const char* LocalizationTable[ImGuiLocKey_COUNT];
2020-09-04 17:19:51 +08:00
// Capture/Logging
2022-02-08 12:43:16 +08:00
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.
2020-09-04 17:19:51 +08:00
// Debug Tools
ImGuiDebugLogFlags DebugLogFlags;
ImGuiTextBuffer DebugLogBuf;
2023-01-24 17:20:31 +08:00
ImGuiTextIndex DebugLogIndex;
ImU8 DebugLocateFrames; // For DebugLocateItemOnHover(). This is used together with DebugLocateId which is in a hot/cached spot above.
2022-02-08 12:43:16 +08:00
bool DebugItemPickerActive; // Item picker is active (started with DebugStartItemPicker())
2023-01-24 17:20:31 +08:00
ImU8 DebugItemPickerMouseButton;
2022-02-08 12:43:16 +08:00
ImGuiID DebugItemPickerBreakId; // Will call IM_DEBUG_BREAK() when encountering this ID
ImGuiMetricsConfig DebugMetricsConfig;
ImGuiStackTool DebugStackTool;
2023-01-24 17:20:31 +08:00
ImGuiDockNode* DebugHoveredDockNode; // Hovered dock node.
2020-09-04 17:19:51 +08:00
// Misc
2023-01-24 17:20:31 +08:00
float FramerateSecPerFrame[60]; // Calculate estimate of framerate for user over the last 60 frames..
2022-02-08 12:43:16 +08:00
int FramerateSecPerFrameIdx;
int FramerateSecPerFrameCount;
float FramerateSecPerFrameAccum;
int WantCaptureMouseNextFrame; // Explicit capture override via SetNextFrameWantCaptureMouse()/SetNextFrameWantCaptureKeyboard(). Default to -1.
int WantCaptureKeyboardNextFrame; // "
2022-02-08 12:43:16 +08:00
int WantTextInputNextFrame;
ImVector<char> TempBuffer; // Temporary text buffer
2020-09-04 17:19:51 +08:00
ImGuiContext(ImFontAtlas* shared_font_atlas)
2023-08-31 18:14:26 +08:00
: InputTextState(this)
2020-09-04 17:19:51 +08:00
{
2022-02-08 12:43:16 +08:00
Initialized = false;
2020-09-04 17:19:51 +08:00
ConfigFlagsCurrFrame = ConfigFlagsLastFrame = ImGuiConfigFlags_None;
2022-02-08 12:43:16 +08:00
FontAtlasOwnedByContext = shared_font_atlas ? false : true;
Font = NULL;
2020-09-04 17:19:51 +08:00
FontSize = FontBaseSize = 0.0f;
2022-02-08 12:43:16 +08:00
IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)();
Time = 0.0f;
FrameCount = 0;
2020-09-04 17:19:51 +08:00
FrameCountEnded = FrameCountPlatformEnded = FrameCountRendered = -1;
WithinFrameScope = WithinFrameScopeWithImplicitWindow = WithinEndChild = false;
2022-02-08 12:43:16 +08:00
GcCompactAll = false;
TestEngineHookItems = false;
TestEngine = NULL;
WindowsActiveCount = 0;
CurrentWindow = NULL;
HoveredWindow = NULL;
2020-09-04 17:19:51 +08:00
HoveredWindowUnderMovingWindow = NULL;
2022-02-08 12:43:16 +08:00
MovingWindow = NULL;
WheelingWindow = NULL;
2023-01-24 17:20:31 +08:00
WheelingWindowStartFrame = -1;
WheelingWindowReleaseTimer = 0.0f;
2020-09-04 17:19:51 +08:00
2022-02-08 12:43:16 +08:00
DebugHookIdInfo = 0;
2020-09-04 17:19:51 +08:00
HoveredId = HoveredIdPreviousFrame = 0;
2022-02-08 12:43:16 +08:00
HoveredIdAllowOverlap = false;
HoveredIdDisabled = false;
2020-09-04 17:19:51 +08:00
HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f;
2022-02-08 12:43:16 +08:00
ActiveId = 0;
ActiveIdIsAlive = 0;
ActiveIdTimer = 0.0f;
ActiveIdIsJustActivated = false;
ActiveIdAllowOverlap = false;
ActiveIdNoClearOnFocusLoss = false;
ActiveIdHasBeenPressedBefore = false;
ActiveIdHasBeenEditedBefore = false;
ActiveIdHasBeenEditedThisFrame = false;
ActiveIdClickOffset = ImVec2(-1, -1);
ActiveIdWindow = NULL;
ActiveIdSource = ImGuiInputSource_None;
ActiveIdMouseButton = -1;
ActiveIdPreviousFrame = 0;
ActiveIdPreviousFrameIsAlive = false;
2020-09-04 17:19:51 +08:00
ActiveIdPreviousFrameHasBeenEditedBefore = false;
2022-02-08 12:43:16 +08:00
ActiveIdPreviousFrameWindow = NULL;
LastActiveId = 0;
LastActiveIdTimer = 0.0f;
2020-09-04 17:19:51 +08:00
ActiveIdUsingNavDirMask = 0x00;
2023-01-24 17:20:31 +08:00
ActiveIdUsingAllKeyboardKeys = false;
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
ActiveIdUsingNavInputMask = 0x00;
2023-01-24 17:20:31 +08:00
#endif
2023-01-24 17:20:31 +08:00
CurrentFocusScopeId = 0;
2021-08-23 17:49:38 +08:00
CurrentItemFlags = ImGuiItemFlags_None;
2022-02-08 12:43:16 +08:00
BeginMenuCount = 0;
2021-08-23 17:49:38 +08:00
2020-09-04 17:19:51 +08:00
CurrentDpiScale = 0.0f;
CurrentViewport = NULL;
MouseViewport = MouseLastHoveredViewport = NULL;
2022-02-08 12:43:16 +08:00
PlatformLastFocusedViewportId = 0;
2023-08-31 18:14:26 +08:00
ViewportFrontMostStampCount = 0;
2020-09-04 17:19:51 +08:00
NavWindow = NULL;
2023-08-31 18:14:26 +08:00
NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = NavActivateInputId = 0;
2022-02-08 12:43:16 +08:00
NavJustMovedToId = NavJustMovedToFocusScopeId = NavNextActivateId = 0;
NavActivateFlags = NavNextActivateFlags = ImGuiActivateFlags_None;
2023-01-24 17:20:31 +08:00
NavJustMovedToKeyMods = ImGuiMod_None;
2023-08-31 18:14:26 +08:00
NavInputSource = ImGuiInputSource_None;
2022-02-08 12:43:16 +08:00
NavLayer = ImGuiNavLayer_Main;
NavIdIsAlive = false;
NavMousePosDirty = false;
NavDisableHighlight = true;
NavDisableMouseHover = false;
NavAnyRequest = false;
NavInitRequest = false;
NavInitRequestFromMove = false;
2023-08-31 18:14:26 +08:00
NavInitResultId = 0;
2022-02-08 12:43:16 +08:00
NavMoveSubmitted = false;
NavMoveScoringItems = false;
NavMoveForwardToNextFrame = false;
NavMoveFlags = ImGuiNavMoveFlags_None;
NavMoveScrollFlags = ImGuiScrollFlags_None;
2023-01-24 17:20:31 +08:00
NavMoveKeyMods = ImGuiMod_None;
2022-02-08 12:43:16 +08:00
NavMoveDir = NavMoveDirForDebug = NavMoveClipDir = ImGuiDir_None;
NavScoringDebugCount = 0;
NavTabbingDir = 0;
NavTabbingCounter = 0;
2020-09-04 17:19:51 +08:00
2023-01-24 17:20:31 +08:00
ConfigNavWindowingKeyNext = ImGuiMod_Ctrl | ImGuiKey_Tab;
ConfigNavWindowingKeyPrev = ImGuiMod_Ctrl | ImGuiMod_Shift | ImGuiKey_Tab;
2020-09-04 17:19:51 +08:00
NavWindowingTarget = NavWindowingTargetAnim = NavWindowingListWindow = NULL;
NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f;
2022-02-08 12:43:16 +08:00
NavWindowingToggleLayer = false;
2020-09-04 17:19:51 +08:00
2022-02-08 12:43:16 +08:00
DimBgRatio = 0.0f;
2023-08-31 18:14:26 +08:00
MouseCursor = ImGuiMouseCursor_Arrow;
2020-09-04 17:19:51 +08:00
DragDropActive = DragDropWithinSource = DragDropWithinTarget = false;
2022-02-08 12:43:16 +08:00
DragDropSourceFlags = ImGuiDragDropFlags_None;
DragDropSourceFrameCount = -1;
DragDropMouseButton = -1;
DragDropTargetId = 0;
DragDropAcceptFlags = ImGuiDragDropFlags_None;
DragDropAcceptIdCurrRectSurface = 0.0f;
2020-09-04 17:19:51 +08:00
DragDropAcceptIdPrev = DragDropAcceptIdCurr = 0;
2022-02-08 12:43:16 +08:00
DragDropAcceptFrameCount = -1;
DragDropHoldJustPressedId = 0;
2020-09-04 17:19:51 +08:00
memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal));
2022-02-08 12:43:16 +08:00
ClipperTempDataStacked = 0;
CurrentTable = NULL;
TablesTempDataStacked = 0;
CurrentTabBar = NULL;
2020-09-04 17:19:51 +08:00
2023-08-31 18:14:26 +08:00
HoverDelayId = HoverDelayIdPreviousFrame = 0;
HoverDelayTimer = HoverDelayClearTimer = 0.0f;
2023-01-24 17:20:31 +08:00
2022-02-08 12:43:16 +08:00
TempInputId = 0;
ColorEditOptions = ImGuiColorEditFlags_DefaultOptions_;
2023-08-31 18:14:26 +08:00
ColorEditLastHue = ColorEditLastSat = 0.0f;
ColorEditLastColor = 0;
SliderGrabClickOffset = 0.0f;
2022-02-08 12:43:16 +08:00
SliderCurrentAccum = 0.0f;
SliderCurrentAccumDirty = false;
DragCurrentAccumDirty = false;
DragCurrentAccum = 0.0f;
DragSpeedDefaultRatio = 1.0f / 100.0f;
2023-01-24 17:20:31 +08:00
ScrollbarClickDeltaToGrabCenter = 0.0f;
2022-02-08 12:43:16 +08:00
DisabledAlphaBackup = 0.0f;
DisabledStackSize = 0;
TooltipOverrideCount = 0;
PlatformImeData.InputPos = ImVec2(0.0f, 0.0f);
PlatformImeDataPrev.InputPos = ImVec2(-1.0f, -1.0f); // Different to ensure initial submission
PlatformImeViewport = 0;
PlatformLocaleDecimalPoint = '.';
SettingsLoaded = false;
2020-09-04 17:19:51 +08:00
SettingsDirtyTimer = 0.0f;
2022-02-08 12:43:16 +08:00
HookIdNext = 0;
2020-09-04 17:19:51 +08:00
2023-01-24 17:20:31 +08:00
memset(LocalizationTable, 0, sizeof(LocalizationTable));
2022-02-08 12:43:16 +08:00
LogEnabled = false;
LogType = ImGuiLogType_None;
2021-06-15 22:30:54 +08:00
LogNextPrefix = LogNextSuffix = NULL;
2022-02-08 12:43:16 +08:00
LogFile = NULL;
LogLinePosY = FLT_MAX;
LogLineFirstItem = false;
LogDepthRef = 0;
2020-09-04 17:19:51 +08:00
LogDepthToExpand = LogDepthToExpandDefault = 2;
DebugLogFlags = ImGuiDebugLogFlags_OutputToTTY;
2023-01-24 17:20:31 +08:00
DebugLocateId = 0;
DebugLocateFrames = 0;
2022-02-08 12:43:16 +08:00
DebugItemPickerActive = false;
2023-01-24 17:20:31 +08:00
DebugItemPickerMouseButton = ImGuiMouseButton_Left;
2020-09-04 17:19:51 +08:00
DebugItemPickerBreakId = 0;
2023-01-24 17:20:31 +08:00
DebugHoveredDockNode = NULL;
2020-09-04 17:19:51 +08:00
memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame));
2021-06-15 22:30:54 +08:00
FramerateSecPerFrameIdx = FramerateSecPerFrameCount = 0;
2022-02-08 12:43:16 +08:00
FramerateSecPerFrameAccum = 0.0f;
2020-09-04 17:19:51 +08:00
WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = WantTextInputNextFrame = -1;
}
};
//-----------------------------------------------------------------------------
// [SECTION] ImGuiWindowTempData, ImGuiWindow
//-----------------------------------------------------------------------------
2022-02-08 12:43:16 +08:00
// 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)
2020-09-04 17:19:51 +08:00
struct IMGUI_API ImGuiWindowTempData
{
// Layout
2022-02-08 12:43:16 +08:00
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;
bool IsSameLine;
2023-01-24 17:20:31 +08:00
bool IsSetPos;
2022-02-08 12:43:16 +08:00
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;
2023-08-31 18:14:26 +08:00
ImVec2 CursorStartPosLossyness;// Record the loss of precision of CursorStartPos due to really large scrolling amount. This is used by clipper to compensentate and fix the most common use case of large scroll area.
2020-09-04 17:19:51 +08:00
// Keyboard/Gamepad navigation
2022-02-08 12:43:16 +08:00
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)
bool NavHideHighlightOneFrame;
2023-08-31 18:14:26 +08:00
bool NavHasScroll; // Set when scrolling can be used (ScrollMax > 0.0f)
2020-09-04 17:19:51 +08:00
// Miscellaneous
2022-02-08 12:43:16 +08:00
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()
2020-09-04 17:19:51 +08:00
// Local parameters stacks
2022-02-08 12:43:16 +08:00
// 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)
2020-09-04 17:19:51 +08:00
};
// Storage for one window
struct IMGUI_API ImGuiWindow
{
2022-02-08 12:43:16 +08:00
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(). Inactive windows may have a NULL value here if their viewport was discarded.
2022-02-08 12:43:16 +08:00
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().
2023-01-24 17:20:31 +08:00
float DecoOuterSizeX1, DecoOuterSizeY1; // Left/Up offsets. Sum of non-scrolling outer decorations (X1 generally == 0.0f. Y1 generally = TitleBarHeight + MenuBarHeight). Locked during Begin().
float DecoOuterSizeX2, DecoOuterSizeY2; // Right/Down offsets (X2 generally == ScrollbarSize.x, Y2 == ScrollbarSizes.y).
float DecoInnerSizeX1, DecoInnerSizeY1; // Applied AFTER/OVER InnerRect. Specialized for Tables as they use specialized form of clipping and frozen rows/columns are inside InnerRect (and not part of regular decoration sizes).
2022-02-08 12:43:16 +08:00
int NameBufLen; // Size of buffer storing Name. May be larger than strlen(Name)!
ImGuiID MoveId; // == window->GetID("#MOVE")
ImGuiID TabId; // == window->GetID("#TAB")
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 IsExplicitChild; // Set when passed _ChildWindow, left to false by BeginDocked()
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)
2023-01-24 17:20:31 +08:00
short BeginCountPreviousFrame; // Number of Begin() during the previous frame
2022-02-08 12:43:16 +08:00
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;
2021-06-15 22:30:54 +08:00
ImVector<ImGuiOldColumns> ColumnsStorage;
2022-02-08 12:43:16 +08:00
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 _or_ docked window, this is pointing to our parent. Otherwise NULL.
ImGuiWindow* ParentWindowInBeginStack;
ImGuiWindow* RootWindow; // Point to ourself or first ancestor that is not a child window. Doesn't cross through popups/dock nodes.
ImGuiWindow* RootWindowPopupTree; // Point to ourself or first ancestor that is not a child window. Cross through popups parent<>child.
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
2023-01-24 17:20:31 +08:00
ImGuiID NavRootFocusScopeId; // Focus Scope ID at the time of Begin()
2022-02-08 12:43:16 +08:00
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
2020-09-04 17:19:51 +08:00
// Docking
2022-02-08 12:43:16 +08:00
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;
2020-09-04 17:19:51 +08:00
public:
ImGuiWindow(ImGuiContext* context, const char* name);
~ImGuiWindow();
2022-02-08 12:43:16 +08:00
ImGuiID GetID(const char* str, const char* str_end = NULL);
ImGuiID GetID(const void* ptr);
ImGuiID GetID(int n);
ImGuiID GetIDFromRectangle(const ImRect& r_abs);
2020-09-04 17:19:51 +08:00
2023-01-24 17:20:31 +08:00
// We don't use g.FontSize because the window may be != g.CurrentWindow.
2022-02-08 12:43:16 +08:00
ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
2023-08-31 18:14:26 +08:00
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; }
2022-02-08 12:43:16 +08:00
ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight())); }
2023-08-31 18:14:26 +08:00
float MenuBarHeight() const { ImGuiContext& g = *GImGui; return (Flags & ImGuiWindowFlags_MenuBar) ? DC.MenuBarOffset.y + CalcFontSize() + g.Style.FramePadding.y * 2.0f : 0.0f; }
2022-02-08 12:43:16 +08:00
ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight(); return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight()); }
2020-09-04 17:19:51 +08:00
};
//-----------------------------------------------------------------------------
// [SECTION] Tab bar, Tab item support
//-----------------------------------------------------------------------------
// Extend ImGuiTabBarFlags_
enum ImGuiTabBarFlagsPrivate_
{
2022-02-08 12:43:16 +08:00
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,
2023-01-24 17:20:31 +08:00
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
2020-09-04 17:19:51 +08:00
};
// Extend ImGuiTabItemFlags_
enum ImGuiTabItemFlagsPrivate_
{
2022-02-08 12:43:16 +08:00
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.
2023-01-24 17:20:31 +08:00
ImGuiTabItemFlags_Preview = 1 << 23, // [Docking] Display tab shape for docking preview (height is adjusted slightly to compensate for the yet missing tab bar)
2020-09-04 17:19:51 +08:00
};
2021-06-15 22:30:54 +08:00
// Storage for one active tab item (sizeof() 48 bytes)
2020-09-04 17:19:51 +08:00
struct ImGuiTabItem
{
2022-02-08 12:43:16 +08:00
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
float RequestedWidth; // Width optionally requested by caller, -1.0f is unused
2022-02-08 12:43:16 +08:00
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
2023-08-31 18:14:26 +08:00
ImS16 IndexDuringLayout; // Index only used during TabBarLayout()
2022-02-08 12:43:16 +08:00
bool WantClose; // Marked as closed by SetTabItemClosed()
2023-01-24 17:20:31 +08:00
ImGuiTabItem() { memset(this, 0, sizeof(*this)); LastFrameVisible = LastFrameSelected = -1; RequestedWidth = -1.0f; NameOffset = -1; BeginOrder = IndexDuringLayout = -1; }
2020-09-04 17:19:51 +08:00
};
2021-06-15 22:30:54 +08:00
// Storage for a tab bar (sizeof() 152 bytes)
struct IMGUI_API ImGuiTabBar
2020-09-04 17:19:51 +08:00
{
ImVector<ImGuiTabItem> Tabs;
2022-02-08 12:43:16 +08:00
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.
2020-09-04 17:19:51 +08:00
ImGuiTabBar();
2023-08-31 18:14:26 +08:00
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;
}
2020-09-04 17:19:51 +08:00
};
//-----------------------------------------------------------------------------
// [SECTION] Table support
//-----------------------------------------------------------------------------
2022-02-08 12:43:16 +08:00
#define IM_COL32_DISABLE IM_COL32(0,0,0,1) // Special sentinel code which cannot be used as a regular color.
2023-01-24 17:20:31 +08:00
#define IMGUI_TABLE_MAX_COLUMNS 512 // May be further lifted
2021-06-15 22:30:54 +08:00
// Our current column maximum is 64 but we may raise that in the future.
2023-01-24 17:20:31 +08:00
typedef ImS16 ImGuiTableColumnIdx;
typedef ImU16 ImGuiTableDrawChannelIdx;
2021-06-15 22:30:54 +08:00
2023-08-31 18:14:26 +08:00
// [Internal] sizeof() ~ 104
2021-06-15 22:30:54 +08:00
// 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.
2022-02-08 12:43:16 +08:00
// This is in contrast with some user-facing api such as IsItemVisible() / IsRectVisible() which use "Visible" to mean "not clipped".
2021-06-15 22:30:54 +08:00
struct ImGuiTableColumn
{
2022-02-08 12:43:16 +08:00
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)
2023-08-31 18:14:26 +08:00
ImU8 SortDirectionsAvailList; // Ordered of available sort directions (2-bits each)
2021-06-15 22:30:54 +08:00
ImGuiTableColumn()
{
memset(this, 0, sizeof(*this));
StretchWeight = WidthRequest = -1.0f;
2022-02-08 12:43:16 +08:00
NameOffset = -1;
2021-06-15 22:30:54 +08:00
DisplayOrder = IndexWithinEnabledSet = -1;
PrevEnabledColumn = NextEnabledColumn = -1;
2022-02-08 12:43:16 +08:00
SortOrder = -1;
SortDirection = ImGuiSortDirection_None;
2021-06-15 22:30:54 +08:00
DrawChannelCurrent = DrawChannelFrozen = DrawChannelUnfrozen = (ImU8)-1;
}
};
// Transient cell data stored per row.
// sizeof() ~ 6
struct ImGuiTableCellData
{
2022-02-08 12:43:16 +08:00
ImU32 BgColor; // Actual color
ImGuiTableColumnIdx Column; // Column number
};
2023-08-31 18:14:26 +08:00
// Per-instance data that needs preserving across frames (seemingly most others do not need to be preserved aside from debug needs, does that needs they could be moved to ImGuiTableTempData ?)
struct ImGuiTableInstanceData
{
2023-01-24 17:20:31 +08:00
float LastOuterHeight; // Outer height from last frame
float LastFirstRowHeight; // Height of first row from last frame (FIXME: this is used as "header height" and may be reworked)
float LastFrozenHeight; // Height of frozen section from last frame
2023-08-31 18:14:26 +08:00
ImGuiTableInstanceData() { LastOuterHeight = LastFirstRowHeight = LastFrozenHeight = 0.0f; }
};
2023-01-24 17:20:31 +08:00
// FIXME-TABLE: more transient data could be stored in a stacked ImGuiTableTempData: e.g. SortSpecs, incoming RowData
2022-02-08 12:43:16 +08:00
struct IMGUI_API 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.
2023-01-24 17:20:31 +08:00
ImBitArrayPtr EnabledMaskByDisplayOrder; // Column DisplayOrder -> IsEnabled map
ImBitArrayPtr EnabledMaskByIndex; // Column Index -> IsEnabled map (== not hidden by user/api) in a format adequate for iterating column without touching cold data
ImBitArrayPtr VisibleMaskByIndex; // Column Index -> IsVisibleX|IsVisibleY map (== not hidden by user/api && not hidden by scrolling/cliprect)
2022-02-08 12:43:16 +08:00
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 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 ColumnsStretchSumWeights; // Sum of weight of all enabled stretching columns
2022-02-08 12:43:16 +08:00
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, evolve during the frame as we cross frozen rows boundaries
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
ImGuiTableInstanceData InstanceDataFirst;
ImVector<ImGuiTableInstanceData> InstanceDataExtra; // FIXME-OPT: Using a small-vector pattern would be good.
2022-02-08 12:43:16 +08:00
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()
2023-01-24 17:20:31 +08:00
bool HasScrollbarYCurr; // Whether ANY instance of this table had a vertical scrollbar during the current frame.
bool HasScrollbarYPrev; // Whether ANY instance of this table had a vertical scrollbar during the previous.
2022-02-08 12:43:16 +08:00
bool MemoryCompacted;
bool HostSkipItems; // Backup of InnerWindow->SkipItem at the end of BeginTable(), because we will overwrite InnerWindow->SkipItem on a per-column basis
ImGuiTable() { memset(this, 0, sizeof(*this)); LastFrameActive = -1; }
~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.
2021-06-15 22:30:54 +08:00
// - We also leave out of this structure data that tend to be particularly useful for debugging/metrics.
2022-02-08 12:43:16 +08:00
struct IMGUI_API ImGuiTableTempData
2021-06-15 22:30:54 +08:00
{
2022-02-08 12:43:16 +08:00
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()
ImGuiTableTempData() { memset(this, 0, sizeof(*this)); LastTimeActive = -1.0f; }
2021-06-15 22:30:54 +08:00
};
// sizeof() ~ 12
struct ImGuiTableColumnSettings
{
2022-02-08 12:43:16 +08:00
float WidthOrWeight;
ImGuiID UserID;
ImGuiTableColumnIdx Index;
ImGuiTableColumnIdx DisplayOrder;
ImGuiTableColumnIdx SortOrder;
ImU8 SortDirection : 2;
ImU8 IsEnabled : 1; // "Visible" in ini file
ImU8 IsStretch : 1;
2021-06-15 22:30:54 +08:00
ImGuiTableColumnSettings()
{
WidthOrWeight = 0.0f;
2022-02-08 12:43:16 +08:00
UserID = 0;
Index = -1;
2021-06-15 22:30:54 +08:00
DisplayOrder = SortOrder = -1;
2022-02-08 12:43:16 +08:00
SortDirection = ImGuiSortDirection_None;
IsEnabled = 1;
IsStretch = 0;
2021-06-15 22:30:54 +08:00
}
};
// This is designed to be stored in a single ImChunkStream (1 header followed by N ImGuiTableColumnSettings, etc.)
struct ImGuiTableSettings
{
2022-02-08 12:43:16 +08:00
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); }
2021-06-15 22:30:54 +08:00
};
2020-09-04 17:19:51 +08:00
//-----------------------------------------------------------------------------
2021-06-15 22:30:54 +08:00
// [SECTION] ImGui internal API
2020-09-04 17:19:51 +08:00
// No guarantee of forward compatibility here!
//-----------------------------------------------------------------------------
namespace ImGui
{
2022-02-08 12:43:16 +08:00
// 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, bool popup_hierarchy, bool dock_hierarchy);
IMGUI_API bool IsWindowWithinBeginStackOf(ImGuiWindow* window, ImGuiWindow* potential_parent);
IMGUI_API bool IsWindowAbove(ImGuiWindow* potential_above, ImGuiWindow* potential_below);
IMGUI_API bool IsWindowNavFocusable(ImGuiWindow* window);
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);
inline ImRect WindowRectAbsToRel(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x - off.x, r.Min.y - off.y, r.Max.x - off.x, r.Max.y - off.y); }
inline ImRect WindowRectRelToAbs(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x + off.x, r.Min.y + off.y, r.Max.x + off.x, r.Max.y + off.y); }
// Windows: Display Order and Focus Order
2023-08-31 18:14:26 +08:00
IMGUI_API void FocusWindow(ImGuiWindow* window);
IMGUI_API void FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window);
2022-02-08 12:43:16 +08:00
IMGUI_API void BringWindowToFocusFront(ImGuiWindow* window);
IMGUI_API void BringWindowToDisplayFront(ImGuiWindow* window);
IMGUI_API void BringWindowToDisplayBack(ImGuiWindow* window);
IMGUI_API void BringWindowToDisplayBehind(ImGuiWindow* window, ImGuiWindow* above_window);
IMGUI_API int FindWindowDisplayIndex(ImGuiWindow* window);
IMGUI_API ImGuiWindow* FindBottomMostVisibleWindowWithinBeginStack(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();
IMGUI_API void Shutdown(); // Since 1.60 this is a _private_ function. You can call DestroyContext() to destroy the context created by CreateContext().
2022-02-08 12:43:16 +08:00
// NewFrame
IMGUI_API void UpdateInputEvents(bool trickle_fast_inputs);
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);
2020-09-04 17:19:51 +08:00
2022-02-08 12:43:16 +08:00
// 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 SetWindowViewport(ImGuiWindow* window, ImGuiViewportP* viewport);
2022-02-08 12:43:16 +08:00
IMGUI_API void SetCurrentViewport(ImGuiWindow* window, ImGuiViewportP* viewport);
IMGUI_API const ImGuiPlatformMonitor* GetViewportPlatformMonitor(ImGuiViewport* viewport);
IMGUI_API ImGuiViewportP* FindHoveredViewportFromPlatformWindowStack(const ImVec2& mouse_platform_pos);
2020-09-04 17:19:51 +08:00
2022-02-08 12:43:16 +08:00
// Settings
IMGUI_API void MarkIniSettingsDirty();
IMGUI_API void MarkIniSettingsDirty(ImGuiWindow* window);
IMGUI_API void ClearIniSettings();
2023-08-31 18:14:26 +08:00
IMGUI_API ImGuiWindowSettings* CreateNewWindowSettings(const char* name);
IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id);
IMGUI_API ImGuiWindowSettings* FindOrCreateWindowSettings(const char* name);
IMGUI_API void AddSettingsHandler(const ImGuiSettingsHandler* handler);
IMGUI_API void RemoveSettingsHandler(const char* type_name);
2022-02-08 12:43:16 +08:00
IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name);
2023-01-24 17:20:31 +08:00
// Localization
IMGUI_API void LocalizeRegisterEntries(const ImGuiLocEntry* entries, int count);
inline const char* LocalizeGetMsg(ImGuiLocKey key) { ImGuiContext& g = *GImGui; const char* msg = g.LocalizationTable[key]; return msg ? msg : "*Missing Text*"; }
2022-02-08 12:43:16 +08:00
// Scrolling
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);
// Early work-in-progress API (ScrollToItem() will become public)
IMGUI_API void ScrollToItem(ImGuiScrollFlags flags = 0);
IMGUI_API void ScrollToRect(ImGuiWindow* window, const ImRect& rect, ImGuiScrollFlags flags = 0);
IMGUI_API ImVec2 ScrollToRectEx(ImGuiWindow* window, const ImRect& rect, ImGuiScrollFlags flags = 0);
//#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
inline void ScrollToBringRectIntoView(ImGuiWindow* window, const ImRect& rect) { ScrollToRect(window, rect, ImGuiScrollFlags_KeepVisibleEdgeY); }
//#endif
// Basic Accessors
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);
inline void ItemSize(const ImRect& bb, float text_baseline_y = -1.0f) { ItemSize(bb.GetSize(), text_baseline_y); } // FIXME: This is a misleading API since we expect CursorPos to be bb.Min.
2022-02-08 12:43:16 +08:00
IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL, ImGuiItemFlags extra_flags = 0);
2023-08-31 18:14:26 +08:00
IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id);
2022-02-08 12:43:16 +08:00
IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id);
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);
2023-01-24 17:20:31 +08:00
// Parameter stacks (shared)
2022-02-08 12:43:16 +08:00
IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled);
IMGUI_API void PopItemFlag();
// 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 void ClosePopupsExceptModals();
IMGUI_API bool IsPopupOpen(ImGuiID id, ImGuiPopupFlags popup_flags);
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags);
2023-08-31 18:14:26 +08:00
IMGUI_API void BeginTooltipEx(ImGuiTooltipFlags tooltip_flags, ImGuiWindowFlags extra_window_flags);
2022-02-08 12:43:16 +08:00
IMGUI_API ImRect GetPopupAllowedExtentRect(ImGuiWindow* window);
IMGUI_API ImGuiWindow* GetTopMostPopupModal();
IMGUI_API ImGuiWindow* GetTopMostAndVisiblePopupModal();
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);
// Menus
IMGUI_API bool BeginViewportSideBar(const char* name, ImGuiViewport* viewport, ImGuiDir dir, float size, ImGuiWindowFlags window_flags);
IMGUI_API bool BeginMenuEx(const char* label, const char* icon, bool enabled = true);
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 void NavInitRequestApplyResult();
IMGUI_API bool NavMoveRequestButNoResultYet();
IMGUI_API void NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags, ImGuiScrollFlags scroll_flags);
IMGUI_API void NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags, ImGuiScrollFlags scroll_flags);
IMGUI_API void NavMoveRequestResolveWithLastItem(ImGuiNavItemData* result);
IMGUI_API void NavMoveRequestCancel();
IMGUI_API void NavMoveRequestApplyResult();
IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags move_flags);
2023-08-31 18:14:26 +08:00
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 SetNavWindow(ImGuiWindow* window);
2022-02-08 12:43:16 +08:00
IMGUI_API void SetNavID(ImGuiID id, ImGuiNavLayer nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel);
// Inputs
// FIXME: Eventually we should aim to move e.g. IsActiveIdUsingKey() into IsKeyXXX functions.
inline bool IsNamedKey(ImGuiKey key) { return key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END; }
2023-01-24 17:20:31 +08:00
inline bool IsNamedKeyOrModKey(ImGuiKey key) { return (key >= ImGuiKey_NamedKey_BEGIN && key < ImGuiKey_NamedKey_END) || key == ImGuiMod_Ctrl || key == ImGuiMod_Shift || key == ImGuiMod_Alt || key == ImGuiMod_Super || key == ImGuiMod_Shortcut; }
2022-02-08 12:43:16 +08:00
inline bool IsLegacyKey(ImGuiKey key) { return key >= ImGuiKey_LegacyNativeKey_BEGIN && key < ImGuiKey_LegacyNativeKey_END; }
2023-01-24 17:20:31 +08:00
inline bool IsKeyboardKey(ImGuiKey key) { return key >= ImGuiKey_Keyboard_BEGIN && key < ImGuiKey_Keyboard_END; }
2022-02-08 12:43:16 +08:00
inline bool IsGamepadKey(ImGuiKey key) { return key >= ImGuiKey_Gamepad_BEGIN && key < ImGuiKey_Gamepad_END; }
2023-01-24 17:20:31 +08:00
inline bool IsMouseKey(ImGuiKey key) { return key >= ImGuiKey_Mouse_BEGIN && key < ImGuiKey_Mouse_END; }
inline bool IsAliasKey(ImGuiKey key) { return key >= ImGuiKey_Aliases_BEGIN && key < ImGuiKey_Aliases_END; }
inline ImGuiKeyChord ConvertShortcutMod(ImGuiKeyChord key_chord) { ImGuiContext& g = *GImGui; IM_ASSERT_PARANOID(key_chord & ImGuiMod_Shortcut); return (key_chord & ~ImGuiMod_Shortcut) | (g.IO.ConfigMacOSXBehaviors ? ImGuiMod_Super : ImGuiMod_Ctrl); }
2023-08-31 18:14:26 +08:00
inline ImGuiKey ConvertSingleModFlagToKey(ImGuiKey key)
2023-01-24 17:20:31 +08:00
{
2023-08-31 18:14:26 +08:00
ImGuiContext& g = *GImGui;
2023-01-24 17:20:31 +08:00
if (key == ImGuiMod_Ctrl) return ImGuiKey_ReservedForModCtrl;
if (key == ImGuiMod_Shift) return ImGuiKey_ReservedForModShift;
if (key == ImGuiMod_Alt) return ImGuiKey_ReservedForModAlt;
if (key == ImGuiMod_Super) return ImGuiKey_ReservedForModSuper;
if (key == ImGuiMod_Shortcut) return (g.IO.ConfigMacOSXBehaviors ? ImGuiKey_ReservedForModSuper : ImGuiKey_ReservedForModCtrl);
return key;
}
2023-08-31 18:14:26 +08:00
IMGUI_API ImGuiKeyData* GetKeyData(ImGuiKey key);
2023-01-24 17:20:31 +08:00
IMGUI_API void GetKeyChordName(ImGuiKeyChord key_chord, char* out_buf, int out_buf_size);
inline ImGuiKey MouseButtonToKey(ImGuiMouseButton button) { IM_ASSERT(button >= 0 && button < ImGuiMouseButton_COUNT); return (ImGuiKey)(ImGuiKey_MouseLeft + button); }
2022-02-08 12:43:16 +08:00
IMGUI_API bool IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold = -1.0f);
2023-01-24 17:20:31 +08:00
IMGUI_API ImVec2 GetKeyMagnitude2d(ImGuiKey key_left, ImGuiKey key_right, ImGuiKey key_up, ImGuiKey key_down);
IMGUI_API float GetNavTweakPressedAmount(ImGuiAxis axis);
IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate);
IMGUI_API void GetTypematicRepeatRate(ImGuiInputFlags flags, float* repeat_delay, float* repeat_rate);
IMGUI_API void SetActiveIdUsingAllKeyboardKeys();
inline bool IsActiveIdUsingNavDir(ImGuiDir dir) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavDirMask & (1 << dir)) != 0; }
// [EXPERIMENTAL] Low-Level: Key/Input Ownership
// - The idea is that instead of "eating" a given input, we can link to an owner id.
// - Ownership is most often claimed as a result of reacting to a press/down event (but occasionally may be claimed ahead).
// - Input queries can then read input by specifying ImGuiKeyOwner_Any (== 0), ImGuiKeyOwner_None (== -1) or a custom ID.
// - Legacy input queries (without specifying an owner or _Any or _None) are equivalent to using ImGuiKeyOwner_Any (== 0).
// - Input ownership is automatically released on the frame after a key is released. Therefore:
// - for ownership registration happening as a result of a down/press event, the SetKeyOwner() call may be done once (common case).
// - for ownership registration happening ahead of a down/press event, the SetKeyOwner() call needs to be made every frame (happens if e.g. claiming ownership on hover).
// - SetItemKeyOwner() is a shortcut for common simple case. A custom widget will probably want to call SetKeyOwner() multiple times directly based on its interaction state.
// - This is marked experimental because not all widgets are fully honoring the Set/Test idioms. We will need to move forward step by step.
// Please open a GitHub Issue to submit your usage scenario or if there's a use case you need solved.
IMGUI_API ImGuiID GetKeyOwner(ImGuiKey key);
IMGUI_API void SetKeyOwner(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags = 0);
IMGUI_API void SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags = 0); // Set key owner to last item if it is hovered or active. Equivalent to 'if (IsItemHovered() || IsItemActive()) { SetKeyOwner(key, GetItemID());'.
IMGUI_API bool TestKeyOwner(ImGuiKey key, ImGuiID owner_id); // Test that key is either not owned, either owned by 'owner_id'
2023-08-31 18:14:26 +08:00
inline ImGuiKeyOwnerData* GetKeyOwnerData(ImGuiKey key) { if (key & ImGuiMod_Mask_) key = ConvertSingleModFlagToKey(key); IM_ASSERT(IsNamedKey(key)); return &GImGui->KeysOwnerData[key - ImGuiKey_NamedKey_BEGIN]; }
2023-01-24 17:20:31 +08:00
// [EXPERIMENTAL] High-Level: Input Access functions w/ support for Key/Input Ownership
// - Important: legacy IsKeyPressed(ImGuiKey, bool repeat=true) _DEFAULTS_ to repeat, new IsKeyPressed() requires _EXPLICIT_ ImGuiInputFlags_Repeat flag.
// - Expected to be later promoted to public API, the prototypes are designed to replace existing ones (since owner_id can default to Any == 0)
// - Specifying a value for 'ImGuiID owner' will test that EITHER the key is NOT owned (UNLESS locked), EITHER the key is owned by 'owner'.
// Legacy functions use ImGuiKeyOwner_Any meaning that they typically ignore ownership, unless a call to SetKeyOwner() explicitly used ImGuiInputFlags_LockThisFrame or ImGuiInputFlags_LockUntilRelease.
// - Binding generators may want to ignore those for now, or suffix them with Ex() until we decide if this gets moved into public API.
IMGUI_API bool IsKeyDown(ImGuiKey key, ImGuiID owner_id);
IMGUI_API bool IsKeyPressed(ImGuiKey key, ImGuiID owner_id, ImGuiInputFlags flags = 0); // Important: when transitioning from old to new IsKeyPressed(): old API has "bool repeat = true", so would default to repeat. New API requiress explicit ImGuiInputFlags_Repeat.
IMGUI_API bool IsKeyReleased(ImGuiKey key, ImGuiID owner_id);
IMGUI_API bool IsMouseDown(ImGuiMouseButton button, ImGuiID owner_id);
IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, ImGuiID owner_id, ImGuiInputFlags flags = 0);
IMGUI_API bool IsMouseReleased(ImGuiMouseButton button, ImGuiID owner_id);
// [EXPERIMENTAL] Shortcut Routing
// - ImGuiKeyChord = a ImGuiKey optionally OR-red with ImGuiMod_Alt/ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Super.
// ImGuiKey_C (accepted by functions taking ImGuiKey or ImGuiKeyChord)
// ImGuiKey_C | ImGuiMod_Ctrl (accepted by functions taking ImGuiKeyChord)
// ONLY ImGuiMod_XXX values are legal to 'OR' with an ImGuiKey. You CANNOT 'OR' two ImGuiKey values.
// - When using one of the routing flags (e.g. ImGuiInputFlags_RouteFocused): routes requested ahead of time given a chord (key + modifiers) and a routing policy.
// - Routes are resolved during NewFrame(): if keyboard modifiers are matching current ones: SetKeyOwner() is called + route is granted for the frame.
// - Route is granted to a single owner. When multiple requests are made we have policies to select the winning route.
// - Multiple read sites may use the same owner id and will all get the granted route.
// - For routing: when owner_id is 0 we use the current Focus Scope ID as a default owner in order to identify our location.
IMGUI_API bool Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0);
IMGUI_API bool SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0);
IMGUI_API bool TestShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id);
IMGUI_API ImGuiKeyRoutingData* GetShortcutRoutingData(ImGuiKeyChord key_chord);
2022-02-08 12:43:16 +08:00
// 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 void DockContextEndFrame(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);
2023-01-24 17:20:31 +08:00
IMGUI_API bool DockContextCalcDropPosForDocking(ImGuiWindow* target, ImGuiDockNode* target_node, ImGuiWindow* payload_window, ImGuiDockNode* payload_node, ImGuiDir split_dir, bool split_outer, ImVec2* out_pos);
IMGUI_API ImGuiDockNode*DockContextFindNodeByID(ImGuiContext* ctx, ImGuiID id);
2022-02-08 12:43:16 +08:00
IMGUI_API bool DockNodeBeginAmendTabBar(ImGuiDockNode* node);
IMGUI_API void DockNodeEndAmendTabBar();
inline ImGuiDockNode* DockNodeGetRootNode(ImGuiDockNode* node) { while (node->ParentNode) node = node->ParentNode; return node; }
inline bool DockNodeIsInHierarchyOf(ImGuiDockNode* node, ImGuiDockNode* parent) { while (node) { if (node == parent) return true; node = node->ParentNode; } return false; }
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);
2023-01-24 17:20:31 +08:00
// [EXPERIMENTAL] Focus Scope
// This is generally used to identify a unique input location (for e.g. a selection set)
// There is one per window (automatically set in Begin), but:
// - Selection patterns generally need to react (e.g. clear a selection) when landing on one item of the set.
// So in order to identify a set multiple lists in same window may each need a focus scope.
// If you imagine an hypothetical BeginSelectionGroup()/EndSelectionGroup() api, it would likely call PushFocusScope()/EndFocusScope()
// - Shortcut routing also use focus scope as a default location identifier if an owner is not provided.
// We don't use the ID Stack for this as it is common to want them separate.
IMGUI_API void PushFocusScope(ImGuiID id);
IMGUI_API void PopFocusScope();
inline ImGuiID GetCurrentFocusScope() { ImGuiContext& g = *GImGui; return g.CurrentFocusScopeId; } // Focus scope we are outputting into, set by PushFocusScope()
2022-02-08 12:43:16 +08:00
// Drag and Drop
IMGUI_API bool IsDragDropActive();
2022-02-08 12:43:16 +08:00
IMGUI_API bool BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id);
IMGUI_API void ClearDragDrop();
IMGUI_API bool IsDragDropPayloadBeingAccepted();
2023-01-24 17:20:31 +08:00
IMGUI_API void RenderDragDropTargetRect(const ImRect& bb);
2022-02-08 12:43:16 +08:00
// 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);
2023-08-31 18:14:26 +08:00
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.
2022-02-08 12:43:16 +08:00
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);
2023-01-24 17:20:31 +08:00
IMGUI_API bool TableBeginContextMenuPopup(ImGuiTable* table);
2022-02-08 12:43:16 +08:00
IMGUI_API void TableMergeDrawChannels(ImGuiTable* table);
2023-08-31 18:14:26 +08:00
inline ImGuiTableInstanceData* TableGetInstanceData(ImGuiTable* table, int instance_no) { if (instance_no == 0) return &table->InstanceDataFirst; return &table->InstanceDataExtra[instance_no - 1]; }
2022-02-08 12:43:16 +08:00
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);
2023-08-31 18:14:26 +08:00
IMGUI_API ImGuiID TableGetColumnResizeID(const ImGuiTable* table, int column_n, int instance_no = 0);
2022-02-08 12:43:16 +08:00
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 TableSettingsAddSettingsHandler();
2022-02-08 12:43:16 +08:00
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);
2023-08-31 18:14:26 +08:00
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);
2022-02-08 12:43:16 +08:00
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);
2023-01-24 17:20:31 +08:00
IMGUI_API ImVec2 TabItemCalcSize(const char* label, bool has_close_button_or_unsaved_marker);
IMGUI_API ImVec2 TabItemCalcSize(ImGuiWindow* window);
2022-02-08 12:43:16 +08:00
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.
IMGUI_API void RenderMouseCursor(ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow);
2022-02-08 12:43:16 +08:00
// 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 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, const ImRect& outer, const ImRect& inner, ImU32 col, float rounding);
2022-02-08 12:43:16 +08:00
IMGUI_API ImDrawFlags CalcRoundingFlagsForRectInRect(const ImRect& r_in, const ImRect& r_outer, float threshold);
// 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);
2023-01-24 17:20:31 +08:00
IMGUI_API bool ArrowButtonEx(const char* str_id, ImGuiDir dir, ImVec2 size_arg, ImGuiButtonFlags flags = 0);
2023-08-31 18:14:26 +08:00
IMGUI_API bool ImageButtonEx(ImGuiID id, ImTextureID texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& bg_col, const ImVec4& tint_col);
IMGUI_API void SeparatorEx(ImGuiSeparatorFlags flags);
2023-01-24 17:20:31 +08:00
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: Window Decorations
2022-02-08 12:43:16 +08:00
IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos);
IMGUI_API bool CollapseButton(ImGuiID id, const ImVec2& pos, ImGuiDockNode* dock_node);
IMGUI_API void Scrollbar(ImGuiAxis axis);
IMGUI_API bool ScrollbarEx(const ImRect& bb, ImGuiID id, ImGuiAxis axis, ImS64* p_scroll_v, ImS64 avail_v, ImS64 contents_v, ImDrawFlags flags);
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);
// 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, ImU32 bg_col = 0);
IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL);
IMGUI_API void TreePushOverrideID(ImGuiID id);
2023-01-24 17:20:31 +08:00
IMGUI_API void TreeNodeSetOpen(ImGuiID id, bool open);
IMGUI_API bool TreeNodeUpdateNextOpen(ImGuiID id, ImGuiTreeNodeFlags flags); // Return open state. Consume previous SetNextItemOpen() data, if any. May return true when logging.
2022-02-08 12:43:16 +08:00
// 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> IMGUI_API T RoundScalarWithFormatT(const char* format, ImGuiDataType data_type, T v);
2022-02-08 12:43:16 +08:00
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 DataTypeApplyFromText(const char* 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); }
2023-01-24 17:20:31 +08:00
inline ImGuiInputTextState* GetInputTextState(ImGuiID id) { ImGuiContext& g = *GImGui; return (id != 0 && g.InputTextState.ID == id) ? &g.InputTextState : NULL; } // Get input text state if active
2022-02-08 12:43:16 +08:00
// 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
2023-01-24 17:20:31 +08:00
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, const ImVec2& size_arg);
2022-02-08 12:43:16 +08:00
// 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 Log
IMGUI_API void DebugLog(const char* fmt, ...) IM_FMTARGS(1);
IMGUI_API void DebugLogV(const char* fmt, va_list args) IM_FMTLIST(1);
2023-01-24 17:20:31 +08:00
2022-02-08 12:43:16 +08:00
// Debug Tools
IMGUI_API void ErrorCheckEndFrameRecover(ImGuiErrorLogCallback log_callback, void* user_data = NULL);
IMGUI_API void ErrorCheckEndWindowRecover(ImGuiErrorLogCallback log_callback, void* user_data = NULL);
2023-01-24 17:20:31 +08:00
IMGUI_API void ErrorCheckUsingSetCursorPosToExtendParentBoundaries();
IMGUI_API void DebugLocateItem(ImGuiID target_id); // Call sparingly: only 1 at the same time!
IMGUI_API void DebugLocateItemOnHover(ImGuiID target_id); // Only call on reaction to a mouse Hover: because only 1 at the same time!
IMGUI_API void DebugLocateItemResolveWithLastItem();
2022-02-08 12:43:16 +08:00
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 DebugHookIdInfo(ImGuiID id, ImGuiDataType data_type, const void* data_id, const void* data_id_end);
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 DebugNodeFontGlyph(ImFont* font, const ImFontGlyph* glyph);
2022-02-08 12:43:16 +08:00
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 DebugNodeInputTextState(ImGuiInputTextState* state);
2022-02-08 12:43:16 +08:00
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 DebugNodeWindowsListByBeginStackParent(ImGuiWindow** windows, int windows_size, ImGuiWindow* parent_in_begin_stack);
IMGUI_API void DebugNodeViewport(ImGuiViewportP* viewport);
2023-01-24 17:20:31 +08:00
IMGUI_API void DebugRenderKeyboardPreview(ImDrawList* draw_list);
2022-02-08 12:43:16 +08:00
IMGUI_API void DebugRenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewport, const ImRect& bb);
2023-01-24 17:20:31 +08:00
// Obsolete functions
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
inline void SetItemUsingMouseWheel() { SetItemKeyOwner(ImGuiKey_MouseWheelY); } // Changed in 1.89
inline bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0) { return TreeNodeUpdateNextOpen(id, flags); } // Renamed in 1.89
// Refactored focus/nav/tabbing system in 1.82 and 1.84. If you have old/custom copy-and-pasted widgets that used FocusableItemRegister():
// (Old) IMGUI_VERSION_NUM < 18209: using 'ItemAdd(....)' and 'bool tab_focused = FocusableItemRegister(...)'
// (Old) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)' and 'bool tab_focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_Focused) != 0'
2023-08-31 18:14:26 +08:00
// (New) IMGUI_VERSION_NUM >= 18413: using 'ItemAdd(..., ImGuiItemFlags_Inputable)' and 'bool tab_focused = (GetItemStatusFlags() & ImGuiItemStatusFlags_FocusedTabbing) != 0 || g.NavActivateInputId == id' (WIP)
2023-01-24 17:20:31 +08:00
// 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_Inputable flag to ItemAdd()
inline void FocusableItemUnregister(ImGuiWindow* window) { IM_ASSERT(0); IM_UNUSED(window); } // -> unnecessary: TempInputText() uses ImGuiInputTextFlags_MergedItem
#endif
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
inline bool IsKeyPressedMap(ImGuiKey key, bool repeat = true) { IM_ASSERT(IsNamedKey(key)); return IsKeyPressed(key, repeat); } // Removed in 1.87: Mapping from named key is always identity!
#endif
2022-02-08 12:43:16 +08:00
} // namespace ImGui
2020-09-04 17:19:51 +08:00
//-----------------------------------------------------------------------------
2021-06-15 22:30:54 +08:00
// [SECTION] ImFontAtlas internal API
//-----------------------------------------------------------------------------
// This structure is likely to evolve as we add support for incremental atlas updates
struct ImFontBuilderIO
{
2022-02-08 12:43:16 +08:00
bool (*FontBuilder_Build)(ImFontAtlas* atlas);
2021-06-15 22:30:54 +08:00
};
// Helper for font builder
2022-02-08 12:43:16 +08:00
#ifdef IMGUI_ENABLE_STB_TRUETYPE
2021-06-15 22:30:54 +08:00
IMGUI_API const ImFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype();
2022-02-08 12:43:16 +08:00
#endif
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);
2021-06-15 22:30:54 +08:00
//-----------------------------------------------------------------------------
// [SECTION] Test Engine specific hooks (imgui_test_engine)
2020-09-04 17:19:51 +08:00
//-----------------------------------------------------------------------------
2022-02-08 12:43:16 +08:00
#ifdef IMGUI_ENABLE_TEST_ENGINE
2023-08-31 18:14:26 +08:00
extern void ImGuiTestEngineHook_ItemAdd(ImGuiContext* ctx, const ImRect& bb, ImGuiID id);
2022-02-08 12:43:16 +08:00
extern void ImGuiTestEngineHook_ItemInfo(ImGuiContext* ctx, ImGuiID id, const char* label, ImGuiItemStatusFlags flags);
extern void ImGuiTestEngineHook_Log(ImGuiContext* ctx, const char* fmt, ...);
extern const char* ImGuiTestEngine_FindItemDebugLabel(ImGuiContext* ctx, ImGuiID id);
2023-08-31 18:14:26 +08:00
#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
2022-02-08 12:43:16 +08:00
#else
#define IMGUI_TEST_ENGINE_ITEM_ADD(_BB,_ID) ((void)0)
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) ((void)g)
#endif
2020-09-04 17:19:51 +08:00
2021-06-15 22:30:54 +08:00
//-----------------------------------------------------------------------------
2022-02-08 12:43:16 +08:00
#if defined(__clang__)
#pragma clang diagnostic pop
#elif defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
2020-09-04 17:19:51 +08:00
2022-02-08 12:43:16 +08:00
#ifdef _MSC_VER
#pragma warning (pop)
#endif
2020-09-04 17:19:51 +08:00
2022-02-08 12:43:16 +08:00
#endif // #ifndef IMGUI_DISABLE