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