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