siplasplas
imgui_internal.h
1 // dear imgui, v1.50 WIP
2 // (internals)
3 
4 // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility!
5 // Implement maths operators for ImVec2 (disabled by default to not collide with using IM_VEC2_CLASS_EXTRA along with your own math types+operators)
6 // #define IMGUI_DEFINE_MATH_OPERATORS
7 
8 #pragma once
9 
10 #ifndef IMGUI_VERSION
11 #error Must include imgui.h before imgui_internal.h
12 #endif
13 
14 #include <stdio.h> // FILE*
15 #include <math.h> // sqrtf, fabsf, fmodf, powf, floorf, ceilf, cosf, sinf
16 
17 #ifdef _MSC_VER
18 #pragma warning (push)
19 #pragma warning (disable: 4251) // class 'xxx' needs to have dll-interface to be used by clients of struct 'xxx' // when IMGUI_API is set to__declspec(dllexport)
20 #endif
21 
22 #ifdef __clang__
23 #pragma clang diagnostic push
24 #pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h
25 #pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h
26 #pragma clang diagnostic ignored "-Wold-style-cast"
27 #endif
28 
29 //-----------------------------------------------------------------------------
30 // Forward Declarations
31 //-----------------------------------------------------------------------------
32 
33 struct ImRect;
34 struct ImGuiColMod;
35 struct ImGuiStyleMod;
36 struct ImGuiGroupData;
37 struct ImGuiSimpleColumns;
38 struct ImGuiDrawContext;
39 struct ImGuiTextEditState;
40 struct ImGuiIniData;
42 struct ImGuiPopupRef;
43 struct ImGuiWindow;
44 
45 typedef int ImGuiLayoutType; // enum ImGuiLayoutType_
46 typedef int ImGuiButtonFlags; // enum ImGuiButtonFlags_
47 typedef int ImGuiTreeNodeFlags; // enum ImGuiTreeNodeFlags_
48 typedef int ImGuiSliderFlags; // enum ImGuiSliderFlags_
49 
50 //-------------------------------------------------------------------------
51 // STB libraries
52 //-------------------------------------------------------------------------
53 
54 namespace ImGuiStb
55 {
56 
57 #undef STB_TEXTEDIT_STRING
58 #undef STB_TEXTEDIT_CHARTYPE
59 #define STB_TEXTEDIT_STRING ImGuiTextEditState
60 #define STB_TEXTEDIT_CHARTYPE ImWchar
61 #define STB_TEXTEDIT_GETWIDTH_NEWLINE -1.0f
62 #include "stb_textedit.h"
63 
64 } // namespace ImGuiStb
65 
66 //-----------------------------------------------------------------------------
67 // Context
68 //-----------------------------------------------------------------------------
69 
70 extern IMGUI_API ImGuiContext* GImGui; // current implicit ImGui context pointer
71 
72 //-----------------------------------------------------------------------------
73 // Helpers
74 //-----------------------------------------------------------------------------
75 
76 #define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR)))
77 #define IM_PI 3.14159265358979323846f
78 
79 // Helpers: UTF-8 <> wchar
80 IMGUI_API int ImTextStrToUtf8(char* buf, int buf_size, const ImWchar* in_text, const ImWchar* in_text_end); // return output UTF-8 bytes count
81 IMGUI_API int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end); // return input UTF-8 bytes count
82 IMGUI_API int ImTextStrFromUtf8(ImWchar* buf, int buf_size, const char* in_text, const char* in_text_end, const char** in_remaining = NULL); // return input UTF-8 bytes count
83 IMGUI_API int ImTextCountCharsFromUtf8(const char* in_text, const char* in_text_end); // return number of UTF-8 code-points (NOT bytes count)
84 IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end); // return number of bytes to express string as UTF-8 code-points
85 
86 // Helpers: Misc
87 IMGUI_API ImU32 ImHash(const void* data, int data_size, ImU32 seed = 0); // Pass data_size==0 for zero-terminated strings
88 IMGUI_API void* ImLoadFileToMemory(const char* filename, const char* file_open_mode, int* out_file_size = NULL, int padding_bytes = 0);
89 IMGUI_API bool ImIsPointInTriangle(const ImVec2& p, const ImVec2& a, const ImVec2& b, const ImVec2& c);
90 static inline bool ImCharIsSpace(int c) { return c == ' ' || c == '\t' || c == 0x3000; }
91 static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; }
92 
93 // Helpers: String
94 IMGUI_API int ImStricmp(const char* str1, const char* str2);
95 IMGUI_API int ImStrnicmp(const char* str1, const char* str2, int count);
96 IMGUI_API char* ImStrdup(const char* str);
97 IMGUI_API int ImStrlenW(const ImWchar* str);
98 IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line
99 IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end);
100 IMGUI_API int ImFormatString(char* buf, int buf_size, const char* fmt, ...) IM_PRINTFARGS(3);
101 IMGUI_API int ImFormatStringV(char* buf, int buf_size, const char* fmt, va_list args);
102 
103 // Helpers: Math
104 // We are keeping those not leaking to the user by default, in the case the user has implicit cast operators between ImVec2 and its own types (when IM_VEC2_CLASS_EXTRA is defined)
105 #ifdef IMGUI_DEFINE_MATH_OPERATORS
106 static inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x*rhs, lhs.y*rhs); }
107 static inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x/rhs, lhs.y/rhs); }
108 static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x+rhs.x, lhs.y+rhs.y); }
109 static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x-rhs.x, lhs.y-rhs.y); }
110 static inline ImVec2 operator*(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x*rhs.x, lhs.y*rhs.y); }
111 static inline ImVec2 operator/(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x/rhs.x, lhs.y/rhs.y); }
112 static inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; }
113 static inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; }
114 static inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; }
115 static inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; }
116 static inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x-rhs.x, lhs.y-rhs.y, lhs.z-rhs.z, lhs.w-rhs.w); }
117 #endif
118 
119 static inline int ImMin(int lhs, int rhs) { return lhs < rhs ? lhs : rhs; }
120 static inline int ImMax(int lhs, int rhs) { return lhs >= rhs ? lhs : rhs; }
121 static inline float ImMin(float lhs, float rhs) { return lhs < rhs ? lhs : rhs; }
122 static inline float ImMax(float lhs, float rhs) { return lhs >= rhs ? lhs : rhs; }
123 static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(ImMin(lhs.x,rhs.x), ImMin(lhs.y,rhs.y)); }
124 static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(ImMax(lhs.x,rhs.x), ImMax(lhs.y,rhs.y)); }
125 static inline int ImClamp(int v, int mn, int mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
126 static inline float ImClamp(float v, float mn, float mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
127 static inline ImVec2 ImClamp(const ImVec2& f, const ImVec2& mn, ImVec2 mx) { return ImVec2(ImClamp(f.x,mn.x,mx.x), ImClamp(f.y,mn.y,mx.y)); }
128 static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; }
129 static inline float ImLerp(float a, float b, float t) { return a + (b - a) * t; }
130 static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); }
131 static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y; }
132 static inline float ImLengthSqr(const ImVec4& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y + lhs.z*lhs.z + lhs.w*lhs.w; }
133 static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = lhs.x*lhs.x + lhs.y*lhs.y; if (d > 0.0f) return 1.0f / sqrtf(d); return fail_value; }
134 static inline float ImFloor(float f) { return (float)(int)f; }
135 static inline ImVec2 ImFloor(ImVec2 v) { return ImVec2((float)(int)v.x, (float)(int)v.y); }
136 
137 // We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax.
138 // Defining a custom placement new() with a dummy parameter allows us to bypass including <new> which on some platforms complains when user has disabled exceptions.
139 #ifdef IMGUI_DEFINE_PLACEMENT_NEW
140 struct ImPlacementNewDummy {};
141 inline void* operator new(size_t, ImPlacementNewDummy, void* ptr) { return ptr; }
142 inline void operator delete(void*, ImPlacementNewDummy, void*) {}
143 #define IM_PLACEMENT_NEW(_PTR) new(ImPlacementNewDummy(), _PTR)
144 #endif
145 
146 //-----------------------------------------------------------------------------
147 // Types
148 //-----------------------------------------------------------------------------
149 
150 enum ImGuiButtonFlags_
151 {
152  ImGuiButtonFlags_Repeat = 1 << 0, // hold to repeat
153  ImGuiButtonFlags_PressedOnClickRelease = 1 << 1, // (default) return pressed on click+release on same item (default if no PressedOn** flag is set)
154  ImGuiButtonFlags_PressedOnClick = 1 << 2, // return pressed on click (default requires click+release)
155  ImGuiButtonFlags_PressedOnRelease = 1 << 3, // return pressed on release (default requires click+release)
156  ImGuiButtonFlags_PressedOnDoubleClick = 1 << 4, // return pressed on double-click (default requires click+release)
157  ImGuiButtonFlags_FlattenChilds = 1 << 5, // allow interaction even if a child window is overlapping
158  ImGuiButtonFlags_DontClosePopups = 1 << 6, // disable automatically closing parent popup on press
159  ImGuiButtonFlags_Disabled = 1 << 7, // disable interaction
160  ImGuiButtonFlags_AlignTextBaseLine = 1 << 8, // vertically align button to match text baseline - ButtonEx() only
161  ImGuiButtonFlags_NoKeyModifiers = 1 << 9, // disable interaction if a key modifier is held
162  ImGuiButtonFlags_AllowOverlapMode = 1 << 10 // require previous frame HoveredId to either match id or be null before being usable
163 };
164 
165 enum ImGuiSliderFlags_
166 {
167  ImGuiSliderFlags_Vertical = 1 << 0
168 };
169 
170 enum ImGuiSelectableFlagsPrivate_
171 {
172  // NB: need to be in sync with last value of ImGuiSelectableFlags_
173  ImGuiSelectableFlags_Menu = 1 << 3,
174  ImGuiSelectableFlags_MenuItem = 1 << 4,
175  ImGuiSelectableFlags_Disabled = 1 << 5,
176  ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 6
177 };
178 
179 // FIXME: this is in development, not exposed/functional as a generic feature yet.
180 enum ImGuiLayoutType_
181 {
182  ImGuiLayoutType_Vertical,
183  ImGuiLayoutType_Horizontal
184 };
185 
186 enum ImGuiPlotType
187 {
188  ImGuiPlotType_Lines,
189  ImGuiPlotType_Histogram
190 };
191 
192 enum ImGuiDataType
193 {
194  ImGuiDataType_Int,
195  ImGuiDataType_Float
196 };
197 
198 // 2D axis aligned bounding-box
199 // NB: we can't rely on ImVec2 math operators being available here
200 struct IMGUI_API ImRect
201 {
202  ImVec2 Min; // Upper-left
203  ImVec2 Max; // Lower-right
204 
205  ImRect() : Min(FLT_MAX,FLT_MAX), Max(-FLT_MAX,-FLT_MAX) {}
206  ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {}
207  ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {}
208  ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {}
209 
210  ImVec2 GetCenter() const { return ImVec2((Min.x+Max.x)*0.5f, (Min.y+Max.y)*0.5f); }
211  ImVec2 GetSize() const { return ImVec2(Max.x-Min.x, Max.y-Min.y); }
212  float GetWidth() const { return Max.x-Min.x; }
213  float GetHeight() const { return Max.y-Min.y; }
214  ImVec2 GetTL() const { return Min; } // Top-left
215  ImVec2 GetTR() const { return ImVec2(Max.x, Min.y); } // Top-right
216  ImVec2 GetBL() const { return ImVec2(Min.x, Max.y); } // Bottom-left
217  ImVec2 GetBR() const { return Max; } // Bottom-right
218  bool Contains(const ImVec2& p) const { return p.x >= Min.x && p.y >= Min.y && p.x < Max.x && p.y < Max.y; }
219  bool Contains(const ImRect& r) const { return r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x < Max.x && r.Max.y < Max.y; }
220  bool Overlaps(const ImRect& r) const { return r.Min.y < Max.y && r.Max.y > Min.y && r.Min.x < Max.x && r.Max.x > Min.x; }
221  void Add(const ImVec2& rhs) { if (Min.x > rhs.x) Min.x = rhs.x; if (Min.y > rhs.y) Min.y = rhs.y; if (Max.x < rhs.x) Max.x = rhs.x; if (Max.y < rhs.y) Max.y = rhs.y; }
222  void Add(const ImRect& rhs) { if (Min.x > rhs.Min.x) Min.x = rhs.Min.x; if (Min.y > rhs.Min.y) Min.y = rhs.Min.y; if (Max.x < rhs.Max.x) Max.x = rhs.Max.x; if (Max.y < rhs.Max.y) Max.y = rhs.Max.y; }
223  void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; }
224  void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; }
225  void Reduce(const ImVec2& amount) { Min.x += amount.x; Min.y += amount.y; Max.x -= amount.x; Max.y -= amount.y; }
226  void Clip(const ImRect& clip) { if (Min.x < clip.Min.x) Min.x = clip.Min.x; if (Min.y < clip.Min.y) Min.y = clip.Min.y; if (Max.x > clip.Max.x) Max.x = clip.Max.x; if (Max.y > clip.Max.y) Max.y = clip.Max.y; }
227  void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; }
228  ImVec2 GetClosestPoint(ImVec2 p, bool on_edge) const
229  {
230  if (!on_edge && Contains(p))
231  return p;
232  if (p.x > Max.x) p.x = Max.x;
233  else if (p.x < Min.x) p.x = Min.x;
234  if (p.y > Max.y) p.y = Max.y;
235  else if (p.y < Min.y) p.y = Min.y;
236  return p;
237  }
238 };
239 
240 // Stacked color modifier, backup of modified data so we can restore it
242 {
243  ImGuiCol Col;
244  ImVec4 PreviousValue;
245 };
246 
247 // Stacked style modifier, backup of modified data so we can restore it
249 {
250  ImGuiStyleVar Var;
251  ImVec2 PreviousValue;
252 };
253 
254 // Stacked data for BeginGroup()/EndGroup()
256 {
257  ImVec2 BackupCursorPos;
258  ImVec2 BackupCursorMaxPos;
259  float BackupIndentX;
260  float BackupCurrentLineHeight;
261  float BackupCurrentLineTextBaseOffset;
262  float BackupLogLinePosY;
263  bool AdvanceCursor;
264 };
265 
266 // Per column data for Columns()
268 {
269  float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right)
270  //float IndentX;
271 };
272 
273 // Simple column measurement currently used for MenuItem() only. This is very short-sighted/throw-away code and NOT a generic helper.
274 struct IMGUI_API ImGuiSimpleColumns
275 {
276  int Count;
277  float Spacing;
278  float Width, NextWidth;
279  float Pos[8], NextWidths[8];
280 
282  void Update(int count, float spacing, bool clear);
283  float DeclColumns(float w0, float w1, float w2);
284  float CalcExtraSpace(float avail_w);
285 };
286 
287 // Internal state of the currently focused/edited text input box
288 struct IMGUI_API ImGuiTextEditState
289 {
290  ImGuiID Id; // widget id owning the text state
291  ImVector<ImWchar> Text; // edit buffer, we need to persist but can't guarantee the persistence of the user-provided buffer. so we copy into own buffer.
292  ImVector<char> InitialText; // backup of end-user buffer at the time of focus (in UTF-8, unaltered)
293  ImVector<char> TempTextBuffer;
294  int CurLenA, CurLenW; // we need to maintain our buffer length in both UTF-8 and wchar format.
295  int BufSizeA; // end-user buffer size
296  float ScrollX;
298  float CursorAnim;
299  bool CursorFollow;
300  bool SelectedAllMouseLock;
301 
302  ImGuiTextEditState() { memset(this, 0, sizeof(*this)); }
303  void CursorAnimReset() { CursorAnim = -0.30f; } // After a user-input the cursor stays on for a while without blinking
304  void CursorClamp() { StbState.cursor = ImMin(StbState.cursor, CurLenW); StbState.select_start = ImMin(StbState.select_start, CurLenW); StbState.select_end = ImMin(StbState.select_end, CurLenW); }
305  bool HasSelection() const { return StbState.select_start != StbState.select_end; }
306  void ClearSelection() { StbState.select_start = StbState.select_end = StbState.cursor; }
307  void SelectAll() { StbState.select_start = 0; StbState.select_end = CurLenW; StbState.cursor = StbState.select_end; StbState.has_preferred_x = false; }
308  void OnKeyPressed(int key);
309 };
310 
311 // Data saved in imgui.ini file
313 {
314  char* Name;
315  ImGuiID ID;
316  ImVec2 Pos;
317  ImVec2 Size;
318  bool Collapsed;
319 };
320 
321 // Mouse cursor data (used when io.MouseDrawCursor is set)
323 {
324  ImGuiMouseCursor Type;
325  ImVec2 HotOffset;
326  ImVec2 Size;
327  ImVec2 TexUvMin[2];
328  ImVec2 TexUvMax[2];
329 };
330 
331 // Storage for current popup stack
333 {
334  ImGuiID PopupID; // Set on OpenPopup()
335  ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup()
336  ImGuiWindow* ParentWindow; // Set on OpenPopup()
337  ImGuiID ParentMenuSet; // Set on OpenPopup()
338  ImVec2 MousePosOnOpen; // Copy of mouse position at the time of opening popup
339 
340  ImGuiPopupRef(ImGuiID id, ImGuiWindow* parent_window, ImGuiID parent_menu_set, const ImVec2& mouse_pos) { PopupID = id; Window = NULL; ParentWindow = parent_window; ParentMenuSet = parent_menu_set; MousePosOnOpen = mouse_pos; }
341 };
342 
343 // Main state for ImGui
345 {
346  bool Initialized;
347  ImGuiIO IO;
348  ImGuiStyle Style;
349  ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back()
350  float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize()
351  float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Size of characters.
352  ImVec2 FontTexUvWhitePixel; // (Shortcut) == Font->TexUvWhitePixel
353 
354  float Time;
355  int FrameCount;
356  int FrameCountEnded;
357  int FrameCountRendered;
358  ImVector<ImGuiWindow*> Windows;
359  ImVector<ImGuiWindow*> WindowsSortBuffer;
360  ImGuiWindow* CurrentWindow; // Being drawn into
361  ImVector<ImGuiWindow*> CurrentWindowStack;
362  ImGuiWindow* FocusedWindow; // Will catch keyboard inputs
363  ImGuiWindow* HoveredWindow; // Will catch mouse inputs
364  ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only)
365  ImGuiID HoveredId; // Hovered widget
366  bool HoveredIdAllowOverlap;
367  ImGuiID HoveredIdPreviousFrame;
368  ImGuiID ActiveId; // Active widget
369  ImGuiID ActiveIdPreviousFrame;
370  bool ActiveIdIsAlive;
371  bool ActiveIdIsJustActivated; // Set at the time of activation for one frame
372  bool ActiveIdAllowOverlap; // Set only by active widget
373  ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior)
374  ImGuiWindow* ActiveIdWindow;
375  ImGuiWindow* MovedWindow; // Track the child window we clicked on to move a window.
376  ImGuiID MovedWindowMoveId; // == MovedWindow->RootWindow->MoveId
377  ImVector<ImGuiIniData> Settings; // .ini Settings
378  float SettingsDirtyTimer; // Save .ini Settings on disk when time reaches zero
379  ImVector<ImGuiColMod> ColorModifiers; // Stack for PushStyleColor()/PopStyleColor()
380  ImVector<ImGuiStyleMod> StyleModifiers; // Stack for PushStyleVar()/PopStyleVar()
381  ImVector<ImFont*> FontStack; // Stack for PushFont()/PopFont()
382  ImVector<ImGuiPopupRef> OpenPopupStack; // Which popups are open (persistent)
383  ImVector<ImGuiPopupRef> CurrentPopupStack; // Which level of BeginPopup() we are in (reset every frame)
384 
385  // Storage for SetNexWindow** and SetNextTreeNode*** functions
386  ImVec2 SetNextWindowPosVal;
387  ImVec2 SetNextWindowSizeVal;
388  ImVec2 SetNextWindowContentSizeVal;
389  bool SetNextWindowCollapsedVal;
390  ImGuiSetCond SetNextWindowPosCond;
391  ImGuiSetCond SetNextWindowSizeCond;
392  ImGuiSetCond SetNextWindowContentSizeCond;
393  ImGuiSetCond SetNextWindowCollapsedCond;
394  ImRect SetNextWindowSizeConstraintRect; // Valid if 'SetNextWindowSizeConstraint' is true
395  ImGuiSizeConstraintCallback SetNextWindowSizeConstraintCallback;
396  void* SetNextWindowSizeConstraintCallbackUserData;
397  bool SetNextWindowSizeConstraint;
398  bool SetNextWindowFocus;
399  bool SetNextTreeNodeOpenVal;
400  ImGuiSetCond SetNextTreeNodeOpenCond;
401 
402  // Render
403  ImDrawData RenderDrawData; // Main ImDrawData instance to pass render information to the user
404  ImVector<ImDrawList*> RenderDrawLists[3];
405  float ModalWindowDarkeningRatio;
406  ImDrawList OverlayDrawList; // Optional software render of mouse cursors, if io.MouseDrawCursor is set + a few debug overlays
407  ImGuiMouseCursor MouseCursor;
408  ImGuiMouseCursorData MouseCursorData[ImGuiMouseCursor_Count_];
409 
410  // Widget state
411  ImGuiTextEditState InputTextState;
412  ImFont InputTextPasswordFont;
413  ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc.
414  ImGuiStorage ColorEditModeStorage; // Store user selection of color edit mode
415  float DragCurrentValue; // Currently dragged value, always float, not rounded by end-user precision settings
416  ImVec2 DragLastMouseDelta;
417  float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio
418  float DragSpeedScaleSlow;
419  float DragSpeedScaleFast;
420  ImVec2 ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage?
421  char Tooltip[1024];
422  char* PrivateClipboard; // If no custom clipboard handler is defined
423  ImVec2 OsImePosRequest, OsImePosSet; // Cursor position request & last passed to the OS Input Method Editor
424 
425  // Logging
426  bool LogEnabled;
427  FILE* LogFile; // If != NULL log to stdout/ file
428  ImGuiTextBuffer* LogClipboard; // Else log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators.
429  int LogStartDepth;
430  int LogAutoExpandMaxDepth;
431 
432  // Misc
433  float FramerateSecPerFrame[120]; // calculate estimate of framerate for user
434  int FramerateSecPerFrameIdx;
435  float FramerateSecPerFrameAccum;
436  int CaptureMouseNextFrame; // explicit capture via CaptureInputs() sets those flags
437  int CaptureKeyboardNextFrame;
438  char TempBuffer[1024*3+1]; // temporary text buffer
439 
440  ImGuiContext()
441  {
442  Initialized = false;
443  Font = NULL;
444  FontSize = FontBaseSize = 0.0f;
445  FontTexUvWhitePixel = ImVec2(0.0f, 0.0f);
446 
447  Time = 0.0f;
448  FrameCount = 0;
449  FrameCountEnded = FrameCountRendered = -1;
450  CurrentWindow = NULL;
451  FocusedWindow = NULL;
452  HoveredWindow = NULL;
453  HoveredRootWindow = NULL;
454  HoveredId = 0;
455  HoveredIdAllowOverlap = false;
456  HoveredIdPreviousFrame = 0;
457  ActiveId = 0;
458  ActiveIdPreviousFrame = 0;
459  ActiveIdIsAlive = false;
460  ActiveIdIsJustActivated = false;
461  ActiveIdAllowOverlap = false;
462  ActiveIdClickOffset = ImVec2(-1,-1);
463  ActiveIdWindow = NULL;
464  MovedWindow = NULL;
465  MovedWindowMoveId = 0;
466  SettingsDirtyTimer = 0.0f;
467 
468  SetNextWindowPosVal = ImVec2(0.0f, 0.0f);
469  SetNextWindowSizeVal = ImVec2(0.0f, 0.0f);
470  SetNextWindowCollapsedVal = false;
471  SetNextWindowPosCond = 0;
472  SetNextWindowSizeCond = 0;
473  SetNextWindowContentSizeCond = 0;
474  SetNextWindowCollapsedCond = 0;
475  SetNextWindowFocus = false;
476  SetNextWindowSizeConstraintCallback = NULL;
477  SetNextWindowSizeConstraintCallbackUserData = NULL;
478  SetNextTreeNodeOpenVal = false;
479  SetNextTreeNodeOpenCond = 0;
480 
481  ScalarAsInputTextId = 0;
482  DragCurrentValue = 0.0f;
483  DragLastMouseDelta = ImVec2(0.0f, 0.0f);
484  DragSpeedDefaultRatio = 0.01f;
485  DragSpeedScaleSlow = 0.01f;
486  DragSpeedScaleFast = 10.0f;
487  ScrollbarClickDeltaToGrabCenter = ImVec2(0.0f, 0.0f);
488  memset(Tooltip, 0, sizeof(Tooltip));
489  PrivateClipboard = NULL;
490  OsImePosRequest = OsImePosSet = ImVec2(-1.0f, -1.0f);
491 
492  ModalWindowDarkeningRatio = 0.0f;
493  OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging
494  MouseCursor = ImGuiMouseCursor_Arrow;
495  memset(MouseCursorData, 0, sizeof(MouseCursorData));
496 
497  LogEnabled = false;
498  LogFile = NULL;
499  LogClipboard = NULL;
500  LogStartDepth = 0;
501  LogAutoExpandMaxDepth = 2;
502 
503  memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame));
504  FramerateSecPerFrameIdx = 0;
505  FramerateSecPerFrameAccum = 0.0f;
506  CaptureMouseNextFrame = CaptureKeyboardNextFrame = -1;
507  memset(TempBuffer, 0, sizeof(TempBuffer));
508  }
509 };
510 
511 // Transient per-window data, reset at the beginning of the frame
512 // FIXME: That's theory, in practice the delimitation between ImGuiWindow and ImGuiDrawContext is quite tenuous and could be reconsidered.
513 struct IMGUI_API ImGuiDrawContext
514 {
515  ImVec2 CursorPos;
516  ImVec2 CursorPosPrevLine;
517  ImVec2 CursorStartPos;
518  ImVec2 CursorMaxPos; // Implicitly calculate the size of our contents, always extending. Saved into window->SizeContents at the end of the frame
519  float CurrentLineHeight;
520  float CurrentLineTextBaseOffset;
521  float PrevLineHeight;
522  float PrevLineTextBaseOffset;
523  float LogLinePosY;
524  int TreeDepth;
525  ImGuiID LastItemID;
526  ImRect LastItemRect;
527  bool LastItemHoveredAndUsable; // Item rectangle is hovered, and its window is currently interactable with (not blocked by a popup preventing access to the window)
528  bool LastItemHoveredRect; // Item rectangle is hovered, but its window may or not be currently interactable with (might be blocked by a popup preventing access to the window)
529  bool MenuBarAppending;
530  float MenuBarOffsetX;
531  ImVector<ImGuiWindow*> ChildWindows;
532  ImGuiStorage* StateStorage;
533  ImGuiLayoutType LayoutType;
534 
535  // 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.
536  float ItemWidth; // == ItemWidthStack.back(). 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window
537  float TextWrapPos; // == TextWrapPosStack.back() [empty == -1.0f]
538  bool AllowKeyboardFocus; // == AllowKeyboardFocusStack.back() [empty == true]
539  bool ButtonRepeat; // == ButtonRepeatStack.back() [empty == false]
540  ImVector<float> ItemWidthStack;
541  ImVector<float> TextWrapPosStack;
542  ImVector<bool> AllowKeyboardFocusStack;
543  ImVector<bool> ButtonRepeatStack;
544  ImVector<ImGuiGroupData>GroupStack;
545  ImGuiColorEditMode ColorEditMode;
546  int StackSizesBackup[6]; // Store size of various stacks for asserting
547 
548  float IndentX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.)
549  float ColumnsOffsetX; // 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.
550  int ColumnsCurrent;
551  int ColumnsCount;
552  float ColumnsMinX;
553  float ColumnsMaxX;
554  float ColumnsStartPosY;
555  float ColumnsCellMinY;
556  float ColumnsCellMaxY;
557  bool ColumnsShowBorders;
558  ImGuiID ColumnsSetID;
559  ImVector<ImGuiColumnData> ColumnsData;
560 
562  {
563  CursorPos = CursorPosPrevLine = CursorStartPos = CursorMaxPos = ImVec2(0.0f, 0.0f);
564  CurrentLineHeight = PrevLineHeight = 0.0f;
565  CurrentLineTextBaseOffset = PrevLineTextBaseOffset = 0.0f;
566  LogLinePosY = -1.0f;
567  TreeDepth = 0;
568  LastItemID = 0;
569  LastItemRect = ImRect(0.0f,0.0f,0.0f,0.0f);
570  LastItemHoveredAndUsable = LastItemHoveredRect = false;
571  MenuBarAppending = false;
572  MenuBarOffsetX = 0.0f;
573  StateStorage = NULL;
574  LayoutType = ImGuiLayoutType_Vertical;
575  ItemWidth = 0.0f;
576  ButtonRepeat = false;
577  AllowKeyboardFocus = true;
578  TextWrapPos = -1.0f;
579  ColorEditMode = ImGuiColorEditMode_RGB;
580  memset(StackSizesBackup, 0, sizeof(StackSizesBackup));
581 
582  IndentX = 0.0f;
583  ColumnsOffsetX = 0.0f;
584  ColumnsCurrent = 0;
585  ColumnsCount = 1;
586  ColumnsMinX = ColumnsMaxX = 0.0f;
587  ColumnsStartPosY = 0.0f;
588  ColumnsCellMinY = ColumnsCellMaxY = 0.0f;
589  ColumnsShowBorders = true;
590  ColumnsSetID = 0;
591  }
592 };
593 
594 // Windows data
595 struct IMGUI_API ImGuiWindow
596 {
597  char* Name;
598  ImGuiID ID; // == ImHash(Name)
599  ImGuiWindowFlags Flags; // See enum ImGuiWindowFlags_
600  int IndexWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0.
601  ImVec2 PosFloat;
602  ImVec2 Pos; // Position rounded-up to nearest pixel
603  ImVec2 Size; // Current size (==SizeFull or collapsed title bar size)
604  ImVec2 SizeFull; // Size when non collapsed
605  ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame
606  ImVec2 SizeContentsExplicit; // Size of contents explicitly set by the user via SetNextWindowContentSize()
607  ImRect ContentsRegionRect; // Maximum visible content position in window coordinates. ~~ (SizeContentsExplicit ? SizeContentsExplicit : Size - ScrollbarSizes) - CursorStartPos, per axis
608  ImVec2 WindowPadding; // Window padding at the time of begin. We need to lock it, in particular manipulation of the ShowBorder would have an effect
609  ImGuiID MoveID; // == window->GetID("#MOVE")
610  ImVec2 Scroll;
611  ImVec2 ScrollTarget; // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change)
612  ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered
613  bool ScrollbarX, ScrollbarY;
614  ImVec2 ScrollbarSizes;
615  float BorderSize;
616  bool Active; // Set to true on Begin()
617  bool WasActive;
618  bool Accessed; // Set to true when any widget access the current window
619  bool Collapsed; // Set when collapsing window to become only title-bar
620  bool SkipItems; // == Visible && !Collapsed
621  int BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs)
622  ImGuiID PopupID; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling)
623  int AutoFitFramesX, AutoFitFramesY;
624  bool AutoFitOnlyGrows;
625  int AutoPosLastDirection;
626  int HiddenFrames;
627  int SetWindowPosAllowFlags; // bit ImGuiSetCond_*** specify if SetWindowPos() call will succeed with this particular flag.
628  int SetWindowSizeAllowFlags; // bit ImGuiSetCond_*** specify if SetWindowSize() call will succeed with this particular flag.
629  int SetWindowCollapsedAllowFlags; // bit ImGuiSetCond_*** specify if SetWindowCollapsed() call will succeed with this particular flag.
630  bool SetWindowPosCenterWanted;
631 
632  ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame
633  ImVector<ImGuiID> IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack
634  ImRect ClipRect; // = DrawList->clip_rect_stack.back(). Scissoring / clipping rectangle. x1, y1, x2, y2.
635  ImRect WindowRectClipped; // = WindowRect just after setup in Begin(). == window->Rect() for root window.
636  int LastFrameActive;
637  float ItemWidthDefault;
638  ImGuiSimpleColumns MenuColumns; // Simplified columns storage for menu items
639  ImGuiStorage StateStorage;
640  float FontWindowScale; // Scale multiplier per-window
641  ImDrawList* DrawList;
642  ImGuiWindow* RootWindow; // If we are a child window, this is pointing to the first non-child parent window. Else point to ourself.
643  ImGuiWindow* RootNonPopupWindow; // If we are a child window, this is pointing to the first non-child non-popup parent window. Else point to ourself.
644  ImGuiWindow* ParentWindow; // If we are a child window, this is pointing to our parent window. Else point to NULL.
645 
646  // Focus
647  int FocusIdxAllCounter; // Start at -1 and increase as assigned via FocusItemRegister()
648  int FocusIdxTabCounter; // (same, but only count widgets which you can Tab through)
649  int FocusIdxAllRequestCurrent; // Item being requested for focus
650  int FocusIdxTabRequestCurrent; // Tab-able item being requested for focus
651  int FocusIdxAllRequestNext; // Item being requested for focus, for next update (relies on layout to be stable between the frame pressing TAB and the next frame)
652  int FocusIdxTabRequestNext; // "
653 
654 public:
655  ImGuiWindow(const char* name);
656  ~ImGuiWindow();
657 
658  ImGuiID GetID(const char* str, const char* str_end = NULL);
659  ImGuiID GetID(const void* ptr);
660 
661  ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x+Size.x, Pos.y+Size.y); }
662  float CalcFontSize() const { return GImGui->FontBaseSize * FontWindowScale; }
663  float TitleBarHeight() const { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f; }
664  ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight())); }
665  float MenuBarHeight() const { return (Flags & ImGuiWindowFlags_MenuBar) ? CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f : 0.0f; }
666  ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight(); return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight()); }
667 };
668 
669 //-----------------------------------------------------------------------------
670 // Internal API
671 // No guarantee of forward compatibility here.
672 //-----------------------------------------------------------------------------
673 
674 namespace ImGui
675 {
676  // We should always have a CurrentWindow in the stack (there is an implicit "Debug" window)
677  // If this ever crash because g.CurrentWindow is NULL it means that either
678  // - ImGui::NewFrame() has never been called, which is illegal.
679  // - You are calling ImGui functions after ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal.
680  inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; }
681  inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->Accessed = true; return g.CurrentWindow; }
682  IMGUI_API ImGuiWindow* GetParentWindow();
683  IMGUI_API ImGuiWindow* FindWindowByName(const char* name);
684  IMGUI_API void FocusWindow(ImGuiWindow* window);
685 
686  IMGUI_API void EndFrame(); // Ends the ImGui frame. Automatically called by Render()! you most likely don't need to ever call that yourself directly. If you don't need to render you can call EndFrame() but you'll have wasted CPU already. If you don't need to render, don't create any windows instead!
687 
688  IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window);
689  IMGUI_API void SetHoveredID(ImGuiID id);
690  IMGUI_API void KeepAliveID(ImGuiID id);
691 
692  IMGUI_API void ItemSize(const ImVec2& size, float text_offset_y = 0.0f);
693  IMGUI_API void ItemSize(const ImRect& bb, float text_offset_y = 0.0f);
694  IMGUI_API bool ItemAdd(const ImRect& bb, const ImGuiID* id);
695  IMGUI_API bool IsClippedEx(const ImRect& bb, const ImGuiID* id, bool clip_even_when_logged);
696  IMGUI_API bool IsHovered(const ImRect& bb, ImGuiID id, bool flatten_childs = false);
697  IMGUI_API bool FocusableItemRegister(ImGuiWindow* window, bool is_active, bool tab_stop = true); // Return true if focus is requested
698  IMGUI_API void FocusableItemUnregister(ImGuiWindow* window);
699  IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y);
700  IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x);
701 
702  IMGUI_API void OpenPopupEx(const char* str_id, bool reopen_existing);
703 
704  inline IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul) { ImVec4 c = GImGui->Style.Colors[idx]; c.w *= GImGui->Style.Alpha * alpha_mul; return ImGui::ColorConvertFloat4ToU32(c); }
705  inline IMGUI_API ImU32 GetColorU32(const ImVec4& col) { ImVec4 c = col; c.w *= GImGui->Style.Alpha; return ImGui::ColorConvertFloat4ToU32(c); }
706 
707  // NB: All position are in absolute pixels coordinates (not window coordinates)
708  // FIXME: All those functions are a mess and needs to be refactored into something decent. Avoid use outside of imgui.cpp!
709  // We need: a sort of symbol library, preferably baked into font atlas when possible + decent text rendering helpers.
710  IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true);
711  IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width);
712  IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, ImGuiAlign align = ImGuiAlign_Default, const ImVec2* clip_min = NULL, const ImVec2* clip_max = NULL);
713  IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f);
714  IMGUI_API void RenderCollapseTriangle(ImVec2 pos, bool is_open, float scale = 1.0f, bool shadow = false);
715  IMGUI_API void RenderBullet(ImVec2 pos);
716  IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col);
717  IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text.
718 
719  IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0);
720  IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0);
721  IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius);
722 
723  IMGUI_API bool SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags = 0);
724  IMGUI_API bool SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power);
725  IMGUI_API bool SliderIntN(const char* label, int* v, int components, int v_min, int v_max, const char* display_format);
726 
727  IMGUI_API bool DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_speed, float v_min, float v_max, int decimal_precision, float power);
728  IMGUI_API bool DragFloatN(const char* label, float* v, int components, float v_speed, float v_min, float v_max, const char* display_format, float power);
729  IMGUI_API bool DragIntN(const char* label, int* v, int components, float v_speed, int v_min, int v_max, const char* display_format);
730 
731  IMGUI_API bool InputTextEx(const char* label, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback = NULL, void* user_data = NULL);
732  IMGUI_API bool InputFloatN(const char* label, float* v, int components, int decimal_precision, ImGuiInputTextFlags extra_flags);
733  IMGUI_API bool InputIntN(const char* label, int* v, int components, ImGuiInputTextFlags extra_flags);
734  IMGUI_API bool InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags);
735  IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision);
736 
737  IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL);
738  IMGUI_API bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextTreeNodeOpened() data, if any. May return true when logging
739  IMGUI_API void TreePushRawID(ImGuiID id);
740 
741  IMGUI_API void PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size);
742 
743  IMGUI_API int ParseFormatPrecision(const char* fmt, int default_value);
744  IMGUI_API float RoundScalar(float value, int decimal_precision);
745 
746 } // namespace ImGui
747 
748 #ifdef __clang__
749 #pragma clang diagnostic pop
750 #endif
751 
752 #ifdef _MSC_VER
753 #pragma warning (pop)
754 #endif
Definition: imgui_internal.h:313
Definition: imgui.h:88
Definition: imgui_internal.h:241
constexpr const T & max(const T &lhs, const T &rhs)
Returns the greatest value of the two given.
Definition: algorithm.hpp:212
Definition: imgui_internal.h:513
Definition: imgui.h:701
Definition: imgui.h:975
Definition: imgui.h:1166
Definition: imgui.cpp:7351
Definition: imgui_internal.h:595
Definition: imgui_internal.h:332
Definition: imgui_internal.h:274
constexpr const T & min(const T &lhs, const T &rhs)
Returns the smallest value of the two given.
Definition: algorithm.hpp:261
Definition: datamodel.hpp:22
Definition: imgui.h:98
Definition: imgui.h:1249
Definition: imgui.h:950
Definition: imgui_internal.h:248
Definition: imgui_internal.h:322
Definition: imgui_internal.h:312
Definition: imgui-SFML.cpp:41
Definition: imgui.h:1344
Definition: imgui_internal.h:255
Definition: imgui.h:732
Definition: imgui_internal.h:200
Definition: imgui_internal.h:344
Definition: imgui_internal.h:267
Definition: imgui_internal.h:288