Karma Engine
Loading...
Searching...
No Matches
KarmaGuiInternal.h
1// Dear ImGui (1.89.2) is Copyright (c) 2014-2023 Omar Cornut. This code is practically ImGui in Karma context!!
2/*
3Index of this file:
4
5// [SECTION] Header mess
6// [SECTION] Forward declarations
7// [SECTION] Context pointer
8// [SECTION] STB libraries includes
9// [SECTION] Macros
10// [SECTION] Generic helpers
11// [SECTION] KGDrawList support
12// [SECTION] Widgets support: flags, enums, data structures
13// [SECTION] Inputs support
14// [SECTION] Clipper support
15// [SECTION] Navigation support
16// [SECTION] Columns support
17// [SECTION] Multi-select support
18// [SECTION] Docking support
19// [SECTION] Viewport support
20// [SECTION] Settings support
21// [SECTION] Localization support
22// [SECTION] Metrics, Debug tools
23// [SECTION] Generic context hooks
24// [SECTION] KarmaGuiContext (main imgui context)
25// [SECTION] KGGuiWindowTempData, KGGuiWindow
26// [SECTION] Tab bar, Tab item support
27// [SECTION] Table support
28// [SECTION] ImGui internal API
29// [SECTION] KGFontAtlas internal API
30// [SECTION] Test Engine specific hooks (imgui_test_engine)
31
32*/
33
34#pragma once
35
36#include "krpch.h"
37#include "KarmaGui.h"
38
39// Enable stb_truetype by default unless FreeType is enabled.
40// You can compile with both by defining both KGGUI_ENABLE_FREETYPE and KGGUI_ENABLE_STB_TRUETYPE together.
41#ifndef KGGUI_ENABLE_FREETYPE
42#define KGGUI_ENABLE_STB_TRUETYPE
43#endif
44
45//-----------------------------------------------------------------------------
46// [SECTION] Forward declarations
47//-----------------------------------------------------------------------------
48
49struct KGBitVector; // Store 1-bit per value
50struct KGRect; // An axis-aligned rectangle (2 points)
51struct KGDrawDataBuilder; // Helper to build a KGDrawData instance
52struct KGDrawListSharedData; // Data shared between all KGDrawList instances
53struct KGGuiColorMod; // Stacked color modifier, backup of modified data so we can restore it
54struct KarmaGuiContext; // Main Dear ImGui context
55struct KGGuiContextHook; // Hook for extensions like ImGuiTestEngine
56struct KGGuiDataTypeInfo; // Type information associated to a KarmaGuiDataType enum
57struct KGGuiDockContext; // Docking system context
58struct KGGuiDockRequest; // Docking system dock/undock queued request
59struct KGGuiDockNode; // Docking system node (hold a list of Windows OR two child dock nodes)
60struct KGGuiDockNodeSettings; // Storage for a dock node in .ini file (we preserve those even if the associated dock node isn't active during the session)
61struct KGGuiGroupData; // Stacked storage data for BeginGroup()/EndGroup()
62struct KGGuiInputTextState; // Internal state of the currently focused/edited text input box
63struct KGGuiLastItemData; // Status storage for last submitted items
64struct KGGuiLocEntry; // A localization entry.
65struct KGGuiMenuColumns; // Simple column measurement, currently used for MenuItem() only
66struct KGGuiNavItemData; // Result of a gamepad/keyboard directional navigation move query result
67struct KGGuiMetricsConfig; // Storage for ShowMetricsWindow() and DebugNodeXXX() functions
68struct KGGuiNextWindowData; // Storage for SetNextWindow** functions
69struct KGGuiNextItemData; // Storage for SetNextItem** functions
70struct KGGuiOldColumnData; // Storage data for a single column for legacy Columns() api
71struct KGGuiOldColumns; // Storage data for a columns set for legacy Columns() api
72struct KGGuiPopupData; // Storage for current popup stack
73struct KGGuiSettingsHandler; // Storage for one type registered in the .ini file
74struct KGGuiStackSizes; // Storage of stack sizes for debugging/asserting
75struct KGGuiStyleMod; // Stacked style modifier, backup of modified data so we can restore it
76struct KGGuiTabBar; // Storage for a tab bar
77struct KGGuiTabItem; // Storage for a tab item (within a tab bar)
78struct KGGuiTable; // Storage for a table
79struct KGGuiTableColumn; // Storage for one column of a table
80struct KGGuiTableInstanceData; // Storage for one instance of a same table
81struct KGGuiTableTempData; // Temporary storage for one table (one per table in the stack), shared between tables.
82struct KGGuiTableSettings; // Storage for a table .ini settings
83struct KGGuiTableColumnsSettings; // Storage for a column .ini settings
84struct KGGuiWindow; // Storage for one window
85struct KGGuiWindowTempData; // 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)
86struct KGGuiWindowSettings; // Storage for a window .ini settings (we keep one of those even if the actual window wasn't instanced during this session)
87
88//KarmaGuiContext* GKarmaGui;
89
90// Enumerations
91// Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists.
92enum KGGuiLocKey : int; // -> enum KGGuiLocKey // Enum: a localization entry for translation.
93typedef int KGGuiDataAuthority; // -> enum KGGuiDataAuthority_ // Enum: for storing the source authority (dock node vs window) of a field
94typedef int KGGuiLayoutType; // -> enum KGGuiLayoutType_ // Enum: Horizontal or vertical
95
96// Flags
97typedef int KGGuiActivateFlags; // -> enum KGGuiActivateFlags_ // Flags: for navigation/focus function (will be for ActivateItem() later)
98typedef int KGGuiDebugLogFlags; // -> enum KGGuiDebugLogFlags_ // Flags: for ShowDebugLogWindow(), g.DebugLogFlags
99typedef int KGGuiItemFlags; // -> enum KGGuiItemFlags_ // Flags: for PushItemFlag(), g.LastItemData.InFlags
100typedef int KGGuiItemStatusFlags; // -> enum KGGuiItemStatusFlags_ // Flags: for g.LastItemData.StatusFlags
101typedef int KGGuiOldColumnFlags; // -> enum KGGuiOldColumnFlags_ // Flags: for BeginColumns()
102typedef int KGGuiNavHighlightFlags; // -> enum KGGuiNavHighlightFlags_ // Flags: for RenderNavHighlight()
103typedef int KGGuiNavMoveFlags; // -> enum KGGuiNavMoveFlags_ // Flags: for navigation requests
104typedef int KGGuiNextItemDataFlags; // -> enum KGGuiNextItemDataFlags_ // Flags: for SetNextItemXXX() functions
105typedef int KGGuiNextWindowDataFlags; // -> enum KGGuiNextWindowDataFlags_// Flags: for SetNextWindowXXX() functions
106typedef int KGGuiScrollFlags; // -> enum KGGuiScrollFlags_ // Flags: for ScrollToItem() and navigation requests
107typedef int KGGuiSeparatorFlags; // -> enum KGGuiSeparatorFlags_ // Flags: for SeparatorEx()
108typedef int KGGuiTextFlags; // -> enum KGGuiTextFlags_ // Flags: for TextEx()
109typedef int KGGuiTooltipFlags; // -> enum KGGuiTooltipFlags_ // Flags: for BeginTooltipEx()
110
111typedef void (*KGGuiErrorLogCallback)(void* user_data, const char* fmt, ...);
112
113//-----------------------------------------------------------------------------
114// [SECTION] Context pointer
115// See implementation of this variable in imgui.cpp for comments and details.
116//-----------------------------------------------------------------------------
117
118//#ifndef GKarmaGui
119extern KarmaGuiContext* GKarmaGui; // Current implicit context pointer
120//#endif
121
122//-------------------------------------------------------------------------
123// [SECTION] STB libraries includes
124//-------------------------------------------------------------------------
125namespace KGStb
126{
127#undef STB_TEXTEDIT_STRING
128#undef STB_TEXTEDIT_CHARTYPE
129#define STB_TEXTEDIT_STRING KGGuiInputTextState
130#define STB_TEXTEDIT_CHARTYPE KGWchar
131#define STB_TEXTEDIT_GETWIDTH_NEWLINE (-1.0f)
132#define STB_TEXTEDIT_UNDOSTATECOUNT 99
133#define STB_TEXTEDIT_UNDOCHARCOUNT 999
134#include "KarmaSTBTextEdit.h"
135} // namespace KGStb
136
137//-----------------------------------------------------------------------------
138// [SECTION] Macros
139//-----------------------------------------------------------------------------
140
141// Internal Drag and Drop payload types. String starting with '_' are reserved for Dear KarmaGui.
142#define KARMAGUI_PAYLOAD_TYPE_WINDOW "_IMWINDOW" // Payload == KGGuiWindow*
143
144// Debug Logging for ShowDebugLogWindow(). This is designed for relatively rare events so please don't spam.
145#ifndef KARMAGUI_DISABLE_DEBUG_TOOLS
146#define KARMAGUI_DEBUG_LOG(...) KR_CORE_INFO(...)
147#else
148#define KARMAGUI_DEBUG_LOG(...)
149#endif
150#define KARMAGUI_DEBUG_LOG_ACTIVEID(...) do { if (g.DebugLogFlags & KGGuiDebugLogFlags_EventActiveId) KARMAGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
151#define KARMAGUI_DEBUG_LOG_FOCUS(...) do { if (g.DebugLogFlags & KGGuiDebugLogFlags_EventFocus) KARMAGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
152#define KARMAGUI_DEBUG_LOG_POPUP(...) do { if (g.DebugLogFlags & KGGuiDebugLogFlags_EventPopup) KARMAGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
153#define KARMAGUI_DEBUG_LOG_NAV(...) do { if (g.DebugLogFlags & KGGuiDebugLogFlags_EventNav) KARMAGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
154#define ye_right(...) do { if (g.DebugLogFlags & KGGuiDebugLogFlags_EventClipper) KARMAGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
155#define KARMAGUI_DEBUG_LOG_IO(...) do { if (g.DebugLogFlags & KGGuiDebugLogFlags_EventIO) KARMAGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
156#define KARMAGUI_DEBUG_LOG_DOCKING(...) do { if (g.DebugLogFlags & KGGuiDebugLogFlags_EventDocking) KARMAGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
157#define KARMAGUI_DEBUG_LOG_VIEWPORT(...) do { if (g.DebugLogFlags & KGGuiDebugLogFlags_EventViewport) KARMAGUI_DEBUG_LOG(__VA_ARGS__); } while (0)
158
159// Static Asserts
160#define KG_STATIC_ASSERT(_COND) KR_CORE_ASSERT(_COND, "")
161
162// Misc Macros
163#define KG_PI 3.14159265358979323846f
164#ifdef KR_CORE_WINDOWS
165#define KG_NEWLINE "\r\n" // Play it nice with Windows users (Update: since 2018-05, Notepad finally appears to support Unix-style carriage returns!)
166#else
167#define KG_NEWLINE "\n"
168#endif
169#ifndef KG_TABSIZE // Until we move this to runtime and/or add proper tab support, at least allow users to compile-time override
170#define KG_TABSIZE (4)
171#endif
172#define KG_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
173#define KG_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose
174#define KG_F32_TO_INT8_SAT(_VAL) ((int)(KGSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255
175#define KG_FLOOR(_VAL) ((float)(int)(_VAL)) // KGFloor() is not inlined in MSVC debug builds
176#define KG_ROUND(_VAL) ((float)(int)((_VAL) + 0.5f)) //
177
178// Warnings
179#if defined(_MSC_VER) && !defined(__clang__)
180#define KG_MSVC_WARNING_SUPPRESS(XXXX) __pragma(warning(suppress: XXXX))
181#else
182#define KG_MSVC_WARNING_SUPPRESS(XXXX)
183#endif
184
185//-----------------------------------------------------------------------------
186// [SECTION] Generic helpers
187// Note that the ImXXX helpers functions are lower-level than ImGui functions.
188// ImGui functions or the ImGui context are never called/used from other ImXXX functions.
189//-----------------------------------------------------------------------------
190// - Helpers: Hashing
191// - Helpers: Sorting
192// - Helpers: Bit manipulation
193// - Helpers: String
194// - Helpers: Formatting
195// - Helpers: UTF-8 <> wchar conversions
196// - Helpers: KGVec2/KGVec4 operators
197// - Helpers: Maths
198// - Helpers: Geometry
199// - Helper: KGVec1
200// - Helper: KGVec2ih
201// - Helper: KGRect
202// - Helper: KGBitArray
203// - Helper: KGBitVector
204// - Helper: KGSpan<>, KGSpanAllocator<>
205// - Helper: KGPool<>
206// - Helper: KGChunkStream<>
207// - Helper: KGGuiTextIndex
208//-----------------------------------------------------------------------------
209
210// Helpers: Hashing
211KGGuiID KGHashData(const void* data, size_t data_size, KGU32 seed = 0);
212KGGuiID KGHashStr(const char* data, size_t data_size = 0, KGU32 seed = 0);
213
214// Helpers: Sorting
215//#ifndef KGQsort
216static inline void KGQsort(void* base, size_t count, size_t size_of_element, int(*compare_func)(void const*, void const*)) { if (count > 1) qsort(base, count, size_of_element, compare_func); }
217//#endif
218
219// Helpers: Color Blending
220KGU32 KGAlphaBlendColors(KGU32 col_a, KGU32 col_b);
221
222// Helpers: Bit manipulation
223static inline bool KGIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; }
224static inline bool KGIsPowerOfTwo(KGU64 v) { return v != 0 && (v & (v - 1)) == 0; }
225static inline int KGUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; }
226
227// Helpers: String
228int KGStricmp(const char* str1, const char* str2);
229int KGStrnicmp(const char* str1, const char* str2, size_t count);
230void KGStrncpy(char* dst, const char* src, size_t count);
231char* KGStrdup(const char* str);
232char* KGStrdupcpy(char* dst, size_t* p_dst_size, const char* str);
233const char* KGStrchrRange(const char* str_begin, const char* str_end, char c);
234int KGStrlenW(const KGWchar* str);
235const char* KGStreolRange(const char* str, const char* str_end); // End end-of-line
236const KGWchar* KGStrbolW(const KGWchar* buf_mid_line, const KGWchar* buf_begin); // Find beginning-of-line
237const char* KGStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end);
238void KGStrTrimBlanks(char* str);
239const char* KGStrSkipBlank(const char* str);
240
241static inline char KGToUpper(char c) { return (c >= 'a' && c <= 'z') ? c &= ~32 : c; }
242static inline bool KGCharIsBlankA(char c) { return c == ' ' || c == '\t'; }
243static inline bool KGCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; }
244
245// Helpers: Formatting
246int KGFormatString(char* buf, size_t buf_size, const char* fmt, ...) KG_FMTARGS(3);
247int KGFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) KG_FMTLIST(3);
248void KGFormatStringToTempBuffer(const char** out_buf, const char** out_buf_end, const char* fmt, ...) KG_FMTARGS(3);
249void KGFormatStringToTempBufferV(const char** out_buf, const char** out_buf_end, const char* fmt, va_list args) KG_FMTLIST(3);
250const char* KGParseFormatFindStart(const char* format);
251const char* KGParseFormatFindEnd(const char* format);
252const char* KGParseFormatTrimDecorations(const char* format, char* buf, size_t buf_size);
253void KGParseFormatSanitizeForPrinting(const char* fmt_in, char* fmt_out, size_t fmt_out_size);
254const char* KGParseFormatSanitizeForScanning(const char* fmt_in, char* fmt_out, size_t fmt_out_size);
255int KGParseFormatPrecision(const char* format, int default_value);
256
257// Helpers: UTF-8 <> wchar conversions
258const char* KGTextCharToUtf8(char out_buf[5], unsigned int c); // return out_buf
259int KGTextStrToUtf8(char* out_buf, int out_buf_size, const KGWchar* in_text, const KGWchar* in_text_end); // return output UTF-8 bytes count
260int KGTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end); // read one character. return input UTF-8 bytes count
261int KGTextStrFromUtf8(KGWchar* 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
262int KGTextCountCharsFromUtf8(const char* in_text, const char* in_text_end); // return number of UTF-8 code-points (NOT bytes count)
263int KGTextCountUtf8BytesFromChar(const char* in_text, const char* in_text_end); // return number of bytes to express one char in UTF-8
264int KGTextCountUtf8BytesFromStr(const KGWchar* in_text, const KGWchar* in_text_end); // return number of bytes to express string in UTF-8
265
266#ifndef KARMAGUI_DISABLE_DEFAULT_FILE_FUNCTIONS
267typedef FILE* ImFileHandle;
268ImFileHandle KGFileOpen(const char* filename, const char* mode);
269bool KGFileClose(ImFileHandle file);
270KGU64 KGFileGetSize(ImFileHandle file);
271KGU64 KGFileRead(void* data, KGU64 size, KGU64 count, ImFileHandle file);
272KGU64 KGFileWrite(const void* data, KGU64 size, KGU64 count, ImFileHandle file);
273#else
274#define IMGUI_DISABLE_TTY_FUNCTIONS // Can't use stdout, fflush if we are not using default file functions
275#endif
276void* KGFileLoadToMemory(const char* filename, const char* mode, size_t* out_file_size = NULL, int padding_bytes = 0);
277
278// Helpers: Maths
279// - Wrapper for standard libs functions. Hmm how about normal usage?
280#ifndef KARMAGUI_DISABLE_DEFAULT_MATH_FUNCTIONS
281#define KGFabs(X) fabsf(X)
282#define KGSqrt(X) sqrtf(X)
283#define KGFmod(X, Y) fmodf((X), (Y))
284#define KGCos(X) cosf(X)
285#define KGSin(X) sinf(X)
286#define KGAcos(X) acosf(X)
287#define KGAtan2(Y, X) atan2f((Y), (X))
288#define KGAtof(STR) atof(STR)
289//#define ImFloorStd(X) floorf(X) // We use our own, see KGFloor() and KGFloorSigned()
290#define KGCeil(X) ceilf(X)
291
292static inline KGVec2 operator*(const KGVec2& lhs, const float rhs) { return KGVec2(lhs.x * rhs, lhs.y * rhs); }
293static inline KGVec2 operator/(const KGVec2& lhs, const float rhs) { return KGVec2(lhs.x / rhs, lhs.y / rhs); }
294static inline KGVec2 operator+(const KGVec2& lhs, const KGVec2& rhs) { return KGVec2(lhs.x + rhs.x, lhs.y + rhs.y); }
295static inline KGVec2 operator-(const KGVec2& lhs, const KGVec2& rhs) { return KGVec2(lhs.x - rhs.x, lhs.y - rhs.y); }
296static inline KGVec2 operator*(const KGVec2& lhs, const KGVec2& rhs) { return KGVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
297static inline KGVec2 operator/(const KGVec2& lhs, const KGVec2& rhs) { return KGVec2(lhs.x / rhs.x, lhs.y / rhs.y); }
298static inline KGVec2& operator*=(KGVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; }
299static inline KGVec2& operator/=(KGVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; }
300static inline KGVec2& operator+=(KGVec2& lhs, const KGVec2& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; }
301static inline KGVec2& operator-=(KGVec2& lhs, const KGVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; }
302static inline KGVec2& operator*=(KGVec2& lhs, const KGVec2& rhs) { lhs.x *= rhs.x; lhs.y *= rhs.y; return lhs; }
303static inline KGVec2& operator/=(KGVec2& lhs, const KGVec2& rhs) { lhs.x /= rhs.x; lhs.y /= rhs.y; return lhs; }
304static inline KGVec4 operator+(const KGVec4& lhs, const KGVec4& rhs) { return KGVec4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w); }
305static inline KGVec4 operator-(const KGVec4& lhs, const KGVec4& rhs) { return KGVec4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w); }
306static inline KGVec4 operator*(const KGVec4& lhs, const KGVec4& rhs) { return KGVec4(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w); }
307
308static inline float KGPow(float x, float y) { return powf(x, y); } // DragBehaviorT/SliderBehaviorT uses KGPow with either float/double and need the precision
309static inline double KGPow(double x, double y) { return pow(x, y); }
310static inline float KGLog(float x) { return logf(x); } // DragBehaviorT/SliderBehaviorT uses KGLog with either float/double and need the precision
311static inline double KGLog(double x) { return log(x); }
312static inline int KGAbs(int x) { return x < 0 ? -x : x; }
313static inline float KGAbs(float x) { return fabsf(x); }
314static inline double KGAbs(double x) { return fabs(x); }
315static inline float KGSign(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
316static inline double KGSign(double x) { return (x < 0.0) ? -1.0 : (x > 0.0) ? 1.0 : 0.0; }
317static inline float KGRsqrt(float x) { return 1.0f / sqrtf(x); }
318static inline double KGRsqrt(double x) { return 1.0 / sqrt(x); }
319#endif
320
321// - KGMin/KGMax/KGClamp/KGLerp/KGSwap are used by widgets which support variety of types: signed/unsigned int/long long float/double
322// (Exceptionally using templates here but we could also redefine them for those types)
323template<typename T> static inline T KGMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; }
324template<typename T> static inline T KGMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; }
325template<typename T> static inline T KGClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
326template<typename T> static inline T KGLerp(T a, T b, float t) { return (T)(a + (b - a) * t); }
327template<typename T> static inline void KGSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; }
328template<typename T> static inline T KGAddClampOverflow(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; }
329template<typename T> static inline T KGSubClampOverflow(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; }
330// - Misc maths helpers
331static inline KGVec2 KGMin(const KGVec2& lhs, const KGVec2& rhs) { return KGVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y); }
332static inline KGVec2 KGMax(const KGVec2& lhs, const KGVec2& rhs) { return KGVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y); }
333static inline KGVec2 KGClamp(const KGVec2& v, const KGVec2& mn, KGVec2 mx) { return KGVec2((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); }
334static inline KGVec2 KGLerp(const KGVec2& a, const KGVec2& b, float t) { return KGVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t); }
335static inline KGVec2 KGLerp(const KGVec2& a, const KGVec2& b, const KGVec2& t) { return KGVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); }
336static inline KGVec4 KGLerp(const KGVec4& a, const KGVec4& b, float t) { return KGVec4(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); }
337static inline float KGSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; }
338static inline float KGLengthSqr(const KGVec2& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y); }
339static inline float KGLengthSqr(const KGVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); }
340static inline float KGInvLength(const KGVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return KGRsqrt(d); return fail_value; }
341static inline float KGFloor(float f) { return (float)(int)(f); }
342static inline float KGFloorSigned(float f) { return (float)((f >= 0 || (float)(int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf()
343static inline KGVec2 KGFloor(const KGVec2& v) { return KGVec2((float)(int)(v.x), (float)(int)(v.y)); }
344static inline KGVec2 KGFloorSigned(const KGVec2& v) { return KGVec2(KGFloorSigned(v.x), KGFloorSigned(v.y)); }
345static inline int KGModPositive(int a, int b) { return (a + b) % b; }
346static inline float KGDot(const KGVec2& a, const KGVec2& b) { return a.x * b.x + a.y * b.y; }
347static inline KGVec2 KGRotate(const KGVec2& v, float cos_a, float sin_a) { return KGVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }
348static inline float KGLinearSweep(float current, float target, float speed) { if (current < target) return KGMin(current + speed, target); if (current > target) return KGMax(current - speed, target); return current; }
349static inline KGVec2 KGMul(const KGVec2& lhs, const KGVec2& rhs) { return KGVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
350static inline bool KGIsFloatAboveGuaranteedIntegerPrecision(float f) { return f <= -16777216 || f >= 16777216; }
351static inline float KGExponentialMovingAverage(float avg, float sample, int n) { avg -= avg / n; avg += sample / n; return avg; }
352
353// Helpers: Geometry
354KGVec2 KGBezierCubicCalc(const KGVec2& p1, const KGVec2& p2, const KGVec2& p3, const KGVec2& p4, float t);
355KGVec2 KGBezierCubicClosestPoint(const KGVec2& p1, const KGVec2& p2, const KGVec2& p3, const KGVec2& p4, const KGVec2& p, int num_segments); // For curves with explicit number of segments
356KGVec2 KGBezierCubicClosestPointCasteljau(const KGVec2& p1, const KGVec2& p2, const KGVec2& p3, const KGVec2& p4, const KGVec2& p, float tess_tol);// For auto-tessellated curves you can use tess_tol = style.CurveTessellationTol
357KGVec2 KGBezierQuadraticCalc(const KGVec2& p1, const KGVec2& p2, const KGVec2& p3, float t);
358KGVec2 KGLineClosestPoint(const KGVec2& a, const KGVec2& b, const KGVec2& p);
359bool KGTriangleContainsPoint(const KGVec2& a, const KGVec2& b, const KGVec2& c, const KGVec2& p);
360KGVec2 KGTriangleClosestPoint(const KGVec2& a, const KGVec2& b, const KGVec2& c, const KGVec2& p);
361void KGTriangleBarycentricCoords(const KGVec2& a, const KGVec2& b, const KGVec2& c, const KGVec2& p, float& out_u, float& out_v, float& out_w);
362inline float KGTriangleArea(const KGVec2& a, const KGVec2& b, const KGVec2& c) { return KGFabs((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x * (a.y - b.y))) * 0.5f; }
363KarmaGuiDir KGGetDirQuadrantFromDelta(float dx, float dy);
364
365// Helper: KGVec1 (1D vector)
366// (this odd construct is used to facilitate the transition between 1D and 2D, and the maintenance of some branches/patches)
367
368struct KGVec1
369{
370 float x;
371 constexpr KGVec1() : x(0.0f) { }
372 constexpr KGVec1(float _x) : x(_x) { }
373};
374
375// Helper: KGVec2ih (2D vector, half-size integer, for long-term packed storage)
377{
378 short x, y;
379 constexpr KGVec2ih() : x(0), y(0) {}
380 constexpr KGVec2ih(short _x, short _y) : x(_x), y(_y) {}
381 constexpr explicit KGVec2ih(const KGVec2& rhs) : x((short)rhs.x), y((short)rhs.y) {}
382};
383
384// Helper: KGRect (2D axis aligned bounding-box)
385// NB: we can't rely on KGVec2 math operators being available here!
386struct KGRect
387{
388 KGVec2 Min; // Upper-left
389 KGVec2 Max; // Lower-right
390
391 constexpr KGRect() : Min(0.0f, 0.0f), Max(0.0f, 0.0f) {}
392 constexpr KGRect(const KGVec2& min, const KGVec2& max) : Min(min), Max(max) {}
393 constexpr KGRect(const KGVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {}
394 constexpr KGRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {}
395
396 KGVec2 GetCenter() const { return KGVec2((Min.x + Max.x) * 0.5f, (Min.y + Max.y) * 0.5f); }
397 KGVec2 GetSize() const { return KGVec2(Max.x - Min.x, Max.y - Min.y); }
398 float GetWidth() const { return Max.x - Min.x; }
399 float GetHeight() const { return Max.y - Min.y; }
400 float GetArea() const { return (Max.x - Min.x) * (Max.y - Min.y); }
401 KGVec2 GetTL() const { return Min; } // Top-left
402 KGVec2 GetTR() const { return KGVec2(Max.x, Min.y); } // Top-right
403 KGVec2 GetBL() const { return KGVec2(Min.x, Max.y); } // Bottom-left
404 KGVec2 GetBR() const { return Max; } // Bottom-right
405 bool Contains(const KGVec2& p) const { return p.x >= Min.x && p.y >= Min.y && p.x < Max.x&& p.y < Max.y; }
406 bool Contains(const KGRect& r) const { return r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x <= Max.x && r.Max.y <= Max.y; }
407 bool Overlaps(const KGRect& r) const { return r.Min.y < Max.y&& r.Max.y > Min.y && r.Min.x < Max.x&& r.Max.x > Min.x; }
408 void Add(const KGVec2& 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; }
409 void Add(const KGRect& 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; }
410 void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; }
411 void Expand(const KGVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; }
412 void Translate(const KGVec2& d) { Min.x += d.x; Min.y += d.y; Max.x += d.x; Max.y += d.y; }
413 void TranslateX(float dx) { Min.x += dx; Max.x += dx; }
414 void TranslateY(float dy) { Min.y += dy; Max.y += dy; }
415 void ClipWith(const KGRect& r) { Min = KGMax(Min, r.Min); Max = KGMin(Max, r.Max); } // Simple version, may lead to an inverted rectangle, which is fine for Contains/Overlaps test but not for display.
416 void ClipWithFull(const KGRect& r) { Min = KGClamp(Min, r.Min, r.Max); Max = KGClamp(Max, r.Min, r.Max); } // Full version, ensure both points are fully clipped.
417 void Floor() { Min.x = KG_FLOOR(Min.x); Min.y = KG_FLOOR(Min.y); Max.x = KG_FLOOR(Max.x); Max.y = KG_FLOOR(Max.y); }
418 bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; }
419 KGVec4 ToVec4() const { return KGVec4(Min.x, Min.y, Max.x, Max.y); }
420};
421
422// Helper: KGBitArray
423inline bool KGBitArrayTestBit(const KGU32* arr, int n) { KGU32 mask = (KGU32)1 << (n & 31); return (arr[n >> 5] & mask) != 0; }
424inline void KGBitArrayClearBit(KGU32* arr, int n) { KGU32 mask = (KGU32)1 << (n & 31); arr[n >> 5] &= ~mask; }
425inline void KGBitArraySetBit(KGU32* arr, int n) { KGU32 mask = (KGU32)1 << (n & 31); arr[n >> 5] |= mask; }
426inline void KGBitArraySetBitRange(KGU32* arr, int n, int n2) // Works on range [n..n2)
427{
428 n2--;
429 while (n <= n2)
430 {
431 int a_mod = (n & 31);
432 int b_mod = (n2 > (n | 31) ? 31 : (n2 & 31)) + 1;
433 KGU32 mask = (KGU32)(((KGU64)1 << b_mod) - 1) & ~(KGU32)(((KGU64)1 << a_mod) - 1);
434 arr[n >> 5] |= mask;
435 n = (n + 32) & ~31;
436 }
437}
438
439// Helper: KGBitArray class (wrapper over KGBitArray functions)
440// Store 1-bit per value.
441template<int BITCOUNT, int OFFSET = 0>
443{
444 KGU32 Storage[(BITCOUNT + 31) >> 5];
445 KGBitArray() { ClearAllBits(); }
446 void ClearAllBits() { memset(Storage, 0, sizeof(Storage)); }
447 void SetAllBits() { memset(Storage, 255, sizeof(Storage)); }
448 bool TestBit(int n) const { n += OFFSET; KR_CORE_ASSERT(n >= 0 && n < BITCOUNT, ""); return KGBitArrayTestBit(Storage, n); }
449 void SetBit(int n) { n += OFFSET; KR_CORE_ASSERT(n >= 0 && n < BITCOUNT, ""); KGBitArraySetBit(Storage, n); }
450 void ClearBit(int n) { n += OFFSET; KR_CORE_ASSERT(n >= 0 && n < BITCOUNT, ""); KGBitArrayClearBit(Storage, n); }
451 void SetBitRange(int n, int n2) { n += OFFSET; n2 += OFFSET; KR_CORE_ASSERT(n >= 0 && n < BITCOUNT&& n2 > n && n2 <= BITCOUNT, ""); KGBitArraySetBitRange(Storage, n, n2); } // Works on range [n..n2)
452 bool operator[](int n) const { n += OFFSET; KR_CORE_ASSERT(n >= 0 && n < BITCOUNT, ""); return KGBitArrayTestBit(Storage, n); }
453};
454
455// Helper: KGBitVector
456// Store 1-bit per value.
458{
459 KGVector<KGU32> Storage;
460 void Create(int sz) { Storage.resize((sz + 31) >> 5); memset(Storage.Data, 0, (size_t)Storage.Size * sizeof(Storage.Data[0])); }
461 void Clear() { Storage.clear(); }
462 bool TestBit(int n) const { KR_CORE_ASSERT(n < (Storage.Size << 5), ""); return KGBitArrayTestBit(Storage.Data, n); }
463 void SetBit(int n) { KR_CORE_ASSERT(n < (Storage.Size << 5), ""); KGBitArraySetBit(Storage.Data, n); }
464 void ClearBit(int n) { KR_CORE_ASSERT(n < (Storage.Size << 5), ""); KGBitArrayClearBit(Storage.Data, n); }
465};
466
467// Helper: KGSpan<>
468// Pointing to a span of data we don't own.
469template<typename T>
470struct KGSpan
471{
472 T* Data;
473 T* DataEnd;
474
475 // Constructors, destructor
476 inline KGSpan() { Data = DataEnd = NULL; }
477 inline KGSpan(T* data, int size) { Data = data; DataEnd = data + size; }
478 inline KGSpan(T* data, T* data_end) { Data = data; DataEnd = data_end; }
479
480 inline void set(T* data, int size) { Data = data; DataEnd = data + size; }
481 inline void set(T* data, T* data_end) { Data = data; DataEnd = data_end; }
482 inline int size() const { return (int)(ptrdiff_t)(DataEnd - Data); }
483 inline int size_in_bytes() const { return (int)(ptrdiff_t)(DataEnd - Data) * (int)sizeof(T); }
484 inline T& operator[](int i) { T* p = Data + i; KR_CORE_ASSERT(p >= Data && p < DataEnd, ""); return *p; }
485 inline const T& operator[](int i) const { const T* p = Data + i; KR_CORE_ASSERT(p >= Data && p < DataEnd, ""); return *p; }
486
487 inline T* begin() { return Data; }
488 inline const T* begin() const { return Data; }
489 inline T* end() { return DataEnd; }
490 inline const T* end() const { return DataEnd; }
491
492 // Utilities
493 inline int index_from_ptr(const T* it) const { KR_CORE_ASSERT(it >= Data && it < DataEnd, ""); const ptrdiff_t off = it - Data; return (int)off; }
494};
495
496// Helper: KGSpanAllocator<>
497// Facilitate storing multiple chunks into a single large block (the "arena")
498// - Usage: call Reserve() N times, allocate GetArenaSizeInBytes() worth, pass it to SetArenaBasePtr(), call GetSpan() N times to retrieve the aligned ranges.
499template<int CHUNKS>
501{
502 char* BasePtr;
503 int CurrOff;
504 int CurrIdx;
505 int Offsets[CHUNKS];
506 int Sizes[CHUNKS];
507
508 KGSpanAllocator() { memset(this, 0, sizeof(*this)); }
509 inline void Reserve(int n, size_t sz, int a = 4) { KR_CORE_ASSERT(n == CurrIdx && n < CHUNKS, ""); CurrOff = KG_MEMALIGN(CurrOff, a); Offsets[n] = CurrOff; Sizes[n] = (int)sz; CurrIdx++; CurrOff += (int)sz; }
510 inline int GetArenaSizeInBytes() { return CurrOff; }
511 inline void SetArenaBasePtr(void* base_ptr) { BasePtr = (char*)base_ptr; }
512 inline void* GetSpanPtrBegin(int n) { KR_CORE_ASSERT(n >= 0 && n < CHUNKS&& CurrIdx == CHUNKS, ""); return (void*)(BasePtr + Offsets[n]); }
513 inline void* GetSpanPtrEnd(int n) { KR_CORE_ASSERT(n >= 0 && n < CHUNKS&& CurrIdx == CHUNKS, ""); return (void*)(BasePtr + Offsets[n] + Sizes[n]); }
514 template<typename T>
515 inline void GetSpan(int n, KGSpan<T>* span) { span->set((T*)GetSpanPtrBegin(n), (T*)GetSpanPtrEnd(n)); }
516};
517
518// Helper: KGPool<>
519// Basic keyed storage for contiguous instances, slow/amortized insertion, O(1) indexable, O(Log N) queries by ID over a dense/hot buffer,
520// Honor constructor/destructor. Add/remove invalidate all pointers. Indexes have the same lifetime as the associated object.
521typedef int KGPoolIdx;
522template<typename T>
523struct KGPool
524{
525 KGVector<T> Buf; // Contiguous data
526 KarmaGuiStorage Map; // ID->Index
527 KGPoolIdx FreeIdx; // Next free idx to use
528 KGPoolIdx AliveCount; // Number of active/alive items (for display purpose)
529
530 KGPool() { FreeIdx = AliveCount = 0; }
531 ~KGPool() { Clear(); }
532 T* GetByKey(KGGuiID key) { int idx = Map.GetInt(key, -1); return (idx != -1) ? &Buf[idx] : NULL; }
533 T* GetByIndex(KGPoolIdx n) { return &Buf[n]; }
534 KGPoolIdx GetIndex(const T* p) const { KR_CORE_ASSERT(p >= Buf.Data && p < Buf.Data + Buf.Size, ""); return (KGPoolIdx)(p - Buf.Data); }
535 T* GetOrAddByKey(KGGuiID key) { int* p_idx = Map.GetIntRef(key, -1); if (*p_idx != -1) return &Buf[*p_idx]; *p_idx = FreeIdx; return Add(); }
536 bool Contains(const T* p) const { return (p >= Buf.Data && p < Buf.Data + Buf.Size); }
537 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; }
538 T* Add() { int idx = FreeIdx; if (idx == Buf.Size) { Buf.resize(Buf.Size + 1); FreeIdx++; } else { FreeIdx = *(int*)&Buf[idx]; } KG_PLACEMENT_NEW(&Buf[idx]) T(); AliveCount++; return &Buf[idx]; }
539 void Remove(KGGuiID key, const T* p) { Remove(key, GetIndex(p)); }
540 void Remove(KGGuiID key, KGPoolIdx idx) { Buf[idx].~T(); *(int*)&Buf[idx] = FreeIdx; FreeIdx = idx; Map.SetInt(key, -1); AliveCount--; }
541 void Reserve(int capacity) { Buf.reserve(capacity); Map.Data.reserve(capacity); }
542
543 // To iterate a KGPool: for (int n = 0; n < pool.GetMapSize(); n++) if (T* t = pool.TryGetMapData(n)) { ... }
544 // Can be avoided if you know .Remove() has never been called on the pool, or AliveCount == GetMapSize()
545 int GetAliveCount() const { return AliveCount; } // Number of active/alive items in the pool (for display purpose)
546 int GetBufSize() const { return Buf.Size; }
547 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
548 T* TryGetMapData(KGPoolIdx n) { int idx = Map.Data[n].val_i; if (idx == -1) return NULL; return GetByIndex(idx); }
549#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
550 int GetSize() { return GetMapSize(); } // For ImPlot: should use GetMapSize() from (IMGUI_VERSION_NUM >= 18304)
551#endif
552};
553
554// Helper: KGChunkStream<>
555// Build and iterate a contiguous stream of variable-sized structures.
556// This is used by Settings to store persistent data while reducing allocation count.
557// We store the chunk size first, and align the final size on 4 bytes boundaries.
558// The tedious/zealous amount of casting is to avoid -Wcast-align warnings.
559template<typename T>
561{
562 KGVector<char> Buf;
563
564 void clear() { Buf.clear(); }
565 bool empty() const { return Buf.Size == 0; }
566 int size() const { return Buf.Size; }
567 T* alloc_chunk(size_t sz) { size_t HDR_SZ = 4; sz = KG_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); }
568 T* begin() { size_t HDR_SZ = 4; if (!Buf.Data) return NULL; return (T*)(void*)(Buf.Data + HDR_SZ); }
569 T* next_chunk(T* p) { size_t HDR_SZ = 4; KR_CORE_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; KR_CORE_ASSERT(p < end(), ""); return p; }
570 int chunk_size(const T* p) { return ((const int*)p)[-1]; }
571 T* end() { return (T*)(void*)(Buf.Data + Buf.Size); }
572 int offset_from_ptr(const T* p) { KR_CORE_ASSERT(p >= begin() && p < end(), ""); const ptrdiff_t off = (const char*)p - Buf.Data; return (int)off; }
573 T* ptr_from_offset(int off) { KR_CORE_ASSERT(off >= 4 && off < Buf.Size, ""); return (T*)(void*)(Buf.Data + off); }
574 void swap(KGChunkStream<T>& rhs) { rhs.Buf.swap(Buf); }
575};
576
577// Helper: KGGuiTextIndex<>
578// Maintain a line index for a text buffer. This is a strong candidate to be moved into the public API.
580{
581 KGVector<int> LineOffsets;
582 int EndOffset = 0; // Because we don't own text buffer we need to maintain EndOffset (may bake in LineOffsets?)
583
584 void clear() { LineOffsets.clear(); EndOffset = 0; }
585 int size() { return LineOffsets.Size; }
586 const char* get_line_begin(const char* base, int n) { return base + LineOffsets[n]; }
587 const char* get_line_end(const char* base, int n) { return base + (n + 1 < LineOffsets.Size ? (LineOffsets[n + 1] - 1) : EndOffset); }
588 void append(const char* base, int old_size, int new_size);
589};
590
591//-----------------------------------------------------------------------------
592// [SECTION] KGDrawList support
593//-----------------------------------------------------------------------------
594
595// KGDrawList: Helper function to calculate a circle's segment count given its radius and a "maximum error" value.
596// Estimation of number of circle segment based on error is derived using method described in https://stackoverflow.com/a/2244088/15194693
597// Number of segments (N) is calculated using equation:
598// N = ceil ( pi / acos(1 - error / r) ) where r > 0, error <= r
599// Our equation is significantly simpler that one in the post thanks for choosing segment that is
600// perpendicular to X axis. Follow steps in the article from this starting condition and you will
601// will get this result.
602//
603// Rendering circles with an odd number of segments, while mathematically correct will produce
604// asymmetrical results on the raster grid. Therefore we're rounding N to next even number (7->8, 8->8, 9->10 etc.)
605#define KG_ROUNDUP_TO_EVEN(_V) ((((_V) + 1) / 2) * 2)
606#define KG_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN 4
607#define KG_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX 512
608#define KG_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC(_RAD,_MAXERROR) KGClamp(KG_ROUNDUP_TO_EVEN((int)KGCeil(KG_PI / KGAcos(1 - KGMin((_MAXERROR), (_RAD)) / (_RAD)))), KG_DRAWLIST_CIRCLE_AUTO_SEGMENT_MIN, KG_DRAWLIST_CIRCLE_AUTO_SEGMENT_MAX)
609
610// Raw equation from KG_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC rewritten for 'r' and 'error'.
611#define KG_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_R(_N,_MAXERROR) ((_MAXERROR) / (1 - KGCos(KG_PI / KGMax((float)(_N), KG_PI))))
612#define KG_DRAWLIST_CIRCLE_AUTO_SEGMENT_CALC_ERROR(_N,_RAD) ((1 - KGCos(KG_PI / KGMax((float)(_N), KG_PI))) / (_RAD))
613
614// KGDrawList: Lookup table size for adaptive arc drawing, cover full circle.
615#ifndef KG_DRAWLIST_ARCFAST_TABLE_SIZE
616#define KG_DRAWLIST_ARCFAST_TABLE_SIZE 48 // Number of samples in lookup table.
617#endif
618#define IM_DRAWLIST_ARCFAST_SAMPLE_MAX KG_DRAWLIST_ARCFAST_TABLE_SIZE // Sample index _PathArcToFastEx() for 360 angle.
619
620// Data shared between all KGDrawList instances
621// You may want to create your own instance of this if you want to use KGDrawList completely without ImGui. In that case, watch out for future changes to this structure.
623{
624 KGVec2 TexUvWhitePixel; // UV of white pixel in the atlas
625 KGFont* Font; // Current/default font (optional, for simplified AddText overload)
626 float FontSize; // Current/default font size (optional, for simplified AddText overload)
627 float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo()
628 float CircleSegmentMaxError; // Number of circle segments to use per pixel of radius for AddCircle() etc
629 KGVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen()
630 KGDrawListFlags InitialFlags; // Initial flags at the beginning of the frame (it is possible to alter flags on a per-drawlist basis afterwards)
631
632 // [Internal] Temp write buffer
633 KGVector<KGVec2> TempBuffer;
634
635 // [Internal] Lookup tables
636 KGVec2 ArcFastVtx[KG_DRAWLIST_ARCFAST_TABLE_SIZE]; // Sample points on the quarter of the circle.
637 float ArcFastRadiusCutoff; // Cutoff radius after which arc drawing will fallback to slower PathArcTo()
638 KGU8 CircleSegmentCounts[64]; // Precomputed segment count for given radius before we calculate it dynamically (to avoid calculation overhead)
639 const KGVec4* TexUvLines; // UV of anti-aliased lines in the atlas
640
642 void SetCircleTessellationMaxError(float max_error);
643};
644
646{
647 KGVector<KGDrawList*> Layers[2]; // Global layers for: regular, tooltip
648
649 void Clear() { for (int n = 0; n < KG_ARRAYSIZE(Layers); n++) Layers[n].resize(0); }
650 void ClearFreeMemory() { for (int n = 0; n < KG_ARRAYSIZE(Layers); n++) Layers[n].clear(); }
651 int GetDrawListCount() const { int count = 0; for (int n = 0; n < KG_ARRAYSIZE(Layers); n++) count += Layers[n].Size; return count; }
652 void FlattenIntoSingleLayer();
653};
654
655//-----------------------------------------------------------------------------
656// [SECTION] Widgets support: flags, enums, data structures
657//-----------------------------------------------------------------------------
658
659// Flags used by upcoming items
660// - input: PushItemFlag() manipulates g.CurrentItemFlags, ItemAdd() calls may add extra flags.
661// - output: stored in g.LastItemData.InFlags
662// Current window shared by all windows.
663// This is going to be exposed in imgui.h when stabilized enough.
664enum KGGuiItemFlags_
665{
666 // Controlled by user
667 KGGuiItemFlags_None = 0,
668 KGGuiItemFlags_NoTabStop = 1 << 0, // false // Disable keyboard tabbing (FIXME: should merge with _NoNav)
669 KGGuiItemFlags_ButtonRepeat = 1 << 1, // false // Button() will return true multiple times based on io.KeyRepeatDelay and io.KeyRepeatRate settings.
670 KGGuiItemFlags_Disabled = 1 << 2, // false // Disable interactions but doesn't affect visuals. See BeginDisabled()/EndDisabled(). See github.com/ocornut/imgui/issues/211
671 KGGuiItemFlags_NoNav = 1 << 3, // false // Disable keyboard/gamepad directional navigation (FIXME: should merge with _NoTabStop)
672 KGGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false // Disable item being a candidate for default focus (e.g. used by title bar items)
673 KGGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // Disable MenuItem/Selectable() automatically closing their popup window
674 KGGuiItemFlags_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)
675 KGGuiItemFlags_ReadOnly = 1 << 7, // false // [ALPHA] Allow hovering interactions but underlying value is not changed.
676 KGGuiItemFlags_NoWindowHoverableCheck = 1 << 8, // false // Disable hoverable check in ItemHoverable()
677
678 // Controlled by widget code
679 KGGuiItemFlags_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.
680};
681
682// Status flags for an already submitted item
683// - output: stored in g.LastItemData.StatusFlags
684enum KGGuiItemStatusFlags_
685{
686 KGGuiItemStatusFlags_None = 0,
687 KGGuiItemStatusFlags_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)
688 KGGuiItemStatusFlags_HasDisplayRect = 1 << 1, // g.LastItemData.DisplayRect is valid
689 KGGuiItemStatusFlags_Edited = 1 << 2, // Value exposed by item was edited in the current frame (should match the bool return value of most widgets)
690 KGGuiItemStatusFlags_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.
691 KGGuiItemStatusFlags_ToggledOpen = 1 << 4, // Set when TreeNode() reports toggling their open state.
692 KGGuiItemStatusFlags_HasDeactivated = 1 << 5, // Set if the widget/group is able to provide data for the KGGuiItemStatusFlags_Deactivated flag.
693 KGGuiItemStatusFlags_Deactivated = 1 << 6, // Only valid if KGGuiItemStatusFlags_HasDeactivated is set.
694 KGGuiItemStatusFlags_HoveredWindow = 1 << 7, // Override the HoveredWindow test to allow cross-window hover testing.
695 KGGuiItemStatusFlags_FocusedByTabbing = 1 << 8, // Set when the Focusable item just got focused by Tabbing (FIXME: to be removed soon)
696 KGGuiItemStatusFlags_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()).
697};
698
699// Extend KGGuiInputTextFlags_
700enum KGGuiInputTextFlagsPrivate_
701{
702 // [Internal]
703 KGGuiInputTextFlags_Multiline = 1 << 26, // For internal use by InputTextMultiline()
704 KGGuiInputTextFlags_NoMarkEdited = 1 << 27, // For internal use by functions using InputText() before reformatting data
705 KGGuiInputTextFlags_MergedItem = 1 << 28, // For internal use by TempInputText(), will skip calling ItemAdd(). Require bounding-box to strictly match.
706};
707
708// Extend KGGuiButtonFlags_
709enum KGGuiButtonFlagsPrivate_
710{
711 KGGuiButtonFlags_PressedOnClick = 1 << 4, // return true on click (mouse down event)
712 KGGuiButtonFlags_PressedOnClickRelease = 1 << 5, // [Default] return true on click + release on same item <-- this is what the majority of Button are using
713 KGGuiButtonFlags_PressedOnClickReleaseAnywhere = 1 << 6, // return true on click + release even if the release event is not done while hovering the item
714 KGGuiButtonFlags_PressedOnRelease = 1 << 7, // return true on release (default requires click+release)
715 KGGuiButtonFlags_PressedOnDoubleClick = 1 << 8, // return true on double-click (default requires click+release)
716 KGGuiButtonFlags_PressedOnDragDropHold = 1 << 9, // return true when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers)
717 KGGuiButtonFlags_Repeat = 1 << 10, // hold to repeat
718 KGGuiButtonFlags_FlattenChildren = 1 << 11, // allow interactions even if a child window is overlapping
719 KGGuiButtonFlags_AllowItemOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable, use along with SetItemAllowOverlap()
720 KGGuiButtonFlags_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press // [UNUSED]
721 //KGGuiButtonFlags_Disabled = 1 << 14, // disable interactions -> use BeginDisabled() or KGGuiItemFlags_Disabled
722 KGGuiButtonFlags_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
723 KGGuiButtonFlags_NoKeyModifiers = 1 << 16, // disable mouse interaction if a key modifier is held
724 KGGuiButtonFlags_NoHoldingActiveId = 1 << 17, // don't set ActiveId while holding the mouse (KGGuiButtonFlags_PressedOnClick only)
725 KGGuiButtonFlags_NoNavFocus = 1 << 18, // don't override navigation focus when activated (FIXME: this is essentially used everytime an item uses KGGuiItemFlags_NoNav, but because legacy specs don't requires LastItemData to be set ButtonBehavior(), we can't poll g.LastItemData.InFlags)
726 KGGuiButtonFlags_NoHoveredOnFocus = 1 << 19, // don't report as hovered when nav focus is on this item
727 KGGuiButtonFlags_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 KGGuiKey_MouseLeft!)
728 KGGuiButtonFlags_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 KGGuiKey_MouseLeft!)
729 KGGuiButtonFlags_PressedOnMask_ = KGGuiButtonFlags_PressedOnClick | KGGuiButtonFlags_PressedOnClickRelease | KGGuiButtonFlags_PressedOnClickReleaseAnywhere | KGGuiButtonFlags_PressedOnRelease | KGGuiButtonFlags_PressedOnDoubleClick | KGGuiButtonFlags_PressedOnDragDropHold,
730 KGGuiButtonFlags_PressedOnDefault_ = KGGuiButtonFlags_PressedOnClickRelease,
731};
732
733// Extend KGGuiComboFlags_
734enum KGGuiComboFlagsPrivate_
735{
736 KGGuiComboFlags_CustomPreview = 1 << 20, // enable BeginComboPreview()
737};
738
739// Extend KGGuiSliderFlags_
740enum KGGuiSliderFlagsPrivate_
741{
742 KGGuiSliderFlags_Vertical = 1 << 20, // Should this slider be orientated vertically?
743 KGGuiSliderFlags_ReadOnly = 1 << 21,
744};
745
746// Extend KGGuiSelectableFlags_
747enum KGGuiSelectableFlagsPrivate_
748{
749 // NB: need to be in sync with last value of KGGuiSelectableFlags_
750 KGGuiSelectableFlags_NoHoldingActiveID = 1 << 20,
751 KGGuiSelectableFlags_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.
752 KGGuiSelectableFlags_SelectOnClick = 1 << 22, // Override button behavior to react on Click (default is Click+Release)
753 KGGuiSelectableFlags_SelectOnRelease = 1 << 23, // Override button behavior to react on Release (default is Click+Release)
754 KGGuiSelectableFlags_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)
755 KGGuiSelectableFlags_DrawHoveredWhenHeld = 1 << 25, // Always show active when held, even is not hovered. This concept could probably be renamed/formalized somehow.
756 KGGuiSelectableFlags_SetNavIdOnHover = 1 << 26, // Set Nav/Focus ID on mouse hover (used by MenuItem)
757 KGGuiSelectableFlags_NoPadWithHalfSpacing = 1 << 27, // Disable padding each side with ItemSpacing * 0.5f
758 KGGuiSelectableFlags_NoSetKeyOwner = 1 << 28, // Don't set key/input owner on the initial click (note: mouse buttons are keys! often, the key in question will be KGGuiKey_MouseLeft!)
759};
760
761// Extend KGGuiTreeNodeFlags_
762enum KGGuiTreeNodeFlagsPrivate_
763{
764 KGGuiTreeNodeFlags_ClipLabelForTrailingButton = 1 << 20,
765};
766
767enum KGGuiSeparatorFlags_
768{
769 KGGuiSeparatorFlags_None = 0,
770 KGGuiSeparatorFlags_Horizontal = 1 << 0, // Axis default to current layout type, so generally Horizontal unless e.g. in a menu bar
771 KGGuiSeparatorFlags_Vertical = 1 << 1,
772 KGGuiSeparatorFlags_SpanAllColumns = 1 << 2,
773};
774
775enum KGGuiTextFlags_
776{
777 KGGuiTextFlags_None = 0,
778 KGGuiTextFlags_NoWidthForLargeClippedText = 1 << 0,
779};
780
781enum KGGuiTooltipFlags_
782{
783 KGGuiTooltipFlags_None = 0,
784 KGGuiTooltipFlags_OverridePreviousTooltip = 1 << 0, // Override will clear/ignore previously submitted tooltip (defaults to append)
785};
786
787// FIXME: this is in development, not exposed/functional as a generic feature yet.
788// Horizontal/Vertical enums are fixed to 0/1 so they may be used to index KGVec2
789enum KGGuiLayoutType_
790{
791 KGGuiLayoutType_Horizontal = 0,
792 KGGuiLayoutType_Vertical = 1
793};
794
795enum KGGuiLogType
796{
797 KGGuiLogType_None = 0,
798 KGGuiLogType_TTY,
799 KGGuiLogType_File,
800 KGGuiLogType_Buffer,
801 KGGuiLogType_Clipboard,
802};
803
804// X/Y enums are fixed to 0/1 so they may be used to index KGVec2
805enum KGGuiAxis
806{
807 KGGuiAxis_None = -1,
808 KGGuiAxis_X = 0,
809 KGGuiAxis_Y = 1
810};
811
812enum KGGuiPlotType
813{
814 KGGuiPlotType_Lines,
815 KGGuiPlotType_Histogram,
816};
817
818enum KGGuiPopupPositionPolicy
819{
820 KGGuiPopupPositionPolicy_Default,
821 KGGuiPopupPositionPolicy_ComboBox,
822 KGGuiPopupPositionPolicy_Tooltip,
823};
824
826{
827 KGU8 Data[8]; // Can fit any data up to KGGuiDataType_COUNT
828};
829
830// Type information associated to one KarmaGuiDataType. Retrieve with DataTypeGetInfo().
832{
833 size_t Size; // Size in bytes
834 const char* Name; // Short descriptive name for the type, for debugging
835 const char* PrintFmt; // Default printf format for the type
836 const char* ScanFmt; // Default scanf format for the type
837};
838
839// Extend KGGuiDataType_
840enum KGGuiDataTypePrivate_
841{
842 KGGuiDataType_String = KGGuiDataType_COUNT + 1,
843 KGGuiDataType_Pointer,
844 KGGuiDataType_ID,
845};
846
847// Stacked color modifier, backup of modified data so we can restore it
849{
850 KarmaGuiCol Col;
851 KGVec4 BackupValue;
852};
853
854// Stacked style modifier, backup of modified data so we can restore it. Data type inferred from the variable.
856{
857 KarmaGuiStyleVar VarIdx;
858 union { int BackupInt[2]; float BackupFloat[2]; };
859 KGGuiStyleMod(KarmaGuiStyleVar idx, int v) { VarIdx = idx; BackupInt[0] = v; }
860 KGGuiStyleMod(KarmaGuiStyleVar idx, float v) { VarIdx = idx; BackupFloat[0] = v; }
861 KGGuiStyleMod(KarmaGuiStyleVar idx, KGVec2 v) { VarIdx = idx; BackupFloat[0] = v.x; BackupFloat[1] = v.y; }
862};
863
864// Storage data for BeginComboPreview()/EndComboPreview()
866{
867 KGRect PreviewRect;
868 KGVec2 BackupCursorPos;
869 KGVec2 BackupCursorMaxPos;
870 KGVec2 BackupCursorPosPrevLine;
871 float BackupPrevLineTextBaseOffset;
872 KGGuiLayoutType BackupLayout;
873
874 KGGuiComboPreviewData() { memset(this, 0, sizeof(*this)); }
875};
876
877// Stacked storage data for BeginGroup()/EndGroup()
879{
880 KGGuiID WindowID;
881 KGVec2 BackupCursorPos;
882 KGVec2 BackupCursorMaxPos;
883 KGVec1 BackupIndent;
884 KGVec1 BackupGroupOffset;
885 KGVec2 BackupCurrLineSize;
886 float BackupCurrLineTextBaseOffset;
887 KGGuiID BackupActiveIdIsAlive;
888 bool BackupActiveIdPreviousFrameIsAlive;
889 bool BackupHoveredIdIsAlive;
890 bool EmitItem;
891};
892
893// Simple column measurement, currently used for MenuItem() only.. This is very short-sighted/throw-away code and NOT a generic helper.
895{
896 KGU32 TotalWidth;
897 KGU32 NextTotalWidth;
898 KGU16 Spacing;
899 KGU16 OffsetIcon; // Always zero for now
900 KGU16 OffsetLabel; // Offsets are locked in Update()
901 KGU16 OffsetShortcut;
902 KGU16 OffsetMark;
903 KGU16 Widths[4]; // Width of: Icon, Label, Shortcut, Mark (accumulators for current frame)
904
905 KGGuiMenuColumns() { memset(this, 0, sizeof(*this)); }
906 void Update(float spacing, bool window_reappearing);
907 float DeclColumns(float w_icon, float w_label, float w_shortcut, float w_mark);
908 void CalcNextTotalWidth(bool update_offsets);
909};
910
911// Internal state of the currently focused/edited text input box
912// For a given item ID, access with ImGui::GetInputTextState()
914{
915 KarmaGuiContext* Ctx; // parent dear imgui context
916 KGGuiID ID; // widget id owning the text state
917 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.
918 KGVector<KGWchar> TextW; // edit buffer, we need to persist but can't guarantee the persistence of the user-provided buffer. so we copy into own buffer.
919 KGVector<char> TextA; // temporary UTF8 buffer for callbacks and other operations. this is not updated in every code-path! size=capacity.
920 KGVector<char> InitialTextA; // backup of end-user buffer at the time of focus (in UTF-8, unaltered)
921 bool TextAIsValid; // temporary UTF8 buffer is not initially valid before we make the widget active (until then we pull the data from user argument)
922 int BufCapacityA; // end-user buffer capacity
923 float ScrollX; // horizontal scrolling/offset
924 KGStb::STB_TexteditState Stb; // state for stb_textedit.h
925 float CursorAnim; // timer for cursor blink, reset on every user action so the cursor reappears immediately
926 bool CursorFollow; // set when we want scrolling to follow the current cursor position (not always!)
927 bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection
928 bool Edited; // edited this frame
929 KarmaGuiInputTextFlags Flags; // copy of InputText() flags. may be used to check if e.g. KGGuiInputTextFlags_Password is set.
930
931 KGGuiInputTextState(KarmaGuiContext* ctx) { memset(this, 0, sizeof(*this)); Ctx = ctx; }
932 void ClearText() { CurLenW = CurLenA = 0; TextW[0] = 0; TextA[0] = 0; CursorClamp(); }
933 void ClearFreeMemory() { TextW.clear(); TextA.clear(); InitialTextA.clear(); }
934 int GetUndoAvailCount() const { return Stb.undostate.undo_point; }
935 int GetRedoAvailCount() const { return STB_TEXTEDIT_UNDOSTATECOUNT - Stb.undostate.redo_point; }
936 void OnKeyPressed(int key); // Cannot be inline because we call in code in stb_textedit.h implementation
937
938 // Cursor & Selection
939 void CursorAnimReset() { CursorAnim = -0.30f; } // After a user-input the cursor stays on for a while without blinking
940 void CursorClamp() { Stb.cursor = KGMin(Stb.cursor, CurLenW); Stb.select_start = KGMin(Stb.select_start, CurLenW); Stb.select_end = KGMin(Stb.select_end, CurLenW); }
941 bool HasSelection() const { return Stb.select_start != Stb.select_end; }
942 void ClearSelection() { Stb.select_start = Stb.select_end = Stb.cursor; }
943 int GetCursorPos() const { return Stb.cursor; }
944 int GetSelectionStart() const { return Stb.select_start; }
945 int GetSelectionEnd() const { return Stb.select_end; }
946 void SelectAll() { Stb.select_start = 0; Stb.cursor = Stb.select_end = CurLenW; Stb.has_preferred_x = 0; }
947};
948
949// Storage for current popup stack
951{
952 KGGuiID PopupId; // Set on OpenPopup()
953 KGGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup()
954 KGGuiWindow* BackupNavWindow;// Set on OpenPopup(), a NavWindow that will be restored on popup close
955 int ParentNavLayer; // Resolved on BeginPopup(). Actually a KGGuiNavLayer type (declared down below), initialized to -1 which is not part of an enum, but serves well-enough as "not any of layers" value
956 int OpenFrameCount; // Set on OpenPopup()
957 KGGuiID OpenParentId; // Set on OpenPopup(), we need this to differentiate multiple menu sets from each others (e.g. inside menu bar vs loose menu items)
958 KGVec2 OpenPopupPos; // Set on OpenPopup(), preferred popup position (typically == OpenMousePos when using mouse)
959 KGVec2 OpenMousePos; // Set on OpenPopup(), copy of mouse position at the time of opening popup
960
961 KGGuiPopupData() { memset(this, 0, sizeof(*this)); ParentNavLayer = OpenFrameCount = -1; }
962};
963
964enum KGGuiNextWindowDataFlags_
965{
966 KGGuiNextWindowDataFlags_None = 0,
967 KGGuiNextWindowDataFlags_HasPos = 1 << 0,
968 KGGuiNextWindowDataFlags_HasSize = 1 << 1,
969 KGGuiNextWindowDataFlags_HasContentSize = 1 << 2,
970 KGGuiNextWindowDataFlags_HasCollapsed = 1 << 3,
971 KGGuiNextWindowDataFlags_HasSizeConstraint = 1 << 4,
972 KGGuiNextWindowDataFlags_HasFocus = 1 << 5,
973 KGGuiNextWindowDataFlags_HasBgAlpha = 1 << 6,
974 KGGuiNextWindowDataFlags_HasScroll = 1 << 7,
975 KGGuiNextWindowDataFlags_HasViewport = 1 << 8,
976 KGGuiNextWindowDataFlags_HasDock = 1 << 9,
977 KGGuiNextWindowDataFlags_HasWindowClass = 1 << 10,
978};
979
980// Storage for SetNexWindow** functions
982{
983 KGGuiNextWindowDataFlags Flags;
984 KarmaGuiCond PosCond;
985 KarmaGuiCond SizeCond;
986 KarmaGuiCond CollapsedCond;
987 KarmaGuiCond DockCond;
988 KGVec2 PosVal;
989 KGVec2 PosPivotVal;
990 KGVec2 SizeVal;
991 KGVec2 ContentSizeVal;
992 KGVec2 ScrollVal;
993 bool PosUndock;
994 bool CollapsedVal;
995 KGRect SizeConstraintRect;
996 KarmaGuiSizeCallback SizeCallback;
997 void* SizeCallbackUserData;
998 float BgAlphaVal; // Override background alpha
999 KGGuiID ViewportId;
1000 KGGuiID DockId;
1001 KarmaGuiWindowClass WindowClass;
1002 KGVec2 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?)
1003
1004 KGGuiNextWindowData() { memset(this, 0, sizeof(*this)); }
1005 inline void ClearFlags() { Flags = KGGuiNextWindowDataFlags_None; }
1006};
1007
1008enum KGGuiNextItemDataFlags_
1009{
1010 KGGuiNextItemDataFlags_None = 0,
1011 KGGuiNextItemDataFlags_HasWidth = 1 << 0,
1012 KGGuiNextItemDataFlags_HasOpen = 1 << 1,
1013};
1014
1016{
1017 KGGuiNextItemDataFlags Flags;
1018 float Width; // Set by SetNextItemWidth()
1019 KGGuiID 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)
1020 KarmaGuiCond OpenCond;
1021 bool OpenVal; // Set by SetNextItemOpen()
1022
1023 KGGuiNextItemData() { memset(this, 0, sizeof(*this)); }
1024 inline void ClearFlags() { Flags = KGGuiNextItemDataFlags_None; } // Also cleared manually by ItemAdd()!
1025};
1026
1027// Status storage for the last submitted item
1029{
1030 KGGuiID ID;
1031 KGGuiItemFlags InFlags; // See KGGuiItemFlags_
1032 KGGuiItemStatusFlags StatusFlags; // See KGGuiItemStatusFlags_
1033 KGRect Rect; // Full rectangle
1034 KGRect NavRect; // Navigation scoring rectangle (not displayed)
1035 KGRect DisplayRect; // Display rectangle (only if KGGuiItemStatusFlags_HasDisplayRect is set)
1036
1037 KGGuiLastItemData() { memset(this, 0, sizeof(*this)); }
1038};
1039
1041{
1042 short SizeOfIDStack;
1043 short SizeOfColorStack;
1044 short SizeOfStyleVarStack;
1045 short SizeOfFontStack;
1046 short SizeOfFocusScopeStack;
1047 short SizeOfGroupStack;
1048 short SizeOfItemFlagsStack;
1049 short SizeOfBeginPopupStack;
1050 short SizeOfDisabledStack;
1051
1052 KGGuiStackSizes() { memset(this, 0, sizeof(*this)); }
1053 void SetToCurrentState();
1054 void CompareWithCurrentState();
1055};
1056
1057// Data saved for each window pushed into the stack
1059{
1060 KGGuiWindow* Window;
1061 KGGuiLastItemData ParentLastItemDataBackup;
1062 KGGuiStackSizes StackSizesOnBegin; // Store size of various stacks for asserting
1063};
1064
1066{
1067 int Index;
1068 float Width;
1069 float InitialWidth;
1070};
1071
1073{
1074 void* Ptr; // Either field can be set, not both. e.g. Dock node tab bars are loose while BeginTabBar() ones are in a pool.
1075 int Index; // Usually index in a main pool.
1076
1077 KGGuiPtrOrIndex(void* ptr) { Ptr = ptr; Index = -1; }
1078 KGGuiPtrOrIndex(int index) { Ptr = NULL; Index = index; }
1079};
1080
1081//-----------------------------------------------------------------------------
1082// [SECTION] Inputs support
1083//-----------------------------------------------------------------------------
1084
1085typedef KGBitArray<KGGuiKey_NamedKey_COUNT, -KGGuiKey_NamedKey_BEGIN> KGBitArrayForNamedKeys;
1086
1087// [Internal] Key ranges
1088#define KGGuiKey_LegacyNativeKey_BEGIN 0
1089#define KGGuiKey_LegacyNativeKey_END 512
1090#define KGGuiKey_Keyboard_BEGIN (KGGuiKey_NamedKey_BEGIN)
1091#define KGGuiKey_Keyboard_END (KGGuiKey_GamepadStart)
1092#define KGGuiKey_Gamepad_BEGIN (KGGuiKey_GamepadStart)
1093#define KGGuiKey_Gamepad_END (KGGuiKey_GamepadRStickDown + 1)
1094#define KGGuiKey_Mouse_BEGIN (KGGuiKey_MouseLeft)
1095#define KGGuiKey_Mouse_END (KGGuiKey_MouseWheelY + 1)
1096#define KGGuiKey_Aliases_BEGIN (KGGuiKey_Mouse_BEGIN)
1097#define KGGuiKey_Aliases_END (KGGuiKey_Mouse_END)
1098
1099// [Internal] Named shortcuts for Navigation
1100#define KGGuiKey_NavKeyboardTweakSlow KGGuiMod_Ctrl
1101#define KGGuiKey_NavKeyboardTweakFast KGGuiMod_Shift
1102#define KGGuiKey_NavGamepadTweakSlow KGGuiKey_GamepadL1
1103#define KGGuiKey_NavGamepadTweakFast KGGuiKey_GamepadR1
1104#define KGGuiKey_NavGamepadActivate KGGuiKey_GamepadFaceDown
1105#define KGGuiKey_NavGamepadCancel KGGuiKey_GamepadFaceRight
1106#define KGGuiKey_NavGamepadMenu KGGuiKey_GamepadFaceLeft
1107#define KGGuiKey_NavGamepadInput KGGuiKey_GamepadFaceUp
1108
1109enum KGGuiInputEventType
1110{
1111 KGGuiInputEventType_None = 0,
1112 KGGuiInputEventType_MousePos,
1113 KGGuiInputEventType_MouseWheel,
1114 KGGuiInputEventType_MouseButton,
1115 KGGuiInputEventType_MouseViewport,
1116 KGGuiInputEventType_Key,
1117 KGGuiInputEventType_Text,
1118 KGGuiInputEventType_Focus,
1119 KGGuiInputEventType_COUNT
1120};
1121
1122enum KGGuiInputSource
1123{
1124 KGGuiInputSource_None = 0,
1125 KGGuiInputSource_Mouse,
1126 KGGuiInputSource_Keyboard,
1127 KGGuiInputSource_Gamepad,
1128 KGGuiInputSource_Clipboard, // Currently only used by InputText()
1129 KGGuiInputSource_Nav, // Stored in g.ActiveIdSource only
1130 KGGuiInputSource_COUNT
1131};
1132
1133// FIXME: Structures in the union below need to be declared as anonymous unions appears to be an extension?
1134// Using KGVec2() would fail on Clang 'union member 'MousePos' has a non-trivial default constructor'
1135struct KGGuiInputEventMousePos { float PosX, PosY; };
1136struct KGGuiInputEventMouseWheel { float WheelX, WheelY; };
1137struct KGGuiInputEventMouseButton { int Button; bool Down; };
1138struct KGGuiInputEventMouseViewport { KGGuiID HoveredViewportID; };
1139struct KGGuiInputEventKey { KarmaGuiKey Key; bool Down; float AnalogValue; };
1140struct KGGuiInputEventText { unsigned int Char; };
1141struct KGGuiInputEventAppFocused { bool Focused; };
1142
1144{
1145 KGGuiInputEventType Type;
1146 KGGuiInputSource Source;
1147 union
1148 {
1149 KGGuiInputEventMousePos MousePos; // if Type == KGGuiInputEventType_MousePos
1150 KGGuiInputEventMouseWheel MouseWheel; // if Type == KGGuiInputEventType_MouseWheel
1151 KGGuiInputEventMouseButton MouseButton; // if Type == KGGuiInputEventType_MouseButton
1152 KGGuiInputEventMouseViewport MouseViewport; // if Type == KGGuiInputEventType_MouseViewport
1153 KGGuiInputEventKey Key; // if Type == KGGuiInputEventType_Key
1154 KGGuiInputEventText Text; // if Type == KGGuiInputEventType_Text
1155 KGGuiInputEventAppFocused AppFocused; // if Type == KGGuiInputEventType_Focus
1156 };
1157 bool AddedByTestEngine;
1158
1159 KGGuiInputEvent() { memset(this, 0, sizeof(*this)); }
1160};
1161
1162// Input function taking an 'KGGuiID owner_id' argument defaults to (KGGuiKeyOwner_Any == 0) aka don't test ownership, which matches legacy behavior.
1163#define KGGuiKeyOwner_Any ((KGGuiID)0) // Accept key that have an owner, UNLESS a call to SetKeyOwner() explicitly used KGGuiInputFlags_LockThisFrame or KGGuiInputFlags_LockUntilRelease.
1164#define KGGuiKeyOwner_None ((KGGuiID)-1) // Require key to have no owner.
1165
1166typedef KGS16 KGGuiKeyRoutingIndex;
1167
1168// Routing table entry (sizeof() == 16 bytes)
1170{
1171 KGGuiKeyRoutingIndex NextEntryIndex;
1172 KGU16 Mods; // Technically we'd only need 4-bits but for simplify we store KGGuiMod_ values which need 16-bits. KGGuiMod_Shortcut is already translated to Ctrl/Super.
1173 KGU8 RoutingNextScore; // Lower is better (0: perfect score)
1174 KGGuiID RoutingCurr;
1175 KGGuiID RoutingNext;
1176
1177 KGGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingNextScore = 255; RoutingCurr = RoutingNext = KGGuiKeyOwner_None; }
1178};
1179
1180// Routing table: maintain a desired owner for each possible key-chord (key + mods), and setup owner in NewFrame() when mods are matching.
1181// Stored in main context (1 instance)
1183{
1184 KGGuiKeyRoutingIndex Index[KGGuiKey_NamedKey_COUNT]; // Index of first entry in Entries[]
1186 KGVector<KGGuiKeyRoutingData> EntriesNext; // Double-buffer to avoid reallocation (could use a shared buffer)
1187
1188 KGGuiKeyRoutingTable() { Clear(); }
1189 void Clear() { for (int n = 0; n < KG_ARRAYSIZE(Index); n++) Index[n] = -1; Entries.clear(); EntriesNext.clear(); }
1190};
1191
1192// This extends KarmaGuiKeyData but only for named keys (legacy keys don't support the new features)
1193// Stored in main context (1 per named key). In the future it might be merged into KarmaGuiKeyData.
1195{
1196 KGGuiID OwnerCurr;
1197 KGGuiID OwnerNext;
1198 bool LockThisFrame; // Reading this key requires explicit owner id (until end of frame). Set by KGGuiInputFlags_LockThisFrame.
1199 bool LockUntilRelease; // Reading this key requires explicit owner id (until key is released). Set by KGGuiInputFlags_LockUntilRelease. When this is true LockThisFrame is always true as well.
1200
1201 KGGuiKeyOwnerData() { OwnerCurr = OwnerNext = KGGuiKeyOwner_None; LockThisFrame = LockUntilRelease = false; }
1202};
1203
1204// Extend KGGuiInputFlags_
1205// Flags for extended versions of IsKeyPressed(), IsMouseClicked(), Shortcut(), SetKeyOwner(), SetItemKeyOwner()
1206// Don't mistake with KarmaGuiInputTextFlags! (for ImGui::InputText() function)
1207enum KGGuiInputFlagsPrivate_
1208{
1209 // Flags for IsKeyPressed(), IsMouseClicked(), Shortcut()
1210 KGGuiInputFlags_RepeatRateDefault = 1 << 1, // Repeat rate: Regular (default)
1211 KGGuiInputFlags_RepeatRateNavMove = 1 << 2, // Repeat rate: Fast
1212 KGGuiInputFlags_RepeatRateNavTweak = 1 << 3, // Repeat rate: Faster
1213 KGGuiInputFlags_RepeatRateMask_ = KGGuiInputFlags_RepeatRateDefault | KGGuiInputFlags_RepeatRateNavMove | KGGuiInputFlags_RepeatRateNavTweak,
1214
1215 // Flags for SetItemKeyOwner()
1216 KGGuiInputFlags_CondHovered = 1 << 4, // Only set if item is hovered (default to both)
1217 KGGuiInputFlags_CondActive = 1 << 5, // Only set if item is active (default to both)
1218 KGGuiInputFlags_CondDefault_ = KGGuiInputFlags_CondHovered | KGGuiInputFlags_CondActive,
1219 KGGuiInputFlags_CondMask_ = KGGuiInputFlags_CondHovered | KGGuiInputFlags_CondActive,
1220
1221 // Flags for SetKeyOwner(), SetItemKeyOwner()
1222 KGGuiInputFlags_LockThisFrame = 1 << 6, // Access to key data will require EXPLICIT owner ID (KGGuiKeyOwner_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.
1223 KGGuiInputFlags_LockUntilRelease = 1 << 7, // Access to key data will require EXPLICIT owner ID (KGGuiKeyOwner_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.
1224
1225 // [Internal] Mask of which function support which flags
1226 KGGuiInputFlags_RouteMask_ = KGGuiInputFlags_RouteFocused | KGGuiInputFlags_RouteGlobal | KGGuiInputFlags_RouteGlobalLow | KGGuiInputFlags_RouteGlobalHigh, // _Always not part of this!
1227 KGGuiInputFlags_RouteExtraMask_ = KGGuiInputFlags_RouteAlways | KGGuiInputFlags_RouteUnlessBgFocused,
1228 KGGuiInputFlags_SupportedByIsKeyPressed = KGGuiInputFlags_Repeat | KGGuiInputFlags_RepeatRateMask_,
1229 KGGuiInputFlags_SupportedByShortcut = KGGuiInputFlags_Repeat | KGGuiInputFlags_RepeatRateMask_ | KGGuiInputFlags_RouteMask_ | KGGuiInputFlags_RouteExtraMask_,
1230 KGGuiInputFlags_SupportedBySetKeyOwner = KGGuiInputFlags_LockThisFrame | KGGuiInputFlags_LockUntilRelease,
1231 KGGuiInputFlags_SupportedBySetItemKeyOwner = KGGuiInputFlags_SupportedBySetKeyOwner | KGGuiInputFlags_CondMask_,
1232};
1233
1234//-----------------------------------------------------------------------------
1235// [SECTION] Clipper support
1236//-----------------------------------------------------------------------------
1237
1239{
1240 int Min;
1241 int Max;
1242 bool PosToIndexConvert; // Begin/End are absolute position (will be converted to indices later)
1243 KGS8 PosToIndexOffsetMin; // Add to Min after converting to indices
1244 KGS8 PosToIndexOffsetMax; // Add to Min after converting to indices
1245
1246 static KGGuiListClipperRange FromIndices(int min, int max) { KGGuiListClipperRange r = { min, max, false, 0, 0 }; return r; }
1247 static KGGuiListClipperRange FromPositions(float y1, float y2, int off_min, int off_max) { KGGuiListClipperRange r = { (int)y1, (int)y2, true, (KGS8)off_min, (KGS8)off_max }; return r; }
1248};
1249
1250// Temporary clipper data, buffers shared/reused between instances
1252{
1253 KarmaGuiListClipper* ListClipper;
1254 float LossynessOffset;
1255 int StepNo;
1256 int ItemsFrozen;
1258
1259 KGGuiListClipperData() { memset(this, 0, sizeof(*this)); }
1260 void Reset(KarmaGuiListClipper* clipper) { ListClipper = clipper; StepNo = ItemsFrozen = 0; Ranges.resize(0); }
1261};
1262
1263//-----------------------------------------------------------------------------
1264// [SECTION] Navigation support
1265//-----------------------------------------------------------------------------
1266
1267enum KGGuiActivateFlags_
1268{
1269 KGGuiActivateFlags_None = 0,
1270 KGGuiActivateFlags_PreferInput = 1 << 0, // Favor activation that requires keyboard text input (e.g. for Slider/Drag). Default if keyboard is available.
1271 KGGuiActivateFlags_PreferTweak = 1 << 1, // Favor activation for tweaking with arrows or gamepad (e.g. for Slider/Drag). Default if keyboard is not available.
1272 KGGuiActivateFlags_TryToPreserveState = 1 << 2, // Request widget to preserve state if it can (e.g. InputText will try to preserve cursor/selection)
1273};
1274
1275// Early work-in-progress API for ScrollToItem()
1276enum KGGuiScrollFlags_
1277{
1278 KGGuiScrollFlags_None = 0,
1279 KGGuiScrollFlags_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]
1280 KGGuiScrollFlags_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]
1281 KGGuiScrollFlags_KeepVisibleCenterX = 1 << 2, // If item is not visible: scroll to make the item centered on X axis [rarely used]
1282 KGGuiScrollFlags_KeepVisibleCenterY = 1 << 3, // If item is not visible: scroll to make the item centered on Y axis
1283 KGGuiScrollFlags_AlwaysCenterX = 1 << 4, // Always center the result item on X axis [rarely used]
1284 KGGuiScrollFlags_AlwaysCenterY = 1 << 5, // Always center the result item on Y axis [default for Y axis for appearing window)
1285 KGGuiScrollFlags_NoScrollParent = 1 << 6, // Disable forwarding scrolling to parent window if required to keep item/rect visible (only scroll window the function was applied to).
1286 KGGuiScrollFlags_MaskX_ = KGGuiScrollFlags_KeepVisibleEdgeX | KGGuiScrollFlags_KeepVisibleCenterX | KGGuiScrollFlags_AlwaysCenterX,
1287 KGGuiScrollFlags_MaskY_ = KGGuiScrollFlags_KeepVisibleEdgeY | KGGuiScrollFlags_KeepVisibleCenterY | KGGuiScrollFlags_AlwaysCenterY,
1288};
1289
1290enum KGGuiNavHighlightFlags_
1291{
1292 KGGuiNavHighlightFlags_None = 0,
1293 KGGuiNavHighlightFlags_TypeDefault = 1 << 0,
1294 KGGuiNavHighlightFlags_TypeThin = 1 << 1,
1295 KGGuiNavHighlightFlags_AlwaysDraw = 1 << 2, // Draw rectangular highlight if (g.NavId == id) _even_ when using the mouse.
1296 KGGuiNavHighlightFlags_NoRounding = 1 << 3,
1297};
1298
1299enum KGGuiNavMoveFlags_
1300{
1301 KGGuiNavMoveFlags_None = 0,
1302 KGGuiNavMoveFlags_LoopX = 1 << 0, // On failed request, restart from opposite side
1303 KGGuiNavMoveFlags_LoopY = 1 << 1,
1304 KGGuiNavMoveFlags_WrapX = 1 << 2, // On failed request, request from opposite side one line down (when NavDir==right) or one line up (when NavDir==left)
1305 KGGuiNavMoveFlags_WrapY = 1 << 3, // This is not super useful but provided for completeness
1306 KGGuiNavMoveFlags_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)
1307 KGGuiNavMoveFlags_AlsoScoreVisibleSet = 1 << 5, // Store alternate result in NavMoveResultLocalVisible that only comprise elements that are already fully visible (used by PageUp/PageDown)
1308 KGGuiNavMoveFlags_ScrollToEdgeY = 1 << 6, // Force scrolling to min/max (used by Home/End) // FIXME-NAV: Aim to remove or reword, probably unnecessary
1309 KGGuiNavMoveFlags_Forwarded = 1 << 7,
1310 KGGuiNavMoveFlags_DebugNoResult = 1 << 8, // Dummy scoring for debug purpose, don't apply result
1311 KGGuiNavMoveFlags_FocusApi = 1 << 9,
1312 KGGuiNavMoveFlags_Tabbing = 1 << 10, // == Focus + Activate if item is Inputable + DontChangeNavHighlight
1313 KGGuiNavMoveFlags_Activate = 1 << 11,
1314 KGGuiNavMoveFlags_DontSetNavHighlight = 1 << 12, // Do not alter the visible state of keyboard vs mouse nav highlight
1315};
1316
1317enum KGGuiNavLayer
1318{
1319 KGGuiNavLayer_Main = 0, // Main scrolling layer
1320 KGGuiNavLayer_Menu = 1, // Menu layer (access with Alt)
1321 KGGuiNavLayer_COUNT
1322};
1323
1325{
1326 KGGuiWindow* Window; // Init,Move // Best candidate window (result->ItemWindow->RootWindowForNav == request->Window)
1327 KGGuiID ID; // Init,Move // Best candidate item ID
1328 KGGuiID FocusScopeId; // Init,Move // Best candidate focus scope ID
1329 KGRect RectRel; // Init,Move // Best candidate bounding box in window relative space
1330 KGGuiItemFlags InFlags; // ????,Move // Best candidate item flags
1331 float DistBox; // Move // Best candidate box distance to current NavId
1332 float DistCenter; // Move // Best candidate center distance to current NavId
1333 float DistAxial; // Move // Best candidate axial distance to current NavId
1334
1335 KGGuiNavItemData() { Clear(); }
1336 void Clear() { Window = NULL; ID = FocusScopeId = 0; InFlags = 0; DistBox = DistCenter = DistAxial = FLT_MAX; }
1337};
1338
1339//-----------------------------------------------------------------------------
1340// [SECTION] Columns support
1341//-----------------------------------------------------------------------------
1342
1343// Flags for internal's BeginColumns(). Prefix using BeginTable() nowadays!
1344enum KGGuiOldColumnFlags_
1345{
1346 KGGuiOldColumnFlags_None = 0,
1347 KGGuiOldColumnFlags_NoBorder = 1 << 0, // Disable column dividers
1348 KGGuiOldColumnFlags_NoResize = 1 << 1, // Disable resizing columns when clicking on the dividers
1349 KGGuiOldColumnFlags_NoPreserveWidths = 1 << 2, // Disable column width preservation when adjusting columns
1350 KGGuiOldColumnFlags_NoForceWithinWindow = 1 << 3, // Disable forcing columns to fit within window
1351 KGGuiOldColumnFlags_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.
1352};
1353
1355{
1356 float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right)
1357 float OffsetNormBeforeResize;
1358 KGGuiOldColumnFlags Flags; // Not exposed
1359 KGRect ClipRect;
1360
1361 KGGuiOldColumnData() { memset(this, 0, sizeof(*this)); }
1362};
1363
1365{
1366 KGGuiID ID;
1367 KGGuiOldColumnFlags Flags;
1368 bool IsFirstFrame;
1369 bool IsBeingResized;
1370 int Current;
1371 int Count;
1372 float OffMinX, OffMaxX; // Offsets from HostWorkRect.Min.x
1373 float LineMinY, LineMaxY;
1374 float HostCursorPosY; // Backup of CursorPos at the time of BeginColumns()
1375 float HostCursorMaxPosX; // Backup of CursorMaxPos at the time of BeginColumns()
1376 KGRect HostInitialClipRect; // Backup of ClipRect at the time of BeginColumns()
1377 KGRect HostBackupClipRect; // Backup of ClipRect during PushColumnsBackground()/PopColumnsBackground()
1378 KGRect HostBackupParentWorkRect;//Backup of WorkRect at the time of BeginColumns()
1380 KGDrawListSplitter Splitter;
1381
1382 KGGuiOldColumns() { memset(this, 0, sizeof(*this)); }
1383};
1384
1385//-----------------------------------------------------------------------------
1386// [SECTION] Docking support
1387//-----------------------------------------------------------------------------
1388
1389#define DOCKING_HOST_DRAW_CHANNEL_BG 0 // Dock host: background fill
1390#define DOCKING_HOST_DRAW_CHANNEL_FG 1 // Dock host: decorations and contents
1391
1392//#ifdef KARMAGUI_HAS_DOCK
1393
1394// Extend KGGuiDockNodeFlags_
1395enum KGGuiDockNodeFlagsPrivate_
1396{
1397 // [Internal]
1398 KGGuiDockNodeFlags_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.
1399 KGGuiDockNodeFlags_CentralNode = 1 << 11, // Local, Saved // The central node has 2 main properties: stay visible when empty, only use "remaining" spaces from its neighbor.
1400 KGGuiDockNodeFlags_NoTabBar = 1 << 12, // Local, Saved // Tab bar is completely unavailable. No triangle in the corner to enable it back.
1401 KGGuiDockNodeFlags_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)
1402 KGGuiDockNodeFlags_NoWindowMenuButton = 1 << 14, // Local, Saved // Disable window/docking menu (that one that appears instead of the collapse button)
1403 KGGuiDockNodeFlags_NoCloseButton = 1 << 15, // Local, Saved //
1404 KGGuiDockNodeFlags_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.
1405 KGGuiDockNodeFlags_NoDockingSplitMe = 1 << 17, // [EXPERIMENTAL] Prevent another window/node from splitting this node.
1406 KGGuiDockNodeFlags_NoDockingSplitOther = 1 << 18, // [EXPERIMENTAL] Prevent this node from splitting another window/node.
1407 KGGuiDockNodeFlags_NoDockingOverMe = 1 << 19, // [EXPERIMENTAL] Prevent another window/node to be docked over this node.
1408 KGGuiDockNodeFlags_NoDockingOverOther = 1 << 20, // [EXPERIMENTAL] Prevent this node to be docked over another window or non-empty node.
1409 KGGuiDockNodeFlags_NoDockingOverEmpty = 1 << 21, // [EXPERIMENTAL] Prevent this node to be docked over an empty node (e.g. DockSpace with no other windows)
1410 KGGuiDockNodeFlags_NoResizeX = 1 << 22, // [EXPERIMENTAL]
1411 KGGuiDockNodeFlags_NoResizeY = 1 << 23, // [EXPERIMENTAL]
1412 KGGuiDockNodeFlags_SharedFlagsInheritMask_ = ~0,
1413 KGGuiDockNodeFlags_NoResizeFlagsMask_ = KGGuiDockNodeFlags_NoResize | KGGuiDockNodeFlags_NoResizeX | KGGuiDockNodeFlags_NoResizeY,
1414 KGGuiDockNodeFlags_LocalFlagsMask_ = KGGuiDockNodeFlags_NoSplit | KGGuiDockNodeFlags_NoResizeFlagsMask_ | KGGuiDockNodeFlags_AutoHideTabBar | KGGuiDockNodeFlags_DockSpace | KGGuiDockNodeFlags_CentralNode | KGGuiDockNodeFlags_NoTabBar | KGGuiDockNodeFlags_HiddenTabBar | KGGuiDockNodeFlags_NoWindowMenuButton | KGGuiDockNodeFlags_NoCloseButton | KGGuiDockNodeFlags_NoDocking,
1415 KGGuiDockNodeFlags_LocalFlagsTransferMask_ = KGGuiDockNodeFlags_LocalFlagsMask_ & ~KGGuiDockNodeFlags_DockSpace, // When splitting those flags are moved to the inheriting child, never duplicated
1416 KGGuiDockNodeFlags_SavedFlagsMask_ = KGGuiDockNodeFlags_NoResizeFlagsMask_ | KGGuiDockNodeFlags_DockSpace | KGGuiDockNodeFlags_CentralNode | KGGuiDockNodeFlags_NoTabBar | KGGuiDockNodeFlags_HiddenTabBar | KGGuiDockNodeFlags_NoWindowMenuButton | KGGuiDockNodeFlags_NoCloseButton | KGGuiDockNodeFlags_NoDocking
1417};
1418
1419// Store the source authority (dock node vs window) of a field
1420enum KGGuiDataAuthority_
1421{
1422 KGGuiDataAuthority_Auto,
1423 KGGuiDataAuthority_DockNode,
1424 KGGuiDataAuthority_Window,
1425};
1426
1427enum KGGuiDockNodeState
1428{
1429 KGGuiDockNodeState_Unknown,
1430 KGGuiDockNodeState_HostWindowHiddenBecauseSingleWindow,
1431 KGGuiDockNodeState_HostWindowHiddenBecauseWindowsAreResizing,
1432 KGGuiDockNodeState_HostWindowVisible,
1433};
1434
1435// sizeof() 156~192
1436struct KARMA_API KGGuiDockNode
1437{
1438 KGGuiID ID;
1439 KarmaGuiDockNodeFlags SharedFlags; // (Write) Flags shared by all nodes of a same dockspace hierarchy (inherited from the root node)
1440 KarmaGuiDockNodeFlags LocalFlags; // (Write) Flags specific to this node
1441 KarmaGuiDockNodeFlags LocalFlagsInWindows; // (Write) Flags specific to this node, applied from windows
1442 KarmaGuiDockNodeFlags MergedFlags; // (Read) Effective flags (== SharedFlags | LocalFlagsInNode | LocalFlagsInWindows)
1443 KGGuiDockNodeState State;
1444 KGGuiDockNode* ParentNode;
1445 KGGuiDockNode* ChildNodes[2]; // [Split node only] Child nodes (left/right or top/bottom). Consider switching to an array.
1446 KGVector<KGGuiWindow*> Windows; // Note: unordered list! Iterate TabBar->Tabs for user-order.
1447 KGGuiTabBar* TabBar;
1448 KGVec2 Pos; // Current position
1449 KGVec2 Size; // Current size
1450 KGVec2 SizeRef; // [Split node only] Last explicitly written-to size (overridden when using a splitter affecting the node), used to calculate Size.
1451 KGGuiAxis SplitAxis; // [Split node only] Split axis (X or Y)
1452 KarmaGuiWindowClass WindowClass; // [Root node only]
1453 KGU32 LastBgColor;
1454
1455 KGGuiWindow* HostWindow;
1456 KGGuiWindow* VisibleWindow; // Generally point to window which is ID is == SelectedTabID, but when CTRL+Tabbing this can be a different window.
1457 KGGuiDockNode* CentralNode; // [Root node only] Pointer to central node.
1458 KGGuiDockNode* OnlyNodeWithWindows; // [Root node only] Set when there is a single visible node within the hierarchy.
1459 int CountNodeWithWindows; // [Root node only]
1460 int LastFrameAlive; // Last frame number the node was updated or kept alive explicitly with DockSpace() + KGGuiDockNodeFlags_KeepAliveOnly
1461 int LastFrameActive; // Last frame number the node was updated.
1462 int LastFrameFocused; // Last frame number the node was focused.
1463 KGGuiID LastFocusedNodeId; // [Root node only] Which of our child docking node (any ancestor in the hierarchy) was last focused.
1464 KGGuiID SelectedTabId; // [Leaf node only] Which of our tab/window is selected.
1465 KGGuiID WantCloseTabId; // [Leaf node only] Set when closing a specific tab/window.
1466 KGGuiDataAuthority AuthorityForPos : 3;
1467 KGGuiDataAuthority AuthorityForSize : 3;
1468 KGGuiDataAuthority AuthorityForViewport : 3;
1469 bool IsVisible : 1; // Set to false when the node is hidden (usually disabled as it has no active window)
1470 bool IsFocused : 1;
1471 bool IsBgDrawnThisFrame : 1;
1472 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.
1473 bool HasWindowMenuButton : 1;
1474 bool HasCentralNodeChild : 1;
1475 bool WantCloseAll : 1; // Set when closing all tabs at once.
1476 bool WantLockSizeOnce : 1;
1477 bool WantMouseMove : 1; // After a node extraction we need to transition toward moving the newly created host window
1478 bool WantHiddenTabBarUpdate : 1;
1479 bool WantHiddenTabBarToggle : 1;
1480
1481 KGGuiDockNode(KGGuiID id);
1483 bool IsRootNode() const { return ParentNode == NULL; }
1484 bool IsDockSpace() const { return (MergedFlags & KGGuiDockNodeFlags_DockSpace) != 0; }
1485 bool IsFloatingNode() const { return ParentNode == NULL && (MergedFlags & KGGuiDockNodeFlags_DockSpace) == 0; }
1486 bool IsCentralNode() const { return (MergedFlags & KGGuiDockNodeFlags_CentralNode) != 0; }
1487 bool IsHiddenTabBar() const { return (MergedFlags & KGGuiDockNodeFlags_HiddenTabBar) != 0; } // Hidden tab bar can be shown back by clicking the small triangle
1488 bool IsNoTabBar() const { return (MergedFlags & KGGuiDockNodeFlags_NoTabBar) != 0; } // Never show a tab bar
1489 bool IsSplitNode() const { return ChildNodes[0] != NULL; }
1490 bool IsLeafNode() const { return ChildNodes[0] == NULL; }
1491 bool IsEmpty() const { return ChildNodes[0] == NULL && Windows.Size == 0; }
1492 KGRect Rect() const { return KGRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
1493
1494 void SetLocalFlags(KarmaGuiDockNodeFlags flags) { LocalFlags = flags; UpdateMergedFlags(); }
1495 void UpdateMergedFlags() { MergedFlags = SharedFlags | LocalFlags | LocalFlagsInWindows; }
1496};
1497
1498// List of colors that are stored at the time of Begin() into Docked Windows.
1499// We currently store the packed colors in a simple array window->DockStyle.Colors[].
1500// A better solution may involve appending into a log of colors in KarmaGuiContext + store offsets into those arrays in KGGuiWindow,
1501// 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.
1502enum KGGuiWindowDockStyleCol
1503{
1504 KGGuiWindowDockStyleCol_Text,
1505 KGGuiWindowDockStyleCol_Tab,
1506 KGGuiWindowDockStyleCol_TabHovered,
1507 KGGuiWindowDockStyleCol_TabActive,
1508 KGGuiWindowDockStyleCol_TabUnfocused,
1509 KGGuiWindowDockStyleCol_TabUnfocusedActive,
1510 KGGuiWindowDockStyleCol_COUNT
1511};
1512
1514{
1515 KGU32 Colors[KGGuiWindowDockStyleCol_COUNT];
1516};
1517
1519{
1520 KarmaGuiStorage Nodes; // Map ID -> KGGuiDockNode*: Active nodes
1522 KGVector<KGGuiDockNodeSettings> NodesSettings;
1523 bool WantFullRebuild;
1524 KGGuiDockContext() { memset(this, 0, sizeof(*this)); }
1525};
1526
1527//#endif // #ifdef KARMAGUI_HAS_DOCK
1528
1529//-----------------------------------------------------------------------------
1530// [SECTION] Viewport support
1531//-----------------------------------------------------------------------------
1532
1533// KarmaGuiViewport Private/Internals fields (cardinal sin: we are using inheritance!)
1534// Every instance of KarmaGuiViewport is in fact a KGGuiViewportP.
1536{
1537 int Idx;
1538 int LastFrameActive; // Last frame number this viewport was activated by a window
1539 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
1540 KGGuiID LastNameHash;
1541 KGVec2 LastPos;
1542 float Alpha; // Window opacity (when dragging dockable windows/viewports we make them transparent)
1543 float LastAlpha;
1544 short PlatformMonitor;
1545 KGGuiWindow* Window; // Set when the viewport is owned by a window (and KGGuiViewportFlags_CanHostOtherWindows is NOT set)
1546 int DrawListsLastFrame[2]; // Last frame number the background (0) and foreground (1) draw lists were used
1547 KGDrawList* 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.
1548 KGDrawData DrawDataP;
1549 KGDrawDataBuilder DrawDataBuilder;
1550 KGVec2 LastPlatformPos;
1551 KGVec2 LastPlatformSize;
1552 KGVec2 LastRendererSize;
1553 KGVec2 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!)
1554 KGVec2 WorkOffsetMax; // Work Area: Offset from Pos+Size to bottom-right corner of Work Area. Generally (0,0) or (0,-status_bar_height).
1555 KGVec2 BuildWorkOffsetMin; // Work Area: Offset being built during current frame. Generally >= 0.0f.
1556 KGVec2 BuildWorkOffsetMax; // Work Area: Offset being built during current frame. Generally <= 0.0f.
1557
1558 KGGuiViewportP() { 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 = KGVec2(FLT_MAX, FLT_MAX); }
1559 ~KGGuiViewportP() { if (DrawLists[0]) KG_DELETE(DrawLists[0]); if (DrawLists[1]) KG_DELETE(DrawLists[1]); }
1560 void ClearRequestFlags() { PlatformRequestClose = PlatformRequestMove = PlatformRequestResize = false; }
1561
1562 // 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)
1563 KGVec2 CalcWorkRectPos(const KGVec2& off_min) const { return KGVec2(Pos.x + off_min.x, Pos.y + off_min.y); }
1564 KGVec2 CalcWorkRectSize(const KGVec2& off_min, const KGVec2& off_max) const { return KGVec2(KGMax(0.0f, Size.x - off_min.x + off_max.x), KGMax(0.0f, Size.y - off_min.y + off_max.y)); }
1565 void UpdateWorkRect() { WorkPos = CalcWorkRectPos(WorkOffsetMin); WorkSize = CalcWorkRectSize(WorkOffsetMin, WorkOffsetMax); } // Update public fields
1566
1567 // Helpers to retrieve KGRect (we don't need to store BuildWorkRect as every access tend to change it, hence the code asymmetry)
1568 KGRect GetMainRect() const { return KGRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
1569 KGRect GetWorkRect() const { return KGRect(WorkPos.x, WorkPos.y, WorkPos.x + WorkSize.x, WorkPos.y + WorkSize.y); }
1570 KGRect GetBuildWorkRect() const { KGVec2 pos = CalcWorkRectPos(BuildWorkOffsetMin); KGVec2 size = CalcWorkRectSize(BuildWorkOffsetMin, BuildWorkOffsetMax); return KGRect(pos.x, pos.y, pos.x + size.x, pos.y + size.y); }
1571};
1572
1573//-----------------------------------------------------------------------------
1574// [SECTION] Settings support
1575//-----------------------------------------------------------------------------
1576
1577// Windows data saved in kggui.ini file
1578// Because we never destroy or rename KGGuiWindowSettings, we can store the names in a separate buffer easily.
1579// (this is designed to be stored in a KGChunkStream buffer, with the variable-length Name following our structure)
1581{
1582 KGGuiID ID;
1583 KGVec2ih Pos; // NB: Settings position are stored RELATIVE to the viewport! Whereas runtime ones are absolute positions.
1584 KGVec2ih Size;
1585 KGVec2ih ViewportPos;
1586 KGGuiID ViewportId;
1587 KGGuiID DockId; // ID of last known DockNode (even if the DockNode is invisible because it has only 1 active window), or 0 if none.
1588 KGGuiID ClassId; // ID of window class if specified
1589 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.
1590 bool Collapsed;
1591 bool WantApply; // Set when loaded from .ini data (to enable merging/loading .ini data into an already running context)
1592
1593 KGGuiWindowSettings() { memset(this, 0, sizeof(*this)); DockOrder = -1; }
1594 char* GetName() { return (char*)(this + 1); }
1595};
1596
1598{
1599 const char* TypeName; // Short description stored in .ini file. Disallowed characters: '[' ']'
1600 KGGuiID TypeHash; // == KGHashStr(TypeName)
1601 void (*ClearAllFn)(KarmaGuiContext* ctx, KGGuiSettingsHandler* handler); // Clear all settings data
1602 void (*ReadInitFn)(KarmaGuiContext* ctx, KGGuiSettingsHandler* handler); // Read: Called before reading (in registration order)
1603 void* (*ReadOpenFn)(KarmaGuiContext* ctx, KGGuiSettingsHandler* handler, const char* name); // Read: Called when entering into a new ini entry e.g. "[Window][Name]"
1604 void (*ReadLineFn)(KarmaGuiContext* ctx, KGGuiSettingsHandler* handler, void* entry, const char* line); // Read: Called for every line of text within an ini entry
1605 void (*ApplyAllFn)(KarmaGuiContext* ctx, KGGuiSettingsHandler* handler); // Read: Called after reading (in registration order)
1606 void (*WriteAllFn)(KarmaGuiContext* ctx, KGGuiSettingsHandler* handler, KarmaGuiTextBuffer* out_buf); // Write: Output every entries into 'out_buf'
1607 void* UserData;
1608
1609 KGGuiSettingsHandler() { memset(this, 0, sizeof(*this)); }
1610};
1611
1612//-----------------------------------------------------------------------------
1613// [SECTION] Localization support
1614//-----------------------------------------------------------------------------
1615
1616// This is experimental and not officially supported, it'll probably fall short of features, if/when it does we may backtrack.
1617enum KGGuiLocKey : int
1618{
1619 ImGuiLocKey_TableSizeOne,
1620 ImGuiLocKey_TableSizeAllFit,
1621 ImGuiLocKey_TableSizeAllDefault,
1622 ImGuiLocKey_TableResetOrder,
1623 ImGuiLocKey_WindowingMainMenuBar,
1624 ImGuiLocKey_WindowingPopup,
1625 ImGuiLocKey_WindowingUntitled,
1626 ImGuiLocKey_DockingHideTabBar,
1627 ImGuiLocKey_COUNT
1628};
1629
1631{
1632 KGGuiLocKey Key;
1633 const char* Text;
1634};
1635
1636//-----------------------------------------------------------------------------
1637// [SECTION] Metrics, Debug Tools
1638//-----------------------------------------------------------------------------
1639
1640enum KGGuiDebugLogFlags_
1641{
1642 // Event types
1643 KGGuiDebugLogFlags_None = 0,
1644 KGGuiDebugLogFlags_EventActiveId = 1 << 0,
1645 KGGuiDebugLogFlags_EventFocus = 1 << 1,
1646 KGGuiDebugLogFlags_EventPopup = 1 << 2,
1647 KGGuiDebugLogFlags_EventNav = 1 << 3,
1648 KGGuiDebugLogFlags_EventClipper = 1 << 4,
1649 KGGuiDebugLogFlags_EventIO = 1 << 5,
1650 KGGuiDebugLogFlags_EventDocking = 1 << 6,
1651 KGGuiDebugLogFlags_EventViewport = 1 << 7,
1652 KGGuiDebugLogFlags_EventMask_ = KGGuiDebugLogFlags_EventActiveId | KGGuiDebugLogFlags_EventFocus | KGGuiDebugLogFlags_EventPopup | KGGuiDebugLogFlags_EventNav | KGGuiDebugLogFlags_EventClipper | KGGuiDebugLogFlags_EventIO | KGGuiDebugLogFlags_EventDocking | KGGuiDebugLogFlags_EventViewport,
1653 KGGuiDebugLogFlags_OutputToTTY = 1 << 10, // Also send output to TTY
1654};
1655
1657{
1658 bool ShowDebugLog;
1659 bool ShowStackTool;
1660 bool ShowWindowsRects;
1661 bool ShowWindowsBeginOrder;
1662 bool ShowTablesRects;
1663 bool ShowDrawCmdMesh;
1664 bool ShowDrawCmdBoundingBoxes;
1665 bool ShowDockingNodes;
1666 int ShowWindowsRectsType;
1667 int ShowTablesRectsType;
1668
1670 {
1671 ShowDebugLog = ShowStackTool = ShowWindowsRects = ShowWindowsBeginOrder = ShowTablesRects = false;
1672 ShowDrawCmdMesh = true;
1673 ShowDrawCmdBoundingBoxes = true;
1674 ShowDockingNodes = false;
1675 ShowWindowsRectsType = ShowTablesRectsType = -1;
1676 }
1677};
1678
1680{
1681 KGGuiID ID;
1682 KGS8 QueryFrameCount; // >= 1: Query in progress
1683 bool QuerySuccess; // Obtained result from DebugHookIdInfo()
1684 KarmaGuiDataType DataType : 8;
1685 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.
1686
1687 KGGuiStackLevelInfo() { memset(this, 0, sizeof(*this)); }
1688};
1689
1690// State for Stack tool queries
1692{
1693 int LastActiveFrame;
1694 int StackLevel; // -1: query stack and resize Results, >= 0: individual stack level
1695 KGGuiID QueryId; // ID to query details for
1697 bool CopyToClipboardOnCtrlC;
1698 float CopyToClipboardLastTime;
1699
1700 KGGuiStackTool() { memset(this, 0, sizeof(*this)); CopyToClipboardLastTime = -FLT_MAX; }
1701};
1702
1703//-----------------------------------------------------------------------------
1704// [SECTION] Generic context hooks
1705//-----------------------------------------------------------------------------
1706
1707typedef void (*ImGuiContextHookCallback)(KarmaGuiContext* ctx, KGGuiContextHook* hook);
1708enum ImGuiContextHookType { ImGuiContextHookType_NewFramePre, ImGuiContextHookType_NewFramePost, ImGuiContextHookType_EndFramePre, ImGuiContextHookType_EndFramePost, ImGuiContextHookType_RenderPre, ImGuiContextHookType_RenderPost, ImGuiContextHookType_Shutdown, ImGuiContextHookType_PendingRemoval_ };
1709
1711{
1712 KGGuiID HookId; // A unique ID assigned by AddContextHook()
1713 ImGuiContextHookType Type;
1714 KGGuiID Owner;
1715 ImGuiContextHookCallback Callback;
1716 void* UserData;
1717
1718 KGGuiContextHook() { memset(this, 0, sizeof(*this)); }
1719};
1720
1721//-----------------------------------------------------------------------------
1722// [SECTION] KarmaGuiContext (main Dear ImGui context)
1723//-----------------------------------------------------------------------------
1725{
1726 bool Initialized;
1727 bool FontAtlasOwnedByContext; // IO.Fonts-> is owned by the KarmaGuiContext and will be destructed along with it.
1728 KarmaGuiIO IO;
1729 KarmaGuiPlatformIO PlatformIO;
1730 KGVector<KGGuiInputEvent> InputEventsQueue; // Input events which will be tricked/written into IO structure.
1731 KGVector<KGGuiInputEvent> InputEventsTrail; // Past input events processed in NewFrame(). This is to allow domain-specific application to access e.g mouse/pen trail.
1732 KarmaGuiStyle Style;
1733 KarmaGuiConfigFlags ConfigFlagsCurrFrame; // = g.IO.ConfigFlags at the time of NewFrame()
1734 KarmaGuiConfigFlags ConfigFlagsLastFrame;
1735 KGFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back()
1736 float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window.
1737 float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height.
1738 KGDrawListSharedData DrawListSharedData;
1739 double Time;
1740 int FrameCount;
1741 int FrameCountEnded;
1742 int FrameCountPlatformEnded;
1743 int FrameCountRendered;
1744 bool WithinFrameScope; // Set by NewFrame(), cleared by EndFrame()
1745 bool WithinFrameScopeWithImplicitWindow; // Set by NewFrame(), cleared by EndFrame() when the implicit debug window has been pushed
1746 bool WithinEndChild; // Set within EndChild()
1747 bool GcCompactAll; // Request full GC
1748 bool TestEngineHookItems; // Will call test engine hooks: ImGuiTestEngineHook_ItemAdd(), ImGuiTestEngineHook_ItemInfo(), ImGuiTestEngineHook_Log()
1749 void* TestEngine; // Test engine user data
1750
1751 // Windows state
1752 KGVector<KGGuiWindow*> Windows; // Windows, sorted in display order, back to front
1753 KGVector<KGGuiWindow*> WindowsFocusOrder; // Root windows, sorted in focus order, back to front.
1754 KGVector<KGGuiWindow*> WindowsTempSortBuffer; // Temporary buffer used in EndFrame() to reorder windows so parents are kept before their child
1755 KGVector<KGGuiWindowStackData> CurrentWindowStack;
1756 KarmaGuiStorage WindowsById; // Map window's KGGuiID to KGGuiWindow*
1757 int WindowsActiveCount; // Number of unique windows submitted by frame
1758 KGVec2 WindowsHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == KGMax(style.TouchExtraPadding, WINDOWS_HOVER_PADDING)
1759 KGGuiWindow* CurrentWindow; // Window being drawn into
1760 KGGuiWindow* HoveredWindow; // Window the mouse is hovering. Will typically catch mouse inputs.
1761 KGGuiWindow* HoveredWindowUnderMovingWindow; // Hovered window ignoring MovingWindow. Only set if MovingWindow is set.
1762 KGGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actual window that is moved is generally MovingWindow->RootWindowDockTree.
1763 KGGuiWindow* 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.
1764 KGVec2 WheelingWindowRefMousePos;
1765 int WheelingWindowStartFrame; // This may be set one frame before WheelingWindow is != NULL
1766 float WheelingWindowReleaseTimer;
1767 KGVec2 WheelingWindowWheelRemainder;
1768 KGVec2 WheelingAxisAvg;
1769
1770 // Item/widgets state and tracking information
1771 KGGuiID DebugHookIdInfo; // Will call core hooks: DebugHookIdInfo() from GetID functions, used by Stack Tool [next HoveredId/ActiveId to not pull in an extra cache-line]
1772 KGGuiID HoveredId; // Hovered widget, filled during the frame
1773 KGGuiID HoveredIdPreviousFrame;
1774 bool HoveredIdAllowOverlap;
1775 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.
1776 float HoveredIdTimer; // Measure contiguous hovering time
1777 float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active
1778 KGGuiID ActiveId; // Active widget
1779 KGGuiID ActiveIdIsAlive; // Active widget has been seen this frame (we can't use a bool as the ActiveId may change within the frame)
1780 float ActiveIdTimer;
1781 bool ActiveIdIsJustActivated; // Set at the time of activation for one frame
1782 bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always)
1783 bool ActiveIdNoClearOnFocusLoss; // Disable losing active id if the active id window gets unfocused.
1784 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.
1785 bool ActiveIdHasBeenEditedBefore; // Was the value associated to the widget Edited over the course of the Active state.
1786 bool ActiveIdHasBeenEditedThisFrame;
1787 KGVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior)
1788 KGGuiWindow* ActiveIdWindow;
1789 KGGuiInputSource ActiveIdSource; // Activating with mouse or nav (gamepad/keyboard)
1790 int ActiveIdMouseButton;
1791 KGGuiID ActiveIdPreviousFrame;
1792 bool ActiveIdPreviousFrameIsAlive;
1793 bool ActiveIdPreviousFrameHasBeenEditedBefore;
1794 KGGuiWindow* ActiveIdPreviousFrameWindow;
1795 KGGuiID LastActiveId; // Store the last non-zero ActiveId, useful for animation.
1796 float LastActiveIdTimer; // Store the last non-zero ActiveId timer since the beginning of activation, useful for animation.
1797
1798 // [EXPERIMENTAL] Key/Input Ownership + Shortcut Routing system
1799 // - The idea is that instead of "eating" a given key, we can link to an owner.
1800 // - Input query can then read input by specifying KGGuiKeyOwner_Any (== 0), KGGuiKeyOwner_None (== -1) or a custom ID.
1801 // - Routing is requested ahead of time for a given chord (Key + Mods) and granted in NewFrame().
1802 KGGuiKeyOwnerData KeysOwnerData[KGGuiKey_NamedKey_COUNT];
1803 KGGuiKeyRoutingTable KeysRoutingTable;
1804 KGU32 ActiveIdUsingNavDirMask; // Active widget will want to read those nav move requests (e.g. can activate a button and move away from it)
1805 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)
1806#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
1807 KGU32 ActiveIdUsingNavInputMask; // If you used this. Since (IMGUI_VERSION_NUM >= 18804) : 'g.ActiveIdUsingNavInputMask |= (1 << KGGuiNavInput_Cancel);' becomes 'SetKeyOwner(KGGuiKey_Escape, g.ActiveId) and/or SetKeyOwner(KGGuiKey_NavGamepadCancel, g.ActiveId);'
1808#endif
1809
1810 // Next window/item data
1811 KGGuiID CurrentFocusScopeId; // == g.FocusScopeStack.back()
1812 KGGuiItemFlags CurrentItemFlags; // == g.ItemFlagsStack.back()
1813 KGGuiID DebugLocateId; // Storage for DebugLocateItemOnHover() feature: this is read by ItemAdd() so we keep it in a hot/cached location
1814 KGGuiNextItemData NextItemData; // Storage for SetNextItem** functions
1815 KGGuiLastItemData LastItemData; // Storage for last submitted item (setup by ItemAdd)
1816 KGGuiNextWindowData NextWindowData; // Storage for SetNextWindow** functions
1817
1818 // Shared stacks
1819 KGVector<KGGuiColorMod> ColorStack; // Stack for PushStyleColor()/PopStyleColor() - inherited by Begin()
1820 KGVector<KGGuiStyleMod> StyleVarStack; // Stack for PushStyleVar()/PopStyleVar() - inherited by Begin()
1821 KGVector<KGFont*> FontStack; // Stack for PushFont()/PopFont() - inherited by Begin()
1822 KGVector<KGGuiID> FocusScopeStack; // Stack for PushFocusScope()/PopFocusScope() - inherited by BeginChild(), pushed into by Begin()
1823 KGVector<KGGuiItemFlags>ItemFlagsStack; // Stack for PushItemFlag()/PopItemFlag() - inherited by Begin()
1824 KGVector<KGGuiGroupData>GroupStack; // Stack for BeginGroup()/EndGroup() - not inherited by Begin()
1825 KGVector<KGGuiPopupData>OpenPopupStack; // Which popups are open (persistent)
1826 KGVector<KGGuiPopupData>BeginPopupStack; // Which level of BeginPopup() we are in (reset every frame)
1827 int BeginMenuCount;
1828
1829 // Viewports
1830 KGVector<KGGuiViewportP*> Viewports; // Active viewports (always 1+, and generally 1 unless multi-viewports are enabled). Each viewports hold their copy of KGDrawData.
1831 float CurrentDpiScale; // == CurrentViewport->DpiScale
1832 KGGuiViewportP* CurrentViewport; // We track changes of viewport (happening in Begin) so we can call Platform_OnChangedViewport()
1833 KGGuiViewportP* MouseViewport;
1834 KGGuiViewportP* MouseLastHoveredViewport; // Last known viewport that was hovered by mouse (even if we are not hovering any viewport any more) + honoring the _NoInputs flag.
1835 KGGuiID PlatformLastFocusedViewportId;
1836 KarmaGuiPlatformMonitor FallbackMonitor; // Virtual monitor used as fallback if backend doesn't provide monitor information.
1837 int ViewportFrontMostStampCount; // Every time the front-most window changes, we stamp its viewport with an incrementing counter
1838
1839 // Gamepad/keyboard Navigation
1840 KGGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusedWindow'
1841 KGGuiID NavId; // Focused item for navigation
1842 KGGuiID NavFocusScopeId; // Identify a selection scope (selection code often wants to "clear other items" when landing on an item of the selection set)
1843 KGGuiID NavActivateId; // ~~ (g.ActiveId == 0) && (IsKeyPressed(KGGuiKey_Space) || IsKeyPressed(KGGuiKey_NavGamepadActivate)) ? NavId : 0, also set when calling ActivateItem()
1844 KGGuiID NavActivateDownId; // ~~ IsKeyDown(KGGuiKey_Space) || IsKeyDown(KGGuiKey_NavGamepadActivate) ? NavId : 0
1845 KGGuiID NavActivatePressedId; // ~~ IsKeyPressed(KGGuiKey_Space) || IsKeyPressed(KGGuiKey_NavGamepadActivate) ? NavId : 0 (no repeat)
1846 KGGuiID NavActivateInputId; // ~~ IsKeyPressed(KGGuiKey_Enter) || IsKeyPressed(KGGuiKey_NavGamepadInput) ? NavId : 0; KGGuiActivateFlags_PreferInput will be set and NavActivateId will be 0.
1847 KGGuiActivateFlags NavActivateFlags;
1848 KGGuiID NavJustMovedToId; // Just navigated to this id (result of a successfully MoveRequest).
1849 KGGuiID NavJustMovedToFocusScopeId; // Just navigated to this focus scope id (result of a successfully MoveRequest).
1850 KarmaGuiKeyChord NavJustMovedToKeyMods;
1851 KGGuiID NavNextActivateId; // Set by ActivateItem(), queued until next frame.
1852 KGGuiActivateFlags NavNextActivateFlags;
1853 KGGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS WILL ONLY BE None or NavGamepad or NavKeyboard.
1854 KGGuiNavLayer 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.
1855 bool NavIdIsAlive; // Nav widget has been seen this frame ~~ NavRectRel is valid
1856 bool NavMousePosDirty; // When set we will update mouse position if (io.ConfigFlags & KGGuiConfigFlags_NavEnableSetMousePos) if set (NB: this not enabled by default)
1857 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)
1858 bool NavDisableMouseHover; // When user starts using gamepad/keyboard, we hide mouse hovering highlight until mouse is touched again.
1859
1860 // Navigation: Init & Move Requests
1861 bool NavAnyRequest; // ~~ NavMoveRequest || NavInitRequest this is to perform early out in ItemAdd()
1862 bool NavInitRequest; // Init request for appearing window to select first item
1863 bool NavInitRequestFromMove;
1864 KGGuiID NavInitResultId; // Init request result (first item of the window, or one for which SetItemDefaultFocus() was called)
1865 KGRect NavInitResultRectRel; // Init request result rectangle (relative to parent window)
1866 bool NavMoveSubmitted; // Move request submitted, will process result on next NewFrame()
1867 bool NavMoveScoringItems; // Move request submitted, still scoring incoming items
1868 bool NavMoveForwardToNextFrame;
1869 KGGuiNavMoveFlags NavMoveFlags;
1870 KGGuiScrollFlags NavMoveScrollFlags;
1871 KarmaGuiKeyChord NavMoveKeyMods;
1872 KarmaGuiDir NavMoveDir; // Direction of the move request (left/right/up/down)
1873 KarmaGuiDir NavMoveDirForDebug;
1874 KarmaGuiDir NavMoveClipDir; // FIXME-NAV: Describe the purpose of this better. Might want to rename?
1875 KGRect NavScoringRect; // Rectangle used for scoring, in screen space. Based of window->NavRectRel[], modified for directional navigation scoring.
1876 KGRect NavScoringNoClipRect; // Some nav operations (such as PageUp/PageDown) enforce a region which clipper will attempt to always keep submitted
1877 int NavScoringDebugCount; // Metrics for debugging
1878 int NavTabbingDir; // Generally -1 or +1, 0 when tabbing without a nav id
1879 int NavTabbingCounter; // >0 when counting items for tabbing
1880 KGGuiNavItemData NavMoveResultLocal; // Best move request candidate within NavWindow
1881 KGGuiNavItemData NavMoveResultLocalVisible; // Best move request candidate within NavWindow that are mostly visible (when using KGGuiNavMoveFlags_AlsoScoreVisibleSet flag)
1882 KGGuiNavItemData NavMoveResultOther; // Best move request candidate within NavWindow's flattened hierarchy (when using KGGuiWindowFlags_NavFlattened flag)
1883 KGGuiNavItemData NavTabbingResultFirst; // First tabbing request candidate within NavWindow and flattened hierarchy
1884
1885 // Navigation: Windowing (CTRL+TAB for list, or Menu button + keys or directional pads to move/resize)
1886 KarmaGuiKeyChord ConfigNavWindowingKeyNext; // = KGGuiMod_Ctrl | KGGuiKey_Tab, for reconfiguration (see #4828)
1887 KarmaGuiKeyChord ConfigNavWindowingKeyPrev; // = KGGuiMod_Ctrl | KGGuiMod_Shift | KGGuiKey_Tab
1888 KGGuiWindow* NavWindowingTarget; // Target window when doing CTRL+Tab (or Pad Menu + FocusPrev/Next), this window is temporarily displayed top-most!
1889 KGGuiWindow* NavWindowingTargetAnim; // Record of last valid NavWindowingTarget until DimBgRatio and NavWindowingHighlightAlpha becomes 0.0f, so the fade-out can stay on it.
1890 KGGuiWindow* NavWindowingListWindow; // Internal window actually listing the CTRL+Tab contents
1891 float NavWindowingTimer;
1892 float NavWindowingHighlightAlpha;
1893 bool NavWindowingToggleLayer;
1894 KGVec2 NavWindowingAccumDeltaPos;
1895 KGVec2 NavWindowingAccumDeltaSize;
1896
1897 // Render
1898 float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list)
1899 KarmaGuiMouseCursor MouseCursor;
1900
1901 // Drag and Drop
1902 bool DragDropActive;
1903 bool DragDropWithinSource; // Set when within a BeginDragDropXXX/EndDragDropXXX block for a drag source.
1904 bool DragDropWithinTarget; // Set when within a BeginDragDropXXX/EndDragDropXXX block for a drag target.
1905 KarmaGuiDragDropFlags DragDropSourceFlags;
1906 int DragDropSourceFrameCount;
1907 int DragDropMouseButton;
1908 KarmaGuiPayload DragDropPayload;
1909 KGRect DragDropTargetRect; // Store rectangle of current target candidate (we favor small targets when overlapping)
1910 KGGuiID DragDropTargetId;
1911 KarmaGuiDragDropFlags DragDropAcceptFlags;
1912 float DragDropAcceptIdCurrRectSurface; // Target item surface (we resolve overlapping targets by prioritizing the smaller surface)
1913 KGGuiID DragDropAcceptIdCurr; // Target item id (set at the time of accepting the payload)
1914 KGGuiID DragDropAcceptIdPrev; // Target item id from previous frame (we need to store this to allow for overlapping drag and drop targets)
1915 int DragDropAcceptFrameCount; // Last time a target expressed a desire to accept the source
1916 KGGuiID DragDropHoldJustPressedId; // Set when holding a payload just made ButtonBehavior() return a press.
1917 KGVector<unsigned char> DragDropPayloadBufHeap; // We don't expose the KGVector<> directly, KarmaGuiPayload only holds pointer+size
1918 unsigned char DragDropPayloadBufLocal[16]; // Local buffer for small payloads
1919
1920 // Clipper
1921 int ClipperTempDataStacked;
1922 KGVector<KGGuiListClipperData> ClipperTempData;
1923
1924 // Tables
1925 KGGuiTable* CurrentTable;
1926 int TablesTempDataStacked; // Temporary table data size (because we leave previous instances undestructed, we generally don't use TablesTempData.Size)
1927 KGVector<KGGuiTableTempData> TablesTempData; // Temporary table data (buffers reused/shared across instances, support nesting)
1928 KGPool<KGGuiTable> Tables; // Persistent table data
1929 KGVector<float> TablesLastTimeActive; // Last used timestamp of each tables (SOA, for efficient GC)
1930 KGVector<KGDrawChannel> DrawChannelsTempMergeBuffer;
1931
1932 // Tab bars
1933 KGGuiTabBar* CurrentTabBar;
1934 KGPool<KGGuiTabBar> TabBars;
1935 KGVector<KGGuiPtrOrIndex> CurrentTabBarStack;
1936 KGVector<KGGuiShrinkWidthItem> ShrinkWidthBuffer;
1937
1938 // Hover Delay system
1939 KGGuiID HoverDelayId;
1940 KGGuiID HoverDelayIdPreviousFrame;
1941 float HoverDelayTimer; // Currently used IsItemHovered(), generally inferred from g.HoveredIdTimer but kept uncleared until clear timer elapse.
1942 float HoverDelayClearTimer; // Currently used IsItemHovered(): grace time before g.TooltipHoverTimer gets cleared.
1943
1944 // Widget state
1945 KGVec2 MouseLastValidPos;
1946 KGGuiInputTextState InputTextState;
1947 KGFont InputTextPasswordFont;
1948 KGGuiID TempInputId; // Temporary text input when CTRL+clicking on a slider, etc.
1949 KarmaGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets
1950 float ColorEditLastHue; // Backup of last Hue associated to LastColor, so we can restore Hue in lossy RGB<>HSV round trips
1951 float ColorEditLastSat; // Backup of last Saturation associated to LastColor, so we can restore Saturation in lossy RGB<>HSV round trips
1952 KGU32 ColorEditLastColor; // RGB value with alpha set to 0.
1953 KGVec4 ColorPickerRef; // Initial/reference color at the time of opening the color picker.
1954 KGGuiComboPreviewData ComboPreviewData;
1955 float SliderGrabClickOffset;
1956 float SliderCurrentAccum; // Accumulated slider delta when using navigation controls.
1957 bool SliderCurrentAccumDirty; // Has the accumulated slider delta changed since last time we tried to apply it?
1958 bool DragCurrentAccumDirty;
1959 float DragCurrentAccum; // Accumulator for dragging modification. Always high-precision, not rounded by end-user precision settings
1960 float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio
1961 float ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage?
1962 float DisabledAlphaBackup; // Backup for style.Alpha for BeginDisabled()
1963 short DisabledStackSize;
1964 short TooltipOverrideCount;
1965 KGVector<char> ClipboardHandlerData; // If no custom clipboard handler is defined
1966 KGVector<KGGuiID> MenusIdSubmittedThisFrame; // A list of menu IDs that were rendered at least once
1967
1968 // Platform support
1969 KarmaGuiPlatformImeData PlatformImeData; // Data updated by current frame
1970 KarmaGuiPlatformImeData PlatformImeDataPrev; // Previous frame data (when changing we will call io.SetPlatformImeDataFn
1971 KGGuiID PlatformImeViewport;
1972 char PlatformLocaleDecimalPoint; // '.' or *localeconv()->decimal_point
1973
1974 // Extensions
1975 // FIXME: We could provide an API to register one slot in an array held in KarmaGuiContext?
1976 KGGuiDockContext DockContext;
1977
1978 // Settings
1979 bool SettingsLoaded;
1980 float SettingsDirtyTimer; // Save .ini Settings to memory when time reaches zero
1981 KarmaGuiTextBuffer SettingsIniData; // In memory .ini settings
1982 KGVector<KGGuiSettingsHandler> SettingsHandlers; // List of .ini settings handlers
1983 KGChunkStream<KGGuiWindowSettings> SettingsWindows; // KGGuiWindow .ini settings entries
1984 KGChunkStream<KGGuiTableSettings> SettingsTables; // KGGuiTable .ini settings entries
1985 KGVector<KGGuiContextHook> Hooks; // Hooks for extensions (e.g. test engine)
1986 KGGuiID HookIdNext; // Next available HookId
1987
1988 // Localization
1989 const char* LocalizationTable[ImGuiLocKey_COUNT];
1990
1991 // Capture/Logging
1992 bool LogEnabled; // Currently capturing
1993 KGGuiLogType LogType; // Capture target
1994 ImFileHandle LogFile; // If != NULL log to stdout/ file
1995 KarmaGuiTextBuffer LogBuffer; // Accumulation buffer when log to clipboard. This is pointer so our GKarmaGui static constructor doesn't call heap allocators.
1996 const char* LogNextPrefix;
1997 const char* LogNextSuffix;
1998 float LogLinePosY;
1999 bool LogLineFirstItem;
2000 int LogDepthRef;
2001 int LogDepthToExpand;
2002 int LogDepthToExpandDefault; // Default/stored value for LogDepthMaxExpand if not specified in the LogXXX function call.
2003
2004 // Debug Tools
2005 KGGuiDebugLogFlags DebugLogFlags;
2006 KarmaGuiTextBuffer DebugLogBuf;
2007 KGGuiTextIndex DebugLogIndex;
2008 KGU8 DebugLocateFrames; // For DebugLocateItemOnHover(). This is used together with DebugLocateId which is in a hot/cached spot above.
2009 bool DebugItemPickerActive; // Item picker is active (started with DebugStartItemPicker())
2010 KGU8 DebugItemPickerMouseButton;
2011 KGGuiID DebugItemPickerBreakId; // Will call KR_CORE_ASSERT() when encountering this ID
2012 KGGuiMetricsConfig DebugMetricsConfig;
2013 KGGuiStackTool DebugStackTool;
2014 KGGuiDockNode* DebugHoveredDockNode; // Hovered dock node.
2015
2016 // Misc
2017 float FramerateSecPerFrame[60]; // Calculate estimate of framerate for user over the last 60 frames..
2018 int FramerateSecPerFrameIdx;
2019 int FramerateSecPerFrameCount;
2020 float FramerateSecPerFrameAccum;
2021 int WantCaptureMouseNextFrame; // Explicit capture override via SetNextFrameWantCaptureMouse()/SetNextFrameWantCaptureKeyboard(). Default to -1.
2022 int WantCaptureKeyboardNextFrame; // "
2023 int WantTextInputNextFrame;
2024 KGVector<char> TempBuffer; // Temporary text buffer
2025
2026 KarmaGuiContext(KGFontAtlas* shared_font_atlas)
2027 : InputTextState(this)
2028 {
2029 Initialized = false;
2030 ConfigFlagsCurrFrame = ConfigFlagsLastFrame = KGGuiConfigFlags_None;
2031 FontAtlasOwnedByContext = shared_font_atlas ? false : true;
2032 Font = NULL;
2033 FontSize = FontBaseSize = 0.0f;
2034 IO.Fonts = shared_font_atlas ? shared_font_atlas : KG_NEW(KGFontAtlas)();
2035 Time = 0.0f;
2036 FrameCount = 0;
2037 FrameCountEnded = FrameCountPlatformEnded = FrameCountRendered = -1;
2038 WithinFrameScope = WithinFrameScopeWithImplicitWindow = WithinEndChild = false;
2039 GcCompactAll = false;
2040 TestEngineHookItems = false;
2041 TestEngine = NULL;
2042
2043 WindowsActiveCount = 0;
2044 CurrentWindow = NULL;
2045 HoveredWindow = NULL;
2046 HoveredWindowUnderMovingWindow = NULL;
2047 MovingWindow = NULL;
2048 WheelingWindow = NULL;
2049 WheelingWindowStartFrame = -1;
2050 WheelingWindowReleaseTimer = 0.0f;
2051
2052 DebugHookIdInfo = 0;
2053 HoveredId = HoveredIdPreviousFrame = 0;
2054 HoveredIdAllowOverlap = false;
2055 HoveredIdDisabled = false;
2056 HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f;
2057 ActiveId = 0;
2058 ActiveIdIsAlive = 0;
2059 ActiveIdTimer = 0.0f;
2060 ActiveIdIsJustActivated = false;
2061 ActiveIdAllowOverlap = false;
2062 ActiveIdNoClearOnFocusLoss = false;
2063 ActiveIdHasBeenPressedBefore = false;
2064 ActiveIdHasBeenEditedBefore = false;
2065 ActiveIdHasBeenEditedThisFrame = false;
2066 ActiveIdClickOffset = KGVec2(-1, -1);
2067 ActiveIdWindow = NULL;
2068 ActiveIdSource = KGGuiInputSource_None;
2069 ActiveIdMouseButton = -1;
2070 ActiveIdPreviousFrame = 0;
2071 ActiveIdPreviousFrameIsAlive = false;
2072 ActiveIdPreviousFrameHasBeenEditedBefore = false;
2073 ActiveIdPreviousFrameWindow = NULL;
2074 LastActiveId = 0;
2075 LastActiveIdTimer = 0.0f;
2076
2077 ActiveIdUsingNavDirMask = 0x00;
2078 ActiveIdUsingAllKeyboardKeys = false;
2079#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
2080 ActiveIdUsingNavInputMask = 0x00;
2081#endif
2082
2083 CurrentFocusScopeId = 0;
2084 CurrentItemFlags = KGGuiItemFlags_None;
2085 BeginMenuCount = 0;
2086
2087 CurrentDpiScale = 0.0f;
2088 CurrentViewport = NULL;
2089 MouseViewport = MouseLastHoveredViewport = NULL;
2090 PlatformLastFocusedViewportId = 0;
2091 ViewportFrontMostStampCount = 0;
2092
2093 NavWindow = NULL;
2094 NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = NavActivateInputId = 0;
2095 NavJustMovedToId = NavJustMovedToFocusScopeId = NavNextActivateId = 0;
2096 NavActivateFlags = NavNextActivateFlags = KGGuiActivateFlags_None;
2097 NavJustMovedToKeyMods = KGGuiMod_None;
2098 NavInputSource = KGGuiInputSource_None;
2099 NavLayer = KGGuiNavLayer_Main;
2100 NavIdIsAlive = false;
2101 NavMousePosDirty = false;
2102 NavDisableHighlight = true;
2103 NavDisableMouseHover = false;
2104 NavAnyRequest = false;
2105 NavInitRequest = false;
2106 NavInitRequestFromMove = false;
2107 NavInitResultId = 0;
2108 NavMoveSubmitted = false;
2109 NavMoveScoringItems = false;
2110 NavMoveForwardToNextFrame = false;
2111 NavMoveFlags = KGGuiNavMoveFlags_None;
2112 NavMoveScrollFlags = KGGuiScrollFlags_None;
2113 NavMoveKeyMods = KGGuiMod_None;
2114 NavMoveDir = NavMoveDirForDebug = NavMoveClipDir = KGGuiDir_None;
2115 NavScoringDebugCount = 0;
2116 NavTabbingDir = 0;
2117 NavTabbingCounter = 0;
2118
2119 ConfigNavWindowingKeyNext = KGGuiMod_Ctrl | KGGuiKey_Tab;
2120 ConfigNavWindowingKeyPrev = KGGuiMod_Ctrl | KGGuiMod_Shift | KGGuiKey_Tab;
2121 NavWindowingTarget = NavWindowingTargetAnim = NavWindowingListWindow = NULL;
2122 NavWindowingTimer = NavWindowingHighlightAlpha = 0.0f;
2123 NavWindowingToggleLayer = false;
2124
2125 DimBgRatio = 0.0f;
2126 MouseCursor = KGGuiMouseCursor_Arrow;
2127
2128 DragDropActive = DragDropWithinSource = DragDropWithinTarget = false;
2129 DragDropSourceFlags = KGGuiDragDropFlags_None;
2130 DragDropSourceFrameCount = -1;
2131 DragDropMouseButton = -1;
2132 DragDropTargetId = 0;
2133 DragDropAcceptFlags = KGGuiDragDropFlags_None;
2134 DragDropAcceptIdCurrRectSurface = 0.0f;
2135 DragDropAcceptIdPrev = DragDropAcceptIdCurr = 0;
2136 DragDropAcceptFrameCount = -1;
2137 DragDropHoldJustPressedId = 0;
2138 memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal));
2139
2140 ClipperTempDataStacked = 0;
2141
2142 CurrentTable = NULL;
2143 TablesTempDataStacked = 0;
2144 CurrentTabBar = NULL;
2145
2146 HoverDelayId = HoverDelayIdPreviousFrame = 0;
2147 HoverDelayTimer = HoverDelayClearTimer = 0.0f;
2148
2149 TempInputId = 0;
2150 ColorEditOptions = KGGuiColorEditFlags_DefaultOptions_;
2151 ColorEditLastHue = ColorEditLastSat = 0.0f;
2152 ColorEditLastColor = 0;
2153 SliderGrabClickOffset = 0.0f;
2154 SliderCurrentAccum = 0.0f;
2155 SliderCurrentAccumDirty = false;
2156 DragCurrentAccumDirty = false;
2157 DragCurrentAccum = 0.0f;
2158 DragSpeedDefaultRatio = 1.0f / 100.0f;
2159 ScrollbarClickDeltaToGrabCenter = 0.0f;
2160 DisabledAlphaBackup = 0.0f;
2161 DisabledStackSize = 0;
2162 TooltipOverrideCount = 0;
2163
2164 PlatformImeData.InputPos = KGVec2(0.0f, 0.0f);
2165 PlatformImeDataPrev.InputPos = KGVec2(-1.0f, -1.0f); // Different to ensure initial submission
2166 PlatformImeViewport = 0;
2167 PlatformLocaleDecimalPoint = '.';
2168
2169 SettingsLoaded = false;
2170 SettingsDirtyTimer = 0.0f;
2171 HookIdNext = 0;
2172
2173 memset(LocalizationTable, 0, sizeof(LocalizationTable));
2174
2175 LogEnabled = false;
2176 LogType = KGGuiLogType_None;
2177 LogNextPrefix = LogNextSuffix = NULL;
2178 LogFile = NULL;
2179 LogLinePosY = FLT_MAX;
2180 LogLineFirstItem = false;
2181 LogDepthRef = 0;
2182 LogDepthToExpand = LogDepthToExpandDefault = 2;
2183
2184 DebugLogFlags = KGGuiDebugLogFlags_OutputToTTY;
2185 DebugLocateId = 0;
2186 DebugLocateFrames = 0;
2187 DebugItemPickerActive = false;
2188 DebugItemPickerMouseButton = KGGuiMouseButton_Left;
2189 DebugItemPickerBreakId = 0;
2190 DebugHoveredDockNode = NULL;
2191
2192 memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame));
2193 FramerateSecPerFrameIdx = FramerateSecPerFrameCount = 0;
2194 FramerateSecPerFrameAccum = 0.0f;
2195 WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = WantTextInputNextFrame = -1;
2196 }
2197};
2198
2199//-----------------------------------------------------------------------------
2200// [SECTION] KGGuiWindowTempData, KGGuiWindow
2201//-----------------------------------------------------------------------------
2202
2203// Transient per-window data, reset at the beginning of the frame. This used to be called ImGuiDrawContext, hence the DC variable name in KGGuiWindow.
2204// (That's theory, in practice the delimitation between KGGuiWindow and KGGuiWindowTempData is quite tenuous and could be reconsidered..)
2205// (This doesn't need a constructor because we zero-clear it as part of KGGuiWindow and all frame-temporary data are setup on Begin)
2207{
2208 // Layout
2209 KGVec2 CursorPos; // Current emitting position, in absolute coordinates.
2210 KGVec2 CursorPosPrevLine;
2211 KGVec2 CursorStartPos; // Initial position after Begin(), generally ~ window position + WindowPadding.
2212 KGVec2 CursorMaxPos; // Used to implicitly calculate ContentSize at the beginning of next frame, for scrolling range and auto-resize. Always growing during the frame.
2213 KGVec2 IdealMaxPos; // Used to implicitly calculate ContentSizeIdeal at the beginning of next frame, for auto-resize only. Always growing during the frame.
2214 KGVec2 CurrLineSize;
2215 KGVec2 PrevLineSize;
2216 float CurrLineTextBaseOffset; // Baseline offset (0.0f by default on a new line, generally == style.FramePadding.y when a framed item has been added).
2217 float PrevLineTextBaseOffset;
2218 bool IsSameLine;
2219 bool IsSetPos;
2220 KGVec1 Indent; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.)
2221 KGVec1 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.
2222 KGVec1 GroupOffset;
2223 KGVec2 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.
2224
2225 // Keyboard/Gamepad navigation
2226 KGGuiNavLayer NavLayerCurrent; // Current layer, 0..31 (we currently only use 0..1)
2227 short NavLayersActiveMask; // Which layers have been written to (result from previous frame)
2228 short NavLayersActiveMaskNext;// Which layers have been written to (accumulator for current frame)
2229 bool NavHideHighlightOneFrame;
2230 bool NavHasScroll; // Set when scrolling can be used (ScrollMax > 0.0f)
2231
2232 // Miscellaneous
2233 bool MenuBarAppending; // FIXME: Remove this
2234 KGVec2 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.
2235 KGGuiMenuColumns MenuColumns; // Simplified columns storage for menu items measurement
2236 int TreeDepth; // Current tree depth.
2237 KGU32 TreeJumpToParentOnPopMask; // Store a copy of !g.NavIdIsAlive for TreeDepth 0..31.. Could be turned into a KGU64 if necessary.
2238 KGVector<KGGuiWindow*> ChildWindows;
2239 KarmaGuiStorage* StateStorage; // Current persistent per-window storage (store e.g. tree node open/close state)
2240 KGGuiOldColumns* CurrentColumns; // Current columns set
2241 int CurrentTableIdx; // Current table index (into g.Tables)
2242 KGGuiLayoutType LayoutType;
2243 KGGuiLayoutType ParentLayoutType; // Layout type of parent window at the time of Begin()
2244
2245 // Local parameters stacks
2246 // 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.
2247 float ItemWidth; // Current item width (>0.0: width in pixels, <0.0: align xx pixels to the right of window).
2248 float TextWrapPos; // Current text wrap pos.
2249 KGVector<float> ItemWidthStack; // Store item widths to restore (attention: .back() is not == ItemWidth)
2250 KGVector<float> TextWrapPosStack; // Store text wrap pos to restore (attention: .back() is not == TextWrapPos)
2251};
2252
2253// Storage for one window
2254struct KARMA_API KGGuiWindow
2255{
2256 char* Name; // Window name, owned by the window.
2257 KGGuiID ID; // == KGHashStr(Name)
2258 KarmaGuiWindowFlags Flags, FlagsPreviousFrame; // See enum KGGuiWindowFlags_
2259 KarmaGuiWindowClass WindowClass; // Advanced users only. Set with SetNextWindowClass()
2260 KGGuiViewportP* Viewport; // Always set in Begin(). Inactive windows may have a NULL value here if their viewport was discarded.
2261 KGGuiID ViewportId; // We backup the viewport id (since the viewport may disappear or never be created if the window is inactive)
2262 KGVec2 ViewportPos; // We backup the viewport position (since the viewport may disappear or never be created if the window is inactive)
2263 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
2264 KGVec2 Pos; // Position (always rounded-up to nearest pixel)
2265 KGVec2 Size; // Current size (==SizeFull or collapsed title bar size)
2266 KGVec2 SizeFull; // Size when non collapsed
2267 KGVec2 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.
2268 KGVec2 ContentSizeIdeal;
2269 KGVec2 ContentSizeExplicit; // Size of contents/scrollable client area explicitly request by the user via SetNextWindowContentSize().
2270 KGVec2 WindowPadding; // Window padding at the time of Begin().
2271 KGU32 BgColor; // Client specified window background color
2272 float WindowRounding; // Window rounding at the time of Begin(). May be clamped lower to avoid rendering artifacts with title bar, menu bar etc.
2273 float WindowBorderSize; // Window border size at the time of Begin().
2274 float DecoOuterSizeX1, DecoOuterSizeY1; // Left/Up offsets. Sum of non-scrolling outer decorations (X1 generally == 0.0f. Y1 generally = TitleBarHeight + MenuBarHeight). Locked during Begin().
2275 float DecoOuterSizeX2, DecoOuterSizeY2; // Right/Down offsets (X2 generally == ScrollbarSize.x, Y2 == ScrollbarSizes.y).
2276 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).
2277 int NameBufLen; // Size of buffer storing Name. May be larger than strlen(Name)!
2278 KGGuiID MoveId; // == window->GetID("#MOVE")
2279 KGGuiID TabId; // == window->GetID("#TAB")
2280 KGGuiID ChildId; // ID of corresponding item in parent window (for navigation to return from child window to parent window)
2281 KGVec2 Scroll;
2282 KGVec2 ScrollMax;
2283 KGVec2 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)
2284 KGVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered
2285 KGVec2 ScrollTargetEdgeSnapDist; // 0.0f = no snapping, >0.0f snapping threshold
2286 KGVec2 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.
2287 bool bUseCustomBgColor; // Shoule we use custom (client specified) bg color for window?
2288 bool ScrollbarX, ScrollbarY; // Are scrollbars visible?
2289 bool ViewportOwned;
2290 bool Active; // Set to true on Begin(), unless Collapsed
2291 bool WasActive;
2292 bool WriteAccessed; // Set to true when any widget access the current window
2293 bool Collapsed; // Set when collapsing window to become only title-bar
2294 bool WantCollapseToggle;
2295 bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed)
2296 bool Appearing; // Set during the frame where the window is appearing (or re-appearing)
2297 bool Hidden; // Do not display (== HiddenFrames*** > 0)
2298 bool IsFallbackWindow; // Set on the "Debug##Default" window.
2299 bool IsExplicitChild; // Set when passed _ChildWindow, left to false by BeginDocked()
2300 bool HasCloseButton; // Set when the window has a close button (p_open != NULL)
2301 signed char ResizeBorderHeld; // Current border being held for resize (-1: none, otherwise 0-3)
2302 short BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs)
2303 short BeginCountPreviousFrame; // Number of Begin() during the previous frame
2304 short BeginOrderWithinParent; // Begin() order within immediate parent window, if we are a child window. Otherwise 0.
2305 short BeginOrderWithinContext; // Begin() order within entire imgui context. This is mostly used for debugging submission order related issues.
2306 short FocusOrder; // Order within WindowsFocusOrder[], altered when windows are focused.
2307 KGGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling)
2308 KGS8 AutoFitFramesX, AutoFitFramesY;
2309 KGS8 AutoFitChildAxises;
2310 bool AutoFitOnlyGrows;
2311 KarmaGuiDir AutoPosLastDirection;
2312 KGS8 HiddenFramesCanSkipItems; // Hide the window for N frames
2313 KGS8 HiddenFramesCannotSkipItems; // Hide the window for N frames while allowing items to be submitted so we can measure their size
2314 KGS8 HiddenFramesForRenderOnly; // Hide the window until frame N at Render() time only
2315 KGS8 DisableInputsFrames; // Disable window interactions for N frames
2316 KarmaGuiCond SetWindowPosAllowFlags : 8; // store acceptable condition flags for SetNextWindowPos() use.
2317 KarmaGuiCond SetWindowSizeAllowFlags : 8; // store acceptable condition flags for SetNextWindowSize() use.
2318 KarmaGuiCond SetWindowCollapsedAllowFlags : 8; // store acceptable condition flags for SetNextWindowCollapsed() use.
2319 KarmaGuiCond SetWindowDockAllowFlags : 8; // store acceptable condition flags for SetNextWindowDock() use.
2320 KGVec2 SetWindowPosVal; // store window position when using a non-zero Pivot (position set needs to be processed when we know the window size)
2321 KGVec2 SetWindowPosPivot; // store window pivot for positioning. KGVec2(0, 0) when positioning from top-left corner; KGVec2(0.5f, 0.5f) for centering; KGVec2(1, 1) for bottom right.
2322
2323 KGVector<KGGuiID> 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)
2324 KGGuiWindowTempData DC; // Temporary per-window data, reset at the beginning of the frame. This used to be called ImGuiDrawContext, hence the "DC" variable name.
2325
2326 // The best way to understand what those rectangles are is to use the 'Metrics->Tools->Show Windows Rectangles' viewer.
2327 // The main 'OuterRect', omitted as a field, is window->Rect().
2328 KGRect OuterRectClipped; // == Window->Rect() just after setup in Begin(). == window->Rect() for root window.
2329 KGRect InnerRect; // Inner rectangle (omit title bar, menu bar, scroll bar)
2330 KGRect InnerClipRect; // == InnerRect shrunk by WindowPadding*0.5f on each side, clipped within viewport or parent clip rect.
2331 KGRect 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).
2332 KGRect 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?
2333 KGRect ClipRect; // Current clipping/scissoring rectangle, evolve as we are using PushClipRect(), etc. == DrawList->clip_rect_stack.back().
2334 KGRect 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.
2335 KGVec2ih HitTestHoleSize; // Define an optional rectangular hole where mouse will pass-through the window.
2336 KGVec2ih HitTestHoleOffset;
2337
2338 int LastFrameActive; // Last frame number the window was Active.
2339 int LastFrameJustFocused; // Last frame number the window was made Focused.
2340 float LastTimeActive; // Last timestamp the window was Active (using float as we don't need high precision there)
2341 float ItemWidthDefault;
2342 KarmaGuiStorage StateStorage;
2343 KGVector<KGGuiOldColumns> ColumnsStorage;
2344 float FontWindowScale; // User scale multiplier per-window, via SetWindowFontScale()
2345 float FontDpiScale;
2346 int SettingsOffset; // Offset into SettingsWindows[] (offsets are always valid as we only grow the array from the back)
2347
2348 KGDrawList* DrawList; // == &DrawListInst (for backward compatibility reason with code using imgui_internal.h we keep this a pointer)
2349 KGDrawList DrawListInst;
2350 KGGuiWindow* ParentWindow; // If we are a child _or_ popup _or_ docked window, this is pointing to our parent. Otherwise NULL.
2351 KGGuiWindow* ParentWindowInBeginStack;
2352 KGGuiWindow* RootWindow; // Point to ourself or first ancestor that is not a child window. Doesn't cross through popups/dock nodes.
2353 KGGuiWindow* RootWindowPopupTree; // Point to ourself or first ancestor that is not a child window. Cross through popups parent<>child.
2354 KGGuiWindow* RootWindowDockTree; // Point to ourself or first ancestor that is not a child window. Cross through dock nodes.
2355 KGGuiWindow* RootWindowForTitleBarHighlight; // Point to ourself or first ancestor which will display TitleBgActive color when this window is active.
2356 KGGuiWindow* RootWindowForNav; // Point to ourself or first ancestor which doesn't have the NavFlattened flag.
2357
2358 KGGuiWindow* 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.)
2359 KGGuiID NavLastIds[KGGuiNavLayer_COUNT]; // Last known NavId for this window, per layer (0/1)
2360 KGRect NavRectRel[KGGuiNavLayer_COUNT]; // Reference rectangle, in window relative space
2361 KGGuiID NavRootFocusScopeId; // Focus Scope ID at the time of Begin()
2362
2363 int MemoryDrawListIdxCapacity; // Backup of last idx/vtx count, so when waking up the window we can preallocate and avoid iterative alloc/copy
2364 int MemoryDrawListVtxCapacity;
2365 bool MemoryCompacted; // Set when window extraneous data have been garbage collected
2366
2367 // Docking
2368 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).
2369 bool DockNodeIsVisible : 1;
2370 bool DockTabIsVisible : 1; // Is our window visible this frame? ~~ is the corresponding tab selected?
2371 bool DockTabWantClose : 1;
2372 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.
2373 KGGuiWindowDockStyle DockStyle;
2374 KGGuiDockNode* 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.
2375 KGGuiDockNode* DockNodeAsHost; // Which node are we owning (for parent windows)
2376 KGGuiID DockId; // Backup of last valid DockNode->ID, so single window remember their dock node id even when they are not bound any more
2377 KGGuiItemStatusFlags DockTabItemStatusFlags;
2378 KGRect DockTabItemRect;
2379
2380public:
2381 KGGuiWindow(KarmaGuiContext* context, const char* name);
2382 ~KGGuiWindow();
2383
2384 KGGuiID GetID(const char* str, const char* str_end = NULL);
2385 KGGuiID GetID(const void* ptr);
2386 KGGuiID GetID(int n);
2387 KGGuiID GetIDFromRectangle(const KGRect& r_abs);
2388
2389 // We don't use g.FontSize because the window may be != g.CurrentWindow.
2390 KGRect Rect() const { return KGRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); }
2391 float CalcFontSize() const;
2392 float TitleBarHeight() const;
2393 KGRect TitleBarRect() const { return KGRect(Pos, KGVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight())); }
2394 float MenuBarHeight() const;
2395 KGRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight(); return KGRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight()); }
2396};
2397
2398//-----------------------------------------------------------------------------
2399// [SECTION] Tab bar, Tab item support
2400//-----------------------------------------------------------------------------
2401
2402// Extend KGGuiTabBarFlags_
2403enum KGGuiTabBarFlagsPrivate_
2404{
2405 KGGuiTabBarFlags_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]
2406 KGGuiTabBarFlags_IsFocused = 1 << 21,
2407 KGGuiTabBarFlags_SaveSettings = 1 << 22, // FIXME: Settings are handled by the docking system, this only request the tab bar to mark settings dirty when reordering tabs
2408};
2409
2410// Extend KGGuiTabItemFlags_
2411enum KGGuiTabItemFlagsPrivate_
2412{
2413 KGGuiTabItemFlags_SectionMask_ = KGGuiTabItemFlags_Leading | KGGuiTabItemFlags_Trailing,
2414 KGGuiTabItemFlags_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)
2415 KGGuiTabItemFlags_Button = 1 << 21, // Used by TabItemButton, change the tab item behavior to mimic a button
2416 KGGuiTabItemFlags_Unsorted = 1 << 22, // [Docking] Trailing tabs with the _Unsorted flag will be sorted based on the DockOrder of their Window.
2417 KGGuiTabItemFlags_Preview = 1 << 23, // [Docking] Display tab shape for docking preview (height is adjusted slightly to compensate for the yet missing tab bar)
2418};
2419
2420// Storage for one active tab item (sizeof() 48 bytes)
2422{
2423 KGGuiID ID;
2424 KarmaGuiTabItemFlags Flags;
2425 KGGuiWindow* Window; // When TabItem is part of a DockNode's TabBar, we hold on to a window.
2426 int LastFrameVisible;
2427 int LastFrameSelected; // This allows us to infer an ordered list of the last activated tabs with little maintenance
2428 float Offset; // Position relative to beginning of tab
2429 float Width; // Width currently displayed
2430 float ContentWidth; // Width of label, stored during BeginTabItem() call
2431 float RequestedWidth; // Width optionally requested by caller, -1.0f is unused
2432 KGS32 NameOffset; // When Window==NULL, offset to name within parent KGGuiTabBar::TabsNames
2433 KGS16 BeginOrder; // BeginTabItem() order, used to re-order tabs after toggling KGGuiTabBarFlags_Reorderable
2434 KGS16 IndexDuringLayout; // Index only used during TabBarLayout()
2435 bool WantClose; // Marked as closed by SetTabItemClosed()
2436
2437 KGGuiTabItem() { memset(this, 0, sizeof(*this)); LastFrameVisible = LastFrameSelected = -1; RequestedWidth = -1.0f; NameOffset = -1; BeginOrder = IndexDuringLayout = -1; }
2438};
2439
2440// Storage for a tab bar (sizeof() 152 bytes)
2442{
2444 KarmaGuiTabBarFlags Flags;
2445 KGGuiID ID; // Zero for tab-bars used by docking
2446 KGGuiID SelectedTabId; // Selected tab/window
2447 KGGuiID NextSelectedTabId; // Next selected tab/window. Will also trigger a scrolling animation
2448 KGGuiID VisibleTabId; // Can occasionally be != SelectedTabId (e.g. when previewing contents for CTRL+TAB preview)
2449 int CurrFrameVisible;
2450 int PrevFrameVisible;
2451 KGRect BarRect;
2452 float CurrTabsContentsHeight;
2453 float PrevTabsContentsHeight; // Record the height of contents submitted below the tab bar
2454 float WidthAllTabs; // Actual width of all tabs (locked during layout)
2455 float WidthAllTabsIdeal; // Ideal width if all tabs were visible and not clipped
2456 float ScrollingAnim;
2457 float ScrollingTarget;
2458 float ScrollingTargetDistToVisibility;
2459 float ScrollingSpeed;
2460 float ScrollingRectMinX;
2461 float ScrollingRectMaxX;
2462 KGGuiID ReorderRequestTabId;
2463 KGS16 ReorderRequestOffset;
2464 KGS8 BeginCount;
2465 bool WantLayout;
2466 bool VisibleTabWasSubmitted;
2467 bool TabsAddedNew; // Set to true when a new tab item or button has been added to the tab bar during last frame
2468 KGS16 TabsActiveCount; // Number of tabs submitted this frame.
2469 KGS16 LastTabItemIdx; // Index of last BeginTabItem() tab for use by EndTabItem()
2470 float ItemSpacingY;
2471 KGVec2 FramePadding; // style.FramePadding locked at the time of BeginTabBar()
2472 KGVec2 BackupCursorPos;
2473 KarmaGuiTextBuffer TabsNames; // For non-docking tab bar we re-append names in a contiguous buffer.
2474
2475 KGGuiTabBar();
2476 int GetTabOrder(const KGGuiTabItem* tab) const { return Tabs.index_from_ptr(tab); }
2477 const char* GetTabName(const KGGuiTabItem* tab) const
2478 {
2479 if (tab->Window)
2480 return tab->Window->Name;
2481 KR_CORE_ASSERT(tab->NameOffset != -1 && tab->NameOffset < TabsNames.Buf.Size, "");
2482 return TabsNames.Buf.Data + tab->NameOffset;
2483 }
2484};
2485
2486//-----------------------------------------------------------------------------
2487// [SECTION] Table support
2488//-----------------------------------------------------------------------------
2489
2490#define KG_COL32_DISABLE KG_COL32(0,0,0,1) // Special sentinel code which cannot be used as a regular color.
2491#define KARMAGUI_TABLE_MAX_COLUMNS 64 // sizeof(KGU64) * 8. This is solely because we frequently encode columns set in a KGU64.
2492#define KARMAGUI_TABLE_MAX_DRAW_CHANNELS (4 + 64 * 2) // See TableSetupDrawChannels()
2493
2494// Our current column maximum is 64 but we may raise that in the future.
2495typedef KGS8 KGGuiTableColumnIdx;
2496typedef KGU8 KGGuiTableDrawChannelIdx;
2497
2498// [Internal] sizeof() ~ 104
2499// We use the terminology "Enabled" to refer to a column that is not Hidden by user/api.
2500// We use the terminology "Clipped" to refer to a column that is out of sight because of scrolling/clipping.
2501// This is in contrast with some user-facing api such as IsItemVisible() / IsRectVisible() which use "Visible" to mean "not clipped".
2503{
2504 KarmaGuiTableColumnFlags Flags; // Flags after some patching (not directly same as provided by user). See KGGuiTableColumnFlags_
2505 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.
2506 float MinX; // Absolute positions
2507 float MaxX;
2508 float WidthRequest; // Master width absolute value when !(Flags & _WidthStretch). When Stretch this is derived every frame from StretchWeight in TableUpdateLayout()
2509 float WidthAuto; // Automatic width
2510 float StretchWeight; // Master width weight when (Flags & _WidthStretch). Often around ~1.0f initially.
2511 float InitStretchWeightOrWidth; // Value passed to TableSetupColumn(). For Width it is a content width (_without padding_).
2512 KGRect ClipRect; // Clipping rectangle for the column
2513 KGGuiID UserID; // Optional, value passed to TableSetupColumn()
2514 float WorkMinX; // Contents region min ~(MinX + CellPaddingX + CellSpacingX1) == cursor start position when entering column
2515 float WorkMaxX; // Contents region max ~(MaxX - CellPaddingX - CellSpacingX2)
2516 float ItemWidth; // Current item width for the column, preserved across rows
2517 float ContentMaxXFrozen; // Contents maximum position for frozen rows (apart from headers), from which we can infer content width.
2518 float ContentMaxXUnfrozen;
2519 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
2520 float ContentMaxXHeadersIdeal;
2521 KGS16 NameOffset; // Offset into parent ColumnsNames[]
2522 KGGuiTableColumnIdx DisplayOrder; // Index within Table's IndexToDisplayOrder[] (column may be reordered by users)
2523 KGGuiTableColumnIdx IndexWithinEnabledSet; // Index within enabled/visible set (<= IndexToDisplayOrder)
2524 KGGuiTableColumnIdx PrevEnabledColumn; // Index of prev enabled/visible column within Columns[], -1 if first enabled/visible column
2525 KGGuiTableColumnIdx NextEnabledColumn; // Index of next enabled/visible column within Columns[], -1 if last enabled/visible column
2526 KGGuiTableColumnIdx 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
2527 KGGuiTableDrawChannelIdx DrawChannelCurrent; // Index within DrawSplitter.Channels[]
2528 KGGuiTableDrawChannelIdx DrawChannelFrozen; // Draw channels for frozen rows (often headers)
2529 KGGuiTableDrawChannelIdx DrawChannelUnfrozen; // Draw channels for unfrozen rows
2530 bool IsEnabled; // IsUserEnabled && (Flags & KGGuiTableColumnFlags_Disabled) == 0
2531 bool IsUserEnabled; // Is the column not marked Hidden by the user? (unrelated to being off view, e.g. clipped by scrolling).
2532 bool IsUserEnabledNextFrame;
2533 bool IsVisibleX; // Is actually in view (e.g. overlapping the host window clipping rectangle, not scrolled).
2534 bool IsVisibleY;
2535 bool IsRequestOutput; // Return value for TableSetColumnIndex() / TableNextColumn(): whether we request user to output contents or not.
2536 bool IsSkipItems; // Do we want item submissions to this column to be completely ignored (no layout will happen).
2537 bool IsPreserveWidthAuto;
2538 KGS8 NavLayerCurrent; // KGGuiNavLayer in 1 byte
2539 KGU8 AutoFitQueue; // Queue of 8 values for the next 8 frames to request auto-fit
2540 KGU8 CannotSkipItemsQueue; // Queue of 8 values for the next 8 frames to disable Clipped/SkipItem
2541 KGU8 SortDirection : 2; // KGGuiSortDirection_Ascending or KGGuiSortDirection_Descending
2542 KGU8 SortDirectionsAvailCount : 2; // Number of available sort directions (0 to 3)
2543 KGU8 SortDirectionsAvailMask : 4; // Mask of available sort directions (1-bit each)
2544 KGU8 SortDirectionsAvailList; // Ordered of available sort directions (2-bits each)
2545
2547 {
2548 memset(this, 0, sizeof(*this));
2549 StretchWeight = WidthRequest = -1.0f;
2550 NameOffset = -1;
2551 DisplayOrder = IndexWithinEnabledSet = -1;
2552 PrevEnabledColumn = NextEnabledColumn = -1;
2553 SortOrder = -1;
2554 SortDirection = KGGuiSortDirection_None;
2555 DrawChannelCurrent = DrawChannelFrozen = DrawChannelUnfrozen = (KGU8)-1;
2556 }
2557};
2558
2559// Transient cell data stored per row.
2560// sizeof() ~ 6
2562{
2563 KGU32 BgColor; // Actual color
2564 KGGuiTableColumnIdx Column; // Column number
2565};
2566
2567// 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 KGGuiTableTempData ?)
2569{
2570 float LastOuterHeight; // Outer height from last frame
2571 float LastFirstRowHeight; // Height of first row from last frame (FIXME: this is used as "header height" and may be reworked)
2572 float LastFrozenHeight; // Height of frozen section from last frame
2573
2574 KGGuiTableInstanceData() { LastOuterHeight = LastFirstRowHeight = LastFrozenHeight = 0.0f; }
2575};
2576
2577// FIXME-TABLE: more transient data could be stored in a stacked KGGuiTableTempData: e.g. SortSpecs, incoming RowData
2579{
2580 KGGuiID ID;
2581 KarmaGuiTableFlags Flags;
2582 void* RawData; // Single allocation to hold Columns[], DisplayOrderToIndex[] and RowCellData[]
2583 KGGuiTableTempData* TempData; // Transient data while table is active. Point within g.CurrentTableStack[]
2584 KGSpan<KGGuiTableColumn> Columns; // Point within RawData[]
2585 KGSpan<KGGuiTableColumnIdx> DisplayOrderToIndex; // Point within RawData[]. Store display order of columns (when not reordered, the values are 0...Count-1)
2586 KGSpan<KGGuiTableCellData> RowCellData; // Point within RawData[]. Store cells background requests for current row.
2587 KGU64 EnabledMaskByDisplayOrder; // Column DisplayOrder -> IsEnabled map
2588 KGU64 EnabledMaskByIndex; // Column Index -> IsEnabled map (== not hidden by user/api) in a format adequate for iterating column without touching cold data
2589 KGU64 VisibleMaskByIndex; // Column Index -> IsVisibleX|IsVisibleY map (== not hidden by user/api && not hidden by scrolling/cliprect)
2590 KGU64 RequestOutputMaskByIndex; // Column Index -> IsVisible || AutoFit (== expect user to submit items)
2591 KarmaGuiTableFlags SettingsLoadedFlags; // Which data were loaded from the .ini file (e.g. when order is not altered we won't save order)
2592 int SettingsOffset; // Offset in g.SettingsTables
2593 int LastFrameActive;
2594 int ColumnsCount; // Number of columns declared in BeginTable()
2595 int CurrentRow;
2596 int CurrentColumn;
2597 KGS16 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.
2598 KGS16 InstanceInteracted; // Mark which instance (generally 0) of the same ID is being interacted with
2599 float RowPosY1;
2600 float RowPosY2;
2601 float RowMinHeight; // Height submitted to TableNextRow()
2602 float RowTextBaseline;
2603 float RowIndentOffsetX;
2604 KarmaGuiTableRowFlags RowFlags : 16; // Current row flags, see KGGuiTableRowFlags_
2605 KarmaGuiTableRowFlags LastRowFlags : 16;
2606 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.
2607 KGU32 RowBgColor[2]; // Background color override for current row.
2608 KGU32 BorderColorStrong;
2609 KGU32 BorderColorLight;
2610 float BorderX1;
2611 float BorderX2;
2612 float HostIndentX;
2613 float MinColumnWidth;
2614 float OuterPaddingX;
2615 float CellPaddingX; // Padding from each borders
2616 float CellPaddingY;
2617 float CellSpacingX1; // Spacing between non-bordered cells
2618 float CellSpacingX2;
2619 float InnerWidth; // User value passed to BeginTable(), see comments at the top of BeginTable() for details.
2620 float ColumnsGivenWidth; // Sum of current column width
2621 float ColumnsAutoFitWidth; // Sum of ideal column width in order nothing to be clipped, used for auto-fitting and content width submission in outer window
2622 float ColumnsStretchSumWeights; // Sum of weight of all enabled stretching columns
2623 float ResizedColumnNextWidth;
2624 float ResizeLockMinContentsX2; // Lock minimum contents width while resizing down in order to not create feedback loops. But we allow growing the table.
2625 float RefScale; // Reference scale to be able to rescale columns on font/dpi changes.
2626 KGRect OuterRect; // Note: for non-scrolling table, OuterRect.Max.y is often FLT_MAX until EndTable(), unless a height has been specified in BeginTable().
2627 KGRect InnerRect; // InnerRect but without decoration. As with OuterRect, for non-scrolling tables, InnerRect.Max.y is
2628 KGRect WorkRect;
2629 KGRect InnerClipRect;
2630 KGRect BgClipRect; // We use this to cpu-clip cell background color fill, evolve during the frame as we cross frozen rows boundaries
2631 KGRect Bg0ClipRectForDrawCmd; // Actual KGDrawCmd clip rect for BG0/1 channel. This tends to be == OuterWindow->ClipRect at BeginTable() because output in BG0/BG1 is cpu-clipped
2632 KGRect Bg2ClipRectForDrawCmd; // Actual KGDrawCmd 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.
2633 KGRect HostClipRect; // This is used to check if we can eventually merge our columns draw calls into the current draw call of the current window.
2634 KGRect HostBackupInnerClipRect; // Backup of InnerWindow->ClipRect during PushTableBackground()/PopTableBackground()
2635 KGGuiWindow* OuterWindow; // Parent window for the table
2636 KGGuiWindow* InnerWindow; // Window holding the table data (== OuterWindow or a child window)
2637 KarmaGuiTextBuffer ColumnsNames; // Contiguous buffer holding columns names
2638 KGDrawListSplitter* DrawSplitter; // Shortcut to TempData->DrawSplitter while in table. Isolate draw commands per columns to avoid switching clip rect constantly
2639 KGGuiTableInstanceData InstanceDataFirst;
2640 KGVector<KGGuiTableInstanceData> InstanceDataExtra; // FIXME-OPT: Using a small-vector pattern would be good.
2641 KarmaGuiTableColumnSortSpecs SortSpecsSingle;
2642 KGVector<KarmaGuiTableColumnSortSpecs> SortSpecsMulti; // FIXME-OPT: Using a small-vector pattern would be good.
2643 KarmaGuiTableSortSpecs SortSpecs; // Public facing sorts specs, this is what we return in TableGetSortSpecs()
2644 KGGuiTableColumnIdx SortSpecsCount;
2645 KGGuiTableColumnIdx ColumnsEnabledCount; // Number of enabled columns (<= ColumnsCount)
2646 KGGuiTableColumnIdx ColumnsEnabledFixedCount; // Number of enabled columns (<= ColumnsCount)
2647 KGGuiTableColumnIdx DeclColumnsCount; // Count calls to TableSetupColumn()
2648 KGGuiTableColumnIdx HoveredColumnBody; // Index of column whose visible region is being hovered. Important: == ColumnsCount when hovering empty region after the right-most column!
2649 KGGuiTableColumnIdx HoveredColumnBorder; // Index of column whose right-border is being hovered (for resizing).
2650 KGGuiTableColumnIdx AutoFitSingleColumn; // Index of single column requesting auto-fit.
2651 KGGuiTableColumnIdx ResizedColumn; // Index of column being resized. Reset when InstanceCurrent==0.
2652 KGGuiTableColumnIdx LastResizedColumn; // Index of column being resized from previous frame.
2653 KGGuiTableColumnIdx HeldHeaderColumn; // Index of column header being held.
2654 KGGuiTableColumnIdx ReorderColumn; // Index of column being reordered. (not cleared)
2655 KGGuiTableColumnIdx ReorderColumnDir; // -1 or +1
2656 KGGuiTableColumnIdx LeftMostEnabledColumn; // Index of left-most non-hidden column.
2657 KGGuiTableColumnIdx RightMostEnabledColumn; // Index of right-most non-hidden column.
2658 KGGuiTableColumnIdx LeftMostStretchedColumn; // Index of left-most stretched column.
2659 KGGuiTableColumnIdx RightMostStretchedColumn; // Index of right-most stretched column.
2660 KGGuiTableColumnIdx ContextPopupColumn; // Column right-clicked on, of -1 if opening context menu from a neutral/empty spot
2661 KGGuiTableColumnIdx FreezeRowsRequest; // Requested frozen rows count
2662 KGGuiTableColumnIdx FreezeRowsCount; // Actual frozen row count (== FreezeRowsRequest, or == 0 when no scrolling offset)
2663 KGGuiTableColumnIdx FreezeColumnsRequest; // Requested frozen columns count
2664 KGGuiTableColumnIdx FreezeColumnsCount; // Actual frozen columns count (== FreezeColumnsRequest, or == 0 when no scrolling offset)
2665 KGGuiTableColumnIdx RowCellDataCurrent; // Index of current RowCellData[] entry in current row
2666 KGGuiTableDrawChannelIdx DummyDrawChannel; // Redirect non-visible columns here.
2667 KGGuiTableDrawChannelIdx Bg2DrawChannelCurrent; // For Selectable() and other widgets drawing across columns after the freezing line. Index within DrawSplitter.Channels[]
2668 KGGuiTableDrawChannelIdx Bg2DrawChannelUnfrozen;
2669 bool IsLayoutLocked; // Set by TableUpdateLayout() which is called when beginning the first row.
2670 bool IsInsideRow; // Set when inside TableBeginRow()/TableEndRow().
2671 bool IsInitializing;
2672 bool IsSortSpecsDirty;
2673 bool IsUsingHeaders; // Set when the first row had the KGGuiTableRowFlags_Headers flag.
2674 bool IsContextPopupOpen; // Set when default context menu is open (also see: ContextPopupColumn, InstanceInteracted).
2675 bool IsSettingsRequestLoad;
2676 bool IsSettingsDirty; // Set when table settings have changed and needs to be reported into ImGuiTableSetttings data.
2677 bool IsDefaultDisplayOrder; // Set when display order is unchanged from default (DisplayOrder contains 0...Count-1)
2678 bool IsResetAllRequest;
2679 bool IsResetDisplayOrderRequest;
2680 bool IsUnfrozenRows; // Set when we got past the frozen row.
2681 bool IsDefaultSizingPolicy; // Set if user didn't explicitly set a sizing policy in BeginTable()
2682 bool HasScrollbarYCurr; // Whether ANY instance of this table had a vertical scrollbar during the current frame.
2683 bool HasScrollbarYPrev; // Whether ANY instance of this table had a vertical scrollbar during the previous.
2684 bool MemoryCompacted;
2685 bool HostSkipItems; // Backup of InnerWindow->SkipItem at the end of BeginTable(), because we will overwrite InnerWindow->SkipItem on a per-column basis
2686
2687 KGGuiTable() { memset(this, 0, sizeof(*this)); LastFrameActive = -1; }
2688 ~KGGuiTable() { KG_FREE(RawData); }
2689};
2690
2691// Transient data that are only needed between BeginTable() and EndTable(), those buffers are shared (1 per level of stacked table).
2692// - Accessing those requires chasing an extra pointer so for very frequently used data we leave them in the main table structure.
2693// - We also leave out of this structure data that tend to be particularly useful for debugging/metrics.
2695{
2696 int TableIndex; // Index in g.Tables.Buf[] pool
2697 float LastTimeActive; // Last timestamp this structure was used
2698
2699 KGVec2 UserOuterSize; // outer_size.x passed to BeginTable()
2700 KGDrawListSplitter DrawSplitter;
2701
2702 KGRect HostBackupWorkRect; // Backup of InnerWindow->WorkRect at the end of BeginTable()
2703 KGRect HostBackupParentWorkRect; // Backup of InnerWindow->ParentWorkRect at the end of BeginTable()
2704 KGVec2 HostBackupPrevLineSize; // Backup of InnerWindow->DC.PrevLineSize at the end of BeginTable()
2705 KGVec2 HostBackupCurrLineSize; // Backup of InnerWindow->DC.CurrLineSize at the end of BeginTable()
2706 KGVec2 HostBackupCursorMaxPos; // Backup of InnerWindow->DC.CursorMaxPos at the end of BeginTable()
2707 KGVec1 HostBackupColumnsOffset; // Backup of OuterWindow->DC.ColumnsOffset at the end of BeginTable()
2708 float HostBackupItemWidth; // Backup of OuterWindow->DC.ItemWidth at the end of BeginTable()
2709 int HostBackupItemWidthStackSize;//Backup of OuterWindow->DC.ItemWidthStack.Size at the end of BeginTable()
2710
2711 KGGuiTableTempData() { memset(this, 0, sizeof(*this)); LastTimeActive = -1.0f; }
2712};
2713
2714// sizeof() ~ 12
2716{
2717 float WidthOrWeight;
2718 KGGuiID UserID;
2719 KGGuiTableColumnIdx Index;
2720 KGGuiTableColumnIdx DisplayOrder;
2721 KGGuiTableColumnIdx SortOrder;
2722 KGU8 SortDirection : 2;
2723 KGU8 IsEnabled : 1; // "Visible" in ini file
2724 KGU8 IsStretch : 1;
2725
2727 {
2728 WidthOrWeight = 0.0f;
2729 UserID = 0;
2730 Index = -1;
2731 DisplayOrder = SortOrder = -1;
2732 SortDirection = KGGuiSortDirection_None;
2733 IsEnabled = 1;
2734 IsStretch = 0;
2735 }
2736};
2737
2738// This is designed to be stored in a single KGChunkStream (1 header followed by N KGGuiTableColumnSettings, etc.)
2740{
2741 KGGuiID ID; // Set to 0 to invalidate/delete the setting
2742 KarmaGuiTableFlags SaveFlags; // Indicate data we want to save using the Resizable/Reorderable/Sortable/Hideable flags (could be using its own flags..)
2743 float RefScale; // Reference scale to be able to rescale columns on font/dpi changes.
2744 KGGuiTableColumnIdx ColumnsCount;
2745 KGGuiTableColumnIdx ColumnsCountMax; // Maximum number of columns this settings instance can store, we can recycle a settings instance with lower number of columns but not higher
2746 bool WantApply; // Set when loaded from .ini data (to enable merging/loading .ini data into an already running context)
2747
2748 KGGuiTableSettings() { memset(this, 0, sizeof(*this)); }
2749 KGGuiTableColumnSettings* GetColumnSettings() { return (KGGuiTableColumnSettings*)(this + 1); }
2750};
2751
2752namespace Karma
2753{
2754 class KARMA_API KarmaGuiInternal
2755 {
2756 public:
2757 //static KarmaGuiContext* GKarmaGui;
2758 static KarmaGuiMemAllocFunc GImAllocatorAllocFunc;
2759 static KarmaGuiMemFreeFunc GImAllocatorFreeFunc;
2760 static void* GImAllocatorUserData;
2761 public:
2762 // Some helpers defined in KarmaGui.cpp
2763 static void SetCurrentWindow(KGGuiWindow* window);
2764 static void FindHoveredWindow();
2765 static KGGuiWindow* CreateNewWindow(const char* name, KarmaGuiWindowFlags flags);
2766 static KGVec2 CalcNextScrollFromScrollTargetAndClamp(KGGuiWindow* window);
2767
2768 static void AddDrawListToDrawData(KGVector<KGDrawList*>* out_list, KGDrawList* draw_list);
2769 static void AddWindowToSortBuffer(KGVector<KGGuiWindow*>* out_sorted_windows, KGGuiWindow* window);
2770
2771 // Settings
2772 static void WindowSettingsHandler_ClearAll(KarmaGuiContext*, KGGuiSettingsHandler*);
2773 static void* WindowSettingsHandler_ReadOpen(KarmaGuiContext*, KGGuiSettingsHandler*, const char* name);
2774 static void WindowSettingsHandler_ReadLine(KarmaGuiContext*, KGGuiSettingsHandler*, void* entry, const char* line);
2775 static void WindowSettingsHandler_ApplyAll(KarmaGuiContext*, KGGuiSettingsHandler*);
2776 static void WindowSettingsHandler_WriteAll(KarmaGuiContext*, KGGuiSettingsHandler*, KarmaGuiTextBuffer* buf);
2777
2778 // Platform Dependents default implementation for IO functions
2779 static const char* GetClipboardTextFn_DefaultImpl(void* user_data);
2780 static void SetClipboardTextFn_DefaultImpl(void* user_data, const char* text);
2781 static void SetPlatformImeDataFn_DefaultImpl(KarmaGuiViewport* viewport, KarmaGuiPlatformImeData* data);
2782
2783 // Navigation
2784 static void NavUpdate();
2785 static void NavUpdateWindowing();
2786 static void NavUpdateWindowingOverlay();
2787 static void NavUpdateCancelRequest();
2788 static void NavUpdateCreateMoveRequest();
2789 static void NavUpdateCreateTabbingRequest();
2790 static float NavUpdatePageUpPageDown();
2791 static inline void NavUpdateAnyRequestFlag();
2792 static void NavUpdateCreateWrappingRequest();
2793 static void NavEndFrame();
2794 static bool NavScoreItem(KGGuiNavItemData* result);
2795 static void NavApplyItemToResult(KGGuiNavItemData* result);
2796 static void NavProcessItem();
2797 static void NavProcessItemForTabbingRequest(KGGuiID id);
2798 static KGVec2 NavCalcPreferredRefPos();
2799 static void NavSaveLastChildNavWindowIntoParent(KGGuiWindow* nav_window);
2800 static KGGuiWindow* NavRestoreLastChildNavWindow(KGGuiWindow* window);
2801 static void NavRestoreLayer(KGGuiNavLayer layer);
2802 static void NavRestoreHighlightAfterMove();
2803 static int FindWindowFocusIndex(KGGuiWindow* window);
2804
2805 // Error Checking and Debug Tools
2806 static void ErrorCheckNewFrameSanityChecks();
2807 static void ErrorCheckEndFrameSanityChecks();
2808 static void UpdateDebugToolItemPicker();
2809 static void UpdateDebugToolStackQueries();
2810
2811 // Inputs
2812 static void UpdateKeyboardInputs();
2813 static void UpdateMouseInputs();
2814 static void UpdateMouseWheel();
2815 static void UpdateKeyRoutingTable(KGGuiKeyRoutingTable* rt);
2816
2817 // Misc
2818 static void UpdateSettings();
2819 static bool UpdateWindowManualResize(KGGuiWindow* window, const KGVec2& size_auto_fit, int* border_held, int resize_grip_count, KGU32 resize_grip_col[4], const KGRect& visibility_rect);
2820 static void RenderWindowOuterBorders(KGGuiWindow* window);
2821 static void RenderWindowDecorations(KGGuiWindow* window, const KGRect& title_bar_rect, bool title_bar_is_highlight, bool handle_borders_and_resize_grips, int resize_grip_count, const KGU32 resize_grip_col[4], float resize_grip_draw_size);
2822 static void RenderWindowTitleBarContents(KGGuiWindow* window, const KGRect& title_bar_rect, const char* name, bool* p_open);
2823 static void RenderDimmedBackgroundBehindWindow(KGGuiWindow* window, KGU32 col);
2824 static void RenderDimmedBackgrounds();
2825 static KGGuiWindow* FindBlockingModal(KGGuiWindow* window);
2826
2827 // Viewports
2828 const static KGGuiID IMGUI_VIEWPORT_DEFAULT_ID = 0x11111111; // Using an arbitrary constant instead of e.g. KGHashStr("ViewportDefault", 0); so it's easier to spot in the debugger. The exact value doesn't matter.
2829 static KGGuiViewportP* AddUpdateViewport(KGGuiWindow* window, KGGuiID id, const KGVec2& platform_pos, const KGVec2& size, KarmaGuiViewportFlags flags);
2830 static void DestroyViewport(KGGuiViewportP* viewport);
2831 static void UpdateViewportsNewFrame();
2832 static void UpdateViewportsEndFrame();
2833 static void WindowSelectViewport(KGGuiWindow* window);
2834 static void WindowSyncOwnedViewport(KGGuiWindow* window, KGGuiWindow* parent_window_in_stack);
2835 static bool UpdateTryMergeWindowIntoHostViewport(KGGuiWindow* window, KGGuiViewportP* host_viewport);
2836 static bool UpdateTryMergeWindowIntoHostViewports(KGGuiWindow* window);
2837 static bool GetWindowAlwaysWantOwnViewport(KGGuiWindow* window);
2838 static int FindPlatformMonitorForPos(const KGVec2& pos);
2839 static int FindPlatformMonitorForRect(const KGRect& r);
2840 static void UpdateViewportPlatformMonitor(KGGuiViewportP* viewport);
2841
2843
2844 public:
2845 // Windows
2846 // We should always have a CurrentWindow in the stack (there is an implicit "Debug" window)
2847 // If this ever crash because g.CurrentWindow is NULL it means that either
2848 // - ImGui::NewFrame() has never been called, which is illegal.
2849 // - You are calling ImGui functions after ImGui::EndFrame()/ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal.
2850 static KGGuiWindow* GetCurrentWindowRead();
2851 static KGGuiWindow* GetCurrentWindow();
2852 static KGGuiWindow* FindWindowByID(KGGuiID id);
2853 static KGGuiWindow* FindWindowByName(const char* name);
2854 static void UpdateWindowParentAndRootLinks(KGGuiWindow* window, KarmaGuiWindowFlags flags, KGGuiWindow* parent_window);
2855 static KGVec2 CalcWindowNextAutoFitSize(KGGuiWindow* window);
2856 static bool IsWindowChildOf(KGGuiWindow* window, KGGuiWindow* potential_parent, bool popup_hierarchy, bool dock_hierarchy);
2857 static bool IsWindowWithinBeginStackOf(KGGuiWindow* window, KGGuiWindow* potential_parent);
2858 static bool IsWindowAbove(KGGuiWindow* potential_above, KGGuiWindow* potential_below);
2859 static bool IsWindowNavFocusable(KGGuiWindow* window);
2860 static void SetWindowPos(KGGuiWindow* window, const KGVec2& pos, KarmaGuiCond cond = 0);
2861 static void SetWindowSize(KGGuiWindow* window, const KGVec2& size, KarmaGuiCond cond = 0);
2862 static void SetWindowCollapsed(KGGuiWindow* window, bool collapsed, KarmaGuiCond cond = 0);
2863 static void SetWindowHitTestHole(KGGuiWindow* window, const KGVec2& pos, const KGVec2& size);
2864 static inline KGRect WindowRectAbsToRel(KGGuiWindow* window, const KGRect& r) { KGVec2 off = window->DC.CursorStartPos; return KGRect(r.Min.x - off.x, r.Min.y - off.y, r.Max.x - off.x, r.Max.y - off.y); }
2865 static inline KGRect WindowRectRelToAbs(KGGuiWindow* window, const KGRect& r) { KGVec2 off = window->DC.CursorStartPos; return KGRect(r.Min.x + off.x, r.Min.y + off.y, r.Max.x + off.x, r.Max.y + off.y); }
2866
2867 // Windows: Display Order and Focus Order
2868 static void FocusWindow(KGGuiWindow* window);
2869 static void FocusTopMostWindowUnderOne(KGGuiWindow* under_this_window, KGGuiWindow* ignore_window);
2870 static void BringWindowToFocusFront(KGGuiWindow* window);
2871 static void BringWindowToDisplayFront(KGGuiWindow* window);
2872 static void BringWindowToDisplayBack(KGGuiWindow* window);
2873 static void BringWindowToDisplayBehind(KGGuiWindow* window, KGGuiWindow* above_window);
2874 static int FindWindowDisplayIndex(KGGuiWindow* window);
2875 static KGGuiWindow* FindBottomMostVisibleWindowWithinBeginStack(KGGuiWindow* window);
2876
2877 // Fonts, drawing
2878 static void SetCurrentFont(KGFont* font);
2879 static KGFont* GetDefaultFont();
2880 static inline KGDrawList* GetForegroundDrawList(KGGuiWindow* window) { return KarmaGui::GetForegroundDrawList(window->Viewport); }
2881
2882 // Init
2883 static void Initialize();
2884 static void Shutdown(); // Since 1.60 this is a _private_ function. You can call DestroyContext() to destroy the context created by CreateContext().
2885
2886 // NewFrame
2887 static void UpdateInputEvents(bool trickle_fast_inputs);
2888 static void UpdateHoveredWindowAndCaptureFlags();
2889 static void StartMouseMovingWindow(KGGuiWindow* window);
2890 static void StartMouseMovingWindowOrNode(KGGuiWindow* window, KGGuiDockNode* node, bool undock_floating_node);
2891 static void UpdateMouseMovingWindowNewFrame();
2892 static void UpdateMouseMovingWindowEndFrame();
2893
2894 // Generic context hooks
2895 static KGGuiID AddContextHook(KarmaGuiContext* context, const KGGuiContextHook* hook);
2896 static void RemoveContextHook(KarmaGuiContext* context, KGGuiID hook_to_remove);
2897 static void CallContextHooks(KarmaGuiContext* context, ImGuiContextHookType type);
2898
2899 // Viewports
2900 static void TranslateWindowsInViewport(KGGuiViewportP* viewport, const KGVec2& old_pos, const KGVec2& new_pos);
2901 static void ScaleWindowsInViewport(KGGuiViewportP* viewport, float scale);
2902 static void DestroyPlatformWindow(KGGuiViewportP* viewport);
2903 static void SetWindowViewport(KGGuiWindow* window, KGGuiViewportP* viewport);
2904 static void SetCurrentViewport(KGGuiWindow* window, KGGuiViewportP* viewport);
2905 static const KarmaGuiPlatformMonitor* GetViewportPlatformMonitor(KarmaGuiViewport* viewport);
2906 static KGGuiViewportP* FindHoveredViewportFromPlatformWindowStack(const KGVec2& mouse_platform_pos);
2907
2908 // Settings
2909 static void MarkIniSettingsDirty();
2910 static void MarkIniSettingsDirty(KGGuiWindow* window);
2911 static void ClearIniSettings();
2912 static KGGuiWindowSettings* CreateNewWindowSettings(const char* name);
2913 static KGGuiWindowSettings* FindWindowSettings(KGGuiID id);
2914 static KGGuiWindowSettings* FindOrCreateWindowSettings(const char* name);
2915 static void AddSettingsHandler(const KGGuiSettingsHandler* handler);
2916 static void RemoveSettingsHandler(const char* type_name);
2917 static KGGuiSettingsHandler* FindSettingsHandler(const char* type_name);
2918
2919 // Localization
2920 static void LocalizeRegisterEntries(const KGGuiLocEntry* entries, int count);
2921 static const char* LocalizeGetMsg(KGGuiLocKey key);
2922
2923 // Scrolling
2924 static void SetScrollX(KGGuiWindow* window, float scroll_x);
2925 static void SetScrollY(KGGuiWindow* window, float scroll_y);
2926 static void SetScrollFromPosX(KGGuiWindow* window, float local_x, float center_x_ratio);
2927 static void SetScrollFromPosY(KGGuiWindow* window, float local_y, float center_y_ratio);
2928
2929 // Early work-in-progress API (ScrollToItem() will become public)
2930 static void ScrollToItem(KGGuiScrollFlags flags = 0);
2931 static void ScrollToRect(KGGuiWindow* window, const KGRect& rect, KGGuiScrollFlags flags = 0);
2932 static KGVec2 ScrollToRectEx(KGGuiWindow* window, const KGRect& rect, KGGuiScrollFlags flags = 0);
2933
2934 // Basic Accessors
2935 static inline KGGuiItemStatusFlags GetItemStatusFlags() { KarmaGuiContext& g = *GKarmaGui; return g.LastItemData.StatusFlags; }
2936 static inline KGGuiItemFlags GetItemFlags() { KarmaGuiContext& g = *GKarmaGui; return g.LastItemData.InFlags; }
2937 static inline KGGuiID GetActiveID() { KarmaGuiContext& g = *GKarmaGui; return g.ActiveId; }
2938 static inline KGGuiID GetFocusID() { KarmaGuiContext& g = *GKarmaGui; return g.NavId; }
2939 static void SetActiveID(KGGuiID id, KGGuiWindow* window);
2940 static void SetFocusID(KGGuiID id, KGGuiWindow* window);
2941 static void ClearActiveID();
2942 static KGGuiID GetHoveredID();
2943 static void SetHoveredID(KGGuiID id);
2944 static void KeepAliveID(KGGuiID id);
2945 static void MarkItemEdited(KGGuiID id); // Mark data associated to given item as "edited", used by IsItemDeactivatedAfterEdit() function.
2946 static void PushOverrideID(KGGuiID id); // Push given value as-is at the top of the ID stack (whereas PushID combines old and new hashes)
2947 static KGGuiID GetIDWithSeed(const char* str_id_begin, const char* str_id_end, KGGuiID seed);
2948
2949 // Basic Helpers for widget code
2950 static void ItemSize(const KGVec2& size, float text_baseline_y = -1.0f);
2951 static inline void ItemSize(const KGRect& 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.
2952 static bool ItemAdd(const KGRect& bb, KGGuiID id, const KGRect* nav_bb = NULL, KGGuiItemFlags extra_flags = 0);
2953 static bool ItemHoverable(const KGRect& bb, KGGuiID id);
2954 static bool IsClippedEx(const KGRect& bb, KGGuiID id);
2955 static void SetLastItemData(KGGuiID item_id, KGGuiItemFlags in_flags, KGGuiItemStatusFlags status_flags, const KGRect& item_rect);
2956 static KGVec2 CalcItemSize(KGVec2 size, float default_w, float default_h);
2957 static float CalcWrapWidthForPos(const KGVec2& pos, float wrap_pos_x);
2958 static void PushMultiItemsWidths(int components, float width_full);
2959 static bool IsItemToggledSelection(); // Was the last item selection toggled? (after Selectable(), TreeNode() etc. We only returns toggle _event_ in order to handle clipping correctly)
2960 static KGVec2 GetContentRegionMaxAbs();
2961 static void ShrinkWidths(KGGuiShrinkWidthItem* items, int count, float width_excess);
2962
2963 // Parameter stacks (shared)
2964 static void PushItemFlag(KGGuiItemFlags option, bool enabled);
2965 static void PopItemFlag();
2966
2967 // Logging/Capture
2968 static void LogBegin(KGGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name.
2969 static void LogToBuffer(int auto_open_depth = -1); // Start logging/capturing to internal buffer
2970 static void LogRenderedText(const KGVec2* ref_pos, const char* text, const char* text_end = NULL);
2971 static void LogSetNextTextDecoration(const char* prefix, const char* suffix);
2972
2973 // Popups, Modals, Tooltips
2974 static bool BeginChildEx(const char* name, KGGuiID id, const KGVec2& size_arg, bool border, KarmaGuiWindowFlags flags);
2975 static void OpenPopupEx(KGGuiID id, KarmaGuiPopupFlags popup_flags = KGGuiPopupFlags_None);
2976 static void ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup);
2977 static void ClosePopupsOverWindow(KGGuiWindow* ref_window, bool restore_focus_to_window_under_popup);
2978 static void ClosePopupsExceptModals();
2979 static bool IsPopupOpen(KGGuiID id, KarmaGuiPopupFlags popup_flags);
2980 static bool BeginPopupEx(KGGuiID id, KarmaGuiWindowFlags extra_flags);
2981 static void BeginTooltipEx(KGGuiTooltipFlags tooltip_flags, KarmaGuiWindowFlags extra_window_flags);
2982 static KGRect GetPopupAllowedExtentRect(KGGuiWindow* window);
2983 static KGGuiWindow* GetTopMostPopupModal();
2984 static KGGuiWindow* GetTopMostAndVisiblePopupModal();
2985 static KGVec2 FindBestWindowPosForPopup(KGGuiWindow* window);
2986 static KGVec2 FindBestWindowPosForPopupEx(const KGVec2& ref_pos, const KGVec2& size, KarmaGuiDir* last_dir, const KGRect& r_outer, const KGRect& r_avoid, KGGuiPopupPositionPolicy policy);
2987
2988 // Menus
2989 static bool BeginViewportSideBar(const char* name, KarmaGuiViewport* viewport, KarmaGuiDir dir, float size, KarmaGuiWindowFlags window_flags);
2990 static bool BeginMenuEx(const char* label, const char* icon, bool enabled = true);
2991 static bool MenuItemEx(const char* label, const char* icon, const char* shortcut = NULL, bool selected = false, bool enabled = true);
2992
2993 // Combos
2994 static bool BeginComboPopup(KGGuiID popup_id, const KGRect& bb, KarmaGuiComboFlags flags);
2995 static bool BeginComboPreview();
2996 static void EndComboPreview();
2997
2998 // Gamepad/Keyboard Navigation
2999 static void NavInitWindow(KGGuiWindow* window, bool force_reinit);
3000 static void NavInitRequestApplyResult();
3001 static bool NavMoveRequestButNoResultYet();
3002 static void NavMoveRequestSubmit(KarmaGuiDir move_dir, KarmaGuiDir clip_dir, KGGuiNavMoveFlags move_flags, KGGuiScrollFlags scroll_flags);
3003 static void NavMoveRequestForward(KarmaGuiDir move_dir, KarmaGuiDir clip_dir, KGGuiNavMoveFlags move_flags, KGGuiScrollFlags scroll_flags);
3004 static void NavMoveRequestResolveWithLastItem(KGGuiNavItemData* result);
3005 static void NavMoveRequestCancel();
3006 static void NavMoveRequestApplyResult();
3007 static void NavMoveRequestTryWrapping(KGGuiWindow* window, KGGuiNavMoveFlags move_flags);
3008 static void ActivateItem(KGGuiID 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.
3009 static void SetNavWindow(KGGuiWindow* window);
3010 static void SetNavID(KGGuiID id, KGGuiNavLayer nav_layer, KGGuiID focus_scope_id, const KGRect& rect_rel);
3011
3012 // Inputs
3013 // FIXME: Eventually we should aim to move e.g. IsActiveIdUsingKey() into IsKeyXXX functions.
3014 static inline bool IsNamedKey(KarmaGuiKey key) { return key >= KGGuiKey_NamedKey_BEGIN && key < KGGuiKey_NamedKey_END; }
3015 static inline bool IsNamedKeyOrModKey(KarmaGuiKey key) { return (key >= KGGuiKey_NamedKey_BEGIN && key < KGGuiKey_NamedKey_END) || key == KGGuiMod_Ctrl || key == KGGuiMod_Shift || key == KGGuiMod_Alt || key == KGGuiMod_Super || key == KGGuiMod_Shortcut; }
3016 static inline bool IsLegacyKey(KarmaGuiKey key) { return key >= KGGuiKey_LegacyNativeKey_BEGIN && key < KGGuiKey_LegacyNativeKey_END; }
3017 static inline bool IsKeyboardKey(KarmaGuiKey key) { return key >= KGGuiKey_Keyboard_BEGIN && key < KGGuiKey_Keyboard_END; }
3018 static inline bool IsGamepadKey(KarmaGuiKey key) { return key >= KGGuiKey_Gamepad_BEGIN && key < KGGuiKey_Gamepad_END; }
3019 static inline bool IsMouseKey(KarmaGuiKey key) { return key >= KGGuiKey_Mouse_BEGIN && key < KGGuiKey_Mouse_END; }
3020 static inline bool IsAliasKey(KarmaGuiKey key) { return key >= KGGuiKey_Aliases_BEGIN && key < KGGuiKey_Aliases_END; }
3021 static KarmaGuiKeyChord ConvertShortcutMod(KarmaGuiKeyChord key_chord);
3022 static KarmaGuiKey ConvertSingleModFlagToKey(KarmaGuiKey key);
3023 static KarmaGuiKeyData* GetKeyData(KarmaGuiKey key);
3024 static void GetKeyChordName(KarmaGuiKeyChord key_chord, char* out_buf, int out_buf_size);
3025 static inline KarmaGuiKey MouseButtonToKey(KarmaGuiMouseButton button) { KR_CORE_ASSERT(button >= 0 && button < KGGuiMouseButton_COUNT, ""); return (KarmaGuiKey)(KGGuiKey_MouseLeft + button); }
3026 static bool IsMouseDragPastThreshold(KarmaGuiMouseButton button, float lock_threshold = -1.0f);
3027 static KGVec2 GetKeyMagnitude2d(KarmaGuiKey key_left, KarmaGuiKey key_right, KarmaGuiKey key_up, KarmaGuiKey key_down);
3028 static float GetNavTweakPressedAmount(KGGuiAxis axis);
3029 static int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate);
3030 static void GetTypematicRepeatRate(KarmaGuiInputFlags flags, float* repeat_delay, float* repeat_rate);
3031 static void SetActiveIdUsingAllKeyboardKeys();
3032 static inline bool IsActiveIdUsingNavDir(KarmaGuiDir dir);
3033
3034 // [EXPERIMENTAL] Low-Level: Key/Input Ownership
3035 // - The idea is that instead of "eating" a given input, we can link to an owner id.
3036 // - Ownership is most often claimed as a result of reacting to a press/down event (but occasionally may be claimed ahead).
3037 // - Input queries can then read input by specifying KGGuiKeyOwner_Any (== 0), KGGuiKeyOwner_None (== -1) or a custom ID.
3038 // - Legacy input queries (without specifying an owner or _Any or _None) are equivalent to using KGGuiKeyOwner_Any (== 0).
3039 // - Input ownership is automatically released on the frame after a key is released. Therefore:
3040 // - for ownership registration happening as a result of a down/press event, the SetKeyOwner() call may be done once (common case).
3041 // - 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).
3042 // - 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.
3043 // - This is marked experimental because not all widgets are fully honoring the Set/Test idioms. We will need to move forward step by step.
3044 // Please open a GitHub Issue to submit your usage scenario or if there's a use case you need solved.
3045 static KGGuiID GetKeyOwner(KarmaGuiKey key);
3046 static void SetKeyOwner(KarmaGuiKey key, KGGuiID owner_id, KarmaGuiInputFlags flags = 0);
3047 static void SetItemKeyOwner(KarmaGuiKey key, KarmaGuiInputFlags flags = 0); // Set key owner to last item if it is hovered or active. Equivalent to 'if (IsItemHovered() || IsItemActive()) { SetKeyOwner(key, GetItemID());'.
3048 static bool TestKeyOwner(KarmaGuiKey key, KGGuiID owner_id); // Test that key is either not owned, either owned by 'owner_id'
3049 static KGGuiKeyOwnerData* GetKeyOwnerData(KarmaGuiKey key);
3050
3051 // [EXPERIMENTAL] High-Level: Input Access functions w/ support for Key/Input Ownership
3052 // - Important: legacy IsKeyPressed(KarmaGuiKey, bool repeat=true) _DEFAULTS_ to repeat, new IsKeyPressed() requires _EXPLICIT_ KGGuiInputFlags_Repeat flag.
3053 // - Expected to be later promoted to public API, the prototypes are designed to replace existing ones (since owner_id can default to Any == 0)
3054 // - Specifying a value for 'KGGuiID owner' will test that EITHER the key is NOT owned (UNLESS locked), EITHER the key is owned by 'owner'.
3055 // Legacy functions use KGGuiKeyOwner_Any meaning that they typically ignore ownership, unless a call to SetKeyOwner() explicitly used KGGuiInputFlags_LockThisFrame or KGGuiInputFlags_LockUntilRelease.
3056 // - Binding generators may want to ignore those for now, or suffix them with Ex() until we decide if this gets moved into public API.
3057 static bool IsKeyDown(KarmaGuiKey key, KGGuiID owner_id);
3058 static bool IsKeyPressed(KarmaGuiKey key, KGGuiID owner_id, KarmaGuiInputFlags 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 KGGuiInputFlags_Repeat.
3059 static bool IsKeyReleased(KarmaGuiKey key, KGGuiID owner_id);
3060 static bool IsMouseDown(KarmaGuiMouseButton button, KGGuiID owner_id);
3061 static bool IsMouseClicked(KarmaGuiMouseButton button, KGGuiID owner_id, KarmaGuiInputFlags flags = 0);
3062 static bool IsMouseReleased(KarmaGuiMouseButton button, KGGuiID owner_id);
3063
3064 // [EXPERIMENTAL] Low-Level: Shortcut Routing
3065 // - Routes are resolved during NewFrame(): if keyboard modifiers are matching current ones: SetKeyOwner() is called + route is granted for the frame.
3066 // - Route is granted to a single owner. When multiple requests are made we have policies to select the winning route.
3067 // - Multiple read sites may use the same owner id and will all get the granted route.
3068 // - For routing: when owner_id is 0 we use the current Focus Scope ID as a default owner in order to identify our location.
3069 static bool SetShortcutRouting(KarmaGuiKeyChord key_chord, KGGuiID owner_id = 0, KarmaGuiInputFlags flags = 0);
3070 static bool TestShortcutRouting(KarmaGuiKeyChord key_chord, KGGuiID owner_id);
3071 static KGGuiKeyRoutingData* GetShortcutRoutingData(KarmaGuiKeyChord key_chord);
3072
3073 // Docking
3074 // (some functions are only declared in imgui.cpp, see Docking section)
3075 static void DockContextInitialize(KarmaGuiContext* ctx);
3076 static void DockContextShutdown(KarmaGuiContext* ctx);
3077 static void DockContextClearNodes(KarmaGuiContext* ctx, KGGuiID root_id, bool clear_settings_refs); // Use root_id==0 to clear all
3078 static void DockContextRebuildNodes(KarmaGuiContext* ctx);
3079 static void DockContextNewFrameUpdateUndocking(KarmaGuiContext* ctx);
3080 static void DockContextNewFrameUpdateDocking(KarmaGuiContext* ctx);
3081 static void DockContextEndFrame(KarmaGuiContext* ctx);
3082 static KGGuiID DockContextGenNodeID(KarmaGuiContext* ctx);
3083 static KGGuiDockNode* DockContextAddNode(KarmaGuiContext* ctx, KGGuiID id);
3084 static void DockContextRemoveNode(KarmaGuiContext* ctx, KGGuiDockNode* node, bool merge_sibling_into_parent_node);
3085 static void DockContextQueueDock(KarmaGuiContext* ctx, KGGuiWindow* target, KGGuiDockNode* target_node, KGGuiWindow* payload, KarmaGuiDir split_dir, float split_ratio, bool split_outer);
3086 static void DockContextQueueUndockWindow(KarmaGuiContext* ctx, KGGuiWindow* window);
3087 static void DockContextQueueUndockNode(KarmaGuiContext* ctx, KGGuiDockNode* node);
3088 static bool DockContextCalcDropPosForDocking(KGGuiWindow* target, KGGuiDockNode* target_node, KGGuiWindow* payload_window, KGGuiDockNode* payload_node, KarmaGuiDir split_dir, bool split_outer, KGVec2* out_pos);
3089 static KGGuiDockNode* DockContextFindNodeByID(KarmaGuiContext* ctx, KGGuiID id);
3090 static bool DockNodeBeginAmendTabBar(KGGuiDockNode* node);
3091 static void DockNodeEndAmendTabBar();
3092 static inline KGGuiDockNode* DockNodeGetRootNode(KGGuiDockNode* node) { while (node->ParentNode) node = node->ParentNode; return node; }
3093 static inline bool DockNodeIsInHierarchyOf(KGGuiDockNode* node, KGGuiDockNode* parent) { while (node) { if (node == parent) return true; node = node->ParentNode; } return false; }
3094 static inline int DockNodeGetDepth(const KGGuiDockNode* node) { int depth = 0; while (node->ParentNode) { node = node->ParentNode; depth++; } return depth; }
3095 static inline KGGuiID DockNodeGetWindowMenuButtonId(const KGGuiDockNode* node) { return KGHashStr("#COLLAPSE", 0, node->ID); }
3096 static inline KGGuiDockNode* GetWindowDockNode() { KarmaGuiContext& g = *GKarmaGui; return g.CurrentWindow->DockNode; }
3097 static bool GetWindowAlwaysWantOwnTabBar(KGGuiWindow* window);
3098 static void BeginDocked(KGGuiWindow* window, bool* p_open);
3099 static void BeginDockableDragDropSource(KGGuiWindow* window);
3100 static void BeginDockableDragDropTarget(KGGuiWindow* window);
3101 static void SetWindowDock(KGGuiWindow* window, KGGuiID dock_id, KarmaGuiCond cond);
3102
3103 // Docking - Builder function needs to be generally called before the node is used/submitted.
3104 // - The DockBuilderXXX functions are designed to _eventually_ become a public API, but it is too early to expose it and guarantee stability.
3105 // - Do not hold on KGGuiDockNode* pointers! They may be invalidated by any split/merge/remove operation and every frame.
3106 // - To create a DockSpace() node, make sure to set the KGGuiDockNodeFlags_DockSpace flag when calling DockBuilderAddNode().
3107 // You can create dockspace nodes (attached to a window) _or_ floating nodes (carry its own window) with this API.
3108 // - DockBuilderSplitNode() create 2 child nodes within 1 node. The initial node becomes a parent node.
3109 // - If you intend to split the node immediately after creation using DockBuilderSplitNode(), make sure
3110 // to call DockBuilderSetNodeSize() beforehand. If you don't, the resulting split sizes may not be reliable.
3111 // - Call DockBuilderFinish() after you are done.
3112 static void DockBuilderDockWindow(const char* window_name, KGGuiID node_id);
3113 //static KGGuiDockNode* DockBuilderGetNode(KGGuiID node_id);
3114 //static inline KGGuiDockNode* DockBuilderGetCentralNode(KGGuiID node_id) { KGGuiDockNode* node = DockBuilderGetNode(node_id); if (!node) return NULL; return DockNodeGetRootNode(node)->CentralNode; }
3115 static KGGuiID DockBuilderAddNode(KGGuiID node_id = 0, KarmaGuiDockNodeFlags flags = 0);
3116 static void DockBuilderRemoveNode(KGGuiID node_id); // Remove node and all its child, undock all windows
3117 static void DockBuilderRemoveNodeDockedWindows(KGGuiID node_id, bool clear_settings_refs = true);
3118 static void DockBuilderRemoveNodeChildNodes(KGGuiID node_id); // Remove all split/hierarchy. All remaining docked windows will be re-docked to the remaining root node (node_id).
3119 static void DockBuilderSetNodePos(KGGuiID node_id, KGVec2 pos);
3120 static void DockBuilderSetNodeSize(KGGuiID node_id, KGVec2 size);
3121 static KGGuiID DockBuilderSplitNode(KGGuiID node_id, KarmaGuiDir split_dir, float size_ratio_for_node_at_dir, KGGuiID* out_id_at_dir, KGGuiID* out_id_at_opposite_dir); // Create 2 child nodes in this parent node.
3122 static void DockBuilderCopyDockSpace(KGGuiID src_dockspace_id, KGGuiID dst_dockspace_id, KGVector<const char*>* in_window_remap_pairs);
3123 static void DockBuilderCopyNode(KGGuiID src_node_id, KGGuiID dst_node_id, KGVector<KGGuiID>* out_node_remap_pairs);
3124 static void DockBuilderCopyWindowSettings(const char* src_name, const char* dst_name);
3125 static void DockBuilderFinish(KGGuiID node_id);
3126
3127 // [EXPERIMENTAL] Focus Scope
3128 // This is generally used to identify a unique input location (for e.g. a selection set)
3129 // There is one per window (automatically set in Begin), but:
3130 // - Selection patterns generally need to react (e.g. clear a selection) when landing on one item of the set.
3131 // So in order to identify a set multiple lists in same window may each need a focus scope.
3132 // If you imagine an hypothetical BeginSelectionGroup()/EndSelectionGroup() api, it would likely call PushFocusScope()/EndFocusScope()
3133 // - Shortcut routing also use focus scope as a default location identifier if an owner is not provided.
3134 // We don't use the ID Stack for this as it is common to want them separate.
3135 static void PushFocusScope(KGGuiID id);
3136 static void PopFocusScope();
3137 static inline KGGuiID GetCurrentFocusScope() { KarmaGuiContext& g = *GKarmaGui; return g.CurrentFocusScopeId; } // Focus scope we are outputting into, set by PushFocusScope()
3138
3139 // Drag and Drop
3140 static bool IsDragDropActive();
3141 static bool BeginDragDropTargetCustom(const KGRect& bb, KGGuiID id);
3142 static void ClearDragDrop();
3143 static bool IsDragDropPayloadBeingAccepted();
3144 static void RenderDragDropTargetRect(const KGRect& bb);
3145
3146 // Internal Columns API (this is not exposed because we will encourage transitioning to the Tables API)
3147 static void SetWindowClipRectBeforeSetChannel(KGGuiWindow* window, const KGRect& clip_rect);
3148 static void BeginColumns(const char* str_id, int count, KGGuiOldColumnFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns().
3149 static void EndColumns(); // close columns
3150 static void PushColumnClipRect(int column_index);
3151 static void PushColumnsBackground();
3152 static void PopColumnsBackground();
3153 static KGGuiID GetColumnsID(const char* str_id, int count);
3154 static KGGuiOldColumns* FindOrCreateColumns(KGGuiWindow* window, KGGuiID id);
3155 static float GetColumnOffsetFromNorm(const KGGuiOldColumns* columns, float offset_norm);
3156 static float GetColumnNormFromOffset(const KGGuiOldColumns* columns, float offset);
3157
3158 // Tables: Candidates for public API
3159 static void TableOpenContextMenu(int column_n = -1);
3160 static void TableSetColumnWidth(int column_n, float width);
3161 static void TableSetColumnSortDirection(int column_n, KarmaGuiSortDirection sort_direction, bool append_to_sort_specs);
3162 static int TableGetHoveredColumn(); // May use (TableGetColumnFlags() & KGGuiTableColumnFlags_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.
3163 static float TableGetHeaderRowHeight();
3164 static void TablePushBackgroundChannel();
3165 static void TablePopBackgroundChannel();
3166
3167 // Tables: Internals
3168 static inline KGGuiTable* GetCurrentTable() { KarmaGuiContext& g = *GKarmaGui; return g.CurrentTable; }
3169 static KGGuiTable* TableFindByID(KGGuiID id);
3170 static bool BeginTableEx(const char* name, KGGuiID id, int columns_count, KarmaGuiTableFlags flags = 0, const KGVec2& outer_size = KGVec2(0, 0), float inner_width = 0.0f);
3171 static void TableBeginInitMemory(KGGuiTable* table, int columns_count);
3172 static void TableBeginApplyRequests(KGGuiTable* table);
3173 static void TableSetupDrawChannels(KGGuiTable* table);
3174 static void TableUpdateLayout(KGGuiTable* table);
3175 static void TableUpdateBorders(KGGuiTable* table);
3176 static void TableUpdateColumnsWeightFromWidth(KGGuiTable* table);
3177 static void TableDrawBorders(KGGuiTable* table);
3178 static void TableDrawContextMenu(KGGuiTable* table);
3179 static bool TableBeginContextMenuPopup(KGGuiTable* table);
3180 static void TableMergeDrawChannels(KGGuiTable* table);
3181 static inline KGGuiTableInstanceData* TableGetInstanceData(KGGuiTable* table, int instance_no) { if (instance_no == 0) return &table->InstanceDataFirst; return &table->InstanceDataExtra[instance_no - 1]; }
3182 static void TableSortSpecsSanitize(KGGuiTable* table);
3183 static void TableSortSpecsBuild(KGGuiTable* table);
3184 static KarmaGuiSortDirection TableGetColumnNextSortDirection(KGGuiTableColumn* column);
3185 static void TableFixColumnSortDirection(KGGuiTable* table, KGGuiTableColumn* column);
3186 static float TableGetColumnWidthAuto(KGGuiTable* table, KGGuiTableColumn* column);
3187 static void TableBeginRow(KGGuiTable* table);
3188 static void TableEndRow(KGGuiTable* table);
3189 static void TableBeginCell(KGGuiTable* table, int column_n);
3190 static void TableEndCell(KGGuiTable* table);
3191 static KGRect TableGetCellBgRect(const KGGuiTable* table, int column_n);
3192 static const char* TableGetColumnName(const KGGuiTable* table, int column_n);
3193 static KGGuiID TableGetColumnResizeID(const KGGuiTable* table, int column_n, int instance_no = 0);
3194 static float TableGetMaxColumnWidth(const KGGuiTable* table, int column_n);
3195 static void TableSetColumnWidthAutoSingle(KGGuiTable* table, int column_n);
3196 static void TableSetColumnWidthAutoAll(KGGuiTable* table);
3197 static void TableRemove(KGGuiTable* table);
3198 static void TableGcCompactTransientBuffers(KGGuiTable* table);
3199 static void TableGcCompactTransientBuffers(KGGuiTableTempData* table);
3200 static void TableGcCompactSettings();
3201
3202 // Tables: Settings
3203 static void TableLoadSettings(KGGuiTable* table);
3204 static void TableSaveSettings(KGGuiTable* table);
3205 static void TableResetSettings(KGGuiTable* table);
3206 static KGGuiTableSettings* TableGetBoundSettings(KGGuiTable* table);
3207 static void TableSettingsAddSettingsHandler();
3208 static KGGuiTableSettings* TableSettingsCreate(KGGuiID id, int columns_count);
3209 static KGGuiTableSettings* TableSettingsFindByID(KGGuiID id);
3210
3211 // Tab Bars
3212 static bool BeginTabBarEx(KGGuiTabBar* tab_bar, const KGRect& bb, KarmaGuiTabBarFlags flags, KGGuiDockNode* dock_node);
3213 static KGGuiTabItem* TabBarFindTabByID(KGGuiTabBar* tab_bar, KGGuiID tab_id);
3214 static KGGuiTabItem* TabBarFindMostRecentlySelectedTabForActiveWindow(KGGuiTabBar* tab_bar);
3215 static void TabBarAddTab(KGGuiTabBar* tab_bar, KarmaGuiTabItemFlags tab_flags, KGGuiWindow* window);
3216 static void TabBarRemoveTab(KGGuiTabBar* tab_bar, KGGuiID tab_id);
3217 static void TabBarCloseTab(KGGuiTabBar* tab_bar, KGGuiTabItem* tab);
3218 static void TabBarQueueReorder(KGGuiTabBar* tab_bar, const KGGuiTabItem* tab, int offset);
3219 static void TabBarQueueReorderFromMousePos(KGGuiTabBar* tab_bar, const KGGuiTabItem* tab, KGVec2 mouse_pos);
3220 static bool TabBarProcessReorder(KGGuiTabBar* tab_bar);
3221 static bool TabItemEx(KGGuiTabBar* tab_bar, const char* label, bool* p_open, KarmaGuiTabItemFlags flags, KGGuiWindow* docked_window);
3222 static KGVec2 TabItemCalcSize(const char* label, bool has_close_button_or_unsaved_marker);
3223 static KGVec2 TabItemCalcSize(KGGuiWindow* window);
3224 static void TabItemBackground(KGDrawList* draw_list, const KGRect& bb, KarmaGuiTabItemFlags flags, KGU32 col);
3225 static void TabItemLabelAndCloseButton(KGDrawList* draw_list, const KGRect& bb, KarmaGuiTabItemFlags flags, KGVec2 frame_padding, const char* label, KGGuiID tab_id, KGGuiID close_button_id, bool is_contents_visible, bool* out_just_closed, bool* out_text_clipped);
3226
3227 // Render helpers
3228 // 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.
3229 // NB: All position are in absolute pixels coordinates (we are never using window coordinates internally)
3230 static void RenderText(KGVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true);
3231 static void RenderTextWrapped(KGVec2 pos, const char* text, const char* text_end, float wrap_width);
3232 static void RenderTextClipped(const KGVec2& pos_min, const KGVec2& pos_max, const char* text, const char* text_end, const KGVec2* text_size_if_known, const KGVec2& align = KGVec2(0, 0), const KGRect* clip_rect = NULL);
3233 static void RenderTextClippedEx(KGDrawList* draw_list, const KGVec2& pos_min, const KGVec2& pos_max, const char* text, const char* text_end, const KGVec2* text_size_if_known, const KGVec2& align = KGVec2(0, 0), const KGRect* clip_rect = NULL);
3234 static void RenderTextEllipsis(KGDrawList* draw_list, const KGVec2& pos_min, const KGVec2& pos_max, float clip_max_x, float ellipsis_max_x, const char* text, const char* text_end, const KGVec2* text_size_if_known);
3235 static void RenderFrame(KGVec2 p_min, KGVec2 p_max, KGU32 fill_col, bool border = true, float rounding = 0.0f);
3236 static void RenderFrameBorder(KGVec2 p_min, KGVec2 p_max, float rounding = 0.0f);
3237 static void RenderColorRectWithAlphaCheckerboard(KGDrawList* draw_list, KGVec2 p_min, KGVec2 p_max, KGU32 fill_col, float grid_step, KGVec2 grid_off, float rounding = 0.0f, KGDrawFlags flags = 0);
3238 static void RenderNavHighlight(const KGRect& bb, KGGuiID id, KGGuiNavHighlightFlags flags = KGGuiNavHighlightFlags_TypeDefault); // Navigation highlight
3239 static const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text.
3240 static void RenderMouseCursor(KGVec2 pos, float scale, KarmaGuiMouseCursor mouse_cursor, KGU32 col_fill, KGU32 col_border, KGU32 col_shadow);
3241
3242 // Render helpers (those functions don't access any ImGui state!)
3243 static void RenderArrow(KGDrawList* draw_list, KGVec2 pos, KGU32 col, KarmaGuiDir dir, float scale = 1.0f);
3244 static void RenderBullet(KGDrawList* draw_list, KGVec2 pos, KGU32 col);
3245 static void RenderCheckMark(KGDrawList* draw_list, KGVec2 pos, KGU32 col, float sz);
3246 static void RenderArrowPointingAt(KGDrawList* draw_list, KGVec2 pos, KGVec2 half_sz, KarmaGuiDir direction, KGU32 col);
3247 static void RenderArrowDockMenu(KGDrawList* draw_list, KGVec2 p_min, float sz, KGU32 col);
3248 static void RenderRectFilledRangeH(KGDrawList* draw_list, const KGRect& rect, KGU32 col, float x_start_norm, float x_end_norm, float rounding);
3249 static void RenderRectFilledWithHole(KGDrawList* draw_list, const KGRect& outer, const KGRect& inner, KGU32 col, float rounding);
3250 static KGDrawFlags CalcRoundingFlagsForRectInRect(const KGRect& r_in, const KGRect& r_outer, float threshold);
3251
3252 // Widgets
3253 static void TextEx(const char* text, const char* text_end = NULL, KGGuiTextFlags flags = 0);
3254 static bool ButtonEx(const char* label, const KGVec2& size_arg = KGVec2(0, 0), KarmaGuiButtonFlags flags = 0);
3255 static bool ArrowButtonEx(const char* str_id, KarmaGuiDir dir, KGVec2 size_arg, KarmaGuiButtonFlags flags = 0);
3256 static bool ImageButtonEx(KGGuiID id, KGTextureID texture_id, const KGVec2& size, const KGVec2& uv0, const KGVec2& uv1, const KGVec4& bg_col, const KGVec4& tint_col);
3257 static void SeparatorEx(KGGuiSeparatorFlags flags);
3258 static bool CheckboxFlags(const char* label, KGS64* flags, KGS64 flags_value);
3259 static bool CheckboxFlags(const char* label, KGU64* flags, KGU64 flags_value);
3260
3261 // Widgets: Window Decorations
3262 static bool CloseButton(KGGuiID id, const KGVec2& pos);
3263 static bool CollapseButton(KGGuiID id, const KGVec2& pos, KGGuiDockNode* dock_node);
3264 static void Scrollbar(KGGuiAxis axis);
3265 static bool ScrollbarEx(const KGRect& bb, KGGuiID id, KGGuiAxis axis, KGS64* p_scroll_v, KGS64 avail_v, KGS64 contents_v, KGDrawFlags flags);
3266 static KGRect GetWindowScrollbarRect(KGGuiWindow* window, KGGuiAxis axis);
3267 static KGGuiID GetWindowScrollbarID(KGGuiWindow* window, KGGuiAxis axis);
3268 static KGGuiID GetWindowResizeCornerID(KGGuiWindow* window, int n); // 0..3: corners
3269 static KGGuiID GetWindowResizeBorderID(KGGuiWindow* window, KarmaGuiDir dir);
3270
3271 // Widgets low-level behaviors
3272 static bool ButtonBehavior(const KGRect& bb, KGGuiID id, bool* out_hovered, bool* out_held, KarmaGuiButtonFlags flags = 0);
3273 static bool DragBehavior(KGGuiID id, KarmaGuiDataType data_type, void* p_v, float v_speed, const void* p_min, const void* p_max, const char* format, KarmaGuiSliderFlags flags);
3274 static bool SliderBehavior(const KGRect& bb, KGGuiID id, KarmaGuiDataType data_type, void* p_v, const void* p_min, const void* p_max, const char* format, KarmaGuiSliderFlags flags, KGRect* out_grab_bb);
3275 static bool SplitterBehavior(const KGRect& bb, KGGuiID id, KGGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f, float hover_visibility_delay = 0.0f, KGU32 bg_col = 0);
3276 static bool TreeNodeBehavior(KGGuiID id, KarmaGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL);
3277 static void TreePushOverrideID(KGGuiID id);
3278 static void TreeNodeSetOpen(KGGuiID id, bool open);
3279 static bool TreeNodeUpdateNextOpen(KGGuiID id, KarmaGuiTreeNodeFlags flags); // Return open state. Consume previous SetNextItemOpen() data, if any. May return true when logging.
3280
3281 // Template functions are instantiated in imgui_widgets.cpp for a finite number of types.
3282 // 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).
3283 // e.g. " extern template float RoundScalarWithFormatT<float, float>(const char* format, KarmaGuiDataType data_type, float v); "
3284 template<typename T, typename SIGNED_T, typename FLOAT_T> static float ScaleRatioFromValueT(KarmaGuiDataType data_type, T v, T v_min, T v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_size);
3285 template<typename T, typename SIGNED_T, typename FLOAT_T> T static ScaleValueFromRatioT(KarmaGuiDataType data_type, float t, T v_min, T v_max, bool is_logarithmic, float logarithmic_zero_epsilon, float zero_deadzone_size);
3286 template<typename T, typename SIGNED_T, typename FLOAT_T> static bool DragBehaviorT(KarmaGuiDataType data_type, T* v, float v_speed, T v_min, T v_max, const char* format, KarmaGuiSliderFlags flags);
3287 template<typename T, typename SIGNED_T, typename FLOAT_T> bool static SliderBehaviorT(const KGRect& bb, KGGuiID id, KarmaGuiDataType data_type, T* v, T v_min, T v_max, const char* format, KarmaGuiSliderFlags flags, KGRect* out_grab_bb);
3288 template<typename T> T static RoundScalarWithFormatT(const char* format, KarmaGuiDataType data_type, T v);
3289 template<typename T> static bool CheckboxFlagsT(const char* label, T* flags, T flags_value);
3290
3291 // Data type helpers
3292 static const KGGuiDataTypeInfo* DataTypeGetInfo(KarmaGuiDataType data_type);
3293 static int DataTypeFormatString(char* buf, int buf_size, KarmaGuiDataType data_type, const void* p_data, const char* format);
3294 static void DataTypeApplyOp(KarmaGuiDataType data_type, int op, void* output, const void* arg_1, const void* arg_2);
3295 static bool DataTypeApplyFromText(const char* buf, KarmaGuiDataType data_type, void* p_data, const char* format);
3296 static int DataTypeCompare(KarmaGuiDataType data_type, const void* arg_1, const void* arg_2);
3297 static bool DataTypeClamp(KarmaGuiDataType data_type, void* p_data, const void* p_min, const void* p_max);
3298
3299 // InputText
3300 static bool InputTextEx(const char* label, const char* hint, char* buf, int buf_size, const KGVec2& size_arg, KarmaGuiInputTextFlags flags, KarmaGuiInputTextCallback callback = NULL, void* user_data = NULL);
3301 static bool TempInputText(const KGRect& bb, KGGuiID id, const char* label, char* buf, int buf_size, KarmaGuiInputTextFlags flags);
3302 static bool TempInputScalar(const KGRect& bb, KGGuiID id, const char* label, KarmaGuiDataType data_type, void* p_data, const char* format, const void* p_clamp_min = NULL, const void* p_clamp_max = NULL);
3303 static bool TempInputIsActive(KGGuiID id);
3304 static KGGuiInputTextState* GetInputTextState(KGGuiID id);
3305 // Color
3306 static void ColorTooltip(const char* text, const float* col, KarmaGuiColorEditFlags flags);
3307 static void ColorEditOptionsPopup(const float* col, KarmaGuiColorEditFlags flags);
3308 static void ColorPickerOptionsPopup(const float* ref_col, KarmaGuiColorEditFlags flags);
3309
3310 // Plot
3311 static int PlotEx(KGGuiPlotType 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, KGVec2 frame_size);
3312
3313 // Shade functions (write over already created vertices)
3314 static void ShadeVertsLinearColorGradientKeepAlpha(KGDrawList* draw_list, int vert_start_idx, int vert_end_idx, KGVec2 gradient_p0, KGVec2 gradient_p1, KGU32 col0, KGU32 col1);
3315 static void ShadeVertsLinearUV(KGDrawList* draw_list, int vert_start_idx, int vert_end_idx, const KGVec2& a, const KGVec2& b, const KGVec2& uv_a, const KGVec2& uv_b, bool clamp);
3316
3317 // Garbage collection
3318 static void GcCompactTransientMiscBuffers();
3319 static void GcCompactTransientWindowBuffers(KGGuiWindow* window);
3320 static void GcAwakeTransientWindowBuffers(KGGuiWindow* window);
3321
3322 // Debug Tools
3323 static void ErrorCheckEndFrameRecover(KGGuiErrorLogCallback log_callback, void* user_data = NULL);
3324 static void ErrorCheckEndWindowRecover(KGGuiErrorLogCallback log_callback, void* user_data = NULL);
3325 static void ErrorCheckUsingSetCursorPosToExtendParentBoundaries();
3326 static void DebugLocateItem(KGGuiID target_id); // Call sparingly: only 1 at the same time!
3327 static void DebugLocateItemOnHover(KGGuiID target_id); // Only call on reaction to a mouse Hover: because only 1 at the same time!
3328 static void DebugLocateItemResolveWithLastItem();
3329 static inline void DebugDrawItemRect(KGU32 col = KG_COL32(255, 0, 0, 255)) { KarmaGuiContext& g = *GKarmaGui; KGGuiWindow* window = g.CurrentWindow; GetForegroundDrawList(window)->AddRect(g.LastItemData.Rect.Min, g.LastItemData.Rect.Max, col); }
3330 static void DebugStartItemPicker();
3331 static void ShowFontAtlas(KGFontAtlas* atlas);
3332 static void DebugHookIdInfo(KGGuiID id, KarmaGuiDataType data_type, const void* data_id, const void* data_id_end);
3333 static void DebugNodeColumns(KGGuiOldColumns* columns);
3334 static void DebugNodeDockNode(KGGuiDockNode* node, const char* label);
3335 static void DebugNodeDrawList(KGGuiWindow* window, KGGuiViewportP* viewport, const KGDrawList* draw_list, const char* label);
3336 static void DebugNodeDrawCmdShowMeshAndBoundingBox(KGDrawList* out_draw_list, const KGDrawList* draw_list, const KGDrawCmd* draw_cmd, bool show_mesh, bool show_aabb);
3337 static void DebugNodeFont(KGFont* font);
3338 static void DebugNodeFontGlyph(KGFont* font, const KGFontGlyph* glyph);
3339 static void DebugNodeStorage(KarmaGuiStorage* storage, const char* label);
3340 static void DebugNodeTabBar(KGGuiTabBar* tab_bar, const char* label);
3341 static void DebugNodeTable(KGGuiTable* table);
3342 static void DebugNodeTableSettings(KGGuiTableSettings* settings);
3343 static void DebugNodeInputTextState(KGGuiInputTextState* state);
3344 static void DebugNodeWindow(KGGuiWindow* window, const char* label);
3345 static void DebugNodeWindowSettings(KGGuiWindowSettings* settings);
3346 static void DebugNodeWindowsList(KGVector<KGGuiWindow*>* windows, const char* label);
3347 static void DebugNodeWindowsListByBeginStackParent(KGGuiWindow** windows, int windows_size, KGGuiWindow* parent_in_begin_stack);
3348 static void DebugNodeViewport(KGGuiViewportP* viewport);
3349 static void DebugRenderKeyboardPreview(KGDrawList* draw_list);
3350 static void DebugRenderViewportThumbnail(KGDrawList* draw_list, KGGuiViewportP* viewport, const KGRect& bb);
3351 };
3352} // namespace Karma
3353
3354//-----------------------------------------------------------------------------
3355// [SECTION] KGFontAtlas internal API
3356//-----------------------------------------------------------------------------
3357
3358// This structure is likely to evolve as we add support for incremental atlas updates
3360{
3361 bool (*FontBuilder_Build)(KGFontAtlas* atlas);
3362};
3363
3364// Helper for font builder
3365#ifdef KGGUI_ENABLE_STB_TRUETYPE
3366const KGFontBuilderIO* ImFontAtlasGetBuilderForStbTruetype();
3367#endif
3368namespace Karma
3369{
3370 static void KGFontAtlasBuildInit(KGFontAtlas* atlas);
3371 static void KGFontAtlasBuildSetupFont(KGFontAtlas* atlas, KGFont* font, KGFontConfig* font_config, float ascent, float descent);
3372 static void KGFontAtlasBuildPackCustomRects(KGFontAtlas* atlas, void* stbrp_context_opaque);
3373 static void KGFontAtlasBuildFinish(KGFontAtlas* atlas);
3374 static void KGFontAtlasBuildRender8bppRectFromString(KGFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned char in_marker_pixel_value);
3375 static void KGFontAtlasBuildRender32bppRectFromString(KGFontAtlas* atlas, int x, int y, int w, int h, const char* in_str, char in_marker_char, unsigned int in_marker_pixel_value);
3376 static void KGFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor);
3377 static void KGFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride);
3378}
3379
3380//-----------------------------------------------------------------------------
3381// [SECTION] Test Engine specific hooks (imgui_test_engine)
3382//-----------------------------------------------------------------------------
3383
3384#define KARMAGUI_TEST_ENGINE_ITEM_ADD(_BB,_ID) ((void)0)
3385#define KARMAGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) ((void)g)
Definition KarmaGuiInternal.h:2755
Definition KarmaGuiInternal.h:443
Definition KarmaGuiInternal.h:458
Definition KarmaGuiInternal.h:561
Definition KarmaGui.h:2415
Definition KarmaGuiInternal.h:646
Definition KarmaGui.h:2647
Definition KarmaGuiInternal.h:623
Definition KarmaGui.h:2466
Definition KarmaGui.h:2521
Definition KarmaGui.h:2764
Definition KarmaGuiInternal.h:3360
Definition KarmaGui.h:2670
Definition KarmaGui.h:2699
Definition KarmaGui.h:2867
Definition KarmaGuiInternal.h:849
Definition KarmaGuiInternal.h:866
Definition KarmaGuiInternal.h:1711
Definition KarmaGuiInternal.h:832
Definition KarmaGuiInternal.h:826
Definition KarmaGuiInternal.h:1519
Definition KarmaGui.cpp:13581
Definition KarmaGuiInternal.h:1437
Definition KarmaGui.cpp:13542
Definition KarmaGuiInternal.h:879
Definition KarmaGuiInternal.h:1141
Definition KarmaGuiInternal.h:1139
Definition KarmaGuiInternal.h:1137
Definition KarmaGuiInternal.h:1135
Definition KarmaGuiInternal.h:1138
Definition KarmaGuiInternal.h:1136
Definition KarmaGuiInternal.h:1140
Definition KarmaGuiInternal.h:1144
Definition KarmaGuiInternal.h:914
Definition KarmaGuiInternal.h:1195
Definition KarmaGuiInternal.h:1170
Definition KarmaGuiInternal.h:1183
Definition KarmaGuiInternal.h:1029
Definition KarmaGuiInternal.h:1252
Definition KarmaGuiInternal.h:1239
Definition KarmaGuiInternal.h:1631
Definition KarmaGuiInternal.h:895
Definition KarmaGuiInternal.h:1657
Definition KarmaGuiInternal.h:1325
Definition KarmaGuiInternal.h:1016
Definition KarmaGuiInternal.h:982
Definition KarmaGuiInternal.h:1355
Definition KarmaGuiInternal.h:1365
Definition KarmaGuiInternal.h:951
Definition KarmaGuiInternal.h:1073
Definition KarmaGuiInternal.h:1598
Definition KarmaGuiInternal.h:1066
Definition KarmaGuiInternal.h:1680
Definition KarmaGuiInternal.h:1041
Definition KarmaGuiInternal.h:1692
Definition KarmaGuiInternal.h:856
Definition KarmaGuiInternal.h:2442
Definition KarmaGuiInternal.h:2422
Definition KarmaGuiInternal.h:2562
Definition KarmaGuiInternal.h:2716
Definition KarmaGuiInternal.h:2503
Definition KarmaGuiInternal.h:2569
Definition KarmaGuiInternal.h:2740
Definition KarmaGuiInternal.h:2695
Definition KarmaGuiInternal.h:2579
Definition KarmaGuiInternal.h:580
Definition KarmaGuiInternal.h:1536
Definition KarmaGuiInternal.h:1514
Definition KarmaGuiInternal.h:1581
Definition KarmaGuiInternal.h:1059
Definition KarmaGuiInternal.h:2207
Definition KarmaGuiInternal.h:2255
Definition KarmaGuiInternal.h:524
Definition KarmaGuiInternal.h:387
Definition KarmaGuiInternal.h:501
Definition KarmaGuiInternal.h:471
Definition KarmaGuiWidgets.cpp:320
Definition KarmaGuiInternal.h:369
Definition KarmaGui.h:145
Definition KarmaGuiInternal.h:377
Definition KarmaGui.h:155
Definition KarmaGui.h:1761
Definition KarmaGuiInternal.h:1725
Definition KarmaGui.h:1896
Definition KarmaGui.h:1888
Definition KarmaGui.h:2326
Definition KarmaGui.h:2145
Definition KarmaGui.h:3032
Definition KarmaGui.h:3104
Definition KarmaGui.h:3095
Definition KarmaGui.h:2266
Definition KarmaGui.h:2263
Definition KarmaGui.h:1831
Definition KarmaGui.h:2167
Definition KarmaGui.h:2181
Definition KarmaGui.h:2236
Definition KarmaGui.h:2948
Definition KarmaGui.h:2130