imgui.cpp
Go to the documentation of this file.
1 // dear imgui, v1.76 WIP
2 // (main code and documentation)
3 
4 // Help:
5 // - Read FAQ at http://dearimgui.org/faq
6 // - Newcomers, read 'Programmer guide' below for notes on how to setup Dear ImGui in your codebase.
7 // - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code. All applications in examples/ are doing that.
8 // Read imgui.cpp for details, links and comments.
9 
10 // Resources:
11 // - FAQ http://dearimgui.org/faq
12 // - Homepage & latest https://github.com/ocornut/imgui
13 // - Releases & changelog https://github.com/ocornut/imgui/releases
14 // - Gallery https://github.com/ocornut/imgui/issues/3075 (please post your screenshots/video there!)
15 // - Glossary https://github.com/ocornut/imgui/wiki/Glossary
16 // - Wiki https://github.com/ocornut/imgui/wiki
17 // - Issues & support https://github.com/ocornut/imgui/issues
18 
19 // Developed by Omar Cornut and every direct or indirect contributors to the GitHub.
20 // See LICENSE.txt for copyright and licensing details (standard MIT License).
21 // This library is free but I need your support to sustain development and maintenance.
22 // Businesses: you can support continued development via invoiced technical support, maintenance and sponsoring contracts. Please reach out to "contact AT dearimgui.org".
23 // Individuals: you can support continued development via donations. See docs/README or web page.
24 
25 // It is recommended that you don't modify imgui.cpp! It will become difficult for you to update the library.
26 // Note that 'ImGui::' being a namespace, you can add functions into the namespace from your own source files, without
27 // modifying imgui.h or imgui.cpp. You may include imgui_internal.h to access internal data structures, but it doesn't
28 // come with any guarantee of forward compatibility. Discussing your changes on the GitHub Issue Tracker may lead you
29 // to a better solution or official support for them.
30 
31 /*
32 
33 Index of this file:
34 
35 DOCUMENTATION
36 
37 - MISSION STATEMENT
38 - END-USER GUIDE
39 - PROGRAMMER GUIDE
40  - READ FIRST
41  - HOW TO UPDATE TO A NEWER VERSION OF DEAR IMGUI
42  - GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE/ENGINE
43  - HOW A SIMPLE APPLICATION MAY LOOK LIKE (2 variations)
44  - HOW A SIMPLE RENDERING FUNCTION MAY LOOK LIKE
45  - USING GAMEPAD/KEYBOARD NAVIGATION CONTROLS
46 - API BREAKING CHANGES (read me when you update!)
47 - FREQUENTLY ASKED QUESTIONS (FAQ)
48  - Read all answers online: https://www.dearimgui.org/faq, or in docs/FAQ.md (with a Markdown viewer)
49 
50 CODE
51 (search for "[SECTION]" in the code to find them)
52 
53 // [SECTION] INCLUDES
54 // [SECTION] FORWARD DECLARATIONS
55 // [SECTION] CONTEXT AND MEMORY ALLOCATORS
56 // [SECTION] USER FACING STRUCTURES (ImGuiStyle, ImGuiIO)
57 // [SECTION] MISC HELPERS/UTILITIES (Geometry functions)
58 // [SECTION] MISC HELPERS/UTILITIES (String, Format, Hash functions)
59 // [SECTION] MISC HELPERS/UTILITIES (File functions)
60 // [SECTION] MISC HELPERS/UTILITIES (ImText* functions)
61 // [SECTION] MISC HELPERS/UTILITIES (Color functions)
62 // [SECTION] ImGuiStorage
63 // [SECTION] ImGuiTextFilter
64 // [SECTION] ImGuiTextBuffer
65 // [SECTION] ImGuiListClipper
66 // [SECTION] STYLING
67 // [SECTION] RENDER HELPERS
68 // [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!)
69 // [SECTION] ERROR CHECKING
70 // [SECTION] LAYOUT
71 // [SECTION] SCROLLING
72 // [SECTION] TOOLTIPS
73 // [SECTION] POPUPS
74 // [SECTION] KEYBOARD/GAMEPAD NAVIGATION
75 // [SECTION] DRAG AND DROP
76 // [SECTION] LOGGING/CAPTURING
77 // [SECTION] SETTINGS
78 // [SECTION] PLATFORM DEPENDENT HELPERS
79 // [SECTION] METRICS/DEBUG WINDOW
80 
81 */
82 
83 //-----------------------------------------------------------------------------
84 // DOCUMENTATION
85 //-----------------------------------------------------------------------------
86 
87 /*
88 
89  MISSION STATEMENT
90  =================
91 
92  - Easy to use to create code-driven and data-driven tools.
93  - Easy to use to create ad hoc short-lived tools and long-lived, more elaborate tools.
94  - Easy to hack and improve.
95  - Minimize screen real-estate usage.
96  - Minimize setup and maintenance.
97  - Minimize state storage on user side.
98  - Portable, minimize dependencies, run on target (consoles, phones, etc.).
99  - Efficient runtime and memory consumption (NB- we do allocate when "growing" content e.g. creating a window,.
100  opening a tree node for the first time, etc. but a typical frame should not allocate anything).
101 
102  Designed for developers and content-creators, not the typical end-user! Some of the weaknesses includes:
103  - Doesn't look fancy, doesn't animate.
104  - Limited layout features, intricate layouts are typically crafted in code.
105 
106 
107  END-USER GUIDE
108  ==============
109 
110  - Double-click on title bar to collapse window.
111  - Click upper right corner to close a window, available when 'bool* p_open' is passed to ImGui::Begin().
112  - Click and drag on lower right corner to resize window (double-click to auto fit window to its contents).
113  - Click and drag on any empty space to move window.
114  - TAB/SHIFT+TAB to cycle through keyboard editable fields.
115  - CTRL+Click on a slider or drag box to input value as text.
116  - Use mouse wheel to scroll.
117  - Text editor:
118  - Hold SHIFT or use mouse to select text.
119  - CTRL+Left/Right to word jump.
120  - CTRL+Shift+Left/Right to select words.
121  - CTRL+A our Double-Click to select all.
122  - CTRL+X,CTRL+C,CTRL+V to use OS clipboard/
123  - CTRL+Z,CTRL+Y to undo/redo.
124  - ESCAPE to revert text to its original value.
125  - You can apply arithmetic operators +,*,/ on numerical values. Use +- to subtract (because - would set a negative value!)
126  - Controls are automatically adjusted for OSX to match standard OSX text editing operations.
127  - General Keyboard controls: enable with ImGuiConfigFlags_NavEnableKeyboard.
128  - General Gamepad controls: enable with ImGuiConfigFlags_NavEnableGamepad. See suggested mappings in imgui.h ImGuiNavInput_ + download PNG/PSD at http://goo.gl/9LgVZW
129 
130 
131  PROGRAMMER GUIDE
132  ================
133 
134  READ FIRST
135  ----------
136  - Remember to read the FAQ (https://www.dearimgui.org/faq)
137  - Your code creates the UI, if your code doesn't run the UI is gone! The UI can be highly dynamic, there are no construction
138  or destruction steps, less superfluous data retention on your side, less state duplication, less state synchronization, less bugs.
139  - Call and read ImGui::ShowDemoWindow() for demo code demonstrating most features.
140  - The library is designed to be built from sources. Avoid pre-compiled binaries and packaged versions. See imconfig.h to configure your build.
141  - Dear ImGui is an implementation of the IMGUI paradigm (immediate-mode graphical user interface, a term coined by Casey Muratori).
142  You can learn about IMGUI principles at http://www.johno.se/book/imgui.html, http://mollyrocket.com/861 & more links docs/README.md.
143  - Dear ImGui is a "single pass" rasterizing implementation of the IMGUI paradigm, aimed at ease of use and high-performances.
144  For every application frame your UI code will be called only once. This is in contrast to e.g. Unity's own implementation of an IMGUI,
145  where the UI code is called multiple times ("multiple passes") from a single entry point. There are pros and cons to both approaches.
146  - Our origin are on the top-left. In axis aligned bounding boxes, Min = top-left, Max = bottom-right.
147  - This codebase is also optimized to yield decent performances with typical "Debug" builds settings.
148  - Please make sure you have asserts enabled (IM_ASSERT redirects to assert() by default, but can be redirected).
149  If you get an assert, read the messages and comments around the assert.
150  - C++: this is a very C-ish codebase: we don't rely on C++11, we don't include any C++ headers, and ImGui:: is a namespace.
151  - C++: ImVec2/ImVec4 do not expose math operators by default, because it is expected that you use your own math types.
152  See FAQ "How can I use my own math types instead of ImVec2/ImVec4?" for details about setting up imconfig.h for that.
153  However, imgui_internal.h can optionally export math operators for ImVec2/ImVec4, which we use in this codebase.
154  - C++: pay attention that ImVector<> manipulates plain-old-data and does not honor construction/destruction (avoid using it in your code!).
155 
156  HOW TO UPDATE TO A NEWER VERSION OF DEAR IMGUI
157  ----------------------------------------------
158  - Overwrite all the sources files except for imconfig.h (if you have made modification to your copy of imconfig.h)
159  - Or maintain your own branch where you have imconfig.h modified.
160  - Read the "API BREAKING CHANGES" section (below). This is where we list occasional API breaking changes.
161  If a function/type has been renamed / or marked obsolete, try to fix the name in your code before it is permanently removed
162  from the public API. If you have a problem with a missing function/symbols, search for its name in the code, there will
163  likely be a comment about it. Please report any issue to the GitHub page!
164  - Try to keep your copy of dear imgui reasonably up to date.
165 
166  GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE/ENGINE
167  ---------------------------------------------------------------
168  - Run and study the examples and demo in imgui_demo.cpp to get acquainted with the library.
169  - In the majority of cases you should be able to use unmodified back-ends files available in the examples/ folder.
170  - Add the Dear ImGui source files to your projects or using your preferred build system.
171  It is recommended you build and statically link the .cpp files as part of your project and NOT as shared library (DLL).
172  - You can later customize the imconfig.h file to tweak some compile-time behavior, such as integrating Dear ImGui types with your own maths types.
173  - When using Dear ImGui, your programming IDE is your friend: follow the declaration of variables, functions and types to find comments about them.
174  - Dear ImGui never touches or knows about your GPU state. The only function that knows about GPU is the draw function that you provide.
175  Effectively it means you can create widgets at any time in your code, regardless of considerations of being in "update" vs "render"
176  phases of your own application. All rendering information are stored into command-lists that you will retrieve after calling ImGui::Render().
177  - Refer to the bindings and demo applications in the examples/ folder for instruction on how to setup your code.
178  - If you are running over a standard OS with a common graphics API, you should be able to use unmodified imgui_impl_*** files from the examples/ folder.
179 
180  HOW A SIMPLE APPLICATION MAY LOOK LIKE
181  --------------------------------------
182  EXHIBIT 1: USING THE EXAMPLE BINDINGS (imgui_impl_XXX.cpp files from the examples/ folder).
183 
184  // Application init: create a dear imgui context, setup some options, load fonts
185  ImGui::CreateContext();
186  ImGuiIO& io = ImGui::GetIO();
187  // TODO: Set optional io.ConfigFlags values, e.g. 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard' to enable keyboard controls.
188  // TODO: Fill optional fields of the io structure later.
189  // TODO: Load TTF/OTF fonts if you don't want to use the default font.
190 
191  // Initialize helper Platform and Renderer bindings (here we are using imgui_impl_win32.cpp and imgui_impl_dx11.cpp)
192  ImGui_ImplWin32_Init(hwnd);
193  ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);
194 
195  // Application main loop
196  while (true)
197  {
198  // Feed inputs to dear imgui, start new frame
199  ImGui_ImplDX11_NewFrame();
200  ImGui_ImplWin32_NewFrame();
201  ImGui::NewFrame();
202 
203  // Any application code here
204  ImGui::Text("Hello, world!");
205 
206  // Render dear imgui into screen
207  ImGui::Render();
208  ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
209  g_pSwapChain->Present(1, 0);
210  }
211 
212  // Shutdown
213  ImGui_ImplDX11_Shutdown();
214  ImGui_ImplWin32_Shutdown();
215  ImGui::DestroyContext();
216 
217  EXHIBIT 2: IMPLEMENTING CUSTOM BINDING / CUSTOM ENGINE
218 
219  // Application init: create a dear imgui context, setup some options, load fonts
220  ImGui::CreateContext();
221  ImGuiIO& io = ImGui::GetIO();
222  // TODO: Set optional io.ConfigFlags values, e.g. 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard' to enable keyboard controls.
223  // TODO: Fill optional fields of the io structure later.
224  // TODO: Load TTF/OTF fonts if you don't want to use the default font.
225 
226  // Build and load the texture atlas into a texture
227  // (In the examples/ app this is usually done within the ImGui_ImplXXX_Init() function from one of the demo Renderer)
228  int width, height;
229  unsigned char* pixels = NULL;
230  io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
231 
232  // At this point you've got the texture data and you need to upload that your your graphic system:
233  // After we have created the texture, store its pointer/identifier (_in whichever format your engine uses_) in 'io.Fonts->TexID'.
234  // This will be passed back to your via the renderer. Basically ImTextureID == void*. Read FAQ for details about ImTextureID.
235  MyTexture* texture = MyEngine::CreateTextureFromMemoryPixels(pixels, width, height, TEXTURE_TYPE_RGBA32)
236  io.Fonts->TexID = (void*)texture;
237 
238  // Application main loop
239  while (true)
240  {
241  // Setup low-level inputs, e.g. on Win32: calling GetKeyboardState(), or write to those fields from your Windows message handlers, etc.
242  // (In the examples/ app this is usually done within the ImGui_ImplXXX_NewFrame() function from one of the demo Platform bindings)
243  io.DeltaTime = 1.0f/60.0f; // set the time elapsed since the previous frame (in seconds)
244  io.DisplaySize.x = 1920.0f; // set the current display width
245  io.DisplaySize.y = 1280.0f; // set the current display height here
246  io.MousePos = my_mouse_pos; // set the mouse position
247  io.MouseDown[0] = my_mouse_buttons[0]; // set the mouse button states
248  io.MouseDown[1] = my_mouse_buttons[1];
249 
250  // Call NewFrame(), after this point you can use ImGui::* functions anytime
251  // (So you want to try calling NewFrame() as early as you can in your mainloop to be able to use Dear ImGui everywhere)
252  ImGui::NewFrame();
253 
254  // Most of your application code here
255  ImGui::Text("Hello, world!");
256  MyGameUpdate(); // may use any Dear ImGui functions, e.g. ImGui::Begin("My window"); ImGui::Text("Hello, world!"); ImGui::End();
257  MyGameRender(); // may use any Dear ImGui functions as well!
258 
259  // Render dear imgui, swap buffers
260  // (You want to try calling EndFrame/Render as late as you can, to be able to use Dear ImGui in your own game rendering code)
261  ImGui::EndFrame();
262  ImGui::Render();
263  ImDrawData* draw_data = ImGui::GetDrawData();
264  MyImGuiRenderFunction(draw_data);
265  SwapBuffers();
266  }
267 
268  // Shutdown
269  ImGui::DestroyContext();
270 
271  HOW A SIMPLE RENDERING FUNCTION MAY LOOK LIKE
272  ---------------------------------------------
273  void void MyImGuiRenderFunction(ImDrawData* draw_data)
274  {
275  // TODO: Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
276  // TODO: Setup viewport covering draw_data->DisplayPos to draw_data->DisplayPos + draw_data->DisplaySize
277  // TODO: Setup orthographic projection matrix cover draw_data->DisplayPos to draw_data->DisplayPos + draw_data->DisplaySize
278  // TODO: Setup shader: vertex { float2 pos, float2 uv, u32 color }, fragment shader sample color from 1 texture, multiply by vertex color.
279  for (int n = 0; n < draw_data->CmdListsCount; n++)
280  {
281  const ImDrawList* cmd_list = draw_data->CmdLists[n];
282  const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; // vertex buffer generated by Dear ImGui
283  const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; // index buffer generated by Dear ImGui
284  for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
285  {
286  const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
287  if (pcmd->UserCallback)
288  {
289  pcmd->UserCallback(cmd_list, pcmd);
290  }
291  else
292  {
293  // The texture for the draw call is specified by pcmd->TextureId.
294  // The vast majority of draw calls will use the Dear ImGui texture atlas, which value you have set yourself during initialization.
295  MyEngineBindTexture((MyTexture*)pcmd->TextureId);
296 
297  // We are using scissoring to clip some objects. All low-level graphics API should supports it.
298  // - If your engine doesn't support scissoring yet, you may ignore this at first. You will get some small glitches
299  // (some elements visible outside their bounds) but you can fix that once everything else works!
300  // - Clipping coordinates are provided in imgui coordinates space (from draw_data->DisplayPos to draw_data->DisplayPos + draw_data->DisplaySize)
301  // In a single viewport application, draw_data->DisplayPos will always be (0,0) and draw_data->DisplaySize will always be == io.DisplaySize.
302  // However, in the interest of supporting multi-viewport applications in the future (see 'viewport' branch on github),
303  // always subtract draw_data->DisplayPos from clipping bounds to convert them to your viewport space.
304  // - Note that pcmd->ClipRect contains Min+Max bounds. Some graphics API may use Min+Max, other may use Min+Size (size being Max-Min)
305  ImVec2 pos = draw_data->DisplayPos;
306  MyEngineScissor((int)(pcmd->ClipRect.x - pos.x), (int)(pcmd->ClipRect.y - pos.y), (int)(pcmd->ClipRect.z - pos.x), (int)(pcmd->ClipRect.w - pos.y));
307 
308  // Render 'pcmd->ElemCount/3' indexed triangles.
309  // By default the indices ImDrawIdx are 16-bit, you can change them to 32-bit in imconfig.h if your engine doesn't support 16-bit indices.
310  MyEngineDrawIndexedTriangles(pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer, vtx_buffer);
311  }
312  idx_buffer += pcmd->ElemCount;
313  }
314  }
315  }
316 
317  - The examples/ folders contains many actual implementation of the pseudo-codes above.
318  - When calling NewFrame(), the 'io.WantCaptureMouse', 'io.WantCaptureKeyboard' and 'io.WantTextInput' flags are updated.
319  They tell you if Dear ImGui intends to use your inputs. When a flag is set you want to hide the corresponding inputs from the
320  rest of your application. In every cases you need to pass on the inputs to Dear ImGui.
321  - Refer to the FAQ for more information. Amusingly, it is called a FAQ because people frequently run into the same issues!
322 
323  USING GAMEPAD/KEYBOARD NAVIGATION CONTROLS
324  ------------------------------------------
325  - The gamepad/keyboard navigation is fairly functional and keeps being improved.
326  - Gamepad support is particularly useful to use Dear ImGui on a console system (e.g. PS4, Switch, XB1) without a mouse!
327  - You can ask questions and report issues at https://github.com/ocornut/imgui/issues/787
328  - The initial focus was to support game controllers, but keyboard is becoming increasingly and decently usable.
329  - Keyboard:
330  - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable.
331  NewFrame() will automatically fill io.NavInputs[] based on your io.KeysDown[] + io.KeyMap[] arrays.
332  - When keyboard navigation is active (io.NavActive + ImGuiConfigFlags_NavEnableKeyboard), the io.WantCaptureKeyboard flag
333  will be set. For more advanced uses, you may want to read from:
334  - io.NavActive: true when a window is focused and it doesn't have the ImGuiWindowFlags_NoNavInputs flag set.
335  - io.NavVisible: true when the navigation cursor is visible (and usually goes false when mouse is used).
336  - or query focus information with e.g. IsWindowFocused(ImGuiFocusedFlags_AnyWindow), IsItemFocused() etc. functions.
337  Please reach out if you think the game vs navigation input sharing could be improved.
338  - Gamepad:
339  - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad to enable.
340  - Backend: Set io.BackendFlags |= ImGuiBackendFlags_HasGamepad + fill the io.NavInputs[] fields before calling NewFrame().
341  Note that io.NavInputs[] is cleared by EndFrame().
342  - See 'enum ImGuiNavInput_' in imgui.h for a description of inputs. For each entry of io.NavInputs[], set the following values:
343  0.0f= not held. 1.0f= fully held. Pass intermediate 0.0f..1.0f values for analog triggers/sticks.
344  - We uses a simple >0.0f test for activation testing, and won't attempt to test for a dead-zone.
345  Your code will probably need to transform your raw inputs (such as e.g. remapping your 0.2..0.9 raw input range to 0.0..1.0 imgui range, etc.).
346  - You can download PNG/PSD files depicting the gamepad controls for common controllers at: http://goo.gl/9LgVZW.
347  - If you need to share inputs between your game and the imgui parts, the easiest approach is to go all-or-nothing, with a buttons combo
348  to toggle the target. Please reach out if you think the game vs navigation input sharing could be improved.
349  - Mouse:
350  - PS4 users: Consider emulating a mouse cursor with DualShock4 touch pad or a spare analog stick as a mouse-emulation fallback.
351  - Consoles/Tablet/Phone users: Consider using a Synergy 1.x server (on your PC) + uSynergy.c (on your console/tablet/phone app) to share your PC mouse/keyboard.
352  - On a TV/console system where readability may be lower or mouse inputs may be awkward, you may want to set the ImGuiConfigFlags_NavEnableSetMousePos flag.
353  Enabling ImGuiConfigFlags_NavEnableSetMousePos + ImGuiBackendFlags_HasSetMousePos instructs dear imgui to move your mouse cursor along with navigation movements.
354  When enabled, the NewFrame() function may alter 'io.MousePos' and set 'io.WantSetMousePos' to notify you that it wants the mouse cursor to be moved.
355  When that happens your back-end NEEDS to move the OS or underlying mouse cursor on the next frame. Some of the binding in examples/ do that.
356  (If you set the NavEnableSetMousePos flag but don't honor 'io.WantSetMousePos' properly, imgui will misbehave as it will see your mouse as moving back and forth!)
357  (In a setup when you may not have easy control over the mouse cursor, e.g. uSynergy.c doesn't expose moving remote mouse cursor, you may want
358  to set a boolean to ignore your other external mouse positions until the external source is moved again.)
359 
360 
361  API BREAKING CHANGES
362  ====================
363 
364  Occasionally introducing changes that are breaking the API. We try to make the breakage minor and easy to fix.
365  Below is a change-log of API breaking changes only. If you are using one of the functions listed, expect to have to fix some code.
366  When you are not sure about a old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
367  You can read releases logs https://github.com/ocornut/imgui/releases for more details.
368 
369  - 2020/01/22 (1.75) - ImDrawList::AddCircle()/AddCircleFilled() functions don't accept negative radius any more.
370  - 2019/12/17 (1.75) - made Columns() limited to 64 columns by asserting above that limit. While the current code technically supports it, future code may not so we're putting the restriction ahead.
371  - 2019/12/13 (1.75) - [imgui_internal.h] changed ImRect() default constructor initializes all fields to 0.0f instead of (FLT_MAX,FLT_MAX,-FLT_MAX,-FLT_MAX). If you used ImRect::Add() to create bounding boxes by adding multiple points into it, you may need to fix your initial value.
372  - 2019/12/08 (1.75) - removed redirecting functions/enums that were marked obsolete in 1.53 (December 2017):
373  - ShowTestWindow() -> use ShowDemoWindow()
374  - IsRootWindowFocused() -> use IsWindowFocused(ImGuiFocusedFlags_RootWindow)
375  - IsRootWindowOrAnyChildFocused() -> use IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows)
376  - SetNextWindowContentWidth(w) -> use SetNextWindowContentSize(ImVec2(w, 0.0f)
377  - GetItemsLineHeightWithSpacing() -> use GetFrameHeightWithSpacing()
378  - ImGuiCol_ChildWindowBg -> use ImGuiCol_ChildBg
379  - ImGuiStyleVar_ChildWindowRounding -> use ImGuiStyleVar_ChildRounding
380  - ImGuiTreeNodeFlags_AllowOverlapMode -> use ImGuiTreeNodeFlags_AllowItemOverlap
381  - IMGUI_DISABLE_TEST_WINDOWS -> use IMGUI_DISABLE_DEMO_WINDOWS
382  - 2019/12/08 (1.75) - obsoleted calling ImDrawList::PrimReserve() with a negative count (which was the vaguely documented and rarely if ever used). Instead we added an explicit PrimUnreserve() API.
383  - 2019/12/06 (1.75) - removed implicit default parameter to IsMouseDragging(int button = 0) to be consistent with other mouse functions (none of the other functions have it).
384  - 2019/11/21 (1.74) - ImFontAtlas::AddCustomRectRegular() now requires an ID larger than 0x110000 (instead of 0x10000) to conform with supporting Unicode planes 1-16 in a future update. ID below 0x110000 will now assert.
385  - 2019/11/19 (1.74) - renamed IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS to IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS for consistency.
386  - 2019/11/19 (1.74) - renamed IMGUI_DISABLE_MATH_FUNCTIONS to IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS for consistency.
387  - 2019/10/22 (1.74) - removed redirecting functions/enums that were marked obsolete in 1.52 (October 2017):
388  - Begin() [old 5 args version] -> use Begin() [3 args], use SetNextWindowSize() SetNextWindowBgAlpha() if needed
389  - IsRootWindowOrAnyChildHovered() -> use IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows)
390  - AlignFirstTextHeightToWidgets() -> use AlignTextToFramePadding()
391  - SetNextWindowPosCenter() -> use SetNextWindowPos() with a pivot of (0.5f, 0.5f)
392  - ImFont::Glyph -> use ImFontGlyph
393  - 2019/10/14 (1.74) - inputs: Fixed a miscalculation in the keyboard/mouse "typematic" repeat delay/rate calculation, used by keys and e.g. repeating mouse buttons as well as the GetKeyPressedAmount() function.
394  if you were using a non-default value for io.KeyRepeatRate (previous default was 0.250), you can add +io.KeyRepeatDelay to it to compensate for the fix.
395  The function was triggering on: 0.0 and (delay+rate*N) where (N>=1). Fixed formula responds to (N>=0). Effectively it made io.KeyRepeatRate behave like it was set to (io.KeyRepeatRate + io.KeyRepeatDelay).
396  If you never altered io.KeyRepeatRate nor used GetKeyPressedAmount() this won't affect you.
397  - 2019/07/15 (1.72) - removed TreeAdvanceToLabelPos() which is rarely used and only does SetCursorPosX(GetCursorPosX() + GetTreeNodeToLabelSpacing()). Kept redirection function (will obsolete).
398  - 2019/07/12 (1.72) - renamed ImFontAtlas::CustomRect to ImFontAtlasCustomRect. Kept redirection typedef (will obsolete).
399  - 2019/06/14 (1.72) - removed redirecting functions/enums names that were marked obsolete in 1.51 (June 2017): ImGuiCol_Column*, ImGuiSetCond_*, IsItemHoveredRect(), IsPosHoveringAnyWindow(), IsMouseHoveringAnyWindow(), IsMouseHoveringWindow(), IMGUI_ONCE_UPON_A_FRAME. Grep this log for details and new names, or see how they were implemented until 1.71.
400  - 2019/06/07 (1.71) - rendering of child window outer decorations (bg color, border, scrollbars) is now performed as part of the parent window. If you have
401  overlapping child windows in a same parent, and relied on their relative z-order to be mapped to their submission order, this will affect your rendering.
402  This optimization is disabled if the parent window has no visual output, because it appears to be the most common situation leading to the creation of overlapping child windows.
403  Please reach out if you are affected.
404  - 2019/05/13 (1.71) - renamed SetNextTreeNodeOpen() to SetNextItemOpen(). Kept inline redirection function (will obsolete).
405  - 2019/05/11 (1.71) - changed io.AddInputCharacter(unsigned short c) signature to io.AddInputCharacter(unsigned int c).
406  - 2019/04/29 (1.70) - improved ImDrawList thick strokes (>1.0f) preserving correct thickness up to 90 degrees angles (e.g. rectangles). If you have custom rendering using thick lines, they will appear thicker now.
407  - 2019/04/29 (1.70) - removed GetContentRegionAvailWidth(), use GetContentRegionAvail().x instead. Kept inline redirection function (will obsolete).
408  - 2019/03/04 (1.69) - renamed GetOverlayDrawList() to GetForegroundDrawList(). Kept redirection function (will obsolete).
409  - 2019/02/26 (1.69) - renamed ImGuiColorEditFlags_RGB/ImGuiColorEditFlags_HSV/ImGuiColorEditFlags_HEX to ImGuiColorEditFlags_DisplayRGB/ImGuiColorEditFlags_DisplayHSV/ImGuiColorEditFlags_DisplayHex. Kept redirection enums (will obsolete).
410  - 2019/02/14 (1.68) - made it illegal/assert when io.DisplayTime == 0.0f (with an exception for the first frame). If for some reason your time step calculation gives you a zero value, replace it with a dummy small value!
411  - 2019/02/01 (1.68) - removed io.DisplayVisibleMin/DisplayVisibleMax (which were marked obsolete and removed from viewport/docking branch already).
412  - 2019/01/06 (1.67) - renamed io.InputCharacters[], marked internal as was always intended. Please don't access directly, and use AddInputCharacter() instead!
413  - 2019/01/06 (1.67) - renamed ImFontAtlas::GlyphRangesBuilder to ImFontGlyphRangesBuilder. Kept redirection typedef (will obsolete).
414  - 2018/12/20 (1.67) - made it illegal to call Begin("") with an empty string. This somehow half-worked before but had various undesirable side-effects.
415  - 2018/12/10 (1.67) - renamed io.ConfigResizeWindowsFromEdges to io.ConfigWindowsResizeFromEdges as we are doing a large pass on configuration flags.
416  - 2018/10/12 (1.66) - renamed misc/stl/imgui_stl.* to misc/cpp/imgui_stdlib.* in prevision for other C++ helper files.
417  - 2018/09/28 (1.66) - renamed SetScrollHere() to SetScrollHereY(). Kept redirection function (will obsolete).
418  - 2018/09/06 (1.65) - renamed stb_truetype.h to imstb_truetype.h, stb_textedit.h to imstb_textedit.h, and stb_rect_pack.h to imstb_rectpack.h.
419  If you were conveniently using the imgui copy of those STB headers in your project you will have to update your include paths.
420  - 2018/09/05 (1.65) - renamed io.OptCursorBlink/io.ConfigCursorBlink to io.ConfigInputTextCursorBlink. (#1427)
421  - 2018/08/31 (1.64) - added imgui_widgets.cpp file, extracted and moved widgets code out of imgui.cpp into imgui_widgets.cpp. Re-ordered some of the code remaining in imgui.cpp.
422  NONE OF THE FUNCTIONS HAVE CHANGED. THE CODE IS SEMANTICALLY 100% IDENTICAL, BUT _EVERY_ FUNCTION HAS BEEN MOVED.
423  Because of this, any local modifications to imgui.cpp will likely conflict when you update. Read docs/CHANGELOG.txt for suggestions.
424  - 2018/08/22 (1.63) - renamed IsItemDeactivatedAfterChange() to IsItemDeactivatedAfterEdit() for consistency with new IsItemEdited() API. Kept redirection function (will obsolete soonish as IsItemDeactivatedAfterChange() is very recent).
425  - 2018/08/21 (1.63) - renamed ImGuiTextEditCallback to ImGuiInputTextCallback, ImGuiTextEditCallbackData to ImGuiInputTextCallbackData for consistency. Kept redirection types (will obsolete).
426  - 2018/08/21 (1.63) - removed ImGuiInputTextCallbackData::ReadOnly since it is a duplication of (ImGuiInputTextCallbackData::Flags & ImGuiInputTextFlags_ReadOnly).
427  - 2018/08/01 (1.63) - removed per-window ImGuiWindowFlags_ResizeFromAnySide beta flag in favor of a global io.ConfigResizeWindowsFromEdges [update 1.67 renamed to ConfigWindowsResizeFromEdges] to enable the feature.
428  - 2018/08/01 (1.63) - renamed io.OptCursorBlink to io.ConfigCursorBlink [-> io.ConfigInputTextCursorBlink in 1.65], io.OptMacOSXBehaviors to ConfigMacOSXBehaviors for consistency.
429  - 2018/07/22 (1.63) - changed ImGui::GetTime() return value from float to double to avoid accumulating floating point imprecisions over time.
430  - 2018/07/08 (1.63) - style: renamed ImGuiCol_ModalWindowDarkening to ImGuiCol_ModalWindowDimBg for consistency with other features. Kept redirection enum (will obsolete).
431  - 2018/06/08 (1.62) - examples: the imgui_impl_xxx files have been split to separate platform (Win32, Glfw, SDL2, etc.) from renderer (DX11, OpenGL, Vulkan, etc.).
432  old bindings will still work as is, however prefer using the separated bindings as they will be updated to support multi-viewports.
433  when adopting new bindings follow the main.cpp code of your preferred examples/ folder to know which functions to call.
434  in particular, note that old bindings called ImGui::NewFrame() at the end of their ImGui_ImplXXXX_NewFrame() function.
435  - 2018/06/06 (1.62) - renamed GetGlyphRangesChinese() to GetGlyphRangesChineseFull() to distinguish other variants and discourage using the full set.
436  - 2018/06/06 (1.62) - TreeNodeEx()/TreeNodeBehavior(): the ImGuiTreeNodeFlags_CollapsingHeader helper now include the ImGuiTreeNodeFlags_NoTreePushOnOpen flag. See Changelog for details.
437  - 2018/05/03 (1.61) - DragInt(): the default compile-time format string has been changed from "%.0f" to "%d", as we are not using integers internally any more.
438  If you used DragInt() with custom format strings, make sure you change them to use %d or an integer-compatible format.
439  To honor backward-compatibility, the DragInt() code will currently parse and modify format strings to replace %*f with %d, giving time to users to upgrade their code.
440  If you have IMGUI_DISABLE_OBSOLETE_FUNCTIONS enabled, the code will instead assert! You may run a reg-exp search on your codebase for e.g. "DragInt.*%f" to help you find them.
441  - 2018/04/28 (1.61) - obsoleted InputFloat() functions taking an optional "int decimal_precision" in favor of an equivalent and more flexible "const char* format",
442  consistent with other functions. Kept redirection functions (will obsolete).
443  - 2018/04/09 (1.61) - IM_DELETE() helper function added in 1.60 doesn't clear the input _pointer_ reference, more consistent with expectation and allows passing r-value.
444  - 2018/03/20 (1.60) - renamed io.WantMoveMouse to io.WantSetMousePos for consistency and ease of understanding (was added in 1.52, _not_ used by core and only honored by some binding ahead of merging the Nav branch).
445  - 2018/03/12 (1.60) - removed ImGuiCol_CloseButton, ImGuiCol_CloseButtonActive, ImGuiCol_CloseButtonHovered as the closing cross uses regular button colors now.
446  - 2018/03/08 (1.60) - changed ImFont::DisplayOffset.y to default to 0 instead of +1. Fixed rounding of Ascent/Descent to match TrueType renderer. If you were adding or subtracting to ImFont::DisplayOffset check if your fonts are correctly aligned vertically.
447  - 2018/03/03 (1.60) - renamed ImGuiStyleVar_Count_ to ImGuiStyleVar_COUNT and ImGuiMouseCursor_Count_ to ImGuiMouseCursor_COUNT for consistency with other public enums.
448  - 2018/02/18 (1.60) - BeginDragDropSource(): temporarily removed the optional mouse_button=0 parameter because it is not really usable in many situations at the moment.
449  - 2018/02/16 (1.60) - obsoleted the io.RenderDrawListsFn callback, you can call your graphics engine render function after ImGui::Render(). Use ImGui::GetDrawData() to retrieve the ImDrawData* to display.
450  - 2018/02/07 (1.60) - reorganized context handling to be more explicit,
451  - YOU NOW NEED TO CALL ImGui::CreateContext() AT THE BEGINNING OF YOUR APP, AND CALL ImGui::DestroyContext() AT THE END.
452  - removed Shutdown() function, as DestroyContext() serve this purpose.
453  - you may pass a ImFontAtlas* pointer to CreateContext() to share a font atlas between contexts. Otherwise CreateContext() will create its own font atlas instance.
454  - removed allocator parameters from CreateContext(), they are now setup with SetAllocatorFunctions(), and shared by all contexts.
455  - removed the default global context and font atlas instance, which were confusing for users of DLL reloading and users of multiple contexts.
456  - 2018/01/31 (1.60) - moved sample TTF files from extra_fonts/ to misc/fonts/. If you loaded files directly from the imgui repo you may need to update your paths.
457  - 2018/01/11 (1.60) - obsoleted IsAnyWindowHovered() in favor of IsWindowHovered(ImGuiHoveredFlags_AnyWindow). Kept redirection function (will obsolete).
458  - 2018/01/11 (1.60) - obsoleted IsAnyWindowFocused() in favor of IsWindowFocused(ImGuiFocusedFlags_AnyWindow). Kept redirection function (will obsolete).
459  - 2018/01/03 (1.60) - renamed ImGuiSizeConstraintCallback to ImGuiSizeCallback, ImGuiSizeConstraintCallbackData to ImGuiSizeCallbackData.
460  - 2017/12/29 (1.60) - removed CalcItemRectClosestPoint() which was weird and not really used by anyone except demo code. If you need it it's easy to replicate on your side.
461  - 2017/12/24 (1.53) - renamed the emblematic ShowTestWindow() function to ShowDemoWindow(). Kept redirection function (will obsolete).
462  - 2017/12/21 (1.53) - ImDrawList: renamed style.AntiAliasedShapes to style.AntiAliasedFill for consistency and as a way to explicitly break code that manipulate those flag at runtime. You can now manipulate ImDrawList::Flags
463  - 2017/12/21 (1.53) - ImDrawList: removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Prefer manipulating ImDrawList::Flags if you need to toggle them during the frame.
464  - 2017/12/14 (1.53) - using the ImGuiWindowFlags_NoScrollWithMouse flag on a child window forwards the mouse wheel event to the parent window, unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set.
465  - 2017/12/13 (1.53) - renamed GetItemsLineHeightWithSpacing() to GetFrameHeightWithSpacing(). Kept redirection function (will obsolete).
466  - 2017/12/13 (1.53) - obsoleted IsRootWindowFocused() in favor of using IsWindowFocused(ImGuiFocusedFlags_RootWindow). Kept redirection function (will obsolete).
467  - obsoleted IsRootWindowOrAnyChildFocused() in favor of using IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows). Kept redirection function (will obsolete).
468  - 2017/12/12 (1.53) - renamed ImGuiTreeNodeFlags_AllowOverlapMode to ImGuiTreeNodeFlags_AllowItemOverlap. Kept redirection enum (will obsolete).
469  - 2017/12/10 (1.53) - removed SetNextWindowContentWidth(), prefer using SetNextWindowContentSize(). Kept redirection function (will obsolete).
470  - 2017/11/27 (1.53) - renamed ImGuiTextBuffer::append() helper to appendf(), appendv() to appendfv(). If you copied the 'Log' demo in your code, it uses appendv() so that needs to be renamed.
471  - 2017/11/18 (1.53) - Style, Begin: removed ImGuiWindowFlags_ShowBorders window flag. Borders are now fully set up in the ImGuiStyle structure (see e.g. style.FrameBorderSize, style.WindowBorderSize). Use ImGui::ShowStyleEditor() to look them up.
472  Please note that the style system will keep evolving (hopefully stabilizing in Q1 2018), and so custom styles will probably subtly break over time. It is recommended you use the StyleColorsClassic(), StyleColorsDark(), StyleColorsLight() functions.
473  - 2017/11/18 (1.53) - Style: removed ImGuiCol_ComboBg in favor of combo boxes using ImGuiCol_PopupBg for consistency.
474  - 2017/11/18 (1.53) - Style: renamed ImGuiCol_ChildWindowBg to ImGuiCol_ChildBg.
475  - 2017/11/18 (1.53) - Style: renamed style.ChildWindowRounding to style.ChildRounding, ImGuiStyleVar_ChildWindowRounding to ImGuiStyleVar_ChildRounding.
476  - 2017/11/02 (1.53) - obsoleted IsRootWindowOrAnyChildHovered() in favor of using IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows);
477  - 2017/10/24 (1.52) - renamed IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS to IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS/IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS for consistency.
478  - 2017/10/20 (1.52) - changed IsWindowHovered() default parameters behavior to return false if an item is active in another window (e.g. click-dragging item from another window to this window). You can use the newly introduced IsWindowHovered() flags to requests this specific behavior if you need it.
479  - 2017/10/20 (1.52) - marked IsItemHoveredRect()/IsMouseHoveringWindow() as obsolete, in favor of using the newly introduced flags for IsItemHovered() and IsWindowHovered(). See https://github.com/ocornut/imgui/issues/1382 for details.
480  removed the IsItemRectHovered()/IsWindowRectHovered() names introduced in 1.51 since they were merely more consistent names for the two functions we are now obsoleting.
481  IsItemHoveredRect() --> IsItemHovered(ImGuiHoveredFlags_RectOnly)
482  IsMouseHoveringAnyWindow() --> IsWindowHovered(ImGuiHoveredFlags_AnyWindow)
483  IsMouseHoveringWindow() --> IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) [weird, old behavior]
484  - 2017/10/17 (1.52) - marked the old 5-parameters version of Begin() as obsolete (still available). Use SetNextWindowSize()+Begin() instead!
485  - 2017/10/11 (1.52) - renamed AlignFirstTextHeightToWidgets() to AlignTextToFramePadding(). Kept inline redirection function (will obsolete).
486  - 2017/09/26 (1.52) - renamed ImFont::Glyph to ImFontGlyph. Kept redirection typedef (will obsolete).
487  - 2017/09/25 (1.52) - removed SetNextWindowPosCenter() because SetNextWindowPos() now has the optional pivot information to do the same and more. Kept redirection function (will obsolete).
488  - 2017/08/25 (1.52) - io.MousePos needs to be set to ImVec2(-FLT_MAX,-FLT_MAX) when mouse is unavailable/missing. Previously ImVec2(-1,-1) was enough but we now accept negative mouse coordinates. In your binding if you need to support unavailable mouse, make sure to replace "io.MousePos = ImVec2(-1,-1)" with "io.MousePos = ImVec2(-FLT_MAX,-FLT_MAX)".
489  - 2017/08/22 (1.51) - renamed IsItemHoveredRect() to IsItemRectHovered(). Kept inline redirection function (will obsolete). -> (1.52) use IsItemHovered(ImGuiHoveredFlags_RectOnly)!
490  - renamed IsMouseHoveringAnyWindow() to IsAnyWindowHovered() for consistency. Kept inline redirection function (will obsolete).
491  - renamed IsMouseHoveringWindow() to IsWindowRectHovered() for consistency. Kept inline redirection function (will obsolete).
492  - 2017/08/20 (1.51) - renamed GetStyleColName() to GetStyleColorName() for consistency.
493  - 2017/08/20 (1.51) - added PushStyleColor(ImGuiCol idx, ImU32 col) overload, which _might_ cause an "ambiguous call" compilation error if you are using ImColor() with implicit cast. Cast to ImU32 or ImVec4 explicily to fix.
494  - 2017/08/15 (1.51) - marked the weird IMGUI_ONCE_UPON_A_FRAME helper macro as obsolete. prefer using the more explicit ImGuiOnceUponAFrame type.
495  - 2017/08/15 (1.51) - changed parameter order for BeginPopupContextWindow() from (const char*,int buttons,bool also_over_items) to (const char*,int buttons,bool also_over_items). Note that most calls relied on default parameters completely.
496  - 2017/08/13 (1.51) - renamed ImGuiCol_Column to ImGuiCol_Separator, ImGuiCol_ColumnHovered to ImGuiCol_SeparatorHovered, ImGuiCol_ColumnActive to ImGuiCol_SeparatorActive. Kept redirection enums (will obsolete).
497  - 2017/08/11 (1.51) - renamed ImGuiSetCond_Always to ImGuiCond_Always, ImGuiSetCond_Once to ImGuiCond_Once, ImGuiSetCond_FirstUseEver to ImGuiCond_FirstUseEver, ImGuiSetCond_Appearing to ImGuiCond_Appearing. Kept redirection enums (will obsolete).
498  - 2017/08/09 (1.51) - removed ValueColor() helpers, they are equivalent to calling Text(label) + SameLine() + ColorButton().
499  - 2017/08/08 (1.51) - removed ColorEditMode() and ImGuiColorEditMode in favor of ImGuiColorEditFlags and parameters to the various Color*() functions. The SetColorEditOptions() allows to initialize default but the user can still change them with right-click context menu.
500  - changed prototype of 'ColorEdit4(const char* label, float col[4], bool show_alpha = true)' to 'ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0)', where passing flags = 0x01 is a safe no-op (hello dodgy backward compatibility!). - check and run the demo window, under "Color/Picker Widgets", to understand the various new options.
501  - changed prototype of rarely used 'ColorButton(ImVec4 col, bool small_height = false, bool outline_border = true)' to 'ColorButton(const char* desc_id, ImVec4 col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0,0))'
502  - 2017/07/20 (1.51) - removed IsPosHoveringAnyWindow(ImVec2), which was partly broken and misleading. ASSERT + redirect user to io.WantCaptureMouse
503  - 2017/05/26 (1.50) - removed ImFontConfig::MergeGlyphCenterV in favor of a more multipurpose ImFontConfig::GlyphOffset.
504  - 2017/05/01 (1.50) - renamed ImDrawList::PathFill() (rarely used directly) to ImDrawList::PathFillConvex() for clarity.
505  - 2016/11/06 (1.50) - BeginChild(const char*) now applies the stack id to the provided label, consistently with other functions as it should always have been. It shouldn't affect you unless (extremely unlikely) you were appending multiple times to a same child from different locations of the stack id. If that's the case, generate an id with GetId() and use it instead of passing string to BeginChild().
506  - 2016/10/15 (1.50) - avoid 'void* user_data' parameter to io.SetClipboardTextFn/io.GetClipboardTextFn pointers. We pass io.ClipboardUserData to it.
507  - 2016/09/25 (1.50) - style.WindowTitleAlign is now a ImVec2 (ImGuiAlign enum was removed). set to (0.5f,0.5f) for horizontal+vertical centering, (0.0f,0.0f) for upper-left, etc.
508  - 2016/07/30 (1.50) - SameLine(x) with x>0.0f is now relative to left of column/group if any, and not always to left of window. This was sort of always the intent and hopefully breakage should be minimal.
509  - 2016/05/12 (1.49) - title bar (using ImGuiCol_TitleBg/ImGuiCol_TitleBgActive colors) isn't rendered over a window background (ImGuiCol_WindowBg color) anymore.
510  If your TitleBg/TitleBgActive alpha was 1.0f or you are using the default theme it will not affect you, otherwise if <1.0f you need tweak your custom theme to readjust for the fact that we don't draw a WindowBg background behind the title bar.
511  This helper function will convert an old TitleBg/TitleBgActive color into a new one with the same visual output, given the OLD color and the OLD WindowBg color:
512  ImVec4 ConvertTitleBgCol(const ImVec4& win_bg_col, const ImVec4& title_bg_col) { float new_a = 1.0f - ((1.0f - win_bg_col.w) * (1.0f - title_bg_col.w)), k = title_bg_col.w / new_a; return ImVec4((win_bg_col.x * win_bg_col.w + title_bg_col.x) * k, (win_bg_col.y * win_bg_col.w + title_bg_col.y) * k, (win_bg_col.z * win_bg_col.w + title_bg_col.z) * k, new_a); }
513  If this is confusing, pick the RGB value from title bar from an old screenshot and apply this as TitleBg/TitleBgActive. Or you may just create TitleBgActive from a tweaked TitleBg color.
514  - 2016/05/07 (1.49) - removed confusing set of GetInternalState(), GetInternalStateSize(), SetInternalState() functions. Now using CreateContext(), DestroyContext(), GetCurrentContext(), SetCurrentContext().
515  - 2016/05/02 (1.49) - renamed SetNextTreeNodeOpened() to SetNextTreeNodeOpen(), no redirection.
516  - 2016/05/01 (1.49) - obsoleted old signature of CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false) as extra parameters were badly designed and rarely used. You can replace the "default_open = true" flag in new API with CollapsingHeader(label, ImGuiTreeNodeFlags_DefaultOpen).
517  - 2016/04/26 (1.49) - changed ImDrawList::PushClipRect(ImVec4 rect) to ImDrawList::PushClipRect(Imvec2 min,ImVec2 max,bool intersect_with_current_clip_rect=false). Note that higher-level ImGui::PushClipRect() is preferable because it will clip at logic/widget level, whereas ImDrawList::PushClipRect() only affect your renderer.
518  - 2016/04/03 (1.48) - removed style.WindowFillAlphaDefault setting which was redundant. Bake default BG alpha inside style.Colors[ImGuiCol_WindowBg] and all other Bg color values. (ref github issue #337).
519  - 2016/04/03 (1.48) - renamed ImGuiCol_TooltipBg to ImGuiCol_PopupBg, used by popups/menus and tooltips. popups/menus were previously using ImGuiCol_WindowBg. (ref github issue #337)
520  - 2016/03/21 (1.48) - renamed GetWindowFont() to GetFont(), GetWindowFontSize() to GetFontSize(). Kept inline redirection function (will obsolete).
521  - 2016/03/02 (1.48) - InputText() completion/history/always callbacks: if you modify the text buffer manually (without using DeleteChars()/InsertChars() helper) you need to maintain the BufTextLen field. added an assert.
522  - 2016/01/23 (1.48) - fixed not honoring exact width passed to PushItemWidth(), previously it would add extra FramePadding.x*2 over that width. if you had manual pixel-perfect alignment in place it might affect you.
523  - 2015/12/27 (1.48) - fixed ImDrawList::AddRect() which used to render a rectangle 1 px too large on each axis.
524  - 2015/12/04 (1.47) - renamed Color() helpers to ValueColor() - dangerously named, rarely used and probably to be made obsolete.
525  - 2015/08/29 (1.45) - with the addition of horizontal scrollbar we made various fixes to inconsistencies with dealing with cursor position.
526  GetCursorPos()/SetCursorPos() functions now include the scrolled amount. It shouldn't affect the majority of users, but take note that SetCursorPosX(100.0f) puts you at +100 from the starting x position which may include scrolling, not at +100 from the window left side.
527  GetContentRegionMax()/GetWindowContentRegionMin()/GetWindowContentRegionMax() functions allow include the scrolled amount. Typically those were used in cases where no scrolling would happen so it may not be a problem, but watch out!
528  - 2015/08/29 (1.45) - renamed style.ScrollbarWidth to style.ScrollbarSize
529  - 2015/08/05 (1.44) - split imgui.cpp into extra files: imgui_demo.cpp imgui_draw.cpp imgui_internal.h that you need to add to your project.
530  - 2015/07/18 (1.44) - fixed angles in ImDrawList::PathArcTo(), PathArcToFast() (introduced in 1.43) being off by an extra PI for no justifiable reason
531  - 2015/07/14 (1.43) - add new ImFontAtlas::AddFont() API. For the old AddFont***, moved the 'font_no' parameter of ImFontAtlas::AddFont** functions to the ImFontConfig structure.
532  you need to render your textured triangles with bilinear filtering to benefit from sub-pixel positioning of text.
533  - 2015/07/08 (1.43) - switched rendering data to use indexed rendering. this is saving a fair amount of CPU/GPU and enables us to get anti-aliasing for a marginal cost.
534  this necessary change will break your rendering function! the fix should be very easy. sorry for that :(
535  - if you are using a vanilla copy of one of the imgui_impl_XXXX.cpp provided in the example, you just need to update your copy and you can ignore the rest.
536  - the signature of the io.RenderDrawListsFn handler has changed!
537  old: ImGui_XXXX_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count)
538  new: ImGui_XXXX_RenderDrawLists(ImDrawData* draw_data).
539  parameters: 'cmd_lists' becomes 'draw_data->CmdLists', 'cmd_lists_count' becomes 'draw_data->CmdListsCount'
540  ImDrawList: 'commands' becomes 'CmdBuffer', 'vtx_buffer' becomes 'VtxBuffer', 'IdxBuffer' is new.
541  ImDrawCmd: 'vtx_count' becomes 'ElemCount', 'clip_rect' becomes 'ClipRect', 'user_callback' becomes 'UserCallback', 'texture_id' becomes 'TextureId'.
542  - each ImDrawList now contains both a vertex buffer and an index buffer. For each command, render ElemCount/3 triangles using indices from the index buffer.
543  - if you REALLY cannot render indexed primitives, you can call the draw_data->DeIndexAllBuffers() method to de-index the buffers. This is slow and a waste of CPU/GPU. Prefer using indexed rendering!
544  - refer to code in the examples/ folder or ask on the GitHub if you are unsure of how to upgrade. please upgrade!
545  - 2015/07/10 (1.43) - changed SameLine() parameters from int to float.
546  - 2015/07/02 (1.42) - renamed SetScrollPosHere() to SetScrollFromCursorPos(). Kept inline redirection function (will obsolete).
547  - 2015/07/02 (1.42) - renamed GetScrollPosY() to GetScrollY(). Necessary to reduce confusion along with other scrolling functions, because positions (e.g. cursor position) are not equivalent to scrolling amount.
548  - 2015/06/14 (1.41) - changed ImageButton() default bg_col parameter from (0,0,0,1) (black) to (0,0,0,0) (transparent) - makes a difference when texture have transparence
549  - 2015/06/14 (1.41) - changed Selectable() API from (label, selected, size) to (label, selected, flags, size). Size override should have been rarely be used. Sorry!
550  - 2015/05/31 (1.40) - renamed GetWindowCollapsed() to IsWindowCollapsed() for consistency. Kept inline redirection function (will obsolete).
551  - 2015/05/31 (1.40) - renamed IsRectClipped() to IsRectVisible() for consistency. Note that return value is opposite! Kept inline redirection function (will obsolete).
552  - 2015/05/27 (1.40) - removed the third 'repeat_if_held' parameter from Button() - sorry! it was rarely used and inconsistent. Use PushButtonRepeat(true) / PopButtonRepeat() to enable repeat on desired buttons.
553  - 2015/05/11 (1.40) - changed BeginPopup() API, takes a string identifier instead of a bool. ImGui needs to manage the open/closed state of popups. Call OpenPopup() to actually set the "open" state of a popup. BeginPopup() returns true if the popup is opened.
554  - 2015/05/03 (1.40) - removed style.AutoFitPadding, using style.WindowPadding makes more sense (the default values were already the same).
555  - 2015/04/13 (1.38) - renamed IsClipped() to IsRectClipped(). Kept inline redirection function until 1.50.
556  - 2015/04/09 (1.38) - renamed ImDrawList::AddArc() to ImDrawList::AddArcFast() for compatibility with future API
557  - 2015/04/03 (1.38) - removed ImGuiCol_CheckHovered, ImGuiCol_CheckActive, replaced with the more general ImGuiCol_FrameBgHovered, ImGuiCol_FrameBgActive.
558  - 2014/04/03 (1.38) - removed support for passing -FLT_MAX..+FLT_MAX as the range for a SliderFloat(). Use DragFloat() or Inputfloat() instead.
559  - 2015/03/17 (1.36) - renamed GetItemBoxMin()/GetItemBoxMax()/IsMouseHoveringBox() to GetItemRectMin()/GetItemRectMax()/IsMouseHoveringRect(). Kept inline redirection function until 1.50.
560  - 2015/03/15 (1.36) - renamed style.TreeNodeSpacing to style.IndentSpacing, ImGuiStyleVar_TreeNodeSpacing to ImGuiStyleVar_IndentSpacing
561  - 2015/03/13 (1.36) - renamed GetWindowIsFocused() to IsWindowFocused(). Kept inline redirection function until 1.50.
562  - 2015/03/08 (1.35) - renamed style.ScrollBarWidth to style.ScrollbarWidth (casing)
563  - 2015/02/27 (1.34) - renamed OpenNextNode(bool) to SetNextTreeNodeOpened(bool, ImGuiSetCond). Kept inline redirection function until 1.50.
564  - 2015/02/27 (1.34) - renamed ImGuiSetCondition_*** to ImGuiSetCond_***, and _FirstUseThisSession becomes _Once.
565  - 2015/02/11 (1.32) - changed text input callback ImGuiTextEditCallback return type from void-->int. reserved for future use, return 0 for now.
566  - 2015/02/10 (1.32) - renamed GetItemWidth() to CalcItemWidth() to clarify its evolving behavior
567  - 2015/02/08 (1.31) - renamed GetTextLineSpacing() to GetTextLineHeightWithSpacing()
568  - 2015/02/01 (1.31) - removed IO.MemReallocFn (unused)
569  - 2015/01/19 (1.30) - renamed ImGuiStorage::GetIntPtr()/GetFloatPtr() to GetIntRef()/GetIntRef() because Ptr was conflicting with actual pointer storage functions.
570  - 2015/01/11 (1.30) - big font/image API change! now loads TTF file. allow for multiple fonts. no need for a PNG loader.
571  - 2015/01/11 (1.30) - removed GetDefaultFontData(). uses io.Fonts->GetTextureData*() API to retrieve uncompressed pixels.
572  - old: const void* png_data; unsigned int png_size; ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size); [..Upload texture to GPU..];
573  - new: unsigned char* pixels; int width, height; io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); [..Upload texture to GPU..]; io.Fonts->TexId = YourTexIdentifier;
574  you now have more flexibility to load multiple TTF fonts and manage the texture buffer for internal needs. It is now recommended that you sample the font texture with bilinear interpolation.
575  - 2015/01/11 (1.30) - added texture identifier in ImDrawCmd passed to your render function (we can now render images). make sure to set io.Fonts->TexID.
576  - 2015/01/11 (1.30) - removed IO.PixelCenterOffset (unnecessary, can be handled in user projection matrix)
577  - 2015/01/11 (1.30) - removed ImGui::IsItemFocused() in favor of ImGui::IsItemActive() which handles all widgets
578  - 2014/12/10 (1.18) - removed SetNewWindowDefaultPos() in favor of new generic API SetNextWindowPos(pos, ImGuiSetCondition_FirstUseEver)
579  - 2014/11/28 (1.17) - moved IO.Font*** options to inside the IO.Font-> structure (FontYOffset, FontTexUvForWhite, FontBaseScale, FontFallbackGlyph)
580  - 2014/11/26 (1.17) - reworked syntax of IMGUI_ONCE_UPON_A_FRAME helper macro to increase compiler compatibility
581  - 2014/11/07 (1.15) - renamed IsHovered() to IsItemHovered()
582  - 2014/10/02 (1.14) - renamed IMGUI_INCLUDE_IMGUI_USER_CPP to IMGUI_INCLUDE_IMGUI_USER_INL and imgui_user.cpp to imgui_user.inl (more IDE friendly)
583  - 2014/09/25 (1.13) - removed 'text_end' parameter from IO.SetClipboardTextFn (the string is now always zero-terminated for simplicity)
584  - 2014/09/24 (1.12) - renamed SetFontScale() to SetWindowFontScale()
585  - 2014/09/24 (1.12) - moved IM_MALLOC/IM_REALLOC/IM_FREE preprocessor defines to IO.MemAllocFn/IO.MemReallocFn/IO.MemFreeFn
586  - 2014/08/30 (1.09) - removed IO.FontHeight (now computed automatically)
587  - 2014/08/30 (1.09) - moved IMGUI_FONT_TEX_UV_FOR_WHITE preprocessor define to IO.FontTexUvForWhite
588  - 2014/08/28 (1.09) - changed the behavior of IO.PixelCenterOffset following various rendering fixes
589 
590 
591  FREQUENTLY ASKED QUESTIONS (FAQ)
592  ================================
593 
594  Read all answers online: https://www.dearimgui.org/faq, or in docs/FAQ.md (with a Markdown viewer)
595  Some answers are copied down here to facilitate searching in code.
596 
597  Q&A: Basics
598  ===========
599 
600  Q: Where is the documentation?
601  A: This library is poorly documented at the moment and expects of the user to be acquainted with C/C++.
602  - Run the examples/ and explore them.
603  - See demo code in imgui_demo.cpp and particularly the ImGui::ShowDemoWindow() function.
604  - The demo covers most features of Dear ImGui, so you can read the code and see its output.
605  - See documentation and comments at the top of imgui.cpp + effectively imgui.h.
606  - Dozens of standalone example applications using e.g. OpenGL/DirectX are provided in the
607  examples/ folder to explain how to integrate Dear ImGui with your own engine/application.
608  - The Wiki (https://github.com/ocornut/imgui/wiki) has many resources and links.
609  - The Glossary (https://github.com/ocornut/imgui/wiki/Glossary) page also may be useful.
610  - Your programming IDE is your friend, find the type or function declaration to find comments
611  associated to it.
612 
613  Q: What is this library called?
614  Q: Which version should I get?
615  >> This library is called "Dear ImGui", please don't call it "ImGui" :)
616  >> See https://www.dearimgui.org/faq
617 
618  Q&A: Integration
619  ================
620 
621  Q: How can I tell whether to dispatch mouse/keyboard to Dear ImGui or to my application?
622  A: You should read the 'io.WantCaptureMouse', 'io.WantCaptureKeyboard' and 'io.WantTextInput' flags!
623  >> See https://www.dearimgui.org/faq for fully detailed answer. You really want to read this.
624 
625  Q. How can I enable keyboard controls?
626  Q: How can I use this without a mouse, without a keyboard or without a screen? (gamepad, input share, remote display)
627  Q: I integrated Dear ImGui in my engine and the text or lines are blurry..
628  Q: I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around..
629  >> See https://www.dearimgui.org/faq
630 
631  Q&A: Usage
632  ----------
633 
634  Q: Why are multiple widgets reacting when I interact with a single one?
635  Q: How can I have multiple widgets with the same label or with an empty label?
636  A: A primer on labels and the ID Stack...
637 
638  Dear ImGui internally need to uniquely identify UI elements.
639  Elements that are typically not clickable (such as calls to the Text functions) don't need an ID.
640  Interactive widgets (such as calls to Button buttons) need a unique ID.
641  Unique ID are used internally to track active widgets and occasionally associate state to widgets.
642  Unique ID are implicitly built from the hash of multiple elements that identify the "path" to the UI element.
643 
644  - Unique ID are often derived from a string label:
645 
646  Button("OK"); // Label = "OK", ID = hash of (..., "OK")
647  Button("Cancel"); // Label = "Cancel", ID = hash of (..., "Cancel")
648 
649  - ID are uniquely scoped within windows, tree nodes, etc. which all pushes to the ID stack. Having
650  two buttons labeled "OK" in different windows or different tree locations is fine.
651  We used "..." above to signify whatever was already pushed to the ID stack previously:
652 
653  Begin("MyWindow");
654  Button("OK"); // Label = "OK", ID = hash of ("MyWindow", "OK")
655  End();
656  Begin("MyOtherWindow");
657  Button("OK"); // Label = "OK", ID = hash of ("MyOtherWindow", "OK")
658  End();
659 
660  - If you have a same ID twice in the same location, you'll have a conflict:
661 
662  Button("OK");
663  Button("OK"); // ID collision! Interacting with either button will trigger the first one.
664 
665  Fear not! this is easy to solve and there are many ways to solve it!
666 
667  - Solving ID conflict in a simple/local context:
668  When passing a label you can optionally specify extra ID information within string itself.
669  Use "##" to pass a complement to the ID that won't be visible to the end-user.
670  This helps solving the simple collision cases when you know e.g. at compilation time which items
671  are going to be created:
672 
673  Begin("MyWindow");
674  Button("Play"); // Label = "Play", ID = hash of ("MyWindow", "Play")
675  Button("Play##foo1"); // Label = "Play", ID = hash of ("MyWindow", "Play##foo1") // Different from above
676  Button("Play##foo2"); // Label = "Play", ID = hash of ("MyWindow", "Play##foo2") // Different from above
677  End();
678 
679  - If you want to completely hide the label, but still need an ID:
680 
681  Checkbox("##On", &b); // Label = "", ID = hash of (..., "##On") // No visible label, just a checkbox!
682 
683  - Occasionally/rarely you might want change a label while preserving a constant ID. This allows
684  you to animate labels. For example you may want to include varying information in a window title bar,
685  but windows are uniquely identified by their ID. Use "###" to pass a label that isn't part of ID:
686 
687  Button("Hello###ID"); // Label = "Hello", ID = hash of (..., "###ID")
688  Button("World###ID"); // Label = "World", ID = hash of (..., "###ID") // Same as above, even though the label looks different
689 
690  sprintf(buf, "My game (%f FPS)###MyGame", fps);
691  Begin(buf); // Variable title, ID = hash of "MyGame"
692 
693  - Solving ID conflict in a more general manner:
694  Use PushID() / PopID() to create scopes and manipulate the ID stack, as to avoid ID conflicts
695  within the same window. This is the most convenient way of distinguishing ID when iterating and
696  creating many UI elements programmatically.
697  You can push a pointer, a string or an integer value into the ID stack.
698  Remember that ID are formed from the concatenation of _everything_ pushed into the ID stack.
699  At each level of the stack we store the seed used for items at this level of the ID stack.
700 
701  Begin("Window");
702  for (int i = 0; i < 100; i++)
703  {
704  PushID(i); // Push i to the id tack
705  Button("Click"); // Label = "Click", ID = hash of ("Window", i, "Click")
706  PopID();
707  }
708  for (int i = 0; i < 100; i++)
709  {
710  MyObject* obj = Objects[i];
711  PushID(obj);
712  Button("Click"); // Label = "Click", ID = hash of ("Window", obj pointer, "Click")
713  PopID();
714  }
715  for (int i = 0; i < 100; i++)
716  {
717  MyObject* obj = Objects[i];
718  PushID(obj->Name);
719  Button("Click"); // Label = "Click", ID = hash of ("Window", obj->Name, "Click")
720  PopID();
721  }
722  End();
723 
724  - You can stack multiple prefixes into the ID stack:
725 
726  Button("Click"); // Label = "Click", ID = hash of (..., "Click")
727  PushID("node");
728  Button("Click"); // Label = "Click", ID = hash of (..., "node", "Click")
729  PushID(my_ptr);
730  Button("Click"); // Label = "Click", ID = hash of (..., "node", my_ptr, "Click")
731  PopID();
732  PopID();
733 
734  - Tree nodes implicitly creates a scope for you by calling PushID().
735 
736  Button("Click"); // Label = "Click", ID = hash of (..., "Click")
737  if (TreeNode("node")) // <-- this function call will do a PushID() for you (unless instructed not to, with a special flag)
738  {
739  Button("Click"); // Label = "Click", ID = hash of (..., "node", "Click")
740  TreePop();
741  }
742 
743  - When working with trees, ID are used to preserve the open/close state of each tree node.
744  Depending on your use cases you may want to use strings, indices or pointers as ID.
745  e.g. when following a single pointer that may change over time, using a static string as ID
746  will preserve your node open/closed state when the targeted object change.
747  e.g. when displaying a list of objects, using indices or pointers as ID will preserve the
748  node open/closed state differently. See what makes more sense in your situation!
749 
750  Q: How can I display an image? What is ImTextureID, how does it works?
751  >> See https://www.dearimgui.org/faq and https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples
752 
753  Q: How can I use my own math types instead of ImVec2/ImVec4?
754  Q: How can I interact with standard C++ types (such as std::string and std::vector)?
755  Q: How can I display custom shapes? (using low-level ImDrawList API)
756  >> See https://www.dearimgui.org/faq
757 
758  Q&A: Fonts, Text
759  ================
760 
761  Q: How can I load a different font than the default?
762  Q: How can I easily use icons in my application?
763  Q: How can I load multiple fonts?
764  Q: How can I display and input non-Latin characters such as Chinese, Japanese, Korean, Cyrillic?
765  >> See https://www.dearimgui.org/faq and docs/FONTS.txt
766 
767  Q&A: Concerns
768  =============
769 
770  Q: Who uses Dear ImGui?
771  Q: Can you create elaborate/serious tools with Dear ImGui?
772  Q: Can you reskin the look of Dear ImGui?
773  Q: Why using C++ (as opposed to C)?
774  >> See https://www.dearimgui.org/faq
775 
776  Q&A: Community
777  ==============
778 
779  Q: How can I help?
780  A: - Businesses: please reach out to "contact AT dearimgui.org" if you work in a place using Dear ImGui!
781  We can discuss ways for your company to fund development via invoiced technical support, maintenance or sponsoring contacts.
782  This is among the most useful thing you can do for Dear ImGui. With increased funding we can hire more people working on this project.
783  - Individuals: you can support continued development via PayPal donations. See README.
784  - If you are experienced with Dear ImGui and C++, look at the github issues, look at the Wiki, read docs/TODO.txt
785  and see how you want to help and can help!
786  - Disclose your usage of Dear ImGui via a dev blog post, a tweet, a screenshot, a mention somewhere etc.
787  You may post screenshot or links in the gallery threads (github.com/ocornut/imgui/issues/3075). Visuals are ideal as they inspire other programmers.
788  But even without visuals, disclosing your use of dear imgui help the library grow credibility, and help other teams and programmers with taking decisions.
789  - If you have issues or if you need to hack into the library, even if you don't expect any support it is useful that you share your issues (on github or privately).
790 
791 */
792 
793 //-------------------------------------------------------------------------
794 // [SECTION] INCLUDES
795 //-------------------------------------------------------------------------
796 
797 #if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
798 #define _CRT_SECURE_NO_WARNINGS
799 #endif
800 
801 #include "imgui.h"
802 #ifndef IMGUI_DISABLE
803 
804 #ifndef IMGUI_DEFINE_MATH_OPERATORS
805 #define IMGUI_DEFINE_MATH_OPERATORS
806 #endif
807 #include "imgui_internal.h"
808 
809 // System includes
810 #include <ctype.h> // toupper
811 #include <stdio.h> // vsnprintf, sscanf, printf
812 #if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier
813 #include <stddef.h> // intptr_t
814 #else
815 #include <stdint.h> // intptr_t
816 #endif
817 
818 // [Windows] OS specific includes (optional)
819 #if defined(_WIN32) && defined(IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS) && defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS) && defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS)
820 #define IMGUI_DISABLE_WIN32_FUNCTIONS
821 #endif
822 #if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS)
823 #ifndef WIN32_LEAN_AND_MEAN
824 #define WIN32_LEAN_AND_MEAN
825 #endif
826 #ifndef NOMINMAX
827 #define NOMINMAX
828 #endif
829 #ifndef __MINGW32__
830 #include <Windows.h> // _wfopen, OpenClipboard
831 #else
832 #include <windows.h>
833 #endif
834 #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) // UWP doesn't have all Win32 functions
835 #define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS
836 #define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS
837 #endif
838 #endif
839 
840 // [Apple] OS specific includes
841 #if defined(__APPLE__)
842 #include <TargetConditionals.h>
843 #endif
844 
845 // Visual Studio warnings
846 #ifdef _MSC_VER
847 #pragma warning (disable: 4127) // condition expression is constant
848 #pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
849 #if defined(_MSC_VER) && _MSC_VER >= 1922 // MSVC 2019 16.2 or later
850 #pragma warning (disable: 5054) // operator '|': deprecated between enumerations of different types
851 #endif
852 #endif
853 
854 // Clang/GCC warnings with -Weverything
855 #if defined(__clang__)
856 #pragma clang diagnostic ignored "-Wunknown-pragmas" // warning : unknown warning group '-Wformat-pedantic *' // not all warnings are known by all clang versions.. so ignoring warnings triggers new warnings on some configuration. great!
857 #pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse.
858 #pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok.
859 #pragma clang diagnostic ignored "-Wformat-nonliteral" // warning : format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code.
860 #pragma clang diagnostic ignored "-Wexit-time-destructors" // warning : declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals.
861 #pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference is.
862 #pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness //
863 #pragma clang diagnostic ignored "-Wformat-pedantic" // warning : format specifies type 'void *' but the argument has type 'xxxx *' // unreasonable, would lead to casting every %p arg to void*. probably enabled by -pedantic.
864 #pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int'
865 #if __has_warning("-Wzero-as-null-pointer-constant")
866 #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning : zero as null pointer constant // some standard header variations use #define NULL 0
867 #endif
868 #if __has_warning("-Wdouble-promotion")
869 #pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function // using printf() is a misery with this as C++ va_arg ellipsis changes float to double.
870 #endif
871 #elif defined(__GNUC__)
872 // We disable -Wpragmas because GCC doesn't provide an has_warning equivalent and some forks/patches may not following the warning/version association.
873 #pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
874 #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
875 #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size
876 #pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'void*', but argument 6 has type 'ImGuiWindow*'
877 #pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
878 #pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value
879 #pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
880 #pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when assuming that (X - c) > X is always false
881 #pragma GCC diagnostic ignored "-Wclass-memaccess" // [__GNUC__ >= 8] warning: 'memset/memcpy' clearing/writing an object of type 'xxxx' with no trivial copy-assignment; use assignment or value-initialization instead
882 #endif
883 
884 // Debug options
885 #define IMGUI_DEBUG_NAV_SCORING 0 // Display navigation scoring preview when hovering items. Display last moving direction matches when holding CTRL
886 #define IMGUI_DEBUG_NAV_RECTS 0 // Display the reference navigation rectangle for each window
887 #define IMGUI_DEBUG_INI_SETTINGS 0 // Save additional comments in .ini file (particularly helps for Docking, but makes saving slower)
888 
889 // When using CTRL+TAB (or Gamepad Square+L/R) we delay the visual a little in order to reduce visual noise doing a fast switch.
890 static const float NAV_WINDOWING_HIGHLIGHT_DELAY = 0.20f; // Time before the highlight and screen dimming starts fading in
891 static const float NAV_WINDOWING_LIST_APPEAR_DELAY = 0.15f; // Time before the window list starts to appear
892 
893 // Window resizing from edges (when io.ConfigWindowsResizeFromEdges = true and ImGuiBackendFlags_HasMouseCursors is set in io.BackendFlags by back-end)
894 static const float WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS = 4.0f; // Extend outside and inside windows. Affect FindHoveredWindow().
895 static const float WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER = 0.04f; // Reduce visual noise by only highlighting the border after a certain time.
896 static const float WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER = 2.00f; // Lock scrolled window (so it doesn't pick child windows that are scrolling through) for a certaint time, unless mouse moved.
897 
898 //-------------------------------------------------------------------------
899 // [SECTION] FORWARD DECLARATIONS
900 //-------------------------------------------------------------------------
901 
902 static void SetCurrentWindow(ImGuiWindow* window);
903 static void FindHoveredWindow();
905 static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges);
906 
907 static void AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* draw_list);
908 static void AddWindowToSortBuffer(ImVector<ImGuiWindow*>* out_sorted_windows, ImGuiWindow* window);
909 
910 static ImRect GetViewportRect();
911 
912 // Settings
914 static void WindowSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line);
916 
917 // Platform Dependents default implementation for IO functions
918 static const char* GetClipboardTextFn_DefaultImpl(void* user_data);
919 static void SetClipboardTextFn_DefaultImpl(void* user_data, const char* text);
920 static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y);
921 
922 namespace ImGui
923 {
924 // Navigation
925 static void NavUpdate();
926 static void NavUpdateWindowing();
927 static void NavUpdateWindowingOverlay();
928 static void NavUpdateMoveResult();
929 static float NavUpdatePageUpPageDown();
930 static inline void NavUpdateAnyRequestFlag();
931 static bool NavScoreItem(ImGuiNavMoveResult* result, ImRect cand);
932 static void NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, ImGuiID id);
934 static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window);
936 static int FindWindowFocusIndex(ImGuiWindow* window);
937 
938 // Error Checking
939 static void ErrorCheckNewFrameSanityChecks();
940 static void ErrorCheckEndFrameSanityChecks();
941 static void ErrorCheckBeginEndCompareStacksSize(ImGuiWindow* window, bool write);
942 
943 // Misc
944 static void UpdateSettings();
945 static void UpdateMouseInputs();
946 static void UpdateMouseWheel();
947 static void UpdateTabFocus();
948 static void UpdateDebugToolItemPicker();
949 static bool UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]);
950 static void RenderWindowOuterBorders(ImGuiWindow* window);
951 static void RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size);
952 static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open);
953 
954 }
955 
956 //-----------------------------------------------------------------------------
957 // [SECTION] CONTEXT AND MEMORY ALLOCATORS
958 //-----------------------------------------------------------------------------
959 
960 // Current context pointer. Implicitly used by all Dear ImGui functions. Always assumed to be != NULL.
961 // ImGui::CreateContext() will automatically set this pointer if it is NULL. Change to a different context by calling ImGui::SetCurrentContext().
962 // 1) Important: globals are not shared across DLL boundaries! If you use DLLs or any form of hot-reloading: you will need to call
963 // SetCurrentContext() (with the pointer you got from CreateContext) from each unique static/DLL boundary, and after each hot-reloading.
964 // In your debugger, add GImGui to your watch window and notice how its value changes depending on which location you are currently stepping into.
965 // 2) Important: Dear ImGui functions are not thread-safe because of this pointer.
966 // If you want thread-safety to allow N threads to access N different contexts, you can:
967 // - Change this variable to use thread local storage so each thread can refer to a different context, in imconfig.h:
968 // struct ImGuiContext;
969 // extern thread_local ImGuiContext* MyImGuiTLS;
970 // #define GImGui MyImGuiTLS
971 // And then define MyImGuiTLS in one of your cpp file. Note that thread_local is a C++11 keyword, earlier C++ uses compiler-specific keyword.
972 // - Future development aim to make this context pointer explicit to all calls. Also read https://github.com/ocornut/imgui/issues/586
973 // - If you need a finite number of contexts, you may compile and use multiple instances of the ImGui code from different namespace.
974 #ifndef GImGui
976 #endif
977 
978 // Memory Allocator functions. Use SetAllocatorFunctions() to change them.
979 // If you use DLL hotreloading you might need to call SetAllocatorFunctions() after reloading code from this file.
980 // Otherwise, you probably don't want to modify them mid-program, and if you use global/static e.g. ImVector<> instances you may need to keep them accessible during program destruction.
981 #ifndef IMGUI_DISABLE_DEFAULT_ALLOCATORS
982 static void* MallocWrapper(size_t size, void* user_data) { IM_UNUSED(user_data); return malloc(size); }
983 static void FreeWrapper(void* ptr, void* user_data) { IM_UNUSED(user_data); free(ptr); }
984 #else
985 static void* MallocWrapper(size_t size, void* user_data) { IM_UNUSED(user_data); IM_UNUSED(size); IM_ASSERT(0); return NULL; }
986 static void FreeWrapper(void* ptr, void* user_data) { IM_UNUSED(user_data); IM_UNUSED(ptr); IM_ASSERT(0); }
987 #endif
988 
989 static void* (*GImAllocatorAllocFunc)(size_t size, void* user_data) = MallocWrapper;
990 static void (*GImAllocatorFreeFunc)(void* ptr, void* user_data) = FreeWrapper;
991 static void* GImAllocatorUserData = NULL;
992 
993 //-----------------------------------------------------------------------------
994 // [SECTION] USER FACING STRUCTURES (ImGuiStyle, ImGuiIO)
995 //-----------------------------------------------------------------------------
996 
998 {
999  Alpha = 1.0f; // Global alpha applies to everything in ImGui
1000  WindowPadding = ImVec2(8,8); // Padding within a window
1001  WindowRounding = 7.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows
1002  WindowBorderSize = 1.0f; // Thickness of border around windows. Generally set to 0.0f or 1.0f. Other values not well tested.
1003  WindowMinSize = ImVec2(32,32); // Minimum window size
1004  WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text
1005  WindowMenuButtonPosition= ImGuiDir_Left; // Position of the collapsing/docking button in the title bar (left/right). Defaults to ImGuiDir_Left.
1006  ChildRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular child windows
1007  ChildBorderSize = 1.0f; // Thickness of border around child windows. Generally set to 0.0f or 1.0f. Other values not well tested.
1008  PopupRounding = 0.0f; // Radius of popup window corners rounding. Set to 0.0f to have rectangular child windows
1009  PopupBorderSize = 1.0f; // Thickness of border around popup or tooltip windows. Generally set to 0.0f or 1.0f. Other values not well tested.
1010  FramePadding = ImVec2(4,3); // Padding within a framed rectangle (used by most widgets)
1011  FrameRounding = 0.0f; // Radius of frame corners rounding. Set to 0.0f to have rectangular frames (used by most widgets).
1012  FrameBorderSize = 0.0f; // Thickness of border around frames. Generally set to 0.0f or 1.0f. Other values not well tested.
1013  ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines
1014  ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label)
1015  TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much!
1016  IndentSpacing = 21.0f; // Horizontal spacing when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2).
1017  ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns. Preferably > (FramePadding.x + 1).
1018  ScrollbarSize = 14.0f; // Width of the vertical scrollbar, Height of the horizontal scrollbar
1019  ScrollbarRounding = 9.0f; // Radius of grab corners rounding for scrollbar
1020  GrabMinSize = 10.0f; // Minimum width/height of a grab box for slider/scrollbar
1021  GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs.
1022  TabRounding = 4.0f; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs.
1023  TabBorderSize = 0.0f; // Thickness of border around tabs.
1024  ColorButtonPosition = ImGuiDir_Right; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
1025  ButtonTextAlign = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text.
1026  SelectableTextAlign = ImVec2(0.0f,0.0f);// Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line.
1027  DisplayWindowPadding = ImVec2(19,19); // Window position are clamped to be visible within the display area or monitors by at least this amount. Only applies to regular windows.
1028  DisplaySafeAreaPadding = ImVec2(3,3); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows.
1029  MouseCursorScale = 1.0f; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later.
1030  AntiAliasedLines = true; // Enable anti-aliasing on lines/borders. Disable if you are really short on CPU/GPU.
1031  AntiAliasedFill = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.)
1032  CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality.
1033  CircleSegmentMaxError = 1.60f; // Maximum error (in pixels) allowed when using AddCircle()/AddCircleFilled() or drawing rounded corner rectangles with no explicit segment count specified. Decrease for higher quality but more geometry.
1034 
1035  // Default theme
1036  ImGui::StyleColorsDark(this);
1037 }
1038 
1039 // To scale your entire UI (e.g. if you want your app to use High DPI or generally be DPI aware) you may use this helper function. Scaling the fonts is done separately and is up to you.
1040 // Important: This operation is lossy because we round all sizes to integer. If you need to change your scale multiples, call this over a freshly initialized ImGuiStyle structure rather than scaling multiple times.
1041 void ImGuiStyle::ScaleAllSizes(float scale_factor)
1042 {
1043  WindowPadding = ImFloor(WindowPadding * scale_factor);
1044  WindowRounding = ImFloor(WindowRounding * scale_factor);
1045  WindowMinSize = ImFloor(WindowMinSize * scale_factor);
1046  ChildRounding = ImFloor(ChildRounding * scale_factor);
1047  PopupRounding = ImFloor(PopupRounding * scale_factor);
1048  FramePadding = ImFloor(FramePadding * scale_factor);
1049  FrameRounding = ImFloor(FrameRounding * scale_factor);
1050  ItemSpacing = ImFloor(ItemSpacing * scale_factor);
1051  ItemInnerSpacing = ImFloor(ItemInnerSpacing * scale_factor);
1052  TouchExtraPadding = ImFloor(TouchExtraPadding * scale_factor);
1053  IndentSpacing = ImFloor(IndentSpacing * scale_factor);
1054  ColumnsMinSpacing = ImFloor(ColumnsMinSpacing * scale_factor);
1055  ScrollbarSize = ImFloor(ScrollbarSize * scale_factor);
1056  ScrollbarRounding = ImFloor(ScrollbarRounding * scale_factor);
1057  GrabMinSize = ImFloor(GrabMinSize * scale_factor);
1058  GrabRounding = ImFloor(GrabRounding * scale_factor);
1059  TabRounding = ImFloor(TabRounding * scale_factor);
1062  MouseCursorScale = ImFloor(MouseCursorScale * scale_factor);
1063 }
1064 
1066 {
1067  // Most fields are initialized with zero
1068  memset(this, 0, sizeof(*this));
1069  IM_ASSERT(IM_ARRAYSIZE(ImGuiIO::MouseDown) == ImGuiMouseButton_COUNT && IM_ARRAYSIZE(ImGuiIO::MouseClicked) == ImGuiMouseButton_COUNT); // Our pre-C++11 IM_STATIC_ASSERT() macros triggers warning on modern compilers so we don't use it here.
1070 
1071  // Settings
1074  DisplaySize = ImVec2(-1.0f, -1.0f);
1075  DeltaTime = 1.0f/60.0f;
1076  IniSavingRate = 5.0f;
1077  IniFilename = "imgui.ini";
1078  LogFilename = "imgui_log.txt";
1079  MouseDoubleClickTime = 0.30f;
1080  MouseDoubleClickMaxDist = 6.0f;
1081  for (int i = 0; i < ImGuiKey_COUNT; i++)
1082  KeyMap[i] = -1;
1083  KeyRepeatDelay = 0.275f;
1084  KeyRepeatRate = 0.050f;
1085  UserData = NULL;
1086 
1087  Fonts = NULL;
1088  FontGlobalScale = 1.0f;
1089  FontDefault = NULL;
1090  FontAllowUserScaling = false;
1091  DisplayFramebufferScale = ImVec2(1.0f, 1.0f);
1092 
1093  // Miscellaneous options
1094  MouseDrawCursor = false;
1095 #ifdef __APPLE__
1096  ConfigMacOSXBehaviors = true; // Set Mac OS X style defaults based on __APPLE__ compile time flag
1097 #else
1098  ConfigMacOSXBehaviors = false;
1099 #endif
1104 
1105  // Platform Functions
1108  GetClipboardTextFn = GetClipboardTextFn_DefaultImpl; // Platform dependent default implementations
1113 
1114 #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
1116 #endif
1117 
1118  // Input (NB: we already have memset zero the entire structure!)
1119  MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
1120  MousePosPrev = ImVec2(-FLT_MAX, -FLT_MAX);
1121  MouseDragThreshold = 6.0f;
1122  for (int i = 0; i < IM_ARRAYSIZE(MouseDownDuration); i++) MouseDownDuration[i] = MouseDownDurationPrev[i] = -1.0f;
1123  for (int i = 0; i < IM_ARRAYSIZE(KeysDownDuration); i++) KeysDownDuration[i] = KeysDownDurationPrev[i] = -1.0f;
1124  for (int i = 0; i < IM_ARRAYSIZE(NavInputsDownDuration); i++) NavInputsDownDuration[i] = -1.0f;
1125 }
1126 
1127 // Pass in translated ASCII characters for text input.
1128 // - with glfw you can get those from the callback set in glfwSetCharCallback()
1129 // - on Windows you can get those using ToAscii+keyboard state, or via the WM_CHAR message
1130 void ImGuiIO::AddInputCharacter(unsigned int c)
1131 {
1133 }
1134 
1135 // UTF16 strings use surrogate pairs to encode codepoints >= 0x10000, so
1136 // we should save the high surrogate.
1138 {
1139  if ((c & 0xFC00) == 0xD800) // High surrogate, must save
1140  {
1141  if (InputQueueSurrogate != 0)
1143  InputQueueSurrogate = c;
1144  return;
1145  }
1146 
1147  ImWchar cp = c;
1148  if (InputQueueSurrogate != 0)
1149  {
1150  if ((c & 0xFC00) != 0xDC00) // Invalid low surrogate
1152  else if (IM_UNICODE_CODEPOINT_MAX == (0xFFFF)) // Codepoint will not fit in ImWchar (extra parenthesis around 0xFFFF somehow fixes -Wunreachable-code with Clang)
1154  else
1155  cp = (ImWchar)(((InputQueueSurrogate - 0xD800) << 10) + (c - 0xDC00) + 0x10000);
1156  InputQueueSurrogate = 0;
1157  }
1159 }
1160 
1161 void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars)
1162 {
1163  while (*utf8_chars != 0)
1164  {
1165  unsigned int c = 0;
1166  utf8_chars += ImTextCharFromUtf8(&c, utf8_chars, NULL);
1167  if (c > 0)
1169  }
1170 }
1171 
1173 {
1175 }
1176 
1177 //-----------------------------------------------------------------------------
1178 // [SECTION] MISC HELPERS/UTILITIES (Geometry functions)
1179 //-----------------------------------------------------------------------------
1180 
1181 ImVec2 ImBezierClosestPoint(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, int num_segments)
1182 {
1183  IM_ASSERT(num_segments > 0); // Use ImBezierClosestPointCasteljau()
1184  ImVec2 p_last = p1;
1185  ImVec2 p_closest;
1186  float p_closest_dist2 = FLT_MAX;
1187  float t_step = 1.0f / (float)num_segments;
1188  for (int i_step = 1; i_step <= num_segments; i_step++)
1189  {
1190  ImVec2 p_current = ImBezierCalc(p1, p2, p3, p4, t_step * i_step);
1191  ImVec2 p_line = ImLineClosestPoint(p_last, p_current, p);
1192  float dist2 = ImLengthSqr(p - p_line);
1193  if (dist2 < p_closest_dist2)
1194  {
1195  p_closest = p_line;
1196  p_closest_dist2 = dist2;
1197  }
1198  p_last = p_current;
1199  }
1200  return p_closest;
1201 }
1202 
1203 // Closely mimics PathBezierToCasteljau() in imgui_draw.cpp
1204 static void BezierClosestPointCasteljauStep(const ImVec2& p, ImVec2& p_closest, ImVec2& p_last, float& p_closest_dist2, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level)
1205 {
1206  float dx = x4 - x1;
1207  float dy = y4 - y1;
1208  float d2 = ((x2 - x4) * dy - (y2 - y4) * dx);
1209  float d3 = ((x3 - x4) * dy - (y3 - y4) * dx);
1210  d2 = (d2 >= 0) ? d2 : -d2;
1211  d3 = (d3 >= 0) ? d3 : -d3;
1212  if ((d2+d3) * (d2+d3) < tess_tol * (dx*dx + dy*dy))
1213  {
1214  ImVec2 p_current(x4, y4);
1215  ImVec2 p_line = ImLineClosestPoint(p_last, p_current, p);
1216  float dist2 = ImLengthSqr(p - p_line);
1217  if (dist2 < p_closest_dist2)
1218  {
1219  p_closest = p_line;
1220  p_closest_dist2 = dist2;
1221  }
1222  p_last = p_current;
1223  }
1224  else if (level < 10)
1225  {
1226  float x12 = (x1+x2)*0.5f, y12 = (y1+y2)*0.5f;
1227  float x23 = (x2+x3)*0.5f, y23 = (y2+y3)*0.5f;
1228  float x34 = (x3+x4)*0.5f, y34 = (y3+y4)*0.5f;
1229  float x123 = (x12+x23)*0.5f, y123 = (y12+y23)*0.5f;
1230  float x234 = (x23+x34)*0.5f, y234 = (y23+y34)*0.5f;
1231  float x1234 = (x123+x234)*0.5f, y1234 = (y123+y234)*0.5f;
1232  BezierClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1);
1233  BezierClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1);
1234  }
1235 }
1236 
1237 // tess_tol is generally the same value you would find in ImGui::GetStyle().CurveTessellationTol
1238 // Because those ImXXX functions are lower-level than ImGui:: we cannot access this value automatically.
1239 ImVec2 ImBezierClosestPointCasteljau(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, const ImVec2& p, float tess_tol)
1240 {
1241  IM_ASSERT(tess_tol > 0.0f);
1242  ImVec2 p_last = p1;
1243  ImVec2 p_closest;
1244  float p_closest_dist2 = FLT_MAX;
1245  BezierClosestPointCasteljauStep(p, p_closest, p_last, p_closest_dist2, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, tess_tol, 0);
1246  return p_closest;
1247 }
1248 
1250 {
1251  ImVec2 ap = p - a;
1252  ImVec2 ab_dir = b - a;
1253  float dot = ap.x * ab_dir.x + ap.y * ab_dir.y;
1254  if (dot < 0.0f)
1255  return a;
1256  float ab_len_sqr = ab_dir.x * ab_dir.x + ab_dir.y * ab_dir.y;
1257  if (dot > ab_len_sqr)
1258  return b;
1259  return a + ab_dir * dot / ab_len_sqr;
1260 }
1261 
1262 bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p)
1263 {
1264  bool b1 = ((p.x - b.x) * (a.y - b.y) - (p.y - b.y) * (a.x - b.x)) < 0.0f;
1265  bool b2 = ((p.x - c.x) * (b.y - c.y) - (p.y - c.y) * (b.x - c.x)) < 0.0f;
1266  bool b3 = ((p.x - a.x) * (c.y - a.y) - (p.y - a.y) * (c.x - a.x)) < 0.0f;
1267  return ((b1 == b2) && (b2 == b3));
1268 }
1269 
1270 void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p, float& out_u, float& out_v, float& out_w)
1271 {
1272  ImVec2 v0 = b - a;
1273  ImVec2 v1 = c - a;
1274  ImVec2 v2 = p - a;
1275  const float denom = v0.x * v1.y - v1.x * v0.y;
1276  out_v = (v2.x * v1.y - v1.x * v2.y) / denom;
1277  out_w = (v0.x * v2.y - v2.x * v0.y) / denom;
1278  out_u = 1.0f - out_v - out_w;
1279 }
1280 
1281 ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p)
1282 {
1283  ImVec2 proj_ab = ImLineClosestPoint(a, b, p);
1284  ImVec2 proj_bc = ImLineClosestPoint(b, c, p);
1285  ImVec2 proj_ca = ImLineClosestPoint(c, a, p);
1286  float dist2_ab = ImLengthSqr(p - proj_ab);
1287  float dist2_bc = ImLengthSqr(p - proj_bc);
1288  float dist2_ca = ImLengthSqr(p - proj_ca);
1289  float m = ImMin(dist2_ab, ImMin(dist2_bc, dist2_ca));
1290  if (m == dist2_ab)
1291  return proj_ab;
1292  if (m == dist2_bc)
1293  return proj_bc;
1294  return proj_ca;
1295 }
1296 
1297 //-----------------------------------------------------------------------------
1298 // [SECTION] MISC HELPERS/UTILITIES (String, Format, Hash functions)
1299 //-----------------------------------------------------------------------------
1300 
1301 // Consider using _stricmp/_strnicmp under Windows or strcasecmp/strncasecmp. We don't actually use either ImStricmp/ImStrnicmp in the codebase any more.
1302 int ImStricmp(const char* str1, const char* str2)
1303 {
1304  int d;
1305  while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; }
1306  return d;
1307 }
1308 
1309 int ImStrnicmp(const char* str1, const char* str2, size_t count)
1310 {
1311  int d = 0;
1312  while (count > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; count--; }
1313  return d;
1314 }
1315 
1316 void ImStrncpy(char* dst, const char* src, size_t count)
1317 {
1318  if (count < 1)
1319  return;
1320  if (count > 1)
1321  strncpy(dst, src, count - 1);
1322  dst[count - 1] = 0;
1323 }
1324 
1325 char* ImStrdup(const char* str)
1326 {
1327  size_t len = strlen(str);
1328  void* buf = IM_ALLOC(len + 1);
1329  return (char*)memcpy(buf, (const void*)str, len + 1);
1330 }
1331 
1332 char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* src)
1333 {
1334  size_t dst_buf_size = p_dst_size ? *p_dst_size : strlen(dst) + 1;
1335  size_t src_size = strlen(src) + 1;
1336  if (dst_buf_size < src_size)
1337  {
1338  IM_FREE(dst);
1339  dst = (char*)IM_ALLOC(src_size);
1340  if (p_dst_size)
1341  *p_dst_size = src_size;
1342  }
1343  return (char*)memcpy(dst, (const void*)src, src_size);
1344 }
1345 
1346 const char* ImStrchrRange(const char* str, const char* str_end, char c)
1347 {
1348  const char* p = (const char*)memchr(str, (int)c, str_end - str);
1349  return p;
1350 }
1351 
1352 int ImStrlenW(const ImWchar* str)
1353 {
1354  //return (int)wcslen((const wchar_t*)str); // FIXME-OPT: Could use this when wchar_t are 16-bit
1355  int n = 0;
1356  while (*str++) n++;
1357  return n;
1358 }
1359 
1360 // Find end-of-line. Return pointer will point to either first \n, either str_end.
1361 const char* ImStreolRange(const char* str, const char* str_end)
1362 {
1363  const char* p = (const char*)memchr(str, '\n', str_end - str);
1364  return p ? p : str_end;
1365 }
1366 
1367 const ImWchar* ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin) // find beginning-of-line
1368 {
1369  while (buf_mid_line > buf_begin && buf_mid_line[-1] != '\n')
1370  buf_mid_line--;
1371  return buf_mid_line;
1372 }
1373 
1374 const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end)
1375 {
1376  if (!needle_end)
1377  needle_end = needle + strlen(needle);
1378 
1379  const char un0 = (char)toupper(*needle);
1380  while ((!haystack_end && *haystack) || (haystack_end && haystack < haystack_end))
1381  {
1382  if (toupper(*haystack) == un0)
1383  {
1384  const char* b = needle + 1;
1385  for (const char* a = haystack + 1; b < needle_end; a++, b++)
1386  if (toupper(*a) != toupper(*b))
1387  break;
1388  if (b == needle_end)
1389  return haystack;
1390  }
1391  haystack++;
1392  }
1393  return NULL;
1394 }
1395 
1396 // Trim str by offsetting contents when there's leading data + writing a \0 at the trailing position. We use this in situation where the cost is negligible.
1398 {
1399  char* p = buf;
1400  while (p[0] == ' ' || p[0] == '\t') // Leading blanks
1401  p++;
1402  char* p_start = p;
1403  while (*p != 0) // Find end of string
1404  p++;
1405  while (p > p_start && (p[-1] == ' ' || p[-1] == '\t')) // Trailing blanks
1406  p--;
1407  if (p_start != buf) // Copy memory if we had leading blanks
1408  memmove(buf, p_start, p - p_start);
1409  buf[p - p_start] = 0; // Zero terminate
1410 }
1411 
1412 const char* ImStrSkipBlank(const char* str)
1413 {
1414  while (str[0] == ' ' || str[0] == '\t')
1415  str++;
1416  return str;
1417 }
1418 
1419 // A) MSVC version appears to return -1 on overflow, whereas glibc appears to return total count (which may be >= buf_size).
1420 // Ideally we would test for only one of those limits at runtime depending on the behavior the vsnprintf(), but trying to deduct it at compile time sounds like a pandora can of worm.
1421 // B) When buf==NULL vsnprintf() will return the output size.
1422 #ifndef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS
1423 
1424 // We support stb_sprintf which is much faster (see: https://github.com/nothings/stb/blob/master/stb_sprintf.h)
1425 // You may set IMGUI_USE_STB_SPRINTF to use our default wrapper, or set IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS
1426 // and setup the wrapper yourself. (FIXME-OPT: Some of our high-level operations such as ImGuiTextBuffer::appendfv() are
1427 // designed using two-passes worst case, which probably could be improved using the stbsp_vsprintfcb() function.)
1428 #ifdef IMGUI_USE_STB_SPRINTF
1429 #define STB_SPRINTF_IMPLEMENTATION
1430 #include "stb_sprintf.h"
1431 #endif
1432 
1433 #if defined(_MSC_VER) && !defined(vsnprintf)
1434 #define vsnprintf _vsnprintf
1435 #endif
1436 
1437 int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...)
1438 {
1439  va_list args;
1440  va_start(args, fmt);
1441 #ifdef IMGUI_USE_STB_SPRINTF
1442  int w = stbsp_vsnprintf(buf, (int)buf_size, fmt, args);
1443 #else
1444  int w = vsnprintf(buf, buf_size, fmt, args);
1445 #endif
1446  va_end(args);
1447  if (buf == NULL)
1448  return w;
1449  if (w == -1 || w >= (int)buf_size)
1450  w = (int)buf_size - 1;
1451  buf[w] = 0;
1452  return w;
1453 }
1454 
1455 int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args)
1456 {
1457 #ifdef IMGUI_USE_STB_SPRINTF
1458  int w = stbsp_vsnprintf(buf, (int)buf_size, fmt, args);
1459 #else
1460  int w = vsnprintf(buf, buf_size, fmt, args);
1461 #endif
1462  if (buf == NULL)
1463  return w;
1464  if (w == -1 || w >= (int)buf_size)
1465  w = (int)buf_size - 1;
1466  buf[w] = 0;
1467  return w;
1468 }
1469 #endif // #ifdef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS
1470 
1471 // CRC32 needs a 1KB lookup table (not cache friendly)
1472 // Although the code to generate the table is simple and shorter than the table itself, using a const table allows us to easily:
1473 // - avoid an unnecessary branch/memory tap, - keep the ImHashXXX functions usable by static constructors, - make it thread-safe.
1474 static const ImU32 GCrc32LookupTable[256] =
1475 {
1476  0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535,0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD,0xE7B82D07,0x90BF1D91,
1477  0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,0x6DDDE4EB,0xF4D4B551,0x83D385C7,0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5,
1478  0x3B6E20C8,0x4C69105E,0xD56041E4,0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,0x35B5A8FA,0x42B2986C,0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59,
1479  0x26D930AC,0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F,0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB,0xB6662D3D,
1480  0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F,0x9FBFE4A5,0xE8B8D433,0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,0x086D3D2D,0x91646C97,0xE6635C01,
1481  0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,0x65B0D9C6,0x12B7E950,0x8BBEB8EA,0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65,
1482  0x4DB26158,0x3AB551CE,0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB,0x4369E96A,0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9,
1483  0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,0xCE61E49F,0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,0xB7BD5C3B,0xC0BA6CAD,
1484  0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,0xEAD54739,0x9DD277AF,0x04DB2615,0x73DC1683,0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8,0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1,
1485  0xF00F9344,0x8708A3D2,0x1E01F268,0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7,0xFED41B76,0x89D32BE0,0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5,
1486  0xD6D6A3E8,0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B,0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF,0x4669BE79,
1487  0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703,0x220216B9,0x5505262F,0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7,0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D,
1488  0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A,0x9C0906A9,0xEB0E363F,0x72076785,0x05005713,0x95BF4A82,0xE2B87A14,0x7BB12BAE,0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21,
1489  0x86D3D2D4,0xF1D4E242,0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777,0x88085AE6,0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45,
1490  0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D,0x3E6E77DB,0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,0x47B2CF7F,0x30B5FFE9,
1491  0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,0xCDD70693,0x54DE5729,0x23D967BF,0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D,
1492 };
1493 
1494 // Known size hash
1495 // It is ok to call ImHashData on a string with known length but the ### operator won't be supported.
1496 // FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements.
1497 ImU32 ImHashData(const void* data_p, size_t data_size, ImU32 seed)
1498 {
1499  ImU32 crc = ~seed;
1500  const unsigned char* data = (const unsigned char*)data_p;
1501  const ImU32* crc32_lut = GCrc32LookupTable;
1502  while (data_size-- != 0)
1503  crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ *data++];
1504  return ~crc;
1505 }
1506 
1507 // Zero-terminated string hash, with support for ### to reset back to seed value
1508 // We support a syntax of "label###id" where only "###id" is included in the hash, and only "label" gets displayed.
1509 // Because this syntax is rarely used we are optimizing for the common case.
1510 // - If we reach ### in the string we discard the hash so far and reset to the seed.
1511 // - We don't do 'current += 2; continue;' after handling ### to keep the code smaller/faster (measured ~10% diff in Debug build)
1512 // FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements.
1513 ImU32 ImHashStr(const char* data_p, size_t data_size, ImU32 seed)
1514 {
1515  seed = ~seed;
1516  ImU32 crc = seed;
1517  const unsigned char* data = (const unsigned char*)data_p;
1518  const ImU32* crc32_lut = GCrc32LookupTable;
1519  if (data_size != 0)
1520  {
1521  while (data_size-- != 0)
1522  {
1523  unsigned char c = *data++;
1524  if (c == '#' && data_size >= 2 && data[0] == '#' && data[1] == '#')
1525  crc = seed;
1526  crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c];
1527  }
1528  }
1529  else
1530  {
1531  while (unsigned char c = *data++)
1532  {
1533  if (c == '#' && data[0] == '#' && data[1] == '#')
1534  crc = seed;
1535  crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c];
1536  }
1537  }
1538  return ~crc;
1539 }
1540 
1541 //-----------------------------------------------------------------------------
1542 // [SECTION] MISC HELPERS/UTILITIES (File functions)
1543 //-----------------------------------------------------------------------------
1544 
1545 // Default file functions
1546 #ifndef IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS
1547 
1548 ImFileHandle ImFileOpen(const char* filename, const char* mode)
1549 {
1550 #if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(__CYGWIN__) && !defined(__GNUC__)
1551  // We need a fopen() wrapper because MSVC/Windows fopen doesn't handle UTF-8 filenames.
1552  // Previously we used ImTextCountCharsFromUtf8/ImTextStrFromUtf8 here but we now need to support ImWchar16 and ImWchar32!
1553  const int filename_wsize = ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0);
1554  const int mode_wsize = ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, NULL, 0);
1556  buf.resize(filename_wsize + mode_wsize);
1557  ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, (wchar_t*)&buf[0], filename_wsize);
1558  ::MultiByteToWideChar(CP_UTF8, 0, mode, -1, (wchar_t*)&buf[filename_wsize], mode_wsize);
1559  return ::_wfopen((const wchar_t*)&buf[0], (const wchar_t*)&buf[filename_wsize]);
1560 #else
1561  return fopen(filename, mode);
1562 #endif
1563 }
1564 
1565 // We should in theory be using fseeko()/ftello() with off_t and _fseeki64()/_ftelli64() with __int64, waiting for the PR that does that in a very portable pre-C++11 zero-warnings way.
1566 bool ImFileClose(ImFileHandle f) { return fclose(f) == 0; }
1567 ImU64 ImFileGetSize(ImFileHandle f) { long off = 0, sz = 0; return ((off = ftell(f)) != -1 && !fseek(f, 0, SEEK_END) && (sz = ftell(f)) != -1 && !fseek(f, off, SEEK_SET)) ? (ImU64)sz : (ImU64)-1; }
1568 ImU64 ImFileRead(void* data, ImU64 sz, ImU64 count, ImFileHandle f) { return fread(data, (size_t)sz, (size_t)count, f); }
1569 ImU64 ImFileWrite(const void* data, ImU64 sz, ImU64 count, ImFileHandle f) { return fwrite(data, (size_t)sz, (size_t)count, f); }
1570 #endif // #ifndef IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS
1571 
1572 // Helper: Load file content into memory
1573 // Memory allocated with IM_ALLOC(), must be freed by user using IM_FREE() == ImGui::MemFree()
1574 // This can't really be used with "rt" because fseek size won't match read size.
1575 void* ImFileLoadToMemory(const char* filename, const char* mode, size_t* out_file_size, int padding_bytes)
1576 {
1577  IM_ASSERT(filename && mode);
1578  if (out_file_size)
1579  *out_file_size = 0;
1580 
1581  ImFileHandle f;
1582  if ((f = ImFileOpen(filename, mode)) == NULL)
1583  return NULL;
1584 
1585  size_t file_size = (size_t)ImFileGetSize(f);
1586  if (file_size == (size_t)-1)
1587  {
1588  ImFileClose(f);
1589  return NULL;
1590  }
1591 
1592  void* file_data = IM_ALLOC(file_size + padding_bytes);
1593  if (file_data == NULL)
1594  {
1595  ImFileClose(f);
1596  return NULL;
1597  }
1598  if (ImFileRead(file_data, 1, file_size, f) != file_size)
1599  {
1600  ImFileClose(f);
1601  IM_FREE(file_data);
1602  return NULL;
1603  }
1604  if (padding_bytes > 0)
1605  memset((void*)(((char*)file_data) + file_size), 0, (size_t)padding_bytes);
1606 
1607  ImFileClose(f);
1608  if (out_file_size)
1609  *out_file_size = file_size;
1610 
1611  return file_data;
1612 }
1613 
1614 //-----------------------------------------------------------------------------
1615 // [SECTION] MISC HELPERS/UTILITIES (ImText* functions)
1616 //-----------------------------------------------------------------------------
1617 
1618 // Convert UTF-8 to 32-bit character, process single character input.
1619 // Based on stb_from_utf8() from github.com/nothings/stb/
1620 // We handle UTF-8 decoding error by skipping forward.
1621 int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end)
1622 {
1623  unsigned int c = (unsigned int)-1;
1624  const unsigned char* str = (const unsigned char*)in_text;
1625  if (!(*str & 0x80))
1626  {
1627  c = (unsigned int)(*str++);
1628  *out_char = c;
1629  return 1;
1630  }
1631  if ((*str & 0xe0) == 0xc0)
1632  {
1633  *out_char = IM_UNICODE_CODEPOINT_INVALID; // will be invalid but not end of string
1634  if (in_text_end && in_text_end - (const char*)str < 2) return 1;
1635  if (*str < 0xc2) return 2;
1636  c = (unsigned int)((*str++ & 0x1f) << 6);
1637  if ((*str & 0xc0) != 0x80) return 2;
1638  c += (*str++ & 0x3f);
1639  *out_char = c;
1640  return 2;
1641  }
1642  if ((*str & 0xf0) == 0xe0)
1643  {
1644  *out_char = IM_UNICODE_CODEPOINT_INVALID; // will be invalid but not end of string
1645  if (in_text_end && in_text_end - (const char*)str < 3) return 1;
1646  if (*str == 0xe0 && (str[1] < 0xa0 || str[1] > 0xbf)) return 3;
1647  if (*str == 0xed && str[1] > 0x9f) return 3; // str[1] < 0x80 is checked below
1648  c = (unsigned int)((*str++ & 0x0f) << 12);
1649  if ((*str & 0xc0) != 0x80) return 3;
1650  c += (unsigned int)((*str++ & 0x3f) << 6);
1651  if ((*str & 0xc0) != 0x80) return 3;
1652  c += (*str++ & 0x3f);
1653  *out_char = c;
1654  return 3;
1655  }
1656  if ((*str & 0xf8) == 0xf0)
1657  {
1658  *out_char = IM_UNICODE_CODEPOINT_INVALID; // will be invalid but not end of string
1659  if (in_text_end && in_text_end - (const char*)str < 4) return 1;
1660  if (*str > 0xf4) return 4;
1661  if (*str == 0xf0 && (str[1] < 0x90 || str[1] > 0xbf)) return 4;
1662  if (*str == 0xf4 && str[1] > 0x8f) return 4; // str[1] < 0x80 is checked below
1663  c = (unsigned int)((*str++ & 0x07) << 18);
1664  if ((*str & 0xc0) != 0x80) return 4;
1665  c += (unsigned int)((*str++ & 0x3f) << 12);
1666  if ((*str & 0xc0) != 0x80) return 4;
1667  c += (unsigned int)((*str++ & 0x3f) << 6);
1668  if ((*str & 0xc0) != 0x80) return 4;
1669  c += (*str++ & 0x3f);
1670  // utf-8 encodings of values used in surrogate pairs are invalid
1671  if ((c & 0xFFFFF800) == 0xD800) return 4;
1672  // If codepoint does not fit in ImWchar, use replacement character U+FFFD instead
1674  *out_char = c;
1675  return 4;
1676  }
1677  *out_char = 0;
1678  return 0;
1679 }
1680 
1681 int ImTextStrFromUtf8(ImWchar* buf, int buf_size, const char* in_text, const char* in_text_end, const char** in_text_remaining)
1682 {
1683  ImWchar* buf_out = buf;
1684  ImWchar* buf_end = buf + buf_size;
1685  while (buf_out < buf_end-1 && (!in_text_end || in_text < in_text_end) && *in_text)
1686  {
1687  unsigned int c;
1688  in_text += ImTextCharFromUtf8(&c, in_text, in_text_end);
1689  if (c == 0)
1690  break;
1691  *buf_out++ = (ImWchar)c;
1692  }
1693  *buf_out = 0;
1694  if (in_text_remaining)
1695  *in_text_remaining = in_text;
1696  return (int)(buf_out - buf);
1697 }
1698 
1699 int ImTextCountCharsFromUtf8(const char* in_text, const char* in_text_end)
1700 {
1701  int char_count = 0;
1702  while ((!in_text_end || in_text < in_text_end) && *in_text)
1703  {
1704  unsigned int c;
1705  in_text += ImTextCharFromUtf8(&c, in_text, in_text_end);
1706  if (c == 0)
1707  break;
1708  char_count++;
1709  }
1710  return char_count;
1711 }
1712 
1713 // Based on stb_to_utf8() from github.com/nothings/stb/
1714 static inline int ImTextCharToUtf8(char* buf, int buf_size, unsigned int c)
1715 {
1716  if (c < 0x80)
1717  {
1718  buf[0] = (char)c;
1719  return 1;
1720  }
1721  if (c < 0x800)
1722  {
1723  if (buf_size < 2) return 0;
1724  buf[0] = (char)(0xc0 + (c >> 6));
1725  buf[1] = (char)(0x80 + (c & 0x3f));
1726  return 2;
1727  }
1728  if (c < 0x10000)
1729  {
1730  if (buf_size < 3) return 0;
1731  buf[0] = (char)(0xe0 + (c >> 12));
1732  buf[1] = (char)(0x80 + ((c>> 6) & 0x3f));
1733  buf[2] = (char)(0x80 + ((c ) & 0x3f));
1734  return 3;
1735  }
1736  if (c <= 0x10FFFF)
1737  {
1738  if (buf_size < 4) return 0;
1739  buf[0] = (char)(0xf0 + (c >> 18));
1740  buf[1] = (char)(0x80 + ((c >> 12) & 0x3f));
1741  buf[2] = (char)(0x80 + ((c >> 6) & 0x3f));
1742  buf[3] = (char)(0x80 + ((c ) & 0x3f));
1743  return 4;
1744  }
1745  // Invalid code point, the max unicode is 0x10FFFF
1746  return 0;
1747 }
1748 
1749 // Not optimal but we very rarely use this function.
1750 int ImTextCountUtf8BytesFromChar(const char* in_text, const char* in_text_end)
1751 {
1752  unsigned int dummy = 0;
1753  return ImTextCharFromUtf8(&dummy, in_text, in_text_end);
1754 }
1755 
1756 static inline int ImTextCountUtf8BytesFromChar(unsigned int c)
1757 {
1758  if (c < 0x80) return 1;
1759  if (c < 0x800) return 2;
1760  if (c < 0x10000) return 3;
1761  if (c <= 0x10FFFF) return 4;
1762  return 3;
1763 }
1764 
1765 int ImTextStrToUtf8(char* buf, int buf_size, const ImWchar* in_text, const ImWchar* in_text_end)
1766 {
1767  char* buf_out = buf;
1768  const char* buf_end = buf + buf_size;
1769  while (buf_out < buf_end-1 && (!in_text_end || in_text < in_text_end) && *in_text)
1770  {
1771  unsigned int c = (unsigned int)(*in_text++);
1772  if (c < 0x80)
1773  *buf_out++ = (char)c;
1774  else
1775  buf_out += ImTextCharToUtf8(buf_out, (int)(buf_end-buf_out-1), c);
1776  }
1777  *buf_out = 0;
1778  return (int)(buf_out - buf);
1779 }
1780 
1781 int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end)
1782 {
1783  int bytes_count = 0;
1784  while ((!in_text_end || in_text < in_text_end) && *in_text)
1785  {
1786  unsigned int c = (unsigned int)(*in_text++);
1787  if (c < 0x80)
1788  bytes_count++;
1789  else
1790  bytes_count += ImTextCountUtf8BytesFromChar(c);
1791  }
1792  return bytes_count;
1793 }
1794 
1795 //-----------------------------------------------------------------------------
1796 // [SECTION] MISC HELPERS/UTILITIES (Color functions)
1797 // Note: The Convert functions are early design which are not consistent with other API.
1798 //-----------------------------------------------------------------------------
1799 
1801 {
1802  float t = ((col_b >> IM_COL32_A_SHIFT) & 0xFF) / 255.f;
1803  int r = ImLerp((int)(col_a >> IM_COL32_R_SHIFT) & 0xFF, (int)(col_b >> IM_COL32_R_SHIFT) & 0xFF, t);
1804  int g = ImLerp((int)(col_a >> IM_COL32_G_SHIFT) & 0xFF, (int)(col_b >> IM_COL32_G_SHIFT) & 0xFF, t);
1805  int b = ImLerp((int)(col_a >> IM_COL32_B_SHIFT) & 0xFF, (int)(col_b >> IM_COL32_B_SHIFT) & 0xFF, t);
1806  return IM_COL32(r, g, b, 0xFF);
1807 }
1808 
1810 {
1811  float s = 1.0f/255.0f;
1812  return ImVec4(
1813  ((in >> IM_COL32_R_SHIFT) & 0xFF) * s,
1814  ((in >> IM_COL32_G_SHIFT) & 0xFF) * s,
1815  ((in >> IM_COL32_B_SHIFT) & 0xFF) * s,
1816  ((in >> IM_COL32_A_SHIFT) & 0xFF) * s);
1817 }
1818 
1820 {
1821  ImU32 out;
1822  out = ((ImU32)IM_F32_TO_INT8_SAT(in.x)) << IM_COL32_R_SHIFT;
1823  out |= ((ImU32)IM_F32_TO_INT8_SAT(in.y)) << IM_COL32_G_SHIFT;
1824  out |= ((ImU32)IM_F32_TO_INT8_SAT(in.z)) << IM_COL32_B_SHIFT;
1825  out |= ((ImU32)IM_F32_TO_INT8_SAT(in.w)) << IM_COL32_A_SHIFT;
1826  return out;
1827 }
1828 
1829 // Convert rgb floats ([0-1],[0-1],[0-1]) to hsv floats ([0-1],[0-1],[0-1]), from Foley & van Dam p592
1830 // Optimized http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv
1831 void ImGui::ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v)
1832 {
1833  float K = 0.f;
1834  if (g < b)
1835  {
1836  ImSwap(g, b);
1837  K = -1.f;
1838  }
1839  if (r < g)
1840  {
1841  ImSwap(r, g);
1842  K = -2.f / 6.f - K;
1843  }
1844 
1845  const float chroma = r - (g < b ? g : b);
1846  out_h = ImFabs(K + (g - b) / (6.f * chroma + 1e-20f));
1847  out_s = chroma / (r + 1e-20f);
1848  out_v = r;
1849 }
1850 
1851 // Convert hsv floats ([0-1],[0-1],[0-1]) to rgb floats ([0-1],[0-1],[0-1]), from Foley & van Dam p593
1852 // also http://en.wikipedia.org/wiki/HSL_and_HSV
1853 void ImGui::ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b)
1854 {
1855  if (s == 0.0f)
1856  {
1857  // gray
1858  out_r = out_g = out_b = v;
1859  return;
1860  }
1861 
1862  h = ImFmod(h, 1.0f) / (60.0f/360.0f);
1863  int i = (int)h;
1864  float f = h - (float)i;
1865  float p = v * (1.0f - s);
1866  float q = v * (1.0f - s * f);
1867  float t = v * (1.0f - s * (1.0f - f));
1868 
1869  switch (i)
1870  {
1871  case 0: out_r = v; out_g = t; out_b = p; break;
1872  case 1: out_r = q; out_g = v; out_b = p; break;
1873  case 2: out_r = p; out_g = v; out_b = t; break;
1874  case 3: out_r = p; out_g = q; out_b = v; break;
1875  case 4: out_r = t; out_g = p; out_b = v; break;
1876  case 5: default: out_r = v; out_g = p; out_b = q; break;
1877  }
1878 }
1879 
1880 //-----------------------------------------------------------------------------
1881 // [SECTION] ImGuiStorage
1882 // Helper: Key->value storage
1883 //-----------------------------------------------------------------------------
1884 
1885 // std::lower_bound but without the bullshit
1887 {
1889  ImGuiStorage::ImGuiStoragePair* last = data.Data + data.Size;
1890  size_t count = (size_t)(last - first);
1891  while (count > 0)
1892  {
1893  size_t count2 = count >> 1;
1894  ImGuiStorage::ImGuiStoragePair* mid = first + count2;
1895  if (mid->key < key)
1896  {
1897  first = ++mid;
1898  count -= count2 + 1;
1899  }
1900  else
1901  {
1902  count = count2;
1903  }
1904  }
1905  return first;
1906 }
1907 
1908 // For quicker full rebuild of a storage (instead of an incremental one), you may add all your contents and then sort once.
1910 {
1911  struct StaticFunc
1912  {
1913  static int IMGUI_CDECL PairCompareByID(const void* lhs, const void* rhs)
1914  {
1915  // We can't just do a subtraction because qsort uses signed integers and subtracting our ID doesn't play well with that.
1916  if (((const ImGuiStoragePair*)lhs)->key > ((const ImGuiStoragePair*)rhs)->key) return +1;
1917  if (((const ImGuiStoragePair*)lhs)->key < ((const ImGuiStoragePair*)rhs)->key) return -1;
1918  return 0;
1919  }
1920  };
1921  if (Data.Size > 1)
1922  ImQsort(Data.Data, (size_t)Data.Size, sizeof(ImGuiStoragePair), StaticFunc::PairCompareByID);
1923 }
1924 
1925 int ImGuiStorage::GetInt(ImGuiID key, int default_val) const
1926 {
1928  if (it == Data.end() || it->key != key)
1929  return default_val;
1930  return it->val_i;
1931 }
1932 
1933 bool ImGuiStorage::GetBool(ImGuiID key, bool default_val) const
1934 {
1935  return GetInt(key, default_val ? 1 : 0) != 0;
1936 }
1937 
1938 float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const
1939 {
1941  if (it == Data.end() || it->key != key)
1942  return default_val;
1943  return it->val_f;
1944 }
1945 
1947 {
1949  if (it == Data.end() || it->key != key)
1950  return NULL;
1951  return it->val_p;
1952 }
1953 
1954 // References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer.
1955 int* ImGuiStorage::GetIntRef(ImGuiID key, int default_val)
1956 {
1958  if (it == Data.end() || it->key != key)
1959  it = Data.insert(it, ImGuiStoragePair(key, default_val));
1960  return &it->val_i;
1961 }
1962 
1963 bool* ImGuiStorage::GetBoolRef(ImGuiID key, bool default_val)
1964 {
1965  return (bool*)GetIntRef(key, default_val ? 1 : 0);
1966 }
1967 
1968 float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val)
1969 {
1971  if (it == Data.end() || it->key != key)
1972  it = Data.insert(it, ImGuiStoragePair(key, default_val));
1973  return &it->val_f;
1974 }
1975 
1976 void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val)
1977 {
1979  if (it == Data.end() || it->key != key)
1980  it = Data.insert(it, ImGuiStoragePair(key, default_val));
1981  return &it->val_p;
1982 }
1983 
1984 // FIXME-OPT: Need a way to reuse the result of lower_bound when doing GetInt()/SetInt() - not too bad because it only happens on explicit interaction (maximum one a frame)
1986 {
1988  if (it == Data.end() || it->key != key)
1989  {
1990  Data.insert(it, ImGuiStoragePair(key, val));
1991  return;
1992  }
1993  it->val_i = val;
1994 }
1995 
1997 {
1998  SetInt(key, val ? 1 : 0);
1999 }
2000 
2002 {
2004  if (it == Data.end() || it->key != key)
2005  {
2006  Data.insert(it, ImGuiStoragePair(key, val));
2007  return;
2008  }
2009  it->val_f = val;
2010 }
2011 
2013 {
2015  if (it == Data.end() || it->key != key)
2016  {
2017  Data.insert(it, ImGuiStoragePair(key, val));
2018  return;
2019  }
2020  it->val_p = val;
2021 }
2022 
2024 {
2025  for (int i = 0; i < Data.Size; i++)
2026  Data[i].val_i = v;
2027 }
2028 
2029 //-----------------------------------------------------------------------------
2030 // [SECTION] ImGuiTextFilter
2031 //-----------------------------------------------------------------------------
2032 
2033 // Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]"
2034 ImGuiTextFilter::ImGuiTextFilter(const char* default_filter)
2035 {
2036  if (default_filter)
2037  {
2038  ImStrncpy(InputBuf, default_filter, IM_ARRAYSIZE(InputBuf));
2039  Build();
2040  }
2041  else
2042  {
2043  InputBuf[0] = 0;
2044  CountGrep = 0;
2045  }
2046 }
2047 
2048 bool ImGuiTextFilter::Draw(const char* label, float width)
2049 {
2050  if (width != 0.0f)
2052  bool value_changed = ImGui::InputText(label, InputBuf, IM_ARRAYSIZE(InputBuf));
2053  if (value_changed)
2054  Build();
2055  return value_changed;
2056 }
2057 
2059 {
2060  out->resize(0);
2061  const char* wb = b;
2062  const char* we = wb;
2063  while (we < e)
2064  {
2065  if (*we == separator)
2066  {
2067  out->push_back(ImGuiTextRange(wb, we));
2068  wb = we + 1;
2069  }
2070  we++;
2071  }
2072  if (wb != we)
2073  out->push_back(ImGuiTextRange(wb, we));
2074 }
2075 
2077 {
2078  Filters.resize(0);
2079  ImGuiTextRange input_range(InputBuf, InputBuf+strlen(InputBuf));
2080  input_range.split(',', &Filters);
2081 
2082  CountGrep = 0;
2083  for (int i = 0; i != Filters.Size; i++)
2084  {
2085  ImGuiTextRange& f = Filters[i];
2086  while (f.b < f.e && ImCharIsBlankA(f.b[0]))
2087  f.b++;
2088  while (f.e > f.b && ImCharIsBlankA(f.e[-1]))
2089  f.e--;
2090  if (f.empty())
2091  continue;
2092  if (Filters[i].b[0] != '-')
2093  CountGrep += 1;
2094  }
2095 }
2096 
2097 bool ImGuiTextFilter::PassFilter(const char* text, const char* text_end) const
2098 {
2099  if (Filters.empty())
2100  return true;
2101 
2102  if (text == NULL)
2103  text = "";
2104 
2105  for (int i = 0; i != Filters.Size; i++)
2106  {
2107  const ImGuiTextRange& f = Filters[i];
2108  if (f.empty())
2109  continue;
2110  if (f.b[0] == '-')
2111  {
2112  // Subtract
2113  if (ImStristr(text, text_end, f.b + 1, f.e) != NULL)
2114  return false;
2115  }
2116  else
2117  {
2118  // Grep
2119  if (ImStristr(text, text_end, f.b, f.e) != NULL)
2120  return true;
2121  }
2122  }
2123 
2124  // Implicit * grep
2125  if (CountGrep == 0)
2126  return true;
2127 
2128  return false;
2129 }
2130 
2131 //-----------------------------------------------------------------------------
2132 // [SECTION] ImGuiTextBuffer
2133 //-----------------------------------------------------------------------------
2134 
2135 // On some platform vsnprintf() takes va_list by reference and modifies it.
2136 // va_copy is the 'correct' way to copy a va_list but Visual Studio prior to 2013 doesn't have it.
2137 #ifndef va_copy
2138 #if defined(__GNUC__) || defined(__clang__)
2139 #define va_copy(dest, src) __builtin_va_copy(dest, src)
2140 #else
2141 #define va_copy(dest, src) (dest = src)
2142 #endif
2143 #endif
2144 
2145 char ImGuiTextBuffer::EmptyString[1] = { 0 };
2146 
2147 void ImGuiTextBuffer::append(const char* str, const char* str_end)
2148 {
2149  int len = str_end ? (int)(str_end - str) : (int)strlen(str);
2150 
2151  // Add zero-terminator the first time
2152  const int write_off = (Buf.Size != 0) ? Buf.Size : 1;
2153  const int needed_sz = write_off + len;
2154  if (write_off + len >= Buf.Capacity)
2155  {
2156  int new_capacity = Buf.Capacity * 2;
2157  Buf.reserve(needed_sz > new_capacity ? needed_sz : new_capacity);
2158  }
2159 
2160  Buf.resize(needed_sz);
2161  memcpy(&Buf[write_off - 1], str, (size_t)len);
2162  Buf[write_off - 1 + len] = 0;
2163 }
2164 
2165 void ImGuiTextBuffer::appendf(const char* fmt, ...)
2166 {
2167  va_list args;
2168  va_start(args, fmt);
2169  appendfv(fmt, args);
2170  va_end(args);
2171 }
2172 
2173 // Helper: Text buffer for logging/accumulating text
2174 void ImGuiTextBuffer::appendfv(const char* fmt, va_list args)
2175 {
2176  va_list args_copy;
2177  va_copy(args_copy, args);
2178 
2179  int len = ImFormatStringV(NULL, 0, fmt, args); // FIXME-OPT: could do a first pass write attempt, likely successful on first pass.
2180  if (len <= 0)
2181  {
2182  va_end(args_copy);
2183  return;
2184  }
2185 
2186  // Add zero-terminator the first time
2187  const int write_off = (Buf.Size != 0) ? Buf.Size : 1;
2188  const int needed_sz = write_off + len;
2189  if (write_off + len >= Buf.Capacity)
2190  {
2191  int new_capacity = Buf.Capacity * 2;
2192  Buf.reserve(needed_sz > new_capacity ? needed_sz : new_capacity);
2193  }
2194 
2195  Buf.resize(needed_sz);
2196  ImFormatStringV(&Buf[write_off - 1], (size_t)len + 1, fmt, args_copy);
2197  va_end(args_copy);
2198 }
2199 
2200 //-----------------------------------------------------------------------------
2201 // [SECTION] ImGuiListClipper
2202 // This is currently not as flexible/powerful as it should be and really confusing/spaghetti, mostly because we changed
2203 // the API mid-way through development and support two ways to using the clipper, needs some rework (see TODO)
2204 //-----------------------------------------------------------------------------
2205 
2206 // Helper to calculate coarse clipping of large list of evenly sized items.
2207 // NB: Prefer using the ImGuiListClipper higher-level helper if you can! Read comments and instructions there on how those use this sort of pattern.
2208 // NB: 'items_count' is only used to clamp the result, if you don't know your count you can use INT_MAX
2209 void ImGui::CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end)
2210 {
2211  ImGuiContext& g = *GImGui;
2212  ImGuiWindow* window = g.CurrentWindow;
2213  if (g.LogEnabled)
2214  {
2215  // If logging is active, do not perform any clipping
2216  *out_items_display_start = 0;
2217  *out_items_display_end = items_count;
2218  return;
2219  }
2220  if (window->SkipItems)
2221  {
2222  *out_items_display_start = *out_items_display_end = 0;
2223  return;
2224  }
2225 
2226  // We create the union of the ClipRect and the NavScoringRect which at worst should be 1 page away from ClipRect
2227  ImRect unclipped_rect = window->ClipRect;
2228  if (g.NavMoveRequest)
2229  unclipped_rect.Add(g.NavScoringRectScreen);
2230 
2231  const ImVec2 pos = window->DC.CursorPos;
2232  int start = (int)((unclipped_rect.Min.y - pos.y) / items_height);
2233  int end = (int)((unclipped_rect.Max.y - pos.y) / items_height);
2234 
2235  // When performing a navigation request, ensure we have one item extra in the direction we are moving to
2236  if (g.NavMoveRequest && g.NavMoveClipDir == ImGuiDir_Up)
2237  start--;
2238  if (g.NavMoveRequest && g.NavMoveClipDir == ImGuiDir_Down)
2239  end++;
2240 
2241  start = ImClamp(start, 0, items_count);
2242  end = ImClamp(end + 1, start, items_count);
2243  *out_items_display_start = start;
2244  *out_items_display_end = end;
2245 }
2246 
2247 static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height)
2248 {
2249  // Set cursor position and a few other things so that SetScrollHereY() and Columns() can work when seeking cursor.
2250  // FIXME: It is problematic that we have to do that here, because custom/equivalent end-user code would stumble on the same issue.
2251  // The clipper should probably have a 4th step to display the last item in a regular manner.
2252  ImGuiContext& g = *GImGui;
2253  ImGuiWindow* window = g.CurrentWindow;
2254  window->DC.CursorPos.y = pos_y;
2255  window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, pos_y);
2256  window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHereY() can properly function after the end of our clipper usage.
2257  window->DC.PrevLineSize.y = (line_height - g.Style.ItemSpacing.y); // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list.
2258  if (ImGuiColumns* columns = window->DC.CurrentColumns)
2259  columns->LineMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly
2260 }
2261 
2262 // Use case A: Begin() called from constructor with items_height<0, then called again from Sync() in StepNo 1
2263 // Use case B: Begin() called from constructor with items_height>0
2264 // FIXME-LEGACY: Ideally we should remove the Begin/End functions but they are part of the legacy API we still support. This is why some of the code in Step() calling Begin() and reassign some fields, spaghetti style.
2265 void ImGuiListClipper::Begin(int count, float items_height)
2266 {
2267  ImGuiContext& g = *GImGui;
2268  ImGuiWindow* window = g.CurrentWindow;
2269 
2270  StartPosY = window->DC.CursorPos.y;
2271  ItemsHeight = items_height;
2272  ItemsCount = count;
2273  StepNo = 0;
2274  DisplayEnd = DisplayStart = -1;
2275  if (ItemsHeight > 0.0f)
2276  {
2277  ImGui::CalcListClipping(ItemsCount, ItemsHeight, &DisplayStart, &DisplayEnd); // calculate how many to clip/display
2278  if (DisplayStart > 0)
2279  SetCursorPosYAndSetupDummyPrevLine(StartPosY + DisplayStart * ItemsHeight, ItemsHeight); // advance cursor
2280  StepNo = 2;
2281  }
2282 }
2283 
2285 {
2286  if (ItemsCount < 0)
2287  return;
2288  // In theory here we should assert that ImGui::GetCursorPosY() == StartPosY + DisplayEnd * ItemsHeight, but it feels saner to just seek at the end and not assert/crash the user.
2289  if (ItemsCount < INT_MAX)
2290  SetCursorPosYAndSetupDummyPrevLine(StartPosY + ItemsCount * ItemsHeight, ItemsHeight); // advance cursor
2291  ItemsCount = -1;
2292  StepNo = 3;
2293 }
2294 
2296 {
2297  ImGuiContext& g = *GImGui;
2298  ImGuiWindow* window = g.CurrentWindow;
2299 
2300  if (ItemsCount == 0 || window->SkipItems)
2301  {
2302  ItemsCount = -1;
2303  return false;
2304  }
2305  if (StepNo == 0) // Step 0: the clipper let you process the first element, regardless of it being visible or not, so we can measure the element height.
2306  {
2307  DisplayStart = 0;
2308  DisplayEnd = 1;
2309  StartPosY = window->DC.CursorPos.y;
2310  StepNo = 1;
2311  return true;
2312  }
2313  if (StepNo == 1) // Step 1: the clipper infer height from first element, calculate the actual range of elements to display, and position the cursor before the first element.
2314  {
2315  if (ItemsCount == 1) { ItemsCount = -1; return false; }
2316  float items_height = window->DC.CursorPos.y - StartPosY;
2317  IM_ASSERT(items_height > 0.0f); // If this triggers, it means Item 0 hasn't moved the cursor vertically
2318  Begin(ItemsCount - 1, items_height);
2319  DisplayStart++;
2320  DisplayEnd++;
2321  StepNo = 3;
2322  return true;
2323  }
2324  if (StepNo == 2) // Step 2: dummy step only required if an explicit items_height was passed to constructor or Begin() and user still call Step(). Does nothing and switch to Step 3.
2325  {
2326  IM_ASSERT(DisplayStart >= 0 && DisplayEnd >= 0);
2327  StepNo = 3;
2328  return true;
2329  }
2330  if (StepNo == 3) // Step 3: the clipper validate that we have reached the expected Y position (corresponding to element DisplayEnd), advance the cursor to the end of the list and then returns 'false' to end the loop.
2331  End();
2332  return false;
2333 }
2334 
2335 //-----------------------------------------------------------------------------
2336 // [SECTION] STYLING
2337 //-----------------------------------------------------------------------------
2338 
2340 {
2341  IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext() ?");
2342  return GImGui->Style;
2343 }
2344 
2346 {
2347  ImGuiStyle& style = GImGui->Style;
2348  ImVec4 c = style.Colors[idx];
2349  c.w *= style.Alpha * alpha_mul;
2350  return ColorConvertFloat4ToU32(c);
2351 }
2352 
2354 {
2355  ImGuiStyle& style = GImGui->Style;
2356  ImVec4 c = col;
2357  c.w *= style.Alpha;
2358  return ColorConvertFloat4ToU32(c);
2359 }
2360 
2362 {
2363  ImGuiStyle& style = GImGui->Style;
2364  return style.Colors[idx];
2365 }
2366 
2368 {
2369  ImGuiStyle& style = GImGui->Style;
2370  if (style.Alpha >= 1.0f)
2371  return col;
2372  ImU32 a = (col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT;
2373  a = (ImU32)(a * style.Alpha); // We don't need to clamp 0..255 because Style.Alpha is in 0..1 range.
2374  return (col & ~IM_COL32_A_MASK) | (a << IM_COL32_A_SHIFT);
2375 }
2376 
2377 // FIXME: This may incur a round-trip (if the end user got their data from a float4) but eventually we aim to store the in-flight colors as ImU32
2379 {
2380  ImGuiContext& g = *GImGui;
2381  ImGuiColorMod backup;
2382  backup.Col = idx;
2383  backup.BackupValue = g.Style.Colors[idx];
2384  g.ColorModifiers.push_back(backup);
2385  g.Style.Colors[idx] = ColorConvertU32ToFloat4(col);
2386 }
2387 
2389 {
2390  ImGuiContext& g = *GImGui;
2391  ImGuiColorMod backup;
2392  backup.Col = idx;
2393  backup.BackupValue = g.Style.Colors[idx];
2394  g.ColorModifiers.push_back(backup);
2395  g.Style.Colors[idx] = col;
2396 }
2397 
2399 {
2400  ImGuiContext& g = *GImGui;
2401  while (count > 0)
2402  {
2403  ImGuiColorMod& backup = g.ColorModifiers.back();
2404  g.Style.Colors[backup.Col] = backup.BackupValue;
2405  g.ColorModifiers.pop_back();
2406  count--;
2407  }
2408 }
2409 
2411 {
2415  void* GetVarPtr(ImGuiStyle* style) const { return (void*)((unsigned char*)style + Offset); }
2416 };
2417 
2419 {
2420  { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha
2421  { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding
2422  { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding
2423  { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize
2424  { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize
2425  { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowTitleAlign) }, // ImGuiStyleVar_WindowTitleAlign
2426  { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding
2427  { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize
2428  { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding
2429  { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize
2430  { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding
2431  { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding
2432  { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize
2433  { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing
2434  { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing
2435  { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing
2436  { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarSize) }, // ImGuiStyleVar_ScrollbarSize
2437  { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarRounding) }, // ImGuiStyleVar_ScrollbarRounding
2438  { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize
2439  { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding
2440  { ImGuiDataType_Float, 1, (ImU32)IM_OFFSETOF(ImGuiStyle, TabRounding) }, // ImGuiStyleVar_TabRounding
2441  { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign
2442  { ImGuiDataType_Float, 2, (ImU32)IM_OFFSETOF(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign
2443 };
2444 
2446 {
2447  IM_ASSERT(idx >= 0 && idx < ImGuiStyleVar_COUNT);
2449  return &GStyleVarInfo[idx];
2450 }
2451 
2453 {
2454  const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx);
2455  if (var_info->Type == ImGuiDataType_Float && var_info->Count == 1)
2456  {
2457  ImGuiContext& g = *GImGui;
2458  float* pvar = (float*)var_info->GetVarPtr(&g.Style);
2459  g.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar));
2460  *pvar = val;
2461  return;
2462  }
2463  IM_ASSERT(0 && "Called PushStyleVar() float variant but variable is not a float!");
2464 }
2465 
2467 {
2468  const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx);
2469  if (var_info->Type == ImGuiDataType_Float && var_info->Count == 2)
2470  {
2471  ImGuiContext& g = *GImGui;
2472  ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&g.Style);
2473  g.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar));
2474  *pvar = val;
2475  return;
2476  }
2477  IM_ASSERT(0 && "Called PushStyleVar() ImVec2 variant but variable is not a ImVec2!");
2478 }
2479 
2481 {
2482  ImGuiContext& g = *GImGui;
2483  while (count > 0)
2484  {
2485  // We avoid a generic memcpy(data, &backup.Backup.., GDataTypeSize[info->Type] * info->Count), the overhead in Debug is not worth it.
2486  ImGuiStyleMod& backup = g.StyleModifiers.back();
2487  const ImGuiStyleVarInfo* info = GetStyleVarInfo(backup.VarIdx);
2488  void* data = info->GetVarPtr(&g.Style);
2489  if (info->Type == ImGuiDataType_Float && info->Count == 1) { ((float*)data)[0] = backup.BackupFloat[0]; }
2490  else if (info->Type == ImGuiDataType_Float && info->Count == 2) { ((float*)data)[0] = backup.BackupFloat[0]; ((float*)data)[1] = backup.BackupFloat[1]; }
2491  g.StyleModifiers.pop_back();
2492  count--;
2493  }
2494 }
2495 
2497 {
2498  // Create switch-case from enum with regexp: ImGuiCol_{.*}, --> case ImGuiCol_\1: return "\1";
2499  switch (idx)
2500  {
2501  case ImGuiCol_Text: return "Text";
2502  case ImGuiCol_TextDisabled: return "TextDisabled";
2503  case ImGuiCol_WindowBg: return "WindowBg";
2504  case ImGuiCol_ChildBg: return "ChildBg";
2505  case ImGuiCol_PopupBg: return "PopupBg";
2506  case ImGuiCol_Border: return "Border";
2507  case ImGuiCol_BorderShadow: return "BorderShadow";
2508  case ImGuiCol_FrameBg: return "FrameBg";
2509  case ImGuiCol_FrameBgHovered: return "FrameBgHovered";
2510  case ImGuiCol_FrameBgActive: return "FrameBgActive";
2511  case ImGuiCol_TitleBg: return "TitleBg";
2512  case ImGuiCol_TitleBgActive: return "TitleBgActive";
2513  case ImGuiCol_TitleBgCollapsed: return "TitleBgCollapsed";
2514  case ImGuiCol_MenuBarBg: return "MenuBarBg";
2515  case ImGuiCol_ScrollbarBg: return "ScrollbarBg";
2516  case ImGuiCol_ScrollbarGrab: return "ScrollbarGrab";
2517  case ImGuiCol_ScrollbarGrabHovered: return "ScrollbarGrabHovered";
2518  case ImGuiCol_ScrollbarGrabActive: return "ScrollbarGrabActive";
2519  case ImGuiCol_CheckMark: return "CheckMark";
2520  case ImGuiCol_SliderGrab: return "SliderGrab";
2521  case ImGuiCol_SliderGrabActive: return "SliderGrabActive";
2522  case ImGuiCol_Button: return "Button";
2523  case ImGuiCol_ButtonHovered: return "ButtonHovered";
2524  case ImGuiCol_ButtonActive: return "ButtonActive";
2525  case ImGuiCol_Header: return "Header";
2526  case ImGuiCol_HeaderHovered: return "HeaderHovered";
2527  case ImGuiCol_HeaderActive: return "HeaderActive";
2528  case ImGuiCol_Separator: return "Separator";
2529  case ImGuiCol_SeparatorHovered: return "SeparatorHovered";
2530  case ImGuiCol_SeparatorActive: return "SeparatorActive";
2531  case ImGuiCol_ResizeGrip: return "ResizeGrip";
2532  case ImGuiCol_ResizeGripHovered: return "ResizeGripHovered";
2533  case ImGuiCol_ResizeGripActive: return "ResizeGripActive";
2534  case ImGuiCol_Tab: return "Tab";
2535  case ImGuiCol_TabHovered: return "TabHovered";
2536  case ImGuiCol_TabActive: return "TabActive";
2537  case ImGuiCol_TabUnfocused: return "TabUnfocused";
2538  case ImGuiCol_TabUnfocusedActive: return "TabUnfocusedActive";
2539  case ImGuiCol_PlotLines: return "PlotLines";
2540  case ImGuiCol_PlotLinesHovered: return "PlotLinesHovered";
2541  case ImGuiCol_PlotHistogram: return "PlotHistogram";
2542  case ImGuiCol_PlotHistogramHovered: return "PlotHistogramHovered";
2543  case ImGuiCol_TextSelectedBg: return "TextSelectedBg";
2544  case ImGuiCol_DragDropTarget: return "DragDropTarget";
2545  case ImGuiCol_NavHighlight: return "NavHighlight";
2546  case ImGuiCol_NavWindowingHighlight: return "NavWindowingHighlight";
2547  case ImGuiCol_NavWindowingDimBg: return "NavWindowingDimBg";
2548  case ImGuiCol_ModalWindowDimBg: return "ModalWindowDimBg";
2549  }
2550  IM_ASSERT(0);
2551  return "Unknown";
2552 }
2553 
2554 //-----------------------------------------------------------------------------
2555 // [SECTION] RENDER HELPERS
2556 // Some of those (internal) functions are currently quite a legacy mess - their signature and behavior will change,
2557 // we need a nicer separation between low-level functions and high-level functions relying on the ImGui context.
2558 // Also see imgui_draw.cpp for some more which have been reworked to not rely on ImGui:: context.
2559 //-----------------------------------------------------------------------------
2560 
2561 const char* ImGui::FindRenderedTextEnd(const char* text, const char* text_end)
2562 {
2563  const char* text_display_end = text;
2564  if (!text_end)
2565  text_end = (const char*)-1;
2566 
2567  while (text_display_end < text_end && *text_display_end != '\0' && (text_display_end[0] != '#' || text_display_end[1] != '#'))
2568  text_display_end++;
2569  return text_display_end;
2570 }
2571 
2572 // Internal ImGui functions to render text
2573 // RenderText***() functions calls ImDrawList::AddText() calls ImBitmapFont::RenderText()
2574 void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash)
2575 {
2576  ImGuiContext& g = *GImGui;
2577  ImGuiWindow* window = g.CurrentWindow;
2578 
2579  // Hide anything after a '##' string
2580  const char* text_display_end;
2581  if (hide_text_after_hash)
2582  {
2583  text_display_end = FindRenderedTextEnd(text, text_end);
2584  }
2585  else
2586  {
2587  if (!text_end)
2588  text_end = text + strlen(text); // FIXME-OPT
2589  text_display_end = text_end;
2590  }
2591 
2592  if (text != text_display_end)
2593  {
2594  window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end);
2595  if (g.LogEnabled)
2596  LogRenderedText(&pos, text, text_display_end);
2597  }
2598 }
2599 
2600 void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width)
2601 {
2602  ImGuiContext& g = *GImGui;
2603  ImGuiWindow* window = g.CurrentWindow;
2604 
2605  if (!text_end)
2606  text_end = text + strlen(text); // FIXME-OPT
2607 
2608  if (text != text_end)
2609  {
2610  window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width);
2611  if (g.LogEnabled)
2612  LogRenderedText(&pos, text, text_end);
2613  }
2614 }
2615 
2616 // Default clip_rect uses (pos_min,pos_max)
2617 // Handle clipping on CPU immediately (vs typically let the GPU clip the triangles that are overlapping the clipping rectangle edges)
2618 void ImGui::RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_display_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect)
2619 {
2620  // Perform CPU side clipping for single clipped element to avoid using scissor state
2621  ImVec2 pos = pos_min;
2622  const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_display_end, false, 0.0f);
2623 
2624  const ImVec2* clip_min = clip_rect ? &clip_rect->Min : &pos_min;
2625  const ImVec2* clip_max = clip_rect ? &clip_rect->Max : &pos_max;
2626  bool need_clipping = (pos.x + text_size.x >= clip_max->x) || (pos.y + text_size.y >= clip_max->y);
2627  if (clip_rect) // If we had no explicit clipping rectangle then pos==clip_min
2628  need_clipping |= (pos.x < clip_min->x) || (pos.y < clip_min->y);
2629 
2630  // Align whole block. We should defer that to the better rendering function when we'll have support for individual line alignment.
2631  if (align.x > 0.0f) pos.x = ImMax(pos.x, pos.x + (pos_max.x - pos.x - text_size.x) * align.x);
2632  if (align.y > 0.0f) pos.y = ImMax(pos.y, pos.y + (pos_max.y - pos.y - text_size.y) * align.y);
2633 
2634  // Render
2635  if (need_clipping)
2636  {
2637  ImVec4 fine_clip_rect(clip_min->x, clip_min->y, clip_max->x, clip_max->y);
2638  draw_list->AddText(NULL, 0.0f, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, &fine_clip_rect);
2639  }
2640  else
2641  {
2642  draw_list->AddText(NULL, 0.0f, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, NULL);
2643  }
2644 }
2645 
2646 void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect)
2647 {
2648  // Hide anything after a '##' string
2649  const char* text_display_end = FindRenderedTextEnd(text, text_end);
2650  const int text_len = (int)(text_display_end - text);
2651  if (text_len == 0)
2652  return;
2653 
2654  ImGuiContext& g = *GImGui;
2655  ImGuiWindow* window = g.CurrentWindow;
2656  RenderTextClippedEx(window->DrawList, pos_min, pos_max, text, text_display_end, text_size_if_known, align, clip_rect);
2657  if (g.LogEnabled)
2658  LogRenderedText(&pos_min, text, text_display_end);
2659 }
2660 
2661 
2662 // Another overly complex function until we reorganize everything into a nice all-in-one helper.
2663 // This is made more complex because we have dissociated the layout rectangle (pos_min..pos_max) which define _where_ the ellipsis is, from actual clipping of text and limit of the ellipsis display.
2664 // This is because in the context of tabs we selectively hide part of the text when the Close Button appears, but we don't want the ellipsis to move.
2665 void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float clip_max_x, float ellipsis_max_x, const char* text, const char* text_end_full, const ImVec2* text_size_if_known)
2666 {
2667  ImGuiContext& g = *GImGui;
2668  if (text_end_full == NULL)
2669  text_end_full = FindRenderedTextEnd(text);
2670  const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_end_full, false, 0.0f);
2671 
2672  //draw_list->AddLine(ImVec2(pos_max.x, pos_min.y - 4), ImVec2(pos_max.x, pos_max.y + 4), IM_COL32(0, 0, 255, 255));
2673  //draw_list->AddLine(ImVec2(ellipsis_max_x, pos_min.y-2), ImVec2(ellipsis_max_x, pos_max.y+2), IM_COL32(0, 255, 0, 255));
2674  //draw_list->AddLine(ImVec2(clip_max_x, pos_min.y), ImVec2(clip_max_x, pos_max.y), IM_COL32(255, 0, 0, 255));
2675  // FIXME: We could technically remove (last_glyph->AdvanceX - last_glyph->X1) from text_size.x here and save a few pixels.
2676  if (text_size.x > pos_max.x - pos_min.x)
2677  {
2678  // Hello wo...
2679  // | | |
2680  // min max ellipsis_max
2681  // <-> this is generally some padding value
2682 
2683  const ImFont* font = draw_list->_Data->Font;
2684  const float font_size = draw_list->_Data->FontSize;
2685  const char* text_end_ellipsis = NULL;
2686 
2687  ImWchar ellipsis_char = font->EllipsisChar;
2688  int ellipsis_char_count = 1;
2689  if (ellipsis_char == (ImWchar)-1)
2690  {
2691  ellipsis_char = (ImWchar)'.';
2692  ellipsis_char_count = 3;
2693  }
2694  const ImFontGlyph* glyph = font->FindGlyph(ellipsis_char);
2695 
2696  float ellipsis_glyph_width = glyph->X1; // Width of the glyph with no padding on either side
2697  float ellipsis_total_width = ellipsis_glyph_width; // Full width of entire ellipsis
2698 
2699  if (ellipsis_char_count > 1)
2700  {
2701  // Full ellipsis size without free spacing after it.
2702  const float spacing_between_dots = 1.0f * (draw_list->_Data->FontSize / font->FontSize);
2703  ellipsis_glyph_width = glyph->X1 - glyph->X0 + spacing_between_dots;
2704  ellipsis_total_width = ellipsis_glyph_width * (float)ellipsis_char_count - spacing_between_dots;
2705  }
2706 
2707  // We can now claim the space between pos_max.x and ellipsis_max.x
2708  const float text_avail_width = ImMax((ImMax(pos_max.x, ellipsis_max_x) - ellipsis_total_width) - pos_min.x, 1.0f);
2709  float text_size_clipped_x = font->CalcTextSizeA(font_size, text_avail_width, 0.0f, text, text_end_full, &text_end_ellipsis).x;
2710  if (text == text_end_ellipsis && text_end_ellipsis < text_end_full)
2711  {
2712  // Always display at least 1 character if there's no room for character + ellipsis
2713  text_end_ellipsis = text + ImTextCountUtf8BytesFromChar(text, text_end_full);
2714  text_size_clipped_x = font->CalcTextSizeA(font_size, FLT_MAX, 0.0f, text, text_end_ellipsis).x;
2715  }
2716  while (text_end_ellipsis > text && ImCharIsBlankA(text_end_ellipsis[-1]))
2717  {
2718  // Trim trailing space before ellipsis (FIXME: Supporting non-ascii blanks would be nice, for this we need a function to backtrack in UTF-8 text)
2719  text_end_ellipsis--;
2720  text_size_clipped_x -= font->CalcTextSizeA(font_size, FLT_MAX, 0.0f, text_end_ellipsis, text_end_ellipsis + 1).x; // Ascii blanks are always 1 byte
2721  }
2722 
2723  // Render text, render ellipsis
2724  RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, text_end_ellipsis, &text_size, ImVec2(0.0f, 0.0f));
2725  float ellipsis_x = pos_min.x + text_size_clipped_x;
2726  if (ellipsis_x + ellipsis_total_width <= ellipsis_max_x)
2727  for (int i = 0; i < ellipsis_char_count; i++)
2728  {
2729  font->RenderChar(draw_list, font_size, ImVec2(ellipsis_x, pos_min.y), GetColorU32(ImGuiCol_Text), ellipsis_char);
2730  ellipsis_x += ellipsis_glyph_width;
2731  }
2732  }
2733  else
2734  {
2735  RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, text_end_full, &text_size, ImVec2(0.0f, 0.0f));
2736  }
2737 
2738  if (g.LogEnabled)
2739  LogRenderedText(&pos_min, text, text_end_full);
2740 }
2741 
2742 // Render a rectangle shaped with optional rounding and borders
2743 void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, float rounding)
2744 {
2745  ImGuiContext& g = *GImGui;
2746  ImGuiWindow* window = g.CurrentWindow;
2747  window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding);
2748  const float border_size = g.Style.FrameBorderSize;
2749  if (border && border_size > 0.0f)
2750  {
2751  window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ImDrawCornerFlags_All, border_size);
2752  window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size);
2753  }
2754 }
2755 
2756 void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding)
2757 {
2758  ImGuiContext& g = *GImGui;
2759  ImGuiWindow* window = g.CurrentWindow;
2760  const float border_size = g.Style.FrameBorderSize;
2761  if (border_size > 0.0f)
2762  {
2763  window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ImDrawCornerFlags_All, border_size);
2764  window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size);
2765  }
2766 }
2767 
2769 {
2770  ImGuiContext& g = *GImGui;
2771  if (id != g.NavId)
2772  return;
2773  if (g.NavDisableHighlight && !(flags & ImGuiNavHighlightFlags_AlwaysDraw))
2774  return;
2775  ImGuiWindow* window = g.CurrentWindow;
2776  if (window->DC.NavHideHighlightOneFrame)
2777  return;
2778 
2779  float rounding = (flags & ImGuiNavHighlightFlags_NoRounding) ? 0.0f : g.Style.FrameRounding;
2780  ImRect display_rect = bb;
2781  display_rect.ClipWith(window->ClipRect);
2783  {
2784  const float THICKNESS = 2.0f;
2785  const float DISTANCE = 3.0f + THICKNESS * 0.5f;
2786  display_rect.Expand(ImVec2(DISTANCE,DISTANCE));
2787  bool fully_visible = window->ClipRect.Contains(display_rect);
2788  if (!fully_visible)
2789  window->DrawList->PushClipRect(display_rect.Min, display_rect.Max);
2790  window->DrawList->AddRect(display_rect.Min + ImVec2(THICKNESS*0.5f,THICKNESS*0.5f), display_rect.Max - ImVec2(THICKNESS*0.5f,THICKNESS*0.5f), GetColorU32(ImGuiCol_NavHighlight), rounding, ImDrawCornerFlags_All, THICKNESS);
2791  if (!fully_visible)
2792  window->DrawList->PopClipRect();
2793  }
2795  {
2796  window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavHighlight), rounding, ~0, 1.0f);
2797  }
2798 }
2799 
2800 //-----------------------------------------------------------------------------
2801 // [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!)
2802 //-----------------------------------------------------------------------------
2803 
2804 // ImGuiWindow is mostly a dumb struct. It merely has a constructor and a few helper methods
2806  : DrawListInst(&context->DrawListSharedData)
2807 {
2808  Name = ImStrdup(name);
2809  ID = ImHashStr(name);
2810  IDStack.push_back(ID);
2812  Pos = ImVec2(0.0f, 0.0f);
2813  Size = SizeFull = ImVec2(0.0f, 0.0f);
2815  WindowPadding = ImVec2(0.0f, 0.0f);
2816  WindowRounding = 0.0f;
2817  WindowBorderSize = 0.0f;
2818  NameBufLen = (int)strlen(name) + 1;
2819  MoveId = GetID("#MOVE");
2820  ChildId = 0;
2821  Scroll = ImVec2(0.0f, 0.0f);
2822  ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
2823  ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f);
2824  ScrollbarSizes = ImVec2(0.0f, 0.0f);
2825  ScrollbarX = ScrollbarY = false;
2826  Active = WasActive = false;
2827  WriteAccessed = false;
2828  Collapsed = false;
2829  WantCollapseToggle = false;
2830  SkipItems = false;
2831  Appearing = false;
2832  Hidden = false;
2833  IsFallbackWindow = false;
2834  HasCloseButton = false;
2835  ResizeBorderHeld = -1;
2836  BeginCount = 0;
2839  PopupId = 0;
2841  AutoFitChildAxises = 0x00;
2842  AutoFitOnlyGrows = false;
2846  SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX);
2847 
2848  InnerRect = ImRect(0.0f, 0.0f, 0.0f, 0.0f); // Clear so the InnerRect.GetSize() code in Begin() doesn't lead to overflow even if the result isn't used.
2849 
2850  LastFrameActive = -1;
2851  LastTimeActive = -1.0f;
2852  ItemWidthDefault = 0.0f;
2853  FontWindowScale = 1.0f;
2854  SettingsOffset = -1;
2855 
2858  ParentWindow = NULL;
2859  RootWindow = NULL;
2862 
2863  NavLastIds[0] = NavLastIds[1] = 0;
2864  NavRectRel[0] = NavRectRel[1] = ImRect();
2866 
2867  MemoryCompacted = false;
2869 }
2870 
2872 {
2874  IM_DELETE(Name);
2875  for (int i = 0; i != ColumnsStorage.Size; i++)
2877 }
2878 
2879 ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end)
2880 {
2881  ImGuiID seed = IDStack.back();
2882  ImGuiID id = ImHashStr(str, str_end ? (str_end - str) : 0, seed);
2883  ImGui::KeepAliveID(id);
2884  return id;
2885 }
2886 
2887 ImGuiID ImGuiWindow::GetID(const void* ptr)
2888 {
2889  ImGuiID seed = IDStack.back();
2890  ImGuiID id = ImHashData(&ptr, sizeof(void*), seed);
2891  ImGui::KeepAliveID(id);
2892  return id;
2893 }
2894 
2896 {
2897  ImGuiID seed = IDStack.back();
2898  ImGuiID id = ImHashData(&n, sizeof(n), seed);
2899  ImGui::KeepAliveID(id);
2900  return id;
2901 }
2902 
2903 ImGuiID ImGuiWindow::GetIDNoKeepAlive(const char* str, const char* str_end)
2904 {
2905  ImGuiID seed = IDStack.back();
2906  return ImHashStr(str, str_end ? (str_end - str) : 0, seed);
2907 }
2908 
2910 {
2911  ImGuiID seed = IDStack.back();
2912  return ImHashData(&ptr, sizeof(void*), seed);
2913 }
2914 
2916 {
2917  ImGuiID seed = IDStack.back();
2918  return ImHashData(&n, sizeof(n), seed);
2919 }
2920 
2921 // This is only used in rare/specific situations to manufacture an ID out of nowhere.
2923 {
2924  ImGuiID seed = IDStack.back();
2925  const int r_rel[4] = { (int)(r_abs.Min.x - Pos.x), (int)(r_abs.Min.y - Pos.y), (int)(r_abs.Max.x - Pos.x), (int)(r_abs.Max.y - Pos.y) };
2926  ImGuiID id = ImHashData(&r_rel, sizeof(r_rel), seed);
2927  ImGui::KeepAliveID(id);
2928  return id;
2929 }
2930 
2931 static void SetCurrentWindow(ImGuiWindow* window)
2932 {
2933  ImGuiContext& g = *GImGui;
2934  g.CurrentWindow = window;
2935  if (window)
2936  g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize();
2937 }
2938 
2939 // Free up/compact internal window buffers, we can use this when a window becomes unused.
2940 // This is currently unused by the library, but you may call this yourself for easy GC.
2941 // Not freed:
2942 // - ImGuiWindow, ImGuiWindowSettings, Name
2943 // - StateStorage, ColumnsStorage (may hold useful data)
2944 // This should have no noticeable visual effect. When the window reappear however, expect new allocation/buffer growth/copy cost.
2946 {
2947  window->MemoryCompacted = true;
2950  window->IDStack.clear();
2951  window->DrawList->ClearFreeMemory();
2952  window->DC.ChildWindows.clear();
2953  window->DC.ItemFlagsStack.clear();
2954  window->DC.ItemWidthStack.clear();
2955  window->DC.TextWrapPosStack.clear();
2956  window->DC.GroupStack.clear();
2957 }
2958 
2960 {
2961  // We stored capacity of the ImDrawList buffer to reduce growth-caused allocation/copy when awakening.
2962  // The other buffers tends to amortize much faster.
2963  window->MemoryCompacted = false;
2967 }
2968 
2970 {
2971  ImGuiContext& g = *GImGui;
2972  g.ActiveIdIsJustActivated = (g.ActiveId != id);
2973  if (g.ActiveIdIsJustActivated)
2974  {
2975  g.ActiveIdTimer = 0.0f;
2976  g.ActiveIdHasBeenPressedBefore = false;
2977  g.ActiveIdHasBeenEditedBefore = false;
2978  if (id != 0)
2979  {
2980  g.LastActiveId = id;
2981  g.LastActiveIdTimer = 0.0f;
2982  }
2983  }
2984  g.ActiveId = id;
2985  g.ActiveIdAllowOverlap = false;
2986  g.ActiveIdWindow = window;
2987  g.ActiveIdHasBeenEditedThisFrame = false;
2988  if (id)
2989  {
2990  g.ActiveIdIsAlive = id;
2991  g.ActiveIdSource = (g.NavActivateId == id || g.NavInputId == id || g.NavJustTabbedId == id || g.NavJustMovedToId == id) ? ImGuiInputSource_Nav : ImGuiInputSource_Mouse;
2992  }
2993 
2994  // Clear declaration of inputs claimed by the widget
2995  // (Please note that this is WIP and not all keys/inputs are thoroughly declared by all widgets yet)
2996  g.ActiveIdUsingNavDirMask = 0x00;
2997  g.ActiveIdUsingNavInputMask = 0x00;
2998  g.ActiveIdUsingKeyInputMask = 0x00;
2999 }
3000 
3002 {
3003  SetActiveID(0, NULL);
3004 }
3005 
3007 {
3008  ImGuiContext& g = *GImGui;
3009  g.HoveredId = id;
3010  g.HoveredIdAllowOverlap = false;
3011  if (id != 0 && g.HoveredIdPreviousFrame != id)
3012  g.HoveredIdTimer = g.HoveredIdNotActiveTimer = 0.0f;
3013 }
3014 
3016 {
3017  ImGuiContext& g = *GImGui;
3018  return g.HoveredId ? g.HoveredId : g.HoveredIdPreviousFrame;
3019 }
3020 
3022 {
3023  ImGuiContext& g = *GImGui;
3024  if (g.ActiveId == id)
3025  g.ActiveIdIsAlive = id;
3026  if (g.ActiveIdPreviousFrame == id)
3027  g.ActiveIdPreviousFrameIsAlive = true;
3028 }
3029 
3031 {
3032  // This marking is solely to be able to provide info for IsItemDeactivatedAfterEdit().
3033  // ActiveId might have been released by the time we call this (as in the typical press/release button behavior) but still need need to fill the data.
3034  ImGuiContext& g = *GImGui;
3035  IM_ASSERT(g.ActiveId == id || g.ActiveId == 0 || g.DragDropActive);
3036  IM_UNUSED(id); // Avoid unused variable warnings when asserts are compiled out.
3037  //IM_ASSERT(g.CurrentWindow->DC.LastItemId == id);
3038  g.ActiveIdHasBeenEditedThisFrame = true;
3039  g.ActiveIdHasBeenEditedBefore = true;
3040  g.CurrentWindow->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_Edited;
3041 }
3042 
3044 {
3045  // An active popup disable hovering on other windows (apart from its own children)
3046  // FIXME-OPT: This could be cached/stored within the window.
3047  ImGuiContext& g = *GImGui;
3048  if (g.NavWindow)
3049  if (ImGuiWindow* focused_root_window = g.NavWindow->RootWindow)
3050  if (focused_root_window->WasActive && focused_root_window != window->RootWindow)
3051  {
3052  // For the purpose of those flags we differentiate "standard popup" from "modal popup"
3053  // NB: The order of those two tests is important because Modal windows are also Popups.
3054  if (focused_root_window->Flags & ImGuiWindowFlags_Modal)
3055  return false;
3056  if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiHoveredFlags_AllowWhenBlockedByPopup))
3057  return false;
3058  }
3059  return true;
3060 }
3061 
3062 // This is roughly matching the behavior of internal-facing ItemHoverable()
3063 // - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()
3064 // - this should work even for non-interactive items that have no ID, so we cannot use LastItemId
3066 {
3067  ImGuiContext& g = *GImGui;
3068  ImGuiWindow* window = g.CurrentWindow;
3069  if (g.NavDisableMouseHover && !g.NavDisableHighlight)
3070  return IsItemFocused();
3071 
3072  // Test for bounding box overlap, as updated as ItemAdd()
3074  return false;
3075  IM_ASSERT((flags & (ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows)) == 0); // Flags not supported by this function
3076 
3077  // Test if we are hovering the right window (our window could be behind another window)
3078  // [2017/10/16] Reverted commit 344d48be3 and testing RootWindow instead. I believe it is correct to NOT test for RootWindow but this leaves us unable to use IsItemHovered() after EndChild() itself.
3079  // Until a solution is found I believe reverting to the test from 2017/09/27 is safe since this was the test that has been running for a long while.
3080  //if (g.HoveredWindow != window)
3081  // return false;
3082  if (g.HoveredRootWindow != window->RootWindow && !(flags & ImGuiHoveredFlags_AllowWhenOverlapped))
3083  return false;
3084 
3085  // Test if another item is active (e.g. being dragged)
3087  if (g.ActiveId != 0 && g.ActiveId != window->DC.LastItemId && !g.ActiveIdAllowOverlap && g.ActiveId != window->MoveId)
3088  return false;
3089 
3090  // Test if interactions on this window are blocked by an active popup or modal.
3091  // The ImGuiHoveredFlags_AllowWhenBlockedByPopup flag will be tested here.
3092  if (!IsWindowContentHoverable(window, flags))
3093  return false;
3094 
3095  // Test if the item is disabled
3097  return false;
3098 
3099  // Special handling for the dummy item after Begin() which represent the title bar or tab.
3100  // When the window is collapsed (SkipItems==true) that last item will never be overwritten so we need to detect the case.
3101  if (window->DC.LastItemId == window->MoveId && window->WriteAccessed)
3102  return false;
3103  return true;
3104 }
3105 
3106 // Internal facing ItemHoverable() used when submitting widgets. Differs slightly from IsItemHovered().
3108 {
3109  ImGuiContext& g = *GImGui;
3110  if (g.HoveredId != 0 && g.HoveredId != id && !g.HoveredIdAllowOverlap)
3111  return false;
3112 
3113  ImGuiWindow* window = g.CurrentWindow;
3114  if (g.HoveredWindow != window)
3115  return false;
3116  if (g.ActiveId != 0 && g.ActiveId != id && !g.ActiveIdAllowOverlap)
3117  return false;
3118  if (!IsMouseHoveringRect(bb.Min, bb.Max))
3119  return false;
3120  if (g.NavDisableMouseHover || !IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
3121  return false;
3122  if (window->DC.ItemFlags & ImGuiItemFlags_Disabled)
3123  return false;
3124 
3125  SetHoveredID(id);
3126 
3127  // [DEBUG] Item Picker tool!
3128  // We perform the check here because SetHoveredID() is not frequently called (1~ time a frame), making
3129  // the cost of this tool near-zero. We can get slightly better call-stack and support picking non-hovered
3130  // items if we perform the test in ItemAdd(), but that would incur a small runtime cost.
3131  // #define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX in imconfig.h if you want this check to also be performed in ItemAdd().
3132  if (g.DebugItemPickerActive && g.HoveredIdPreviousFrame == id)
3133  GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 255, 0, 255));
3134  if (g.DebugItemPickerBreakId == id)
3135  IM_DEBUG_BREAK();
3136 
3137  return true;
3138 }
3139 
3140 bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged)
3141 {
3142  ImGuiContext& g = *GImGui;
3143  ImGuiWindow* window = g.CurrentWindow;
3144  if (!bb.Overlaps(window->ClipRect))
3145  if (id == 0 || id != g.ActiveId)
3146  if (clip_even_when_logged || !g.LogEnabled)
3147  return true;
3148  return false;
3149 }
3150 
3151 // Process TAB/Shift+TAB. Be mindful that this function may _clear_ the ActiveID when tabbing out.
3153 {
3154  ImGuiContext& g = *GImGui;
3155 
3156  // Increment counters
3157  const bool is_tab_stop = (window->DC.ItemFlags & (ImGuiItemFlags_NoTabStop | ImGuiItemFlags_Disabled)) == 0;
3158  window->DC.FocusCounterRegular++;
3159  if (is_tab_stop)
3160  window->DC.FocusCounterTabStop++;
3161 
3162  // Process TAB/Shift-TAB to tab *OUT* of the currently focused item.
3163  // (Note that we can always TAB out of a widget that doesn't allow tabbing in)
3164  if (g.ActiveId == id && g.FocusTabPressed && !IsActiveIdUsingKey(ImGuiKey_Tab) && g.FocusRequestNextWindow == NULL)
3165  {
3166  g.FocusRequestNextWindow = window;
3167  g.FocusRequestNextCounterTabStop = window->DC.FocusCounterTabStop + (g.IO.KeyShift ? (is_tab_stop ? -1 : 0) : +1); // Modulo on index will be applied at the end of frame once we've got the total counter of items.
3168  }
3169 
3170  // Handle focus requests
3171  if (g.FocusRequestCurrWindow == window)
3172  {
3173  if (window->DC.FocusCounterRegular == g.FocusRequestCurrCounterRegular)
3174  return true;
3175  if (is_tab_stop && window->DC.FocusCounterTabStop == g.FocusRequestCurrCounterTabStop)
3176  {
3177  g.NavJustTabbedId = id;
3178  return true;
3179  }
3180 
3181  // If another item is about to be focused, we clear our own active id
3182  if (g.ActiveId == id)
3183  ClearActiveID();
3184  }
3185 
3186  return false;
3187 }
3188 
3190 {
3191  window->DC.FocusCounterRegular--;
3192  window->DC.FocusCounterTabStop--;
3193 }
3194 
3195 float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x)
3196 {
3197  if (wrap_pos_x < 0.0f)
3198  return 0.0f;
3199 
3200  ImGuiWindow* window = GImGui->CurrentWindow;
3201  if (wrap_pos_x == 0.0f)
3202  wrap_pos_x = window->WorkRect.Max.x;
3203  else if (wrap_pos_x > 0.0f)
3204  wrap_pos_x += window->Pos.x - window->Scroll.x; // wrap_pos_x is provided is window local space
3205 
3206  return ImMax(wrap_pos_x - pos.x, 1.0f);
3207 }
3208 
3209 // IM_ALLOC() == ImGui::MemAlloc()
3210 void* ImGui::MemAlloc(size_t size)
3211 {
3212  if (ImGuiContext* ctx = GImGui)
3213  ctx->IO.MetricsActiveAllocations++;
3215 }
3216 
3217 // IM_FREE() == ImGui::MemFree()
3218 void ImGui::MemFree(void* ptr)
3219 {
3220  if (ptr)
3221  if (ImGuiContext* ctx = GImGui)
3222  ctx->IO.MetricsActiveAllocations--;
3224 }
3225 
3227 {
3228  ImGuiContext& g = *GImGui;
3229  return g.IO.GetClipboardTextFn ? g.IO.GetClipboardTextFn(g.IO.ClipboardUserData) : "";
3230 }
3231 
3232 void ImGui::SetClipboardText(const char* text)
3233 {
3234  ImGuiContext& g = *GImGui;
3235  if (g.IO.SetClipboardTextFn)
3236  g.IO.SetClipboardTextFn(g.IO.ClipboardUserData, text);
3237 }
3238 
3239 const char* ImGui::GetVersion()
3240 {
3241  return IMGUI_VERSION;
3242 }
3243 
3244 // Internal state access - if you want to share Dear ImGui state between modules (e.g. DLL) or allocate it yourself
3245 // Note that we still point to some static data and members (such as GFontAtlas), so the state instance you end up using will point to the static data within its module
3247 {
3248  return GImGui;
3249 }
3250 
3252 {
3253 #ifdef IMGUI_SET_CURRENT_CONTEXT_FUNC
3254  IMGUI_SET_CURRENT_CONTEXT_FUNC(ctx); // For custom thread-based hackery you may want to have control over this.
3255 #else
3256  GImGui = ctx;
3257 #endif
3258 }
3259 
3260 void ImGui::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data)
3261 {
3262  GImAllocatorAllocFunc = alloc_func;
3263  GImAllocatorFreeFunc = free_func;
3264  GImAllocatorUserData = user_data;
3265 }
3266 
3268 {
3269  ImGuiContext* ctx = IM_NEW(ImGuiContext)(shared_font_atlas);
3270  if (GImGui == NULL)
3271  SetCurrentContext(ctx);
3272  Initialize(ctx);
3273  return ctx;
3274 }
3275 
3277 {
3278  if (ctx == NULL)
3279  ctx = GImGui;
3280  Shutdown(ctx);
3281  if (GImGui == ctx)
3283  IM_DELETE(ctx);
3284 }
3285 
3287 {
3288  IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext() ?");
3289  return GImGui->IO;
3290 }
3291 
3292 // Same value as passed to the old io.RenderDrawListsFn function. Valid after Render() and until the next call to NewFrame()
3294 {
3295  ImGuiContext& g = *GImGui;
3296  return g.DrawData.Valid ? &g.DrawData : NULL;
3297 }
3298 
3300 {
3301  return GImGui->Time;
3302 }
3303 
3305 {
3306  return GImGui->FrameCount;
3307 }
3308 
3310 {
3311  return &GImGui->BackgroundDrawList;
3312 }
3313 
3315 {
3316  return &GImGui->ForegroundDrawList;
3317 }
3318 
3320 {
3321  return &GImGui->DrawListSharedData;
3322 }
3323 
3325 {
3326  // Set ActiveId even if the _NoMove flag is set. Without it, dragging away from a window with _NoMove would activate hover on other windows.
3327  // We _also_ call this when clicking in a window empty space when io.ConfigWindowsMoveFromTitleBarOnly is set, but clear g.MovingWindow afterward.
3328  // This is because we want ActiveId to be set even when the window is not permitted to move.
3329  ImGuiContext& g = *GImGui;
3330  FocusWindow(window);
3331  SetActiveID(window->MoveId, window);
3332  g.NavDisableHighlight = true;
3333  g.ActiveIdClickOffset = g.IO.MousePos - window->RootWindow->Pos;
3334 
3335  bool can_move_window = true;
3336  if ((window->Flags & ImGuiWindowFlags_NoMove) || (window->RootWindow->Flags & ImGuiWindowFlags_NoMove))
3337  can_move_window = false;
3338  if (can_move_window)
3339  g.MovingWindow = window;
3340 }
3341 
3342 // Handle mouse moving window
3343 // Note: moving window with the navigation keys (Square + d-pad / CTRL+TAB + Arrows) are processed in NavUpdateWindowing()
3344 // FIXME: We don't have strong guarantee that g.MovingWindow stay synched with g.ActiveId == g.MovingWindow->MoveId.
3345 // This is currently enforced by the fact that BeginDragDropSource() is setting all g.ActiveIdUsingXXXX flags to inhibit navigation inputs,
3346 // but if we should more thoroughly test cases where g.ActiveId or g.MovingWindow gets changed and not the other.
3348 {
3349  ImGuiContext& g = *GImGui;
3350  if (g.MovingWindow != NULL)
3351  {
3352  // We actually want to move the root window. g.MovingWindow == window we clicked on (could be a child window).
3353  // We track it to preserve Focus and so that generally ActiveIdWindow == MovingWindow and ActiveId == MovingWindow->MoveId for consistency.
3354  KeepAliveID(g.ActiveId);
3355  IM_ASSERT(g.MovingWindow && g.MovingWindow->RootWindow);
3356  ImGuiWindow* moving_window = g.MovingWindow->RootWindow;
3357  if (g.IO.MouseDown[0] && IsMousePosValid(&g.IO.MousePos))
3358  {
3359  ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset;
3360  if (moving_window->Pos.x != pos.x || moving_window->Pos.y != pos.y)
3361  {
3362  MarkIniSettingsDirty(moving_window);
3363  SetWindowPos(moving_window, pos, ImGuiCond_Always);
3364  }
3365  FocusWindow(g.MovingWindow);
3366  }
3367  else
3368  {
3369  ClearActiveID();
3370  g.MovingWindow = NULL;
3371  }
3372  }
3373  else
3374  {
3375  // When clicking/dragging from a window that has the _NoMove flag, we still set the ActiveId in order to prevent hovering others.
3376  if (g.ActiveIdWindow && g.ActiveIdWindow->MoveId == g.ActiveId)
3377  {
3378  KeepAliveID(g.ActiveId);
3379  if (!g.IO.MouseDown[0])
3380  ClearActiveID();
3381  }
3382  }
3383 }
3384 
3385 // Initiate moving window when clicking on empty space or title bar.
3386 // Handle left-click and right-click focus.
3388 {
3389  ImGuiContext& g = *GImGui;
3390  if (g.ActiveId != 0 || g.HoveredId != 0)
3391  return;
3392 
3393  // Unless we just made a window/popup appear
3394  if (g.NavWindow && g.NavWindow->Appearing)
3395  return;
3396 
3397  // Click to focus window and start moving (after we're done with all our widgets)
3398  if (g.IO.MouseClicked[0])
3399  {
3400  if (g.HoveredRootWindow != NULL)
3401  {
3402  StartMouseMovingWindow(g.HoveredWindow);
3403  if (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoTitleBar))
3404  if (!g.HoveredRootWindow->TitleBarRect().Contains(g.IO.MouseClickedPos[0]))
3405  g.MovingWindow = NULL;
3406  }
3407  else if (g.NavWindow != NULL && GetTopMostPopupModal() == NULL)
3408  {
3409  // Clicking on void disable focus
3410  FocusWindow(NULL);
3411  }
3412  }
3413 
3414  // With right mouse button we close popups without changing focus based on where the mouse is aimed
3415  // Instead, focus will be restored to the window under the bottom-most closed popup.
3416  // (The left mouse button path calls FocusWindow on the hovered window, which will lead NewFrame->ClosePopupsOverWindow to trigger)
3417  if (g.IO.MouseClicked[1])
3418  {
3419  // Find the top-most window between HoveredWindow and the top-most Modal Window.
3420  // This is where we can trim the popup stack.
3421  ImGuiWindow* modal = GetTopMostPopupModal();
3422  bool hovered_window_above_modal = false;
3423  if (modal == NULL)
3424  hovered_window_above_modal = true;
3425  for (int i = g.Windows.Size - 1; i >= 0 && hovered_window_above_modal == false; i--)
3426  {
3427  ImGuiWindow* window = g.Windows[i];
3428  if (window == modal)
3429  break;
3430  if (window == g.HoveredWindow)
3431  hovered_window_above_modal = true;
3432  }
3433  ClosePopupsOverWindow(hovered_window_above_modal ? g.HoveredWindow : modal, true);
3434  }
3435 }
3436 
3438 {
3439  return (window->Active) && (!window->Hidden);
3440 }
3441 
3443 {
3444  ImGuiContext& g = *GImGui;
3445 
3446  // Round mouse position to avoid spreading non-rounded position (e.g. UpdateManualResize doesn't support them well)
3447  if (IsMousePosValid(&g.IO.MousePos))
3448  g.IO.MousePos = g.LastValidMousePos = ImFloor(g.IO.MousePos);
3449 
3450  // If mouse just appeared or disappeared (usually denoted by -FLT_MAX components) we cancel out movement in MouseDelta
3451  if (IsMousePosValid(&g.IO.MousePos) && IsMousePosValid(&g.IO.MousePosPrev))
3452  g.IO.MouseDelta = g.IO.MousePos - g.IO.MousePosPrev;
3453  else
3454  g.IO.MouseDelta = ImVec2(0.0f, 0.0f);
3455  if (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f)
3456  g.NavDisableMouseHover = false;
3457 
3458  g.IO.MousePosPrev = g.IO.MousePos;
3459  for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++)
3460  {
3461  g.IO.MouseClicked[i] = g.IO.MouseDown[i] && g.IO.MouseDownDuration[i] < 0.0f;
3462  g.IO.MouseReleased[i] = !g.IO.MouseDown[i] && g.IO.MouseDownDuration[i] >= 0.0f;
3463  g.IO.MouseDownDurationPrev[i] = g.IO.MouseDownDuration[i];
3464  g.IO.MouseDownDuration[i] = g.IO.MouseDown[i] ? (g.IO.MouseDownDuration[i] < 0.0f ? 0.0f : g.IO.MouseDownDuration[i] + g.IO.DeltaTime) : -1.0f;
3465  g.IO.MouseDoubleClicked[i] = false;
3466  if (g.IO.MouseClicked[i])
3467  {
3468  if ((float)(g.Time - g.IO.MouseClickedTime[i]) < g.IO.MouseDoubleClickTime)
3469  {
3470  ImVec2 delta_from_click_pos = IsMousePosValid(&g.IO.MousePos) ? (g.IO.MousePos - g.IO.MouseClickedPos[i]) : ImVec2(0.0f, 0.0f);
3471  if (ImLengthSqr(delta_from_click_pos) < g.IO.MouseDoubleClickMaxDist * g.IO.MouseDoubleClickMaxDist)
3472  g.IO.MouseDoubleClicked[i] = true;
3473  g.IO.MouseClickedTime[i] = -DBL_MAX; // so the third click isn't turned into a double-click
3474  }
3475  else
3476  {
3477  g.IO.MouseClickedTime[i] = g.Time;
3478  }
3479  g.IO.MouseClickedPos[i] = g.IO.MousePos;
3480  g.IO.MouseDownWasDoubleClick[i] = g.IO.MouseDoubleClicked[i];
3481  g.IO.MouseDragMaxDistanceAbs[i] = ImVec2(0.0f, 0.0f);
3482  g.IO.MouseDragMaxDistanceSqr[i] = 0.0f;
3483  }
3484  else if (g.IO.MouseDown[i])
3485  {
3486  // Maintain the maximum distance we reaching from the initial click position, which is used with dragging threshold
3487  ImVec2 delta_from_click_pos = IsMousePosValid(&g.IO.MousePos) ? (g.IO.MousePos - g.IO.MouseClickedPos[i]) : ImVec2(0.0f, 0.0f);
3488  g.IO.MouseDragMaxDistanceSqr[i] = ImMax(g.IO.MouseDragMaxDistanceSqr[i], ImLengthSqr(delta_from_click_pos));
3489  g.IO.MouseDragMaxDistanceAbs[i].x = ImMax(g.IO.MouseDragMaxDistanceAbs[i].x, delta_from_click_pos.x < 0.0f ? -delta_from_click_pos.x : delta_from_click_pos.x);
3490  g.IO.MouseDragMaxDistanceAbs[i].y = ImMax(g.IO.MouseDragMaxDistanceAbs[i].y, delta_from_click_pos.y < 0.0f ? -delta_from_click_pos.y : delta_from_click_pos.y);
3491  }
3492  if (!g.IO.MouseDown[i] && !g.IO.MouseReleased[i])
3493  g.IO.MouseDownWasDoubleClick[i] = false;
3494  if (g.IO.MouseClicked[i]) // Clicking any mouse button reactivate mouse hovering which may have been deactivated by gamepad/keyboard navigation
3495  g.NavDisableMouseHover = false;
3496  }
3497 }
3498 
3500 {
3501  ImGuiContext& g = *GImGui;
3502  if (g.WheelingWindow == window)
3503  return;
3504  g.WheelingWindow = window;
3505  g.WheelingWindowRefMousePos = g.IO.MousePos;
3506  g.WheelingWindowTimer = WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER;
3507 }
3508 
3510 {
3511  ImGuiContext& g = *GImGui;
3512 
3513  // Reset the locked window if we move the mouse or after the timer elapses
3514  if (g.WheelingWindow != NULL)
3515  {
3516  g.WheelingWindowTimer -= g.IO.DeltaTime;
3517  if (IsMousePosValid() && ImLengthSqr(g.IO.MousePos - g.WheelingWindowRefMousePos) > g.IO.MouseDragThreshold * g.IO.MouseDragThreshold)
3518  g.WheelingWindowTimer = 0.0f;
3519  if (g.WheelingWindowTimer <= 0.0f)
3520  {
3521  g.WheelingWindow = NULL;
3522  g.WheelingWindowTimer = 0.0f;
3523  }
3524  }
3525 
3526  if (g.IO.MouseWheel == 0.0f && g.IO.MouseWheelH == 0.0f)
3527  return;
3528 
3529  ImGuiWindow* window = g.WheelingWindow ? g.WheelingWindow : g.HoveredWindow;
3530  if (!window || window->Collapsed)
3531  return;
3532 
3533  // Zoom / Scale window
3534  // FIXME-OBSOLETE: This is an old feature, it still works but pretty much nobody is using it and may be best redesigned.
3535  if (g.IO.MouseWheel != 0.0f && g.IO.KeyCtrl && g.IO.FontAllowUserScaling)
3536  {
3537  StartLockWheelingWindow(window);
3538  const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f);
3539  const float scale = new_font_scale / window->FontWindowScale;
3540  window->FontWindowScale = new_font_scale;
3541  if (!(window->Flags & ImGuiWindowFlags_ChildWindow))
3542  {
3543  const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size;
3544  SetWindowPos(window, window->Pos + offset, 0);
3545  window->Size = ImFloor(window->Size * scale);
3546  window->SizeFull = ImFloor(window->SizeFull * scale);
3547  }
3548  return;
3549  }
3550 
3551  // Mouse wheel scrolling
3552  // If a child window has the ImGuiWindowFlags_NoScrollWithMouse flag, we give a chance to scroll its parent
3553 
3554  // Vertical Mouse Wheel scrolling
3555  const float wheel_y = (g.IO.MouseWheel != 0.0f && !g.IO.KeyShift) ? g.IO.MouseWheel : 0.0f;
3556  if (wheel_y != 0.0f && !g.IO.KeyCtrl)
3557  {
3558  StartLockWheelingWindow(window);
3559  while ((window->Flags & ImGuiWindowFlags_ChildWindow) && ((window->ScrollMax.y == 0.0f) || ((window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))))
3560  window = window->ParentWindow;
3562  {
3563  float max_step = window->InnerRect.GetHeight() * 0.67f;
3564  float scroll_step = ImFloor(ImMin(5 * window->CalcFontSize(), max_step));
3565  SetScrollY(window, window->Scroll.y - wheel_y * scroll_step);
3566  }
3567  }
3568 
3569  // Horizontal Mouse Wheel scrolling, or Vertical Mouse Wheel w/ Shift held
3570  const float wheel_x = (g.IO.MouseWheelH != 0.0f && !g.IO.KeyShift) ? g.IO.MouseWheelH : (g.IO.MouseWheel != 0.0f && g.IO.KeyShift) ? g.IO.MouseWheel : 0.0f;
3571  if (wheel_x != 0.0f && !g.IO.KeyCtrl)
3572  {
3573  StartLockWheelingWindow(window);
3574  while ((window->Flags & ImGuiWindowFlags_ChildWindow) && ((window->ScrollMax.x == 0.0f) || ((window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(window->Flags & ImGuiWindowFlags_NoMouseInputs))))
3575  window = window->ParentWindow;
3577  {
3578  float max_step = window->InnerRect.GetWidth() * 0.67f;
3579  float scroll_step = ImFloor(ImMin(2 * window->CalcFontSize(), max_step));
3580  SetScrollX(window, window->Scroll.x - wheel_x * scroll_step);
3581  }
3582  }
3583 }
3584 
3586 {
3587  ImGuiContext& g = *GImGui;
3588 
3589  // Pressing TAB activate widget focus
3590  g.FocusTabPressed = (g.NavWindow && g.NavWindow->Active && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab));
3591  if (g.ActiveId == 0 && g.FocusTabPressed)
3592  {
3593  // Note that SetKeyboardFocusHere() sets the Next fields mid-frame. To be consistent we also
3594  // manipulate the Next fields even, even though they will be turned into Curr fields by the code below.
3595  g.FocusRequestNextWindow = g.NavWindow;
3596  g.FocusRequestNextCounterRegular = INT_MAX;
3597  if (g.NavId != 0 && g.NavIdTabCounter != INT_MAX)
3598  g.FocusRequestNextCounterTabStop = g.NavIdTabCounter + 1 + (g.IO.KeyShift ? -1 : 1);
3599  else
3600  g.FocusRequestNextCounterTabStop = g.IO.KeyShift ? -1 : 0;
3601  }
3602 
3603  // Turn queued focus request into current one
3604  g.FocusRequestCurrWindow = NULL;
3605  g.FocusRequestCurrCounterRegular = g.FocusRequestCurrCounterTabStop = INT_MAX;
3606  if (g.FocusRequestNextWindow != NULL)
3607  {
3608  ImGuiWindow* window = g.FocusRequestNextWindow;
3609  g.FocusRequestCurrWindow = window;
3610  if (g.FocusRequestNextCounterRegular != INT_MAX && window->DC.FocusCounterRegular != -1)
3611  g.FocusRequestCurrCounterRegular = ImModPositive(g.FocusRequestNextCounterRegular, window->DC.FocusCounterRegular + 1);
3612  if (g.FocusRequestNextCounterTabStop != INT_MAX && window->DC.FocusCounterTabStop != -1)
3613  g.FocusRequestCurrCounterTabStop = ImModPositive(g.FocusRequestNextCounterTabStop, window->DC.FocusCounterTabStop + 1);
3614  g.FocusRequestNextWindow = NULL;
3615  g.FocusRequestNextCounterRegular = g.FocusRequestNextCounterTabStop = INT_MAX;
3616  }
3617 
3618  g.NavIdTabCounter = INT_MAX;
3619 }
3620 
3621 // The reason this is exposed in imgui_internal.h is: on touch-based system that don't have hovering, we want to dispatch inputs to the right target (imgui vs imgui+app)
3623 {
3624  ImGuiContext& g = *GImGui;
3625 
3626  // Find the window hovered by mouse:
3627  // - Child windows can extend beyond the limit of their parent so we need to derive HoveredRootWindow from HoveredWindow.
3628  // - When moving a window we can skip the search, which also conveniently bypasses the fact that window->WindowRectClipped is lagging as this point of the frame.
3629  // - We also support the moved window toggling the NoInputs flag after moving has started in order to be able to detect windows below it, which is useful for e.g. docking mechanisms.
3631 
3632  // Modal windows prevents cursor from hovering behind them.
3633  ImGuiWindow* modal_window = GetTopMostPopupModal();
3634  if (modal_window)
3635  if (g.HoveredRootWindow && !IsWindowChildOf(g.HoveredRootWindow, modal_window))
3636  g.HoveredRootWindow = g.HoveredWindow = NULL;
3637 
3638  // Disabled mouse?
3639  if (g.IO.ConfigFlags & ImGuiConfigFlags_NoMouse)
3640  g.HoveredWindow = g.HoveredRootWindow = NULL;
3641 
3642  // We track click ownership. When clicked outside of a window the click is owned by the application and won't report hovering nor request capture even while dragging over our windows afterward.
3643  int mouse_earliest_button_down = -1;
3644  bool mouse_any_down = false;
3645  for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++)
3646  {
3647  if (g.IO.MouseClicked[i])
3648  g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (!g.OpenPopupStack.empty());
3649  mouse_any_down |= g.IO.MouseDown[i];
3650  if (g.IO.MouseDown[i])
3651  if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[i] < g.IO.MouseClickedTime[mouse_earliest_button_down])
3652  mouse_earliest_button_down = i;
3653  }
3654  const bool mouse_avail_to_imgui = (mouse_earliest_button_down == -1) || g.IO.MouseDownOwned[mouse_earliest_button_down];
3655 
3656  // If mouse was first clicked outside of ImGui bounds we also cancel out hovering.
3657  // FIXME: For patterns of drag and drop across OS windows, we may need to rework/remove this test (first committed 311c0ca9 on 2015/02)
3658  const bool mouse_dragging_extern_payload = g.DragDropActive && (g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) != 0;
3659  if (!mouse_avail_to_imgui && !mouse_dragging_extern_payload)
3660  g.HoveredWindow = g.HoveredRootWindow = NULL;
3661 
3662  // Update io.WantCaptureMouse for the user application (true = dispatch mouse info to imgui, false = dispatch mouse info to Dear ImGui + app)
3663  if (g.WantCaptureMouseNextFrame != -1)
3664  g.IO.WantCaptureMouse = (g.WantCaptureMouseNextFrame != 0);
3665  else
3666  g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (!g.OpenPopupStack.empty());
3667 
3668  // Update io.WantCaptureKeyboard for the user application (true = dispatch keyboard info to imgui, false = dispatch keyboard info to Dear ImGui + app)
3669  if (g.WantCaptureKeyboardNextFrame != -1)
3670  g.IO.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != 0);
3671  else
3672  g.IO.WantCaptureKeyboard = (g.ActiveId != 0) || (modal_window != NULL);
3673  if (g.IO.NavActive && (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard))
3674  g.IO.WantCaptureKeyboard = true;
3675 
3676  // Update io.WantTextInput flag, this is to allow systems without a keyboard (e.g. mobile, hand-held) to show a software keyboard if possible
3677  g.IO.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : false;
3678 }
3679 
3681 {
3682  ImGuiContext& g = *GImGui;
3683  ImGuiKeyModFlags key_mod_flags = ImGuiKeyModFlags_None;
3684  if (g.IO.KeyCtrl) { key_mod_flags |= ImGuiKeyModFlags_Ctrl; }
3685  if (g.IO.KeyShift) { key_mod_flags |= ImGuiKeyModFlags_Shift; }
3686  if (g.IO.KeyAlt) { key_mod_flags |= ImGuiKeyModFlags_Alt; }
3687  if (g.IO.KeySuper) { key_mod_flags |= ImGuiKeyModFlags_Super; }
3688  return key_mod_flags;
3689 }
3690 
3692 {
3693  IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() and ImGui::SetCurrentContext() ?");
3694  ImGuiContext& g = *GImGui;
3695 
3696 #ifdef IMGUI_ENABLE_TEST_ENGINE
3697  ImGuiTestEngineHook_PreNewFrame(&g);
3698 #endif
3699 
3700  // Check and assert for various common IO and Configuration mistakes
3702 
3703  // Load settings on first frame, save settings when modified (after a delay)
3704  UpdateSettings();
3705 
3706  g.Time += g.IO.DeltaTime;
3707  g.WithinFrameScope = true;
3708  g.FrameCount += 1;
3709  g.TooltipOverrideCount = 0;
3710  g.WindowsActiveCount = 0;
3711  g.MenusIdSubmittedThisFrame.resize(0);
3712 
3713  // Calculate frame-rate for the user, as a purely luxurious feature
3714  g.FramerateSecPerFrameAccum += g.IO.DeltaTime - g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx];
3715  g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx] = g.IO.DeltaTime;
3716  g.FramerateSecPerFrameIdx = (g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(g.FramerateSecPerFrame);
3717  g.IO.Framerate = (g.FramerateSecPerFrameAccum > 0.0f) ? (1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame))) : FLT_MAX;
3718 
3719  // Setup current font and draw list shared data
3720  g.IO.Fonts->Locked = true;
3722  IM_ASSERT(g.Font->IsLoaded());
3723  g.DrawListSharedData.ClipRectFullscreen = ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y);
3724  g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol;
3725  g.DrawListSharedData.SetCircleSegmentMaxError(g.Style.CircleSegmentMaxError);
3726  g.DrawListSharedData.InitialFlags = ImDrawListFlags_None;
3727  if (g.Style.AntiAliasedLines)
3728  g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedLines;
3729  if (g.Style.AntiAliasedFill)
3730  g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AntiAliasedFill;
3731  if (g.IO.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset)
3732  g.DrawListSharedData.InitialFlags |= ImDrawListFlags_AllowVtxOffset;
3733 
3734  g.BackgroundDrawList.Clear();
3735  g.BackgroundDrawList.PushTextureID(g.IO.Fonts->TexID);
3736  g.BackgroundDrawList.PushClipRectFullScreen();
3737 
3738  g.ForegroundDrawList.Clear();
3739  g.ForegroundDrawList.PushTextureID(g.IO.Fonts->TexID);
3740  g.ForegroundDrawList.PushClipRectFullScreen();
3741 
3742  // Mark rendering data as invalid to prevent user who may have a handle on it to use it.
3743  g.DrawData.Clear();
3744 
3745  // Drag and drop keep the source ID alive so even if the source disappear our state is consistent
3746  if (g.DragDropActive && g.DragDropPayload.SourceId == g.ActiveId)
3747  KeepAliveID(g.DragDropPayload.SourceId);
3748 
3749  // Update HoveredId data
3750  if (!g.HoveredIdPreviousFrame)
3751  g.HoveredIdTimer = 0.0f;
3752  if (!g.HoveredIdPreviousFrame || (g.HoveredId && g.ActiveId == g.HoveredId))
3753  g.HoveredIdNotActiveTimer = 0.0f;
3754  if (g.HoveredId)
3755  g.HoveredIdTimer += g.IO.DeltaTime;
3756  if (g.HoveredId && g.ActiveId != g.HoveredId)
3757  g.HoveredIdNotActiveTimer += g.IO.DeltaTime;
3758  g.HoveredIdPreviousFrame = g.HoveredId;
3759  g.HoveredId = 0;
3760  g.HoveredIdAllowOverlap = false;
3761 
3762  // Update ActiveId data (clear reference to active widget if the widget isn't alive anymore)
3763  if (g.ActiveIdIsAlive != g.ActiveId && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)
3764  ClearActiveID();
3765  if (g.ActiveId)
3766  g.ActiveIdTimer += g.IO.DeltaTime;
3767  g.LastActiveIdTimer += g.IO.DeltaTime;
3768  g.ActiveIdPreviousFrame = g.ActiveId;
3769  g.ActiveIdPreviousFrameWindow = g.ActiveIdWindow;
3770  g.ActiveIdPreviousFrameHasBeenEditedBefore = g.ActiveIdHasBeenEditedBefore;
3771  g.ActiveIdIsAlive = 0;
3772  g.ActiveIdHasBeenEditedThisFrame = false;
3773  g.ActiveIdPreviousFrameIsAlive = false;
3774  g.ActiveIdIsJustActivated = false;
3775  if (g.TempInputId != 0 && g.ActiveId != g.TempInputId)
3776  g.TempInputId = 0;
3777  if (g.ActiveId == 0)
3778  {
3779  g.ActiveIdUsingNavDirMask = 0x00;
3780  g.ActiveIdUsingNavInputMask = 0x00;
3781  g.ActiveIdUsingKeyInputMask = 0x00;
3782  }
3783 
3784  // Drag and drop
3785  g.DragDropAcceptIdPrev = g.DragDropAcceptIdCurr;
3786  g.DragDropAcceptIdCurr = 0;
3787  g.DragDropAcceptIdCurrRectSurface = FLT_MAX;
3788  g.DragDropWithinSource = false;
3789  g.DragDropWithinTarget = false;
3790 
3791  // Update keyboard input state
3792  // Synchronize io.KeyMods with individual modifiers io.KeyXXX bools
3793  g.IO.KeyMods = GetMergedKeyModFlags();
3794  memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration));
3795  for (int i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++)
3796  g.IO.KeysDownDuration[i] = g.IO.KeysDown[i] ? (g.IO.KeysDownDuration[i] < 0.0f ? 0.0f : g.IO.KeysDownDuration[i] + g.IO.DeltaTime) : -1.0f;
3797 
3798  // Update gamepad/keyboard directional navigation
3799  NavUpdate();
3800 
3801  // Update mouse input state
3803 
3804  // Find hovered window
3805  // (needs to be before UpdateMouseMovingWindowNewFrame so we fill g.HoveredWindowUnderMovingWindow on the mouse release frame)
3807 
3808  // Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering)
3810 
3811  // Background darkening/whitening
3812  if (GetTopMostPopupModal() != NULL || (g.NavWindowingTarget != NULL && g.NavWindowingHighlightAlpha > 0.0f))
3813  g.DimBgRatio = ImMin(g.DimBgRatio + g.IO.DeltaTime * 6.0f, 1.0f);
3814  else
3815  g.DimBgRatio = ImMax(g.DimBgRatio - g.IO.DeltaTime * 10.0f, 0.0f);
3816 
3817  g.MouseCursor = ImGuiMouseCursor_Arrow;
3818  g.WantCaptureMouseNextFrame = g.WantCaptureKeyboardNextFrame = g.WantTextInputNextFrame = -1;
3819  g.PlatformImePos = ImVec2(1.0f, 1.0f); // OS Input Method Editor showing on top-left of our window by default
3820 
3821  // Mouse wheel scrolling, scale
3822  UpdateMouseWheel();
3823 
3824  // Update legacy TAB focus
3825  UpdateTabFocus();
3826 
3827  // Mark all windows as not visible and compact unused memory.
3828  IM_ASSERT(g.WindowsFocusOrder.Size == g.Windows.Size);
3829  const float memory_compact_start_time = (g.IO.ConfigWindowsMemoryCompactTimer >= 0.0f) ? (float)g.Time - g.IO.ConfigWindowsMemoryCompactTimer : FLT_MAX;
3830  for (int i = 0; i != g.Windows.Size; i++)
3831  {
3832  ImGuiWindow* window = g.Windows[i];
3833  window->WasActive = window->Active;
3834  window->BeginCount = 0;
3835  window->Active = false;
3836  window->WriteAccessed = false;
3837 
3838  // Garbage collect transient buffers of recently unused windows
3839  if (!window->WasActive && !window->MemoryCompacted && window->LastTimeActive < memory_compact_start_time)
3841  }
3842 
3843  // Closing the focused window restore focus to the first active root window in descending z-order
3844  if (g.NavWindow && !g.NavWindow->WasActive)
3846 
3847  // No window should be open at the beginning of the frame.
3848  // But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear.
3849  g.CurrentWindowStack.resize(0);
3850  g.BeginPopupStack.resize(0);
3851  ClosePopupsOverWindow(g.NavWindow, false);
3852 
3853  // [DEBUG] Item picker tool - start with DebugStartItemPicker() - useful to visually select an item and break into its call-stack.
3855 
3856  // Create implicit/fallback window - which we will only render it if the user has added something to it.
3857  // We don't use "Debug" to avoid colliding with user trying to create a "Debug" window with custom flags.
3858  // This fallback is particularly important as it avoid ImGui:: calls from crashing.
3859  g.WithinFrameScopeWithImplicitWindow = true;
3861  Begin("Debug##Default");
3862  IM_ASSERT(g.CurrentWindow->IsFallbackWindow == true);
3863 
3864 #ifdef IMGUI_ENABLE_TEST_ENGINE
3865  ImGuiTestEngineHook_PostNewFrame(&g);
3866 #endif
3867 }
3868 
3869 // [DEBUG] Item picker tool - start with DebugStartItemPicker() - useful to visually select an item and break into its call-stack.
3871 {
3872  ImGuiContext& g = *GImGui;
3874  if (g.DebugItemPickerActive)
3875  {
3876  const ImGuiID hovered_id = g.HoveredIdPreviousFrame;
3879  g.DebugItemPickerActive = false;
3880  if (ImGui::IsMouseClicked(0) && hovered_id)
3881  {
3882  g.DebugItemPickerBreakId = hovered_id;
3883  g.DebugItemPickerActive = false;
3884  }
3887  ImGui::Text("HoveredId: 0x%08X", hovered_id);
3888  ImGui::Text("Press ESC to abort picking.");
3889  ImGui::TextColored(GetStyleColorVec4(hovered_id ? ImGuiCol_Text : ImGuiCol_TextDisabled), "Click to break in debugger!");
3891  }
3892 }
3893 
3895 {
3896  ImGuiContext& g = *context;
3897  IM_ASSERT(!g.Initialized && !g.SettingsLoaded);
3898 
3899  // Add .ini handle for ImGuiWindow type
3900  {
3901  ImGuiSettingsHandler ini_handler;
3902  ini_handler.TypeName = "Window";
3903  ini_handler.TypeHash = ImHashStr("Window");
3907  g.SettingsHandlers.push_back(ini_handler);
3908  }
3909 
3910 #ifdef IMGUI_HAS_TABLE
3911  // Add .ini handle for ImGuiTable type
3912  {
3913  ImGuiSettingsHandler ini_handler;
3914  ini_handler.TypeName = "Table";
3915  ini_handler.TypeHash = ImHashStr("Table");
3916  ini_handler.ReadOpenFn = TableSettingsHandler_ReadOpen;
3917  ini_handler.ReadLineFn = TableSettingsHandler_ReadLine;
3918  ini_handler.WriteAllFn = TableSettingsHandler_WriteAll;
3919  g.SettingsHandlers.push_back(ini_handler);
3920  }
3921 #endif // #ifdef IMGUI_HAS_TABLE
3922 
3923 #ifdef IMGUI_HAS_DOCK
3924 #endif // #ifdef IMGUI_HAS_DOCK
3925 
3926  g.Initialized = true;
3927 }
3928 
3929 // This function is merely here to free heap allocations.
3931 {
3932  // The fonts atlas can be used prior to calling NewFrame(), so we clear it even if g.Initialized is FALSE (which would happen if we never called NewFrame)
3933  ImGuiContext& g = *context;
3934  if (g.IO.Fonts && g.FontAtlasOwnedByContext)
3935  {
3936  g.IO.Fonts->Locked = false;
3937  IM_DELETE(g.IO.Fonts);
3938  }
3939  g.IO.Fonts = NULL;
3940 
3941  // Cleanup of other data are conditional on actually having initialized Dear ImGui.
3942  if (!g.Initialized)
3943  return;
3944 
3945  // Save settings (unless we haven't attempted to load them: CreateContext/DestroyContext without a call to NewFrame shouldn't save an empty file)
3946  if (g.SettingsLoaded && g.IO.IniFilename != NULL)
3947  {
3948  ImGuiContext* backup_context = GImGui;
3949  SetCurrentContext(context);
3950  SaveIniSettingsToDisk(g.IO.IniFilename);
3951  SetCurrentContext(backup_context);
3952  }
3953 
3954  // Clear everything else
3955  for (int i = 0; i < g.Windows.Size; i++)
3956  IM_DELETE(g.Windows[i]);
3957  g.Windows.clear();
3958  g.WindowsFocusOrder.clear();
3959  g.WindowsTempSortBuffer.clear();
3960  g.CurrentWindow = NULL;
3961  g.CurrentWindowStack.clear();
3962  g.WindowsById.Clear();
3963  g.NavWindow = NULL;
3964  g.HoveredWindow = g.HoveredRootWindow = NULL;
3965  g.ActiveIdWindow = g.ActiveIdPreviousFrameWindow = NULL;
3966  g.MovingWindow = NULL;
3967  g.ColorModifiers.clear();
3968  g.StyleModifiers.clear();
3969  g.FontStack.clear();
3970  g.OpenPopupStack.clear();
3971  g.BeginPopupStack.clear();
3972  g.DrawDataBuilder.ClearFreeMemory();
3973  g.BackgroundDrawList.ClearFreeMemory();
3974  g.ForegroundDrawList.ClearFreeMemory();
3975 
3976  g.TabBars.Clear();
3977  g.CurrentTabBarStack.clear();
3978  g.ShrinkWidthBuffer.clear();
3979 
3980  g.PrivateClipboard.clear();
3981  g.MenusIdSubmittedThisFrame.clear();
3982  g.InputTextState.ClearFreeMemory();
3983 
3984  g.SettingsWindows.clear();
3985  g.SettingsHandlers.clear();
3986 
3987  if (g.LogFile)
3988  {
3989 #ifndef IMGUI_DISABLE_TTY_FUNCTIONS
3990  if (g.LogFile != stdout)
3991 #endif
3992  ImFileClose(g.LogFile);
3993  g.LogFile = NULL;
3994  }
3995  g.LogBuffer.clear();
3996 
3997  g.Initialized = false;
3998 }
3999 
4000 // FIXME: Add a more explicit sort order in the window structure.
4001 static int IMGUI_CDECL ChildWindowComparer(const void* lhs, const void* rhs)
4002 {
4003  const ImGuiWindow* const a = *(const ImGuiWindow* const *)lhs;
4004  const ImGuiWindow* const b = *(const ImGuiWindow* const *)rhs;
4005  if (int d = (a->Flags & ImGuiWindowFlags_Popup) - (b->Flags & ImGuiWindowFlags_Popup))
4006  return d;
4007  if (int d = (a->Flags & ImGuiWindowFlags_Tooltip) - (b->Flags & ImGuiWindowFlags_Tooltip))
4008  return d;
4009  return (a->BeginOrderWithinParent - b->BeginOrderWithinParent);
4010 }
4011 
4012 static void AddWindowToSortBuffer(ImVector<ImGuiWindow*>* out_sorted_windows, ImGuiWindow* window)
4013 {
4014  out_sorted_windows->push_back(window);
4015  if (window->Active)
4016  {
4017  int count = window->DC.ChildWindows.Size;
4018  if (count > 1)
4019  ImQsort(window->DC.ChildWindows.Data, (size_t)count, sizeof(ImGuiWindow*), ChildWindowComparer);
4020  for (int i = 0; i < count; i++)
4021  {
4022  ImGuiWindow* child = window->DC.ChildWindows[i];
4023  if (child->Active)
4024  AddWindowToSortBuffer(out_sorted_windows, child);
4025  }
4026  }
4027 }
4028 
4029 static void AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* draw_list)
4030 {
4031  if (draw_list->CmdBuffer.empty())
4032  return;
4033 
4034  // Remove trailing command if unused
4035  ImDrawCmd& last_cmd = draw_list->CmdBuffer.back();
4036  if (last_cmd.ElemCount == 0 && last_cmd.UserCallback == NULL)
4037  {
4038  draw_list->CmdBuffer.pop_back();
4039  if (draw_list->CmdBuffer.empty())
4040  return;
4041  }
4042 
4043  // Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc.
4044  // May trigger for you if you are using PrimXXX functions incorrectly.
4045  IM_ASSERT(draw_list->VtxBuffer.Size == 0 || draw_list->_VtxWritePtr == draw_list->VtxBuffer.Data + draw_list->VtxBuffer.Size);
4046  IM_ASSERT(draw_list->IdxBuffer.Size == 0 || draw_list->_IdxWritePtr == draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size);
4047  if (!(draw_list->Flags & ImDrawListFlags_AllowVtxOffset))
4048  IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size);
4049 
4050  // Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = unsigned short = 2 bytes = 64K vertices per ImDrawList = per window)
4051  // If this assert triggers because you are drawing lots of stuff manually:
4052  // - First, make sure you are coarse clipping yourself and not trying to draw many things outside visible bounds.
4053  // Be mindful that the ImDrawList API doesn't filter vertices. Use the Metrics window to inspect draw list contents.
4054  // - If you want large meshes with more than 64K vertices, you can either:
4055  // (A) Handle the ImDrawCmd::VtxOffset value in your renderer back-end, and set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset'.
4056  // Most example back-ends already support this from 1.71. Pre-1.71 back-ends won't.
4057  // Some graphics API such as GL ES 1/2 don't have a way to offset the starting vertex so it is not supported for them.
4058  // (B) Or handle 32-bit indices in your renderer back-end, and uncomment '#define ImDrawIdx unsigned int' line in imconfig.h.
4059  // Most example back-ends already support this. For example, the OpenGL example code detect index size at compile-time:
4060  // glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset);
4061  // Your own engine or render API may use different parameters or function calls to specify index sizes.
4062  // 2 and 4 bytes indices are generally supported by most graphics API.
4063  // - If for some reason neither of those solutions works for you, a workaround is to call BeginChild()/EndChild() before reaching
4064  // the 64K limit to split your draw commands in multiple draw lists.
4065  if (sizeof(ImDrawIdx) == 2)
4066  IM_ASSERT(draw_list->_VtxCurrentIdx < (1 << 16) && "Too many vertices in ImDrawList using 16-bit indices. Read comment above");
4067 
4068  out_list->push_back(draw_list);
4069 }
4070 
4071 static void AddWindowToDrawData(ImVector<ImDrawList*>* out_render_list, ImGuiWindow* window)
4072 {
4073  ImGuiContext& g = *GImGui;
4075  AddDrawListToDrawData(out_render_list, window->DrawList);
4076  for (int i = 0; i < window->DC.ChildWindows.Size; i++)
4077  {
4078  ImGuiWindow* child = window->DC.ChildWindows[i];
4079  if (IsWindowActiveAndVisible(child)) // clipped children may have been marked not active
4080  AddWindowToDrawData(out_render_list, child);
4081  }
4082 }
4083 
4084 // Layer is locked for the root window, however child windows may use a different viewport (e.g. extruding menu)
4086 {
4087  ImGuiContext& g = *GImGui;
4088  int layer = (window->Flags & ImGuiWindowFlags_Tooltip) ? 1 : 0;
4089  AddWindowToDrawData(&g.DrawDataBuilder.Layers[layer], window);
4090 }
4091 
4093 {
4094  int n = Layers[0].Size;
4095  int size = n;
4096  for (int i = 1; i < IM_ARRAYSIZE(Layers); i++)
4097  size += Layers[i].Size;
4098  Layers[0].resize(size);
4099  for (int layer_n = 1; layer_n < IM_ARRAYSIZE(Layers); layer_n++)
4100  {
4101  ImVector<ImDrawList*>& layer = Layers[layer_n];
4102  if (layer.empty())
4103  continue;
4104  memcpy(&Layers[0][n], &layer[0], layer.Size * sizeof(ImDrawList*));
4105  n += layer.Size;
4106  layer.resize(0);
4107  }
4108 }
4109 
4110 static void SetupDrawData(ImVector<ImDrawList*>* draw_lists, ImDrawData* draw_data)
4111 {
4112  ImGuiIO& io = ImGui::GetIO();
4113  draw_data->Valid = true;
4114  draw_data->CmdLists = (draw_lists->Size > 0) ? draw_lists->Data : NULL;
4115  draw_data->CmdListsCount = draw_lists->Size;
4116  draw_data->TotalVtxCount = draw_data->TotalIdxCount = 0;
4117  draw_data->DisplayPos = ImVec2(0.0f, 0.0f);
4118  draw_data->DisplaySize = io.DisplaySize;
4119  draw_data->FramebufferScale = io.DisplayFramebufferScale;
4120  for (int n = 0; n < draw_lists->Size; n++)
4121  {
4122  draw_data->TotalVtxCount += draw_lists->Data[n]->VtxBuffer.Size;
4123  draw_data->TotalIdxCount += draw_lists->Data[n]->IdxBuffer.Size;
4124  }
4125 }
4126 
4127 // When using this function it is sane to ensure that float are perfectly rounded to integer values, to that e.g. (int)(max.x-min.x) in user's render produce correct result.
4128 void ImGui::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect)
4129 {
4130  ImGuiWindow* window = GetCurrentWindow();
4131  window->DrawList->PushClipRect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect);
4132  window->ClipRect = window->DrawList->_ClipRectStack.back();
4133 }
4134 
4136 {
4137  ImGuiWindow* window = GetCurrentWindow();
4138  window->DrawList->PopClipRect();
4139  window->ClipRect = window->DrawList->_ClipRectStack.back();
4140 }
4141 
4142 // This is normally called by Render(). You may want to call it directly if you want to avoid calling Render() but the gain will be very minimal.
4144 {
4145  ImGuiContext& g = *GImGui;
4146  IM_ASSERT(g.Initialized);
4147 
4148  // Don't process EndFrame() multiple times.
4149  if (g.FrameCountEnded == g.FrameCount)
4150  return;
4151  IM_ASSERT(g.WithinFrameScope && "Forgot to call ImGui::NewFrame()?");
4152 
4154 
4155  // Notify OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME)
4156  if (g.IO.ImeSetInputScreenPosFn && (g.PlatformImeLastPos.x == FLT_MAX || ImLengthSqr(g.PlatformImeLastPos - g.PlatformImePos) > 0.0001f))
4157  {
4158  g.IO.ImeSetInputScreenPosFn((int)g.PlatformImePos.x, (int)g.PlatformImePos.y);
4159  g.PlatformImeLastPos = g.PlatformImePos;
4160  }
4161 
4162  // Hide implicit/fallback "Debug" window if it hasn't been used
4163  g.WithinFrameScopeWithImplicitWindow = false;
4164  if (g.CurrentWindow && !g.CurrentWindow->WriteAccessed)
4165  g.CurrentWindow->Active = false;
4166  End();
4167 
4168  // Show CTRL+TAB list window
4169  if (g.NavWindowingTarget != NULL)
4171 
4172  // Drag and Drop: Elapse payload (if delivered, or if source stops being submitted)
4173  if (g.DragDropActive)
4174  {
4175  bool is_delivered = g.DragDropPayload.Delivery;
4176  bool is_elapsed = (g.DragDropPayload.DataFrameCount + 1 < g.FrameCount) && ((g.DragDropSourceFlags & ImGuiDragDropFlags_SourceAutoExpirePayload) || !IsMouseDown(g.DragDropMouseButton));
4177  if (is_delivered || is_elapsed)
4178  ClearDragDrop();
4179  }
4180 
4181  // Drag and Drop: Fallback for source tooltip. This is not ideal but better than nothing.
4182  if (g.DragDropActive && g.DragDropSourceFrameCount < g.FrameCount)
4183  {
4184  g.DragDropWithinSource = true;
4185  SetTooltip("...");
4186  g.DragDropWithinSource = false;
4187  }
4188 
4189  // End frame
4190  g.WithinFrameScope = false;
4191  g.FrameCountEnded = g.FrameCount;
4192 
4193  // Initiate moving window + handle left-click and right-click focus
4195 
4196  // Sort the window list so that all child windows are after their parent
4197  // We cannot do that on FocusWindow() because childs may not exist yet
4198  g.WindowsTempSortBuffer.resize(0);
4199  g.WindowsTempSortBuffer.reserve(g.Windows.Size);
4200  for (int i = 0; i != g.Windows.Size; i++)
4201  {
4202  ImGuiWindow* window = g.Windows[i];
4203  if (window->Active && (window->Flags & ImGuiWindowFlags_ChildWindow)) // if a child is active its parent will add it
4204  continue;
4205  AddWindowToSortBuffer(&g.WindowsTempSortBuffer, window);
4206  }
4207 
4208  // This usually assert if there is a mismatch between the ImGuiWindowFlags_ChildWindow / ParentWindow values and DC.ChildWindows[] in parents, aka we've done something wrong.
4209  IM_ASSERT(g.Windows.Size == g.WindowsTempSortBuffer.Size);
4210  g.Windows.swap(g.WindowsTempSortBuffer);
4211  g.IO.MetricsActiveWindows = g.WindowsActiveCount;
4212 
4213  // Unlock font atlas
4214  g.IO.Fonts->Locked = false;
4215 
4216  // Clear Input data for next frame
4217  g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f;
4218  g.IO.InputQueueCharacters.resize(0);
4219  memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs));
4220 }
4221 
4223 {
4224  ImGuiContext& g = *GImGui;
4225  IM_ASSERT(g.Initialized);
4226 
4227  if (g.FrameCountEnded != g.FrameCount)
4228  EndFrame();
4229  g.FrameCountRendered = g.FrameCount;
4230  g.IO.MetricsRenderWindows = 0;
4231  g.DrawDataBuilder.Clear();
4232 
4233  // Add background ImDrawList
4234  if (!g.BackgroundDrawList.VtxBuffer.empty())
4235  AddDrawListToDrawData(&g.DrawDataBuilder.Layers[0], &g.BackgroundDrawList);
4236 
4237  // Add ImDrawList to render
4238  ImGuiWindow* windows_to_render_top_most[2];
4239  windows_to_render_top_most[0] = (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) ? g.NavWindowingTarget->RootWindow : NULL;
4240  windows_to_render_top_most[1] = (g.NavWindowingTarget ? g.NavWindowingList : NULL);
4241  for (int n = 0; n != g.Windows.Size; n++)
4242  {
4243  ImGuiWindow* window = g.Windows[n];
4244  if (IsWindowActiveAndVisible(window) && (window->Flags & ImGuiWindowFlags_ChildWindow) == 0 && window != windows_to_render_top_most[0] && window != windows_to_render_top_most[1])
4245  AddRootWindowToDrawData(window);
4246  }
4247  for (int n = 0; n < IM_ARRAYSIZE(windows_to_render_top_most); n++)
4248  if (windows_to_render_top_most[n] && IsWindowActiveAndVisible(windows_to_render_top_most[n])) // NavWindowingTarget is always temporarily displayed as the top-most window
4249  AddRootWindowToDrawData(windows_to_render_top_most[n]);
4250  g.DrawDataBuilder.FlattenIntoSingleLayer();
4251 
4252  // Draw software mouse cursor if requested
4253  if (g.IO.MouseDrawCursor)
4254  RenderMouseCursor(&g.ForegroundDrawList, g.IO.MousePos, g.Style.MouseCursorScale, g.MouseCursor, IM_COL32_WHITE, IM_COL32_BLACK, IM_COL32(0, 0, 0, 48));
4255 
4256  // Add foreground ImDrawList
4257  if (!g.ForegroundDrawList.VtxBuffer.empty())
4258  AddDrawListToDrawData(&g.DrawDataBuilder.Layers[0], &g.ForegroundDrawList);
4259 
4260  // Setup ImDrawData structure for end-user
4261  SetupDrawData(&g.DrawDataBuilder.Layers[0], &g.DrawData);
4262  g.IO.MetricsRenderVertices = g.DrawData.TotalVtxCount;
4263  g.IO.MetricsRenderIndices = g.DrawData.TotalIdxCount;
4264 
4265  // (Legacy) Call the Render callback function. The current prefer way is to let the user retrieve GetDrawData() and call the render function themselves.
4266 #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
4267  if (g.DrawData.CmdListsCount > 0 && g.IO.RenderDrawListsFn != NULL)
4268  g.IO.RenderDrawListsFn(&g.DrawData);
4269 #endif
4270 }
4271 
4272 // Calculate text size. Text can be multi-line. Optionally ignore text after a ## marker.
4273 // CalcTextSize("") should return ImVec2(0.0f, g.FontSize)
4274 ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width)
4275 {
4276  ImGuiContext& g = *GImGui;
4277 
4278  const char* text_display_end;
4279  if (hide_text_after_double_hash)
4280  text_display_end = FindRenderedTextEnd(text, text_end); // Hide anything after a '##' string
4281  else
4282  text_display_end = text_end;
4283 
4284  ImFont* font = g.Font;
4285  const float font_size = g.FontSize;
4286  if (text == text_display_end)
4287  return ImVec2(0.0f, font_size);
4288  ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL);
4289 
4290  // Round
4291  text_size.x = IM_FLOOR(text_size.x + 0.95f);
4292 
4293  return text_size;
4294 }
4295 
4296 // Find window given position, search front-to-back
4297 // FIXME: Note that we have an inconsequential lag here: OuterRectClipped is updated in Begin(), so windows moved programatically
4298 // with SetWindowPos() and not SetNextWindowPos() will have that rectangle lagging by a frame at the time FindHoveredWindow() is
4299 // called, aka before the next Begin(). Moving window isn't affected.
4300 static void FindHoveredWindow()
4301 {
4302  ImGuiContext& g = *GImGui;
4303 
4304  ImGuiWindow* hovered_window = NULL;
4305  if (g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoMouseInputs))
4306  hovered_window = g.MovingWindow;
4307 
4308  ImVec2 padding_regular = g.Style.TouchExtraPadding;
4309  ImVec2 padding_for_resize_from_edges = g.IO.ConfigWindowsResizeFromEdges ? ImMax(g.Style.TouchExtraPadding, ImVec2(WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS, WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS)) : padding_regular;
4310  for (int i = g.Windows.Size - 1; i >= 0; i--)
4311  {
4312  ImGuiWindow* window = g.Windows[i];
4313  if (!window->Active || window->Hidden)
4314  continue;
4315  if (window->Flags & ImGuiWindowFlags_NoMouseInputs)
4316  continue;
4317 
4318  // Using the clipped AABB, a child window will typically be clipped by its parent (not always)
4319  ImRect bb(window->OuterRectClipped);
4321  bb.Expand(padding_regular);
4322  else
4323  bb.Expand(padding_for_resize_from_edges);
4324  if (!bb.Contains(g.IO.MousePos))
4325  continue;
4326 
4327  // Those seemingly unnecessary extra tests are because the code here is a little different in viewport/docking branches.
4328  if (hovered_window == NULL)
4329  hovered_window = window;
4330  if (hovered_window)
4331  break;
4332  }
4333 
4334  g.HoveredWindow = hovered_window;
4335  g.HoveredRootWindow = g.HoveredWindow ? g.HoveredWindow->RootWindow : NULL;
4336 
4337 }
4338 
4339 // Test if mouse cursor is hovering given rectangle
4340 // NB- Rectangle is clipped by our current clip setting
4341 // NB- Expand the rectangle to be generous on imprecise inputs systems (g.Style.TouchExtraPadding)
4342 bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip)
4343 {
4344  ImGuiContext& g = *GImGui;
4345 
4346  // Clip
4347  ImRect rect_clipped(r_min, r_max);
4348  if (clip)
4349  rect_clipped.ClipWith(g.CurrentWindow->ClipRect);
4350 
4351  // Expand for touch input
4352  const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding);
4353  if (!rect_for_touch.Contains(g.IO.MousePos))
4354  return false;
4355  return true;
4356 }
4357 
4359 {
4360  IM_ASSERT(imgui_key >= 0 && imgui_key < ImGuiKey_COUNT);
4361  ImGuiContext& g = *GImGui;
4362  return g.IO.KeyMap[imgui_key];
4363 }
4364 
4365 // Note that dear imgui doesn't know the semantic of each entry of io.KeysDown[]!
4366 // Use your own indices/enums according to how your back-end/engine stored them into io.KeysDown[]!
4367 bool ImGui::IsKeyDown(int user_key_index)
4368 {
4369  if (user_key_index < 0)
4370  return false;
4371  ImGuiContext& g = *GImGui;
4372  IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown));
4373  return g.IO.KeysDown[user_key_index];
4374 }
4375 
4376 // t0 = previous time (e.g.: g.Time - g.IO.DeltaTime)
4377 // t1 = current time (e.g.: g.Time)
4378 // An event is triggered at:
4379 // t = 0.0f t = repeat_delay, t = repeat_delay + repeat_rate*N
4380 int ImGui::CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate)
4381 {
4382  if (t1 == 0.0f)
4383  return 1;
4384  if (t0 >= t1)
4385  return 0;
4386  if (repeat_rate <= 0.0f)
4387  return (t0 < repeat_delay) && (t1 >= repeat_delay);
4388  const int count_t0 = (t0 < repeat_delay) ? -1 : (int)((t0 - repeat_delay) / repeat_rate);
4389  const int count_t1 = (t1 < repeat_delay) ? -1 : (int)((t1 - repeat_delay) / repeat_rate);
4390  const int count = count_t1 - count_t0;
4391  return count;
4392 }
4393 
4394 int ImGui::GetKeyPressedAmount(int key_index, float repeat_delay, float repeat_rate)
4395 {
4396  ImGuiContext& g = *GImGui;
4397  if (key_index < 0)
4398  return 0;
4399  IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown));
4400  const float t = g.IO.KeysDownDuration[key_index];
4401  return CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, repeat_delay, repeat_rate);
4402 }
4403 
4404 bool ImGui::IsKeyPressed(int user_key_index, bool repeat)
4405 {
4406  ImGuiContext& g = *GImGui;
4407  if (user_key_index < 0)
4408  return false;
4409  IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown));
4410  const float t = g.IO.KeysDownDuration[user_key_index];
4411  if (t == 0.0f)
4412  return true;
4413  if (repeat && t > g.IO.KeyRepeatDelay)
4414  return GetKeyPressedAmount(user_key_index, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0;
4415  return false;
4416 }
4417 
4418 bool ImGui::IsKeyReleased(int user_key_index)
4419 {
4420  ImGuiContext& g = *GImGui;
4421  if (user_key_index < 0) return false;
4422  IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown));
4423  return g.IO.KeysDownDurationPrev[user_key_index] >= 0.0f && !g.IO.KeysDown[user_key_index];
4424 }
4425 
4427 {
4428  ImGuiContext& g = *GImGui;
4429  IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
4430  return g.IO.MouseDown[button];
4431 }
4432 
4433 bool ImGui::IsMouseClicked(ImGuiMouseButton button, bool repeat)
4434 {
4435  ImGuiContext& g = *GImGui;
4436  IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
4437  const float t = g.IO.MouseDownDuration[button];
4438  if (t == 0.0f)
4439  return true;
4440 
4441  if (repeat && t > g.IO.KeyRepeatDelay)
4442  {
4443  // FIXME: 2019/05/03: Our old repeat code was wrong here and led to doubling the repeat rate, which made it an ok rate for repeat on mouse hold.
4444  int amount = CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate * 0.50f);
4445  if (amount > 0)
4446  return true;
4447  }
4448  return false;
4449 }
4450 
4452 {
4453  ImGuiContext& g = *GImGui;
4454  IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
4455  return g.IO.MouseReleased[button];
4456 }
4457 
4459 {
4460  ImGuiContext& g = *GImGui;
4461  IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
4462  return g.IO.MouseDoubleClicked[button];
4463 }
4464 
4465 // [Internal] This doesn't test if the button is pressed
4466 bool ImGui::IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold)
4467 {
4468  ImGuiContext& g = *GImGui;
4469  IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
4470  if (lock_threshold < 0.0f)
4471  lock_threshold = g.IO.MouseDragThreshold;
4472  return g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold;
4473 }
4474 
4475 bool ImGui::IsMouseDragging(ImGuiMouseButton button, float lock_threshold)
4476 {
4477  ImGuiContext& g = *GImGui;
4478  IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
4479  if (!g.IO.MouseDown[button])
4480  return false;
4481  return IsMouseDragPastThreshold(button, lock_threshold);
4482 }
4483 
4485 {
4486  ImGuiContext& g = *GImGui;
4487  return g.IO.MousePos;
4488 }
4489 
4490 // NB: prefer to call right after BeginPopup(). At the time Selectable/MenuItem is activated, the popup is already closed!
4492 {
4493  ImGuiContext& g = *GImGui;
4494  if (g.BeginPopupStack.Size > 0)
4495  return g.OpenPopupStack[g.BeginPopupStack.Size-1].OpenMousePos;
4496  return g.IO.MousePos;
4497 }
4498 
4499 // We typically use ImVec2(-FLT_MAX,-FLT_MAX) to denote an invalid mouse position.
4500 bool ImGui::IsMousePosValid(const ImVec2* mouse_pos)
4501 {
4502  // The assert is only to silence a false-positive in XCode Static Analysis.
4503  // Because GImGui is not dereferenced in every code path, the static analyzer assume that it may be NULL (which it doesn't for other functions).
4504  IM_ASSERT(GImGui != NULL);
4505  const float MOUSE_INVALID = -256000.0f;
4506  ImVec2 p = mouse_pos ? *mouse_pos : GImGui->IO.MousePos;
4507  return p.x >= MOUSE_INVALID && p.y >= MOUSE_INVALID;
4508 }
4509 
4511 {
4512  ImGuiContext& g = *GImGui;
4513  for (int n = 0; n < IM_ARRAYSIZE(g.IO.MouseDown); n++)
4514  if (g.IO.MouseDown[n])
4515  return true;
4516  return false;
4517 }
4518 
4519 // Return the delta from the initial clicking position while the mouse button is clicked or was just released.
4520 // This is locked and return 0.0f until the mouse moves past a distance threshold at least once.
4521 // NB: This is only valid if IsMousePosValid(). Back-ends in theory should always keep mouse position valid when dragging even outside the client window.
4522 ImVec2 ImGui::GetMouseDragDelta(ImGuiMouseButton button, float lock_threshold)
4523 {
4524  ImGuiContext& g = *GImGui;
4525  IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
4526  if (lock_threshold < 0.0f)
4527  lock_threshold = g.IO.MouseDragThreshold;
4528  if (g.IO.MouseDown[button] || g.IO.MouseReleased[button])
4529  if (g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold)
4530  if (IsMousePosValid(&g.IO.MousePos) && IsMousePosValid(&g.IO.MouseClickedPos[button]))
4531  return g.IO.MousePos - g.IO.MouseClickedPos[button];
4532  return ImVec2(0.0f, 0.0f);
4533 }
4534 
4536 {
4537  ImGuiContext& g = *GImGui;
4538  IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown));
4539  // NB: We don't need to reset g.IO.MouseDragMaxDistanceSqr
4540  g.IO.MouseClickedPos[button] = g.IO.MousePos;
4541 }
4542 
4544 {
4545  return GImGui->MouseCursor;
4546 }
4547 
4549 {
4550  GImGui->MouseCursor = cursor_type;
4551 }
4552 
4554 {
4556 }
4557 
4559 {
4561 }
4562 
4564 {
4565  ImGuiContext& g = *GImGui;
4566  if (g.ActiveId)
4567  {
4568  ImGuiWindow* window = g.CurrentWindow;
4569  return g.ActiveId == window->DC.LastItemId;
4570  }
4571  return false;
4572 }
4573 
4575 {
4576  ImGuiContext& g = *GImGui;
4577  if (g.ActiveId)
4578  {
4579  ImGuiWindow* window = g.CurrentWindow;
4580  if (g.ActiveId == window->DC.LastItemId && g.ActiveIdPreviousFrame != window->DC.LastItemId)
4581  return true;
4582  }
4583  return false;
4584 }
4585 
4587 {
4588  ImGuiContext& g = *GImGui;
4589  ImGuiWindow* window = g.CurrentWindow;
4592  return (g.ActiveIdPreviousFrame == window->DC.LastItemId && g.ActiveIdPreviousFrame != 0 && g.ActiveId != window->DC.LastItemId);
4593 }
4594 
4596 {
4597  ImGuiContext& g = *GImGui;
4598  return IsItemDeactivated() && (g.ActiveIdPreviousFrameHasBeenEditedBefore || (g.ActiveId == 0 && g.ActiveIdHasBeenEditedBefore));
4599 }
4600 
4602 {
4603  ImGuiContext& g = *GImGui;
4604  ImGuiWindow* window = g.CurrentWindow;
4605 
4606  if (g.NavId == 0 || g.NavDisableHighlight || g.NavId != window->DC.LastItemId)
4607  return false;
4608  return true;
4609 }
4610 
4612 {
4613  return IsMouseClicked(mouse_button) && IsItemHovered(ImGuiHoveredFlags_None);
4614 }
4615 
4617 {
4618  ImGuiContext& g = *GImGui;
4619  return (g.CurrentWindow->DC.LastItemStatusFlags & ImGuiItemStatusFlags_ToggledOpen) ? true : false;
4620 }
4621 
4623 {
4624  ImGuiContext& g = *GImGui;
4625  return (g.CurrentWindow->DC.LastItemStatusFlags & ImGuiItemStatusFlags_ToggledSelection) ? true : false;
4626 }
4627 
4629 {
4630  ImGuiContext& g = *GImGui;
4631  return g.HoveredId != 0 || g.HoveredIdPreviousFrame != 0;
4632 }
4633 
4635 {
4636  ImGuiContext& g = *GImGui;
4637  return g.ActiveId != 0;
4638 }
4639 
4641 {
4642  ImGuiContext& g = *GImGui;
4643  return g.NavId != 0 && !g.NavDisableHighlight;
4644 }
4645 
4647 {
4648  ImGuiWindow* window = GetCurrentWindowRead();
4649  return window->ClipRect.Overlaps(window->DC.LastItemRect);
4650 }
4651 
4653 {
4654  ImGuiWindow* window = GetCurrentWindowRead();
4655  return (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_Edited) != 0;
4656 }
4657 
4658 // Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority.
4660 {
4661  ImGuiContext& g = *GImGui;
4662  if (g.HoveredId == g.CurrentWindow->DC.LastItemId)
4663  g.HoveredIdAllowOverlap = true;
4664  if (g.ActiveId == g.CurrentWindow->DC.LastItemId)
4665  g.ActiveIdAllowOverlap = true;
4666 }
4667 
4669 {
4670  ImGuiWindow* window = GetCurrentWindowRead();
4671  return window->DC.LastItemRect.Min;
4672 }
4673 
4675 {
4676  ImGuiWindow* window = GetCurrentWindowRead();
4677  return window->DC.LastItemRect.Max;
4678 }
4679 
4681 {
4682  ImGuiWindow* window = GetCurrentWindowRead();
4683  return window->DC.LastItemRect.GetSize();
4684 }
4685 
4687 {
4688  ImGuiContext& g = *GImGui;
4689  return ImRect(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y);
4690 }
4691 
4692 bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags)
4693 {
4694  ImGuiContext& g = *GImGui;
4695  ImGuiWindow* parent_window = g.CurrentWindow;
4696 
4698  flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove); // Inherit the NoMove flag
4699 
4700  // Size
4701  const ImVec2 content_avail = GetContentRegionAvail();
4702  ImVec2 size = ImFloor(size_arg);
4703  const int auto_fit_axises = ((size.x == 0.0f) ? (1 << ImGuiAxis_X) : 0x00) | ((size.y == 0.0f) ? (1 << ImGuiAxis_Y) : 0x00);
4704  if (size.x <= 0.0f)
4705  size.x = ImMax(content_avail.x + size.x, 4.0f); // Arbitrary minimum child size (0.0f causing too much issues)
4706  if (size.y <= 0.0f)
4707  size.y = ImMax(content_avail.y + size.y, 4.0f);
4709 
4710  // Build up name. If you need to append to a same child from multiple location in the ID stack, use BeginChild(ImGuiID id) with a stable value.
4711  char title[256];
4712  if (name)
4713  ImFormatString(title, IM_ARRAYSIZE(title), "%s/%s_%08X", parent_window->Name, name, id);
4714  else
4715  ImFormatString(title, IM_ARRAYSIZE(title), "%s/%08X", parent_window->Name, id);
4716 
4717  const float backup_border_size = g.Style.ChildBorderSize;
4718  if (!border)
4719  g.Style.ChildBorderSize = 0.0f;
4720  bool ret = Begin(title, NULL, flags);
4721  g.Style.ChildBorderSize = backup_border_size;
4722 
4723  ImGuiWindow* child_window = g.CurrentWindow;
4724  child_window->ChildId = id;
4725  child_window->AutoFitChildAxises = (ImS8)auto_fit_axises;
4726 
4727  // Set the cursor to handle case where the user called SetNextWindowPos()+BeginChild() manually.
4728  // While this is not really documented/defined, it seems that the expected thing to do.
4729  if (child_window->BeginCount == 1)
4730  parent_window->DC.CursorPos = child_window->Pos;
4731 
4732  // Process navigation-in immediately so NavInit can run on first frame
4733  if (g.NavActivateId == id && !(flags & ImGuiWindowFlags_NavFlattened) && (child_window->DC.NavLayerActiveMask != 0 || child_window->DC.NavHasScroll))
4734  {
4735  FocusWindow(child_window);
4736  NavInitWindow(child_window, false);
4737  SetActiveID(id+1, child_window); // Steal ActiveId with a dummy id so that key-press won't activate child item
4738  g.ActiveIdSource = ImGuiInputSource_Nav;
4739  }
4740  return ret;
4741 }
4742 
4743 bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags)
4744 {
4745  ImGuiWindow* window = GetCurrentWindow();
4746  return BeginChildEx(str_id, window->GetID(str_id), size_arg, border, extra_flags);
4747 }
4748 
4749 bool ImGui::BeginChild(ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags)
4750 {
4751  IM_ASSERT(id != 0);
4752  return BeginChildEx(NULL, id, size_arg, border, extra_flags);
4753 }
4754 
4756 {
4757  ImGuiContext& g = *GImGui;
4758  ImGuiWindow* window = g.CurrentWindow;
4759 
4760  IM_ASSERT(g.WithinEndChild == false);
4761  IM_ASSERT(window->Flags & ImGuiWindowFlags_ChildWindow); // Mismatched BeginChild()/EndChild() calls
4762 
4763  g.WithinEndChild = true;
4764  if (window->BeginCount > 1)
4765  {
4766  End();
4767  }
4768  else
4769  {
4770  ImVec2 sz = window->Size;
4771  if (window->AutoFitChildAxises & (1 << ImGuiAxis_X)) // Arbitrary minimum zero-ish child size of 4.0f causes less trouble than a 0.0f
4772  sz.x = ImMax(4.0f, sz.x);
4773  if (window->AutoFitChildAxises & (1 << ImGuiAxis_Y))
4774  sz.y = ImMax(4.0f, sz.y);
4775  End();
4776 
4777  ImGuiWindow* parent_window = g.CurrentWindow;
4778  ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + sz);
4779  ItemSize(sz);
4780  if ((window->DC.NavLayerActiveMask != 0 || window->DC.NavHasScroll) && !(window->Flags & ImGuiWindowFlags_NavFlattened))
4781  {
4782  ItemAdd(bb, window->ChildId);
4783  RenderNavHighlight(bb, window->ChildId);
4784 
4785  // When browsing a window that has no activable items (scroll only) we keep a highlight on the child
4786  if (window->DC.NavLayerActiveMask == 0 && window == g.NavWindow)
4788  }
4789  else
4790  {
4791  // Not navigable into
4792  ItemAdd(bb, 0);
4793  }
4794  }
4795  g.WithinEndChild = false;
4796 }
4797 
4798 // Helper to create a child window / scrolling region that looks like a normal widget frame.
4800 {
4801  ImGuiContext& g = *GImGui;
4802  const ImGuiStyle& style = g.Style;
4807  bool ret = BeginChild(id, size, true, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags);
4808  PopStyleVar(3);
4809  PopStyleColor();
4810  return ret;
4811 }
4812 
4814 {
4815  EndChild();
4816 }
4817 
4819 {
4823 }
4824 
4826 {
4827  ImGuiContext& g = *GImGui;
4828  return (ImGuiWindow*)g.WindowsById.GetVoidPtr(id);
4829 }
4830 
4832 {
4833  ImGuiID id = ImHashStr(name);
4834  return FindWindowByID(id);
4835 }
4836 
4838 {
4839  ImGuiContext& g = *GImGui;
4840  //IMGUI_DEBUG_LOG("CreateNewWindow '%s', flags = 0x%08X\n", name, flags);
4841 
4842  // Create window the first time
4843  ImGuiWindow* window = IM_NEW(ImGuiWindow)(&g, name);
4844  window->Flags = flags;
4845  g.WindowsById.SetVoidPtr(window->ID, window);
4846 
4847  // Default/arbitrary window position. Use SetNextWindowPos() with the appropriate condition flag to change the initial position of a window.
4848  window->Pos = ImVec2(60, 60);
4849 
4850  // User can disable loading and saving of settings. Tooltip and child windows also don't store settings.
4852  if (ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID))
4853  {
4854  // Retrieve settings from .ini file
4855  window->SettingsOffset = g.SettingsWindows.offset_from_ptr(settings);
4857  window->Pos = ImVec2(settings->Pos.x, settings->Pos.y);
4858  window->Collapsed = settings->Collapsed;
4859  if (settings->Size.x > 0 && settings->Size.y > 0)
4860  size = ImVec2(settings->Size.x, settings->Size.y);
4861  }
4862  window->Size = window->SizeFull = ImFloor(size);
4863  window->DC.CursorStartPos = window->DC.CursorMaxPos = window->Pos; // So first call to CalcContentSize() doesn't return crazy values
4864 
4866  {
4867  window->AutoFitFramesX = window->AutoFitFramesY = 2;
4868  window->AutoFitOnlyGrows = false;
4869  }
4870  else
4871  {
4872  if (window->Size.x <= 0.0f)
4873  window->AutoFitFramesX = 2;
4874  if (window->Size.y <= 0.0f)
4875  window->AutoFitFramesY = 2;
4876  window->AutoFitOnlyGrows = (window->AutoFitFramesX > 0) || (window->AutoFitFramesY > 0);
4877  }
4878 
4879  g.WindowsFocusOrder.push_back(window);
4881  g.Windows.push_front(window); // Quite slow but rare and only once
4882  else
4883  g.Windows.push_back(window);
4884  return window;
4885 }
4886 
4888 {
4889  ImGuiContext& g = *GImGui;
4890  if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSizeConstraint)
4891  {
4892  // Using -1,-1 on either X/Y axis to preserve the current size.
4893  ImRect cr = g.NextWindowData.SizeConstraintRect;
4894  new_size.x = (cr.Min.x >= 0 && cr.Max.x >= 0) ? ImClamp(new_size.x, cr.Min.x, cr.Max.x) : window->SizeFull.x;
4895  new_size.y = (cr.Min.y >= 0 && cr.Max.y >= 0) ? ImClamp(new_size.y, cr.Min.y, cr.Max.y) : window->SizeFull.y;
4896  if (g.NextWindowData.SizeCallback)
4897  {
4899  data.UserData = g.NextWindowData.SizeCallbackUserData;
4900  data.Pos = window->Pos;
4901  data.CurrentSize = window->SizeFull;
4902  data.DesiredSize = new_size;
4903  g.NextWindowData.SizeCallback(&data);
4904  new_size = data.DesiredSize;
4905  }
4906  new_size.x = IM_FLOOR(new_size.x);
4907  new_size.y = IM_FLOOR(new_size.y);
4908  }
4909 
4910  // Minimum size
4912  {
4913  ImGuiWindow* window_for_height = window;
4914  new_size = ImMax(new_size, g.Style.WindowMinSize);
4915  new_size.y = ImMax(new_size.y, window_for_height->TitleBarHeight() + window_for_height->MenuBarHeight() + ImMax(0.0f, g.Style.WindowRounding - 1.0f)); // Reduce artifacts with very small windows
4916  }
4917  return new_size;
4918 }
4919 
4921 {
4922  if (window->Collapsed)
4923  if (window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
4924  return window->ContentSize;
4925  if (window->Hidden && window->HiddenFramesCannotSkipItems == 0 && window->HiddenFramesCanSkipItems > 0)
4926  return window->ContentSize;
4927 
4928  ImVec2 sz;
4929  sz.x = IM_FLOOR((window->ContentSizeExplicit.x != 0.0f) ? window->ContentSizeExplicit.x : window->DC.CursorMaxPos.x - window->DC.CursorStartPos.x);
4930  sz.y = IM_FLOOR((window->ContentSizeExplicit.y != 0.0f) ? window->ContentSizeExplicit.y : window->DC.CursorMaxPos.y - window->DC.CursorStartPos.y);
4931  return sz;
4932 }
4933 
4934 static ImVec2 CalcWindowAutoFitSize(ImGuiWindow* window, const ImVec2& size_contents)
4935 {
4936  ImGuiContext& g = *GImGui;
4937  ImGuiStyle& style = g.Style;
4938  ImVec2 size_decorations = ImVec2(0.0f, window->TitleBarHeight() + window->MenuBarHeight());
4939  ImVec2 size_pad = window->WindowPadding * 2.0f;
4940  ImVec2 size_desired = size_contents + size_pad + size_decorations;
4941  if (window->Flags & ImGuiWindowFlags_Tooltip)
4942  {
4943  // Tooltip always resize
4944  return size_desired;
4945  }
4946  else
4947  {
4948  // Maximum window size is determined by the viewport size or monitor size
4949  const bool is_popup = (window->Flags & ImGuiWindowFlags_Popup) != 0;
4950  const bool is_menu = (window->Flags & ImGuiWindowFlags_ChildMenu) != 0;
4951  ImVec2 size_min = style.WindowMinSize;
4952  if (is_popup || is_menu) // Popups and menus bypass style.WindowMinSize by default, but we give then a non-zero minimum size to facilitate understanding problematic cases (e.g. empty popups)
4953  size_min = ImMin(size_min, ImVec2(4.0f, 4.0f));
4954  ImVec2 size_auto_fit = ImClamp(size_desired, size_min, ImMax(size_min, g.IO.DisplaySize - style.DisplaySafeAreaPadding * 2.0f));
4955 
4956  // When the window cannot fit all contents (either because of constraints, either because screen is too small),
4957  // we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than ViewportSize-WindowPadding.
4958  ImVec2 size_auto_fit_after_constraint = CalcWindowSizeAfterConstraint(window, size_auto_fit);
4959  bool will_have_scrollbar_x = (size_auto_fit_after_constraint.x - size_pad.x - size_decorations.x < size_contents.x && !(window->Flags & ImGuiWindowFlags_NoScrollbar) && (window->Flags & ImGuiWindowFlags_HorizontalScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar);
4960  bool will_have_scrollbar_y = (size_auto_fit_after_constraint.y - size_pad.y - size_decorations.y < size_contents.y && !(window->Flags & ImGuiWindowFlags_NoScrollbar)) || (window->Flags & ImGuiWindowFlags_AlwaysVerticalScrollbar);
4961  if (will_have_scrollbar_x)
4962  size_auto_fit.y += style.ScrollbarSize;
4963  if (will_have_scrollbar_y)
4964  size_auto_fit.x += style.ScrollbarSize;
4965  return size_auto_fit;
4966  }
4967 }
4968 
4970 {
4971  ImVec2 size_contents = CalcWindowContentSize(window);
4972  ImVec2 size_auto_fit = CalcWindowAutoFitSize(window, size_contents);
4973  ImVec2 size_final = CalcWindowSizeAfterConstraint(window, size_auto_fit);
4974  return size_final;
4975 }
4976 
4978 {
4980  return ImGuiCol_PopupBg;
4982  return ImGuiCol_ChildBg;
4983  return ImGuiCol_WindowBg;
4984 }
4985 
4986 static void CalcResizePosSizeFromAnyCorner(ImGuiWindow* window, const ImVec2& corner_target, const ImVec2& corner_norm, ImVec2* out_pos, ImVec2* out_size)
4987 {
4988  ImVec2 pos_min = ImLerp(corner_target, window->Pos, corner_norm); // Expected window upper-left
4989  ImVec2 pos_max = ImLerp(window->Pos + window->Size, corner_target, corner_norm); // Expected window lower-right
4990  ImVec2 size_expected = pos_max - pos_min;
4991  ImVec2 size_constrained = CalcWindowSizeAfterConstraint(window, size_expected);
4992  *out_pos = pos_min;
4993  if (corner_norm.x == 0.0f)
4994  out_pos->x -= (size_constrained.x - size_expected.x);
4995  if (corner_norm.y == 0.0f)
4996  out_pos->y -= (size_constrained.y - size_expected.y);
4997  *out_size = size_constrained;
4998 }
4999 
5001 {
5005 };
5006 
5008 {
5009  { ImVec2(1,1), ImVec2(-1,-1), 0, 3 }, // Lower-right
5010  { ImVec2(0,1), ImVec2(+1,-1), 3, 6 }, // Lower-left
5011  { ImVec2(0,0), ImVec2(+1,+1), 6, 9 }, // Upper-left (Unused)
5012  { ImVec2(1,0), ImVec2(-1,+1), 9,12 }, // Upper-right (Unused)
5013 };
5014 
5015 static ImRect GetResizeBorderRect(ImGuiWindow* window, int border_n, float perp_padding, float thickness)
5016 {
5017  ImRect rect = window->Rect();
5018  if (thickness == 0.0f) rect.Max -= ImVec2(1,1);
5019  if (border_n == 0) return ImRect(rect.Min.x + perp_padding, rect.Min.y - thickness, rect.Max.x - perp_padding, rect.Min.y + thickness); // Top
5020  if (border_n == 1) return ImRect(rect.Max.x - thickness, rect.Min.y + perp_padding, rect.Max.x + thickness, rect.Max.y - perp_padding); // Right
5021  if (border_n == 2) return ImRect(rect.Min.x + perp_padding, rect.Max.y - thickness, rect.Max.x - perp_padding, rect.Max.y + thickness); // Bottom
5022  if (border_n == 3) return ImRect(rect.Min.x - thickness, rect.Min.y + perp_padding, rect.Min.x + thickness, rect.Max.y - perp_padding); // Left
5023  IM_ASSERT(0);
5024  return ImRect();
5025 }
5026 
5027 // 0..3: corners (Lower-right, Lower-left, Unused, Unused)
5028 // 4..7: borders (Top, Right, Bottom, Left)
5030 {
5031  IM_ASSERT(n >= 0 && n <= 7);
5032  ImGuiID id = window->ID;
5033  id = ImHashStr("#RESIZE", 0, id);
5034  id = ImHashData(&n, sizeof(int), id);
5035  return id;
5036 }
5037 
5038 // Handle resize for: Resize Grips, Borders, Gamepad
5039 // Return true when using auto-fit (double click on resize grip)
5040 static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4])
5041 {
5042  ImGuiContext& g = *GImGui;
5043  ImGuiWindowFlags flags = window->Flags;
5044 
5046  return false;
5047  if (window->WasActive == false) // Early out to avoid running this code for e.g. an hidden implicit/fallback Debug window.
5048  return false;
5049 
5050  bool ret_auto_fit = false;
5051  const int resize_border_count = g.IO.ConfigWindowsResizeFromEdges ? 4 : 0;
5052  const float grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
5053  const float grip_hover_inner_size = IM_FLOOR(grip_draw_size * 0.75f);
5054  const float grip_hover_outer_size = g.IO.ConfigWindowsResizeFromEdges ? WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS : 0.0f;
5055 
5056  ImVec2 pos_target(FLT_MAX, FLT_MAX);
5057  ImVec2 size_target(FLT_MAX, FLT_MAX);
5058 
5059  // Resize grips and borders are on layer 1
5061  window->DC.NavLayerCurrentMask = (1 << ImGuiNavLayer_Menu);
5062 
5063  // Manual resize grips
5064  PushID("#RESIZE");
5065  for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++)
5066  {
5067  const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n];
5068  const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPosN);
5069 
5070  // Using the FlattenChilds button flag we make the resize button accessible even if we are hovering over a child window
5071  ImRect resize_rect(corner - grip.InnerDir * grip_hover_outer_size, corner + grip.InnerDir * grip_hover_inner_size);
5072  if (resize_rect.Min.x > resize_rect.Max.x) ImSwap(resize_rect.Min.x, resize_rect.Max.x);
5073  if (resize_rect.Min.y > resize_rect.Max.y) ImSwap(resize_rect.Min.y, resize_rect.Max.y);
5074  bool hovered, held;
5075  ButtonBehavior(resize_rect, window->GetID(resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus);
5076  //GetForegroundDrawList(window)->AddRect(resize_rect.Min, resize_rect.Max, IM_COL32(255, 255, 0, 255));
5077  if (hovered || held)
5078  g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE;
5079 
5080  if (held && g.IO.MouseDoubleClicked[0] && resize_grip_n == 0)
5081  {
5082  // Manual auto-fit when double-clicking
5083  size_target = CalcWindowSizeAfterConstraint(window, size_auto_fit);
5084  ret_auto_fit = true;
5085  ClearActiveID();
5086  }
5087  else if (held)
5088  {
5089  // Resize from any of the four corners
5090  // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position
5091  ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + ImLerp(grip.InnerDir * grip_hover_outer_size, grip.InnerDir * -grip_hover_inner_size, grip.CornerPosN); // Corner of the window corresponding to our corner grip
5092  CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerPosN, &pos_target, &size_target);
5093  }
5094  if (resize_grip_n == 0 || held || hovered)
5095  resize_grip_col[resize_grip_n] = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip);
5096  }
5097  for (int border_n = 0; border_n < resize_border_count; border_n++)
5098  {
5099  bool hovered, held;
5100  ImRect border_rect = GetResizeBorderRect(window, border_n, grip_hover_inner_size, WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS);
5101  ButtonBehavior(border_rect, window->GetID(border_n + 4), &hovered, &held, ImGuiButtonFlags_FlattenChildren);
5102  //GetForegroundDrawLists(window)->AddRect(border_rect.Min, border_rect.Max, IM_COL32(255, 255, 0, 255));
5103  if ((hovered && g.HoveredIdTimer > WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER) || held)
5104  {
5105  g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS;
5106  if (held)
5107  *border_held = border_n;
5108  }
5109  if (held)
5110  {
5111  ImVec2 border_target = window->Pos;
5112  ImVec2 border_posn;
5113  if (border_n == 0) { border_posn = ImVec2(0, 0); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Top
5114  if (border_n == 1) { border_posn = ImVec2(1, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Right
5115  if (border_n == 2) { border_posn = ImVec2(0, 1); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Bottom
5116  if (border_n == 3) { border_posn = ImVec2(0, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Left
5117  CalcResizePosSizeFromAnyCorner(window, border_target, border_posn, &pos_target, &size_target);
5118  }
5119  }
5120  PopID();
5121 
5122  // Restore nav layer
5124  window->DC.NavLayerCurrentMask = (1 << ImGuiNavLayer_Main);
5125 
5126  // Navigation resize (keyboard/gamepad)
5127  if (g.NavWindowingTarget && g.NavWindowingTarget->RootWindow == window)
5128  {
5129  ImVec2 nav_resize_delta;
5130  if (g.NavInputSource == ImGuiInputSource_NavKeyboard && g.IO.KeyShift)
5132  if (g.NavInputSource == ImGuiInputSource_NavGamepad)
5134  if (nav_resize_delta.x != 0.0f || nav_resize_delta.y != 0.0f)
5135  {
5136  const float NAV_RESIZE_SPEED = 600.0f;
5137  nav_resize_delta *= ImFloor(NAV_RESIZE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y));
5138  g.NavWindowingToggleLayer = false;
5139  g.NavDisableMouseHover = true;
5140  resize_grip_col[0] = GetColorU32(ImGuiCol_ResizeGripActive);
5141  // FIXME-NAV: Should store and accumulate into a separate size buffer to handle sizing constraints properly, right now a constraint will make us stuck.
5142  size_target = CalcWindowSizeAfterConstraint(window, window->SizeFull + nav_resize_delta);
5143  }
5144  }
5145 
5146  // Apply back modified position/size to window
5147  if (size_target.x != FLT_MAX)
5148  {
5149  window->SizeFull = size_target;
5150  MarkIniSettingsDirty(window);
5151  }
5152  if (pos_target.x != FLT_MAX)
5153  {
5154  window->Pos = ImFloor(pos_target);
5155  MarkIniSettingsDirty(window);
5156  }
5157 
5158  window->Size = window->SizeFull;
5159  return ret_auto_fit;
5160 }
5161 
5162 static inline void ClampWindowRect(ImGuiWindow* window, const ImRect& rect, const ImVec2& padding)
5163 {
5164  ImGuiContext& g = *GImGui;
5165  ImVec2 size_for_clamping = (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(window->Flags & ImGuiWindowFlags_NoTitleBar)) ? ImVec2(window->Size.x, window->TitleBarHeight()) : window->Size;
5166  window->Pos = ImMin(rect.Max - padding, ImMax(window->Pos + size_for_clamping, rect.Min + padding) - size_for_clamping);
5167 }
5168 
5170 {
5171  ImGuiContext& g = *GImGui;
5172  float rounding = window->WindowRounding;
5173  float border_size = window->WindowBorderSize;
5174  if (border_size > 0.0f && !(window->Flags & ImGuiWindowFlags_NoBackground))
5175  window->DrawList->AddRect(window->Pos, window->Pos + window->Size, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size);
5176 
5177  int border_held = window->ResizeBorderHeld;
5178  if (border_held != -1)
5179  {
5180  struct ImGuiResizeBorderDef
5181  {
5182  ImVec2 InnerDir;
5183  ImVec2 CornerPosN1, CornerPosN2;
5184  float OuterAngle;
5185  };
5186  static const ImGuiResizeBorderDef resize_border_def[4] =
5187  {
5188  { ImVec2(0,+1), ImVec2(0,0), ImVec2(1,0), IM_PI*1.50f }, // Top
5189  { ImVec2(-1,0), ImVec2(1,0), ImVec2(1,1), IM_PI*0.00f }, // Right
5190  { ImVec2(0,-1), ImVec2(1,1), ImVec2(0,1), IM_PI*0.50f }, // Bottom
5191  { ImVec2(+1,0), ImVec2(0,1), ImVec2(0,0), IM_PI*1.00f } // Left
5192  };
5193  const ImGuiResizeBorderDef& def = resize_border_def[border_held];
5194  ImRect border_r = GetResizeBorderRect(window, border_held, rounding, 0.0f);
5195  window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.CornerPosN1) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle - IM_PI*0.25f, def.OuterAngle);
5196  window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.CornerPosN2) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle, def.OuterAngle + IM_PI*0.25f);
5197  window->DrawList->PathStroke(GetColorU32(ImGuiCol_SeparatorActive), false, ImMax(2.0f, border_size)); // Thicker than usual
5198  }
5199  if (g.Style.FrameBorderSize > 0 && !(window->Flags & ImGuiWindowFlags_NoTitleBar))
5200  {
5201  float y = window->Pos.y + window->TitleBarHeight() - 1;
5202  window->DrawList->AddLine(ImVec2(window->Pos.x + border_size, y), ImVec2(window->Pos.x + window->Size.x - border_size, y), GetColorU32(ImGuiCol_Border), g.Style.FrameBorderSize);
5203  }
5204 }
5205 
5206 // Draw background and borders
5207 // Draw and handle scrollbars
5208 void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size)
5209 {
5210  ImGuiContext& g = *GImGui;
5211  ImGuiStyle& style = g.Style;
5212  ImGuiWindowFlags flags = window->Flags;
5213 
5214  // Ensure that ScrollBar doesn't read last frame's SkipItems
5215  window->SkipItems = false;
5216 
5217  // Draw window + handle manual resize
5218  // As we highlight the title bar when want_focus is set, multiple reappearing windows will have have their title bar highlighted on their reappearing frame.
5219  const float window_rounding = window->WindowRounding;
5220  const float window_border_size = window->WindowBorderSize;
5221  if (window->Collapsed)
5222  {
5223  // Title bar only
5224  float backup_border_size = style.FrameBorderSize;
5225  g.Style.FrameBorderSize = window->WindowBorderSize;
5226  ImU32 title_bar_col = GetColorU32((title_bar_is_highlight && !g.NavDisableHighlight) ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBgCollapsed);
5227  RenderFrame(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, true, window_rounding);
5228  g.Style.FrameBorderSize = backup_border_size;
5229  }
5230  else
5231  {
5232  // Window background
5234  {
5236  bool override_alpha = false;
5237  float alpha = 1.0f;
5238  if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasBgAlpha)
5239  {
5240  alpha = g.NextWindowData.BgAlphaVal;
5241  override_alpha = true;
5242  }
5243  if (override_alpha)
5244  bg_col = (bg_col & ~IM_COL32_A_MASK) | (IM_F32_TO_INT8_SAT(alpha) << IM_COL32_A_SHIFT);
5245  window->DrawList->AddRectFilled(window->Pos + ImVec2(0, window->TitleBarHeight()), window->Pos + window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Bot);
5246  }
5247 
5248  // Title bar
5250  {
5251  ImU32 title_bar_col = GetColorU32(title_bar_is_highlight ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg);
5252  window->DrawList->AddRectFilled(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, window_rounding, ImDrawCornerFlags_Top);
5253  }
5254 
5255  // Menu bar
5257  {
5258  ImRect menu_bar_rect = window->MenuBarRect();
5259  menu_bar_rect.ClipWith(window->Rect()); // Soft clipping, in particular child window don't have minimum size covering the menu bar so this is useful for them.
5260  window->DrawList->AddRectFilled(menu_bar_rect.Min + ImVec2(window_border_size, 0), menu_bar_rect.Max - ImVec2(window_border_size, 0), GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawCornerFlags_Top);
5261  if (style.FrameBorderSize > 0.0f && menu_bar_rect.Max.y < window->Pos.y + window->Size.y)
5262  window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.FrameBorderSize);
5263  }
5264 
5265  // Scrollbars
5266  if (window->ScrollbarX)
5268  if (window->ScrollbarY)
5270 
5271  // Render resize grips (after their input handling so we don't have a frame of latency)
5273  {
5274  for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++)
5275  {
5276  const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n];
5277  const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPosN);
5278  window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(window_border_size, resize_grip_draw_size) : ImVec2(resize_grip_draw_size, window_border_size)));
5279  window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(resize_grip_draw_size, window_border_size) : ImVec2(window_border_size, resize_grip_draw_size)));
5280  window->DrawList->PathArcToFast(ImVec2(corner.x + grip.InnerDir.x * (window_rounding + window_border_size), corner.y + grip.InnerDir.y * (window_rounding + window_border_size)), window_rounding, grip.AngleMin12, grip.AngleMax12);
5281  window->DrawList->PathFillConvex(resize_grip_col[resize_grip_n]);
5282  }
5283  }
5284 
5285  // Borders
5286  RenderWindowOuterBorders(window);
5287  }
5288 }
5289 
5290 // Render title text, collapse button, close button
5291 void ImGui::RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open)
5292 {
5293  ImGuiContext& g = *GImGui;
5294  ImGuiStyle& style = g.Style;
5295  ImGuiWindowFlags flags = window->Flags;
5296 
5297  const bool has_close_button = (p_open != NULL);
5298  const bool has_collapse_button = !(flags & ImGuiWindowFlags_NoCollapse) && (style.WindowMenuButtonPosition != ImGuiDir_None);
5299 
5300  // Close & Collapse button are on the Menu NavLayer and don't default focus (unless there's nothing else on that layer)
5301  const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags;
5304  window->DC.NavLayerCurrentMask = (1 << ImGuiNavLayer_Menu);
5305 
5306  // Layout buttons
5307  // FIXME: Would be nice to generalize the subtleties expressed here into reusable code.
5308  float pad_l = style.FramePadding.x;
5309  float pad_r = style.FramePadding.x;
5310  float button_sz = g.FontSize;
5311  ImVec2 close_button_pos;
5312  ImVec2 collapse_button_pos;
5313  if (has_close_button)
5314  {
5315  pad_r += button_sz;
5316  close_button_pos = ImVec2(title_bar_rect.Max.x - pad_r - style.FramePadding.x, title_bar_rect.Min.y);
5317  }
5318  if (has_collapse_button && style.WindowMenuButtonPosition == ImGuiDir_Right)
5319  {
5320  pad_r += button_sz;
5321  collapse_button_pos = ImVec2(title_bar_rect.Max.x - pad_r - style.FramePadding.x, title_bar_rect.Min.y);
5322  }
5323  if (has_collapse_button && style.WindowMenuButtonPosition == ImGuiDir_Left)
5324  {
5325  collapse_button_pos = ImVec2(title_bar_rect.Min.x + pad_l - style.FramePadding.x, title_bar_rect.Min.y);
5326  pad_l += button_sz;
5327  }
5328 
5329  // Collapse button (submitting first so it gets priority when choosing a navigation init fallback)
5330  if (has_collapse_button)
5331  if (CollapseButton(window->GetID("#COLLAPSE"), collapse_button_pos))
5332  window->WantCollapseToggle = true; // Defer actual collapsing to next frame as we are too far in the Begin() function
5333 
5334  // Close button
5335  if (has_close_button)
5336  if (CloseButton(window->GetID("#CLOSE"), close_button_pos))
5337  *p_open = false;
5338 
5340  window->DC.NavLayerCurrentMask = (1 << ImGuiNavLayer_Main);
5341  window->DC.ItemFlags = item_flags_backup;
5342 
5343  // Title bar text (with: horizontal alignment, avoiding collapse/close button, optional "unsaved document" marker)
5344  // FIXME: Refactor text alignment facilities along with RenderText helpers, this is WAY too much messy code..
5345  const char* UNSAVED_DOCUMENT_MARKER = "*";
5346  const float marker_size_x = (flags & ImGuiWindowFlags_UnsavedDocument) ? CalcTextSize(UNSAVED_DOCUMENT_MARKER, NULL, false).x : 0.0f;
5347  const ImVec2 text_size = CalcTextSize(name, NULL, true) + ImVec2(marker_size_x, 0.0f);
5348 
5349  // As a nice touch we try to ensure that centered title text doesn't get affected by visibility of Close/Collapse button,
5350  // while uncentered title text will still reach edges correct.
5351  if (pad_l > style.FramePadding.x)
5352  pad_l += g.Style.ItemInnerSpacing.x;
5353  if (pad_r > style.FramePadding.x)
5354  pad_r += g.Style.ItemInnerSpacing.x;
5355  if (style.WindowTitleAlign.x > 0.0f && style.WindowTitleAlign.x < 1.0f)
5356  {
5357  float centerness = ImSaturate(1.0f - ImFabs(style.WindowTitleAlign.x - 0.5f) * 2.0f); // 0.0f on either edges, 1.0f on center
5358  float pad_extend = ImMin(ImMax(pad_l, pad_r), title_bar_rect.GetWidth() - pad_l - pad_r - text_size.x);
5359  pad_l = ImMax(pad_l, pad_extend * centerness);
5360  pad_r = ImMax(pad_r, pad_extend * centerness);
5361  }
5362 
5363  ImRect layout_r(title_bar_rect.Min.x + pad_l, title_bar_rect.Min.y, title_bar_rect.Max.x - pad_r, title_bar_rect.Max.y);
5364  ImRect clip_r(layout_r.Min.x, layout_r.Min.y, layout_r.Max.x + g.Style.ItemInnerSpacing.x, layout_r.Max.y);
5365  //if (g.IO.KeyCtrl) window->DrawList->AddRect(layout_r.Min, layout_r.Max, IM_COL32(255, 128, 0, 255)); // [DEBUG]
5366  RenderTextClipped(layout_r.Min, layout_r.Max, name, NULL, &text_size, style.WindowTitleAlign, &clip_r);
5368  {
5369  ImVec2 marker_pos = ImVec2(ImMax(layout_r.Min.x, layout_r.Min.x + (layout_r.GetWidth() - text_size.x) * style.WindowTitleAlign.x) + text_size.x, layout_r.Min.y) + ImVec2(2 - marker_size_x, 0.0f);
5370  ImVec2 off = ImVec2(0.0f, IM_FLOOR(-g.FontSize * 0.25f));
5371  RenderTextClipped(marker_pos + off, layout_r.Max + off, UNSAVED_DOCUMENT_MARKER, NULL, NULL, ImVec2(0, style.WindowTitleAlign.y), &clip_r);
5372  }
5373 }
5374 
5376 {
5377  window->ParentWindow = parent_window;
5378  window->RootWindow = window->RootWindowForTitleBarHighlight = window->RootWindowForNav = window;
5379  if (parent_window && (flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Tooltip))
5380  window->RootWindow = parent_window->RootWindow;
5384  {
5386  window->RootWindowForNav = window->RootWindowForNav->ParentWindow;
5387  }
5388 }
5389 
5390 // Push a new Dear ImGui window to add widgets to.
5391 // - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair.
5392 // - Begin/End can be called multiple times during the frame with the same window name to append content.
5393 // - The window name is used as a unique identifier to preserve window information across frames (and save rudimentary information to the .ini file).
5394 // You can use the "##" or "###" markers to use the same label with different id, or same id with different label. See documentation at the top of this file.
5395 // - Return false when window is collapsed, so you can early out in your code. You always need to call ImGui::End() even if false is returned.
5396 // - Passing 'bool* p_open' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed.
5397 bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
5398 {
5399  ImGuiContext& g = *GImGui;
5400  const ImGuiStyle& style = g.Style;
5401  IM_ASSERT(name != NULL && name[0] != '\0'); // Window name required
5402  IM_ASSERT(g.WithinFrameScope); // Forgot to call ImGui::NewFrame()
5403  IM_ASSERT(g.FrameCountEnded != g.FrameCount); // Called ImGui::Render() or ImGui::EndFrame() and haven't called ImGui::NewFrame() again yet
5404 
5405  // Find or create
5406  ImGuiWindow* window = FindWindowByName(name);
5407  const bool window_just_created = (window == NULL);
5408  if (window_just_created)
5409  {
5410  ImVec2 size_on_first_use = (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSize) ? g.NextWindowData.SizeVal : ImVec2(0.0f, 0.0f); // Any condition flag will do since we are creating a new window here.
5411  window = CreateNewWindow(name, size_on_first_use, flags);
5412  }
5413 
5414  // Automatically disable manual moving/resizing when NoInputs is set
5417 
5420 
5421  const int current_frame = g.FrameCount;
5422  const bool first_begin_of_the_frame = (window->LastFrameActive != current_frame);
5423  window->IsFallbackWindow = (g.CurrentWindowStack.Size == 0 && g.WithinFrameScopeWithImplicitWindow);
5424 
5425  // Update the Appearing flag
5426  bool window_just_activated_by_user = (window->LastFrameActive < current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on
5427  const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFramesCannotSkipItems > 0);
5429  {
5430  ImGuiPopupData& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size];
5431  window_just_activated_by_user |= (window->PopupId != popup_ref.PopupId); // We recycle popups so treat window as activated if popup id changed
5432  window_just_activated_by_user |= (window != popup_ref.Window);
5433  }
5434  window->Appearing = (window_just_activated_by_user || window_just_appearing_after_hidden_for_resize);
5435  if (window->Appearing)
5437 
5438  // Update Flags, LastFrameActive, BeginOrderXXX fields
5439  if (first_begin_of_the_frame)
5440  {
5441  window->Flags = (ImGuiWindowFlags)flags;
5442  window->LastFrameActive = current_frame;
5443  window->LastTimeActive = (float)g.Time;
5444  window->BeginOrderWithinParent = 0;
5445  window->BeginOrderWithinContext = (short)(g.WindowsActiveCount++);
5446  }
5447  else
5448  {
5449  flags = window->Flags;
5450  }
5451 
5452  // Parent window is latched only on the first call to Begin() of the frame, so further append-calls can be done from a different window stack
5453  ImGuiWindow* parent_window_in_stack = g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back();
5454  ImGuiWindow* parent_window = first_begin_of_the_frame ? ((flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)) ? parent_window_in_stack : NULL) : window->ParentWindow;
5455  IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow));
5456 
5457  // We allow window memory to be compacted so recreate the base stack when needed.
5458  if (window->IDStack.Size == 0)
5459  window->IDStack.push_back(window->ID);
5460 
5461  // Add to stack
5462  // We intentionally set g.CurrentWindow to NULL to prevent usage until when the viewport is set, then will call SetCurrentWindow()
5463  g.CurrentWindowStack.push_back(window);
5464  g.CurrentWindow = NULL;
5467  {
5468  ImGuiPopupData& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size];
5469  popup_ref.Window = window;
5470  g.BeginPopupStack.push_back(popup_ref);
5471  window->PopupId = popup_ref.PopupId;
5472  }
5473 
5474  if (window_just_appearing_after_hidden_for_resize && !(flags & ImGuiWindowFlags_ChildWindow))
5475  window->NavLastIds[0] = 0;
5476 
5477  // Update ->RootWindow and others pointers (before any possible call to FocusWindow)
5478  if (first_begin_of_the_frame)
5479  UpdateWindowParentAndRootLinks(window, flags, parent_window);
5480 
5481  // Process SetNextWindow***() calls
5482  bool window_pos_set_by_api = false;
5483  bool window_size_x_set_by_api = false, window_size_y_set_by_api = false;
5484  if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos)
5485  {
5486  window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.NextWindowData.PosCond) != 0;
5487  if (window_pos_set_by_api && ImLengthSqr(g.NextWindowData.PosPivotVal) > 0.00001f)
5488  {
5489  // May be processed on the next frame if this is our first frame and we are measuring size
5490  // FIXME: Look into removing the branch so everything can go through this same code path for consistency.
5491  window->SetWindowPosVal = g.NextWindowData.PosVal;
5492  window->SetWindowPosPivot = g.NextWindowData.PosPivotVal;
5494  }
5495  else
5496  {
5497  SetWindowPos(window, g.NextWindowData.PosVal, g.NextWindowData.PosCond);
5498  }
5499  }
5500  if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasSize)
5501  {
5502  window_size_x_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.x > 0.0f);
5503  window_size_y_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.y > 0.0f);
5504  SetWindowSize(window, g.NextWindowData.SizeVal, g.NextWindowData.SizeCond);
5505  }
5506  if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasContentSize)
5507  window->ContentSizeExplicit = g.NextWindowData.ContentSizeVal;
5508  else if (first_begin_of_the_frame)
5509  window->ContentSizeExplicit = ImVec2(0.0f, 0.0f);
5510  if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasCollapsed)
5511  SetWindowCollapsed(window, g.NextWindowData.CollapsedVal, g.NextWindowData.CollapsedCond);
5512  if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasFocus)
5513  FocusWindow(window);
5514  if (window->Appearing)
5516 
5517  // When reusing window again multiple times a frame, just append content (don't need to setup again)
5518  if (first_begin_of_the_frame)
5519  {
5520  // Initialize
5521  const bool window_is_child_tooltip = (flags & ImGuiWindowFlags_ChildWindow) && (flags & ImGuiWindowFlags_Tooltip); // FIXME-WIP: Undocumented behavior of Child+Tooltip for pinned tooltip (#1345)
5522  window->Active = true;
5523  window->HasCloseButton = (p_open != NULL);
5524  window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX);
5525  window->IDStack.resize(1);
5526 
5527  // Restore buffer capacity when woken from a compacted state, to avoid
5528  if (window->MemoryCompacted)
5530 
5531  // Update stored window name when it changes (which can _only_ happen with the "###" operator, so the ID would stay unchanged).
5532  // The title bar always display the 'name' parameter, so we only update the string storage if it needs to be visible to the end-user elsewhere.
5533  bool window_title_visible_elsewhere = false;
5534  if (g.NavWindowingList != NULL && (window->Flags & ImGuiWindowFlags_NoNavFocus) == 0) // Window titles visible when using CTRL+TAB
5535  window_title_visible_elsewhere = true;
5536  if (window_title_visible_elsewhere && !window_just_created && strcmp(name, window->Name) != 0)
5537  {
5538  size_t buf_len = (size_t)window->NameBufLen;
5539  window->Name = ImStrdupcpy(window->Name, &buf_len, name);
5540  window->NameBufLen = (int)buf_len;
5541  }
5542 
5543  // UPDATE CONTENTS SIZE, UPDATE HIDDEN STATUS
5544 
5545  // Update contents size from last frame for auto-fitting (or use explicit size)
5546  window->ContentSize = CalcWindowContentSize(window);
5547  if (window->HiddenFramesCanSkipItems > 0)
5548  window->HiddenFramesCanSkipItems--;
5549  if (window->HiddenFramesCannotSkipItems > 0)
5550  window->HiddenFramesCannotSkipItems--;
5551 
5552  // Hide new windows for one frame until they calculate their size
5553  if (window_just_created && (!window_size_x_set_by_api || !window_size_y_set_by_api))
5554  window->HiddenFramesCannotSkipItems = 1;
5555 
5556  // Hide popup/tooltip window when re-opening while we measure size (because we recycle the windows)
5557  // We reset Size/ContentSize for reappearing popups/tooltips early in this function, so further code won't be tempted to use the old size.
5558  if (window_just_activated_by_user && (flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0)
5559  {
5560  window->HiddenFramesCannotSkipItems = 1;
5562  {
5563  if (!window_size_x_set_by_api)
5564  window->Size.x = window->SizeFull.x = 0.f;
5565  if (!window_size_y_set_by_api)
5566  window->Size.y = window->SizeFull.y = 0.f;
5567  window->ContentSize = ImVec2(0.f, 0.f);
5568  }
5569  }
5570 
5571  // SELECT VIEWPORT
5572  // FIXME-VIEWPORT: In the docking/viewport branch, this is the point where we select the current viewport (which may affect the style)
5573  SetCurrentWindow(window);
5574 
5575  // LOCK BORDER SIZE AND PADDING FOR THE FRAME (so that altering them doesn't cause inconsistencies)
5576 
5578  window->WindowBorderSize = style.ChildBorderSize;
5579  else
5581  window->WindowPadding = style.WindowPadding;
5583  window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f);
5584 
5585  // Collapse window by double-clicking on title bar
5586  // At this point we don't have a clipping rectangle setup yet, so we can use the title bar area for hit detection and drawing
5588  {
5589  // We don't use a regular button+id to test for double-click on title bar (mostly due to legacy reason, could be fixed), so verify that we don't have items over the title bar.
5590  ImRect title_bar_rect = window->TitleBarRect();
5591  if (g.HoveredWindow == window && g.HoveredId == 0 && g.HoveredIdPreviousFrame == 0 && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max) && g.IO.MouseDoubleClicked[0])
5592  window->WantCollapseToggle = true;
5593  if (window->WantCollapseToggle)
5594  {
5595  window->Collapsed = !window->Collapsed;
5596  MarkIniSettingsDirty(window);
5597  FocusWindow(window);
5598  }
5599  }
5600  else
5601  {
5602  window->Collapsed = false;
5603  }
5604  window->WantCollapseToggle = false;
5605 
5606  // SIZE
5607 
5608  // Calculate auto-fit size, handle automatic resize
5609  const ImVec2 size_auto_fit = CalcWindowAutoFitSize(window, window->ContentSize);
5610  bool use_current_size_for_scrollbar_x = window_just_created;
5611  bool use_current_size_for_scrollbar_y = window_just_created;
5613  {
5614  // Using SetNextWindowSize() overrides ImGuiWindowFlags_AlwaysAutoResize, so it can be used on tooltips/popups, etc.
5615  if (!window_size_x_set_by_api)
5616  {
5617  window->SizeFull.x = size_auto_fit.x;
5618  use_current_size_for_scrollbar_x = true;
5619  }
5620  if (!window_size_y_set_by_api)
5621  {
5622  window->SizeFull.y = size_auto_fit.y;
5623  use_current_size_for_scrollbar_y = true;
5624  }
5625  }
5626  else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0)
5627  {
5628  // Auto-fit may only grow window during the first few frames
5629  // We still process initial auto-fit on collapsed windows to get a window width, but otherwise don't honor ImGuiWindowFlags_AlwaysAutoResize when collapsed.
5630  if (!window_size_x_set_by_api && window->AutoFitFramesX > 0)
5631  {
5632  window->SizeFull.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x;
5633  use_current_size_for_scrollbar_x = true;
5634  }
5635  if (!window_size_y_set_by_api && window->AutoFitFramesY > 0)
5636  {
5637  window->SizeFull.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y;
5638  use_current_size_for_scrollbar_y = true;
5639  }
5640  if (!window->Collapsed)
5641  MarkIniSettingsDirty(window);
5642  }
5643 
5644  // Apply minimum/maximum window size constraints and final size
5645  window->SizeFull = CalcWindowSizeAfterConstraint(window, window->SizeFull);
5646  window->Size = window->Collapsed && !(flags & ImGuiWindowFlags_ChildWindow) ? window->TitleBarRect().GetSize() : window->SizeFull;
5647 
5648  // Decoration size
5649  const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight();
5650 
5651  // POSITION
5652 
5653  // Popup latch its initial position, will position itself when it appears next frame
5654  if (window_just_activated_by_user)
5655  {
5657  if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api)
5658  window->Pos = g.BeginPopupStack.back().OpenPopupPos;
5659  }
5660 
5661  // Position child window
5663  {
5664  IM_ASSERT(parent_window && parent_window->Active);
5665  window->BeginOrderWithinParent = (short)parent_window->DC.ChildWindows.Size;
5666  parent_window->DC.ChildWindows.push_back(window);
5667  if (!(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api && !window_is_child_tooltip)
5668  window->Pos = parent_window->DC.CursorPos;
5669  }
5670 
5671  const bool window_pos_with_pivot = (window->SetWindowPosVal.x != FLT_MAX && window->HiddenFramesCannotSkipItems == 0);
5672  if (window_pos_with_pivot)
5673  SetWindowPos(window, window->SetWindowPosVal - window->SizeFull * window->SetWindowPosPivot, 0); // Position given a pivot (e.g. for centering)
5674  else if ((flags & ImGuiWindowFlags_ChildMenu) != 0)
5675  window->Pos = FindBestWindowPosForPopup(window);
5676  else if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api && window_just_appearing_after_hidden_for_resize)
5677  window->Pos = FindBestWindowPosForPopup(window);
5678  else if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api && !window_is_child_tooltip)
5679  window->Pos = FindBestWindowPosForPopup(window);
5680 
5681  // Clamp position/size so window stays visible within its viewport or monitor
5682  // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing.
5683  ImRect viewport_rect(GetViewportRect());
5684  if (!window_pos_set_by_api && !(flags & ImGuiWindowFlags_ChildWindow) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
5685  {
5686  ImVec2 clamp_padding = ImMax(style.DisplayWindowPadding, style.DisplaySafeAreaPadding);
5687  if (viewport_rect.GetWidth() > 0 && viewport_rect.GetHeight() > 0.0f)
5688  {
5689  ClampWindowRect(window, viewport_rect, clamp_padding);
5690  }
5691  }
5692  window->Pos = ImFloor(window->Pos);
5693 
5694  // Lock window rounding for the frame (so that altering them doesn't cause inconsistencies)
5696 
5697  // Apply window focus (new and reactivated windows are moved to front)
5698  bool want_focus = false;
5699  if (window_just_activated_by_user && !(flags & ImGuiWindowFlags_NoFocusOnAppearing))
5700  {
5702  want_focus = true;
5704  want_focus = true;
5705  }
5706 
5707  // Handle manual resize: Resize Grips, Borders, Gamepad
5708  int border_held = -1;
5709  ImU32 resize_grip_col[4] = {};
5710  const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it.
5711  const float resize_grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
5712  if (!window->Collapsed)
5713  if (UpdateWindowManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0]))
5714  use_current_size_for_scrollbar_x = use_current_size_for_scrollbar_y = true;
5715  window->ResizeBorderHeld = (signed char)border_held;
5716 
5717  // SCROLLBAR VISIBILITY
5718 
5719  // Update scrollbar visibility (based on the Size that was effective during last frame or the auto-resized Size).
5720  if (!window->Collapsed)
5721  {
5722  // When reading the current size we need to read it after size constraints have been applied.
5723  // When we use InnerRect here we are intentionally reading last frame size, same for ScrollbarSizes values before we set them again.
5724  ImVec2 avail_size_from_current_frame = ImVec2(window->SizeFull.x, window->SizeFull.y - decoration_up_height);
5725  ImVec2 avail_size_from_last_frame = window->InnerRect.GetSize() + window->ScrollbarSizes;
5726  ImVec2 needed_size_from_last_frame = window_just_created ? ImVec2(0, 0) : window->ContentSize + window->WindowPadding * 2.0f;
5727  float size_x_for_scrollbars = use_current_size_for_scrollbar_x ? avail_size_from_current_frame.x : avail_size_from_last_frame.x;
5728  float size_y_for_scrollbars = use_current_size_for_scrollbar_y ? avail_size_from_current_frame.y : avail_size_from_last_frame.y;
5729  //bool scrollbar_y_from_last_frame = window->ScrollbarY; // FIXME: May want to use that in the ScrollbarX expression? How many pros vs cons?
5730  window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((needed_size_from_last_frame.y > size_y_for_scrollbars) && !(flags & ImGuiWindowFlags_NoScrollbar));
5731  window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((needed_size_from_last_frame.x > size_x_for_scrollbars - (window->ScrollbarY ? style.ScrollbarSize : 0.0f)) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar));
5732  if (window->ScrollbarX && !window->ScrollbarY)
5733  window->ScrollbarY = (needed_size_from_last_frame.y > size_y_for_scrollbars) && !(flags & ImGuiWindowFlags_NoScrollbar);
5734  window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f);
5735  }
5736 
5737  // UPDATE RECTANGLES (1- THOSE NOT AFFECTED BY SCROLLING)
5738  // Update various regions. Variables they depends on should be set above in this function.
5739  // We set this up after processing the resize grip so that our rectangles doesn't lag by a frame.
5740 
5741  // Outer rectangle
5742  // Not affected by window border size. Used by:
5743  // - FindHoveredWindow() (w/ extra padding when border resize is enabled)
5744  // - Begin() initial clipping rect for drawing window background and borders.
5745  // - Begin() clipping whole child
5746  const ImRect host_rect = ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_is_child_tooltip) ? parent_window->ClipRect : viewport_rect;
5747  const ImRect outer_rect = window->Rect();
5748  const ImRect title_bar_rect = window->TitleBarRect();
5749  window->OuterRectClipped = outer_rect;
5750  window->OuterRectClipped.ClipWith(host_rect);
5751 
5752  // Inner rectangle
5753  // Not affected by window border size. Used by:
5754  // - InnerClipRect
5755  // - ScrollToBringRectIntoView()
5756  // - NavUpdatePageUpPageDown()
5757  // - Scrollbar()
5758  window->InnerRect.Min.x = window->Pos.x;
5759  window->InnerRect.Min.y = window->Pos.y + decoration_up_height;
5760  window->InnerRect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x;
5761  window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->ScrollbarSizes.y;
5762 
5763  // Inner clipping rectangle.
5764  // Will extend a little bit outside the normal work region.
5765  // This is to allow e.g. Selectable or CollapsingHeader or some separators to cover that space.
5766  // Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result.
5767  // Note that if our window is collapsed we will end up with an inverted (~null) clipping rectangle which is the correct behavior.
5768  // Affected by window/frame border size. Used by:
5769  // - Begin() initial clip rect
5770  float top_border_size = (((flags & ImGuiWindowFlags_MenuBar) || !(flags & ImGuiWindowFlags_NoTitleBar)) ? style.FrameBorderSize : window->WindowBorderSize);
5771  window->InnerClipRect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + ImMax(ImFloor(window->WindowPadding.x * 0.5f), window->WindowBorderSize));
5772  window->InnerClipRect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y + top_border_size);
5773  window->InnerClipRect.Max.x = ImFloor(0.5f + window->InnerRect.Max.x - ImMax(ImFloor(window->WindowPadding.x * 0.5f), window->WindowBorderSize));
5774  window->InnerClipRect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y - window->WindowBorderSize);
5775  window->InnerClipRect.ClipWithFull(host_rect);
5776 
5777  // Default item width. Make it proportional to window size if window manually resizes
5778  if (window->Size.x > 0.0f && !(flags & ImGuiWindowFlags_Tooltip) && !(flags & ImGuiWindowFlags_AlwaysAutoResize))
5779  window->ItemWidthDefault = ImFloor(window->Size.x * 0.65f);
5780  else
5781  window->ItemWidthDefault = ImFloor(g.FontSize * 16.0f);
5782 
5783  // SCROLLING
5784 
5785  // Lock down maximum scrolling
5786  // The value of ScrollMax are ahead from ScrollbarX/ScrollbarY which is intentionally using InnerRect from previous rect in order to accommodate
5787  // for right/bottom aligned items without creating a scrollbar.
5788  window->ScrollMax.x = ImMax(0.0f, window->ContentSize.x + window->WindowPadding.x * 2.0f - window->InnerRect.GetWidth());
5789  window->ScrollMax.y = ImMax(0.0f, window->ContentSize.y + window->WindowPadding.y * 2.0f - window->InnerRect.GetHeight());
5790 
5791  // Apply scrolling
5792  window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window, true);
5793  window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
5794 
5795  // DRAWING
5796 
5797  // Setup draw list and outer clipping rectangle
5798  window->DrawList->Clear();
5799  window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID);
5800  PushClipRect(host_rect.Min, host_rect.Max, false);
5801 
5802  // Draw modal window background (darkens what is behind them, all viewports)
5803  const bool dim_bg_for_modal = (flags & ImGuiWindowFlags_Modal) && window == GetTopMostPopupModal() && window->HiddenFramesCannotSkipItems <= 0;
5804  const bool dim_bg_for_window_list = g.NavWindowingTargetAnim && (window == g.NavWindowingTargetAnim->RootWindow);
5805  if (dim_bg_for_modal || dim_bg_for_window_list)
5806  {
5807  const ImU32 dim_bg_col = GetColorU32(dim_bg_for_modal ? ImGuiCol_ModalWindowDimBg : ImGuiCol_NavWindowingDimBg, g.DimBgRatio);
5808  window->DrawList->AddRectFilled(viewport_rect.Min, viewport_rect.Max, dim_bg_col);
5809  }
5810 
5811  // Draw navigation selection/windowing rectangle background
5812  if (dim_bg_for_window_list && window == g.NavWindowingTargetAnim)
5813  {
5814  ImRect bb = window->Rect();
5815  bb.Expand(g.FontSize);
5816  if (!bb.Contains(viewport_rect)) // Avoid drawing if the window covers all the viewport anyway
5817  window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha * 0.25f), g.Style.WindowRounding);
5818  }
5819 
5820  // Since 1.71, child window can render their decoration (bg color, border, scrollbars, etc.) within their parent to save a draw call.
5821  // When using overlapping child windows, this will break the assumption that child z-order is mapped to submission order.
5822  // We disable this when the parent window has zero vertices, which is a common pattern leading to laying out multiple overlapping child.
5823  // We also disabled this when we have dimming overlay behind this specific one child.
5824  // FIXME: More code may rely on explicit sorting of overlapping child window and would need to disable this somehow. Please get in contact if you are affected.
5825  {
5826  bool render_decorations_in_parent = false;
5827  if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_is_child_tooltip)
5828  if (window->DrawList->CmdBuffer.back().ElemCount == 0 && parent_window->DrawList->VtxBuffer.Size > 0)
5829  render_decorations_in_parent = true;
5830  if (render_decorations_in_parent)
5831  window->DrawList = parent_window->DrawList;
5832 
5833  // Handle title bar, scrollbar, resize grips and resize borders
5834  const ImGuiWindow* window_to_highlight = g.NavWindowingTarget ? g.NavWindowingTarget : g.NavWindow;
5835  const bool title_bar_is_highlight = want_focus || (window_to_highlight && window->RootWindowForTitleBarHighlight == window_to_highlight->RootWindowForTitleBarHighlight);
5836  RenderWindowDecorations(window, title_bar_rect, title_bar_is_highlight, resize_grip_count, resize_grip_col, resize_grip_draw_size);
5837 
5838  if (render_decorations_in_parent)
5839  window->DrawList = &window->DrawListInst;
5840  }
5841 
5842  // Draw navigation selection/windowing rectangle border
5843  if (g.NavWindowingTargetAnim == window)
5844  {
5845  float rounding = ImMax(window->WindowRounding, g.Style.WindowRounding);
5846  ImRect bb = window->Rect();
5847  bb.Expand(g.FontSize);
5848  if (bb.Contains(viewport_rect)) // If a window fits the entire viewport, adjust its highlight inward
5849  {
5850  bb.Expand(-g.FontSize - 1.0f);
5851  rounding = window->WindowRounding;
5852  }
5853  window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), rounding, ~0, 3.0f);
5854  }
5855 
5856  // UPDATE RECTANGLES (2- THOSE AFFECTED BY SCROLLING)
5857 
5858  // Work rectangle.
5859  // Affected by window padding and border size. Used by:
5860  // - Columns() for right-most edge
5861  // - TreeNode(), CollapsingHeader() for right-most edge
5862  // - BeginTabBar() for right-most edge
5863  const bool allow_scrollbar_x = !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar);
5864  const bool allow_scrollbar_y = !(flags & ImGuiWindowFlags_NoScrollbar);
5865  const float work_rect_size_x = (window->ContentSizeExplicit.x != 0.0f ? window->ContentSizeExplicit.x : ImMax(allow_scrollbar_x ? window->ContentSize.x : 0.0f, window->Size.x - window->WindowPadding.x * 2.0f - window->ScrollbarSizes.x));
5866  const float work_rect_size_y = (window->ContentSizeExplicit.y != 0.0f ? window->ContentSizeExplicit.y : ImMax(allow_scrollbar_y ? window->ContentSize.y : 0.0f, window->Size.y - window->WindowPadding.y * 2.0f - decoration_up_height - window->ScrollbarSizes.y));
5867  window->WorkRect.Min.x = ImFloor(window->InnerRect.Min.x - window->Scroll.x + ImMax(window->WindowPadding.x, window->WindowBorderSize));
5868  window->WorkRect.Min.y = ImFloor(window->InnerRect.Min.y - window->Scroll.y + ImMax(window->WindowPadding.y, window->WindowBorderSize));
5869  window->WorkRect.Max.x = window->WorkRect.Min.x + work_rect_size_x;
5870  window->WorkRect.Max.y = window->WorkRect.Min.y + work_rect_size_y;
5871 
5872  // [LEGACY] Content Region
5873  // FIXME-OBSOLETE: window->ContentRegionRect.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it.
5874  // Used by:
5875  // - Mouse wheel scrolling + many other things
5876  window->ContentRegionRect.Min.x = window->Pos.x - window->Scroll.x + window->WindowPadding.x;
5877  window->ContentRegionRect.Min.y = window->Pos.y - window->Scroll.y + window->WindowPadding.y + decoration_up_height;
5878  window->ContentRegionRect.Max.x = window->ContentRegionRect.Min.x + (window->ContentSizeExplicit.x != 0.0f ? window->ContentSizeExplicit.x : (window->Size.x - window->WindowPadding.x * 2.0f - window->ScrollbarSizes.x));
5879  window->ContentRegionRect.Max.y = window->ContentRegionRect.Min.y + (window->ContentSizeExplicit.y != 0.0f ? window->ContentSizeExplicit.y : (window->Size.y - window->WindowPadding.y * 2.0f - decoration_up_height - window->ScrollbarSizes.y));
5880 
5881  // Setup drawing context
5882  // (NB: That term "drawing context / DC" lost its meaning a long time ago. Initially was meant to hold transient data only. Nowadays difference between window-> and window->DC-> is dubious.)
5883  window->DC.Indent.x = 0.0f + window->WindowPadding.x - window->Scroll.x;
5884  window->DC.GroupOffset.x = 0.0f;
5885  window->DC.ColumnsOffset.x = 0.0f;
5886  window->DC.CursorStartPos = window->Pos + ImVec2(window->DC.Indent.x + window->DC.ColumnsOffset.x, decoration_up_height + window->WindowPadding.y - window->Scroll.y);
5887  window->DC.CursorPos = window->DC.CursorStartPos;
5888  window->DC.CursorPosPrevLine = window->DC.CursorPos;
5889  window->DC.CursorMaxPos = window->DC.CursorStartPos;
5890  window->DC.CurrLineSize = window->DC.PrevLineSize = ImVec2(0.0f, 0.0f);
5891  window->DC.CurrLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f;
5892 
5894  window->DC.NavLayerCurrentMask = (1 << ImGuiNavLayer_Main);
5895  window->DC.NavLayerActiveMask = window->DC.NavLayerActiveMaskNext;
5896  window->DC.NavLayerActiveMaskNext = 0x00;
5897  window->DC.NavFocusScopeIdCurrent = parent_window ? parent_window->DC.NavFocusScopeIdCurrent : 0;
5898  window->DC.NavHideHighlightOneFrame = false;
5899  window->DC.NavHasScroll = (window->ScrollMax.y > 0.0f);
5900 
5901  window->DC.MenuBarAppending = false;
5902  window->DC.MenuBarOffset.x = ImMax(ImMax(window->WindowPadding.x, style.ItemSpacing.x), g.NextWindowData.MenuBarOffsetMinVal.x);
5903  window->DC.MenuBarOffset.y = g.NextWindowData.MenuBarOffsetMinVal.y;
5904  window->DC.MenuColumns.Update(3, style.ItemSpacing.x, window_just_activated_by_user);
5905  window->DC.TreeDepth = 0;
5906  window->DC.TreeJumpToParentOnPopMask = 0x00;
5907  window->DC.ChildWindows.resize(0);
5908  window->DC.StateStorage = &window->StateStorage;
5909  window->DC.CurrentColumns = NULL;
5911  window->DC.ParentLayoutType = parent_window ? parent_window->DC.LayoutType : ImGuiLayoutType_Vertical;
5912  window->DC.FocusCounterRegular = window->DC.FocusCounterTabStop = -1;
5913 
5914  window->DC.ItemWidth = window->ItemWidthDefault;
5915  window->DC.TextWrapPos = -1.0f; // disabled
5916  window->DC.ItemFlagsStack.resize(0);
5917  window->DC.ItemWidthStack.resize(0);
5918  window->DC.TextWrapPosStack.resize(0);
5919  window->DC.GroupStack.resize(0);
5920  window->DC.ItemFlags = parent_window ? parent_window->DC.ItemFlags : ImGuiItemFlags_Default_;
5921  if (parent_window)
5922  window->DC.ItemFlagsStack.push_back(window->DC.ItemFlags);
5923 
5924  if (window->AutoFitFramesX > 0)
5925  window->AutoFitFramesX--;
5926  if (window->AutoFitFramesY > 0)
5927  window->AutoFitFramesY--;
5928 
5929  // Apply focus (we need to call FocusWindow() AFTER setting DC.CursorStartPos so our initial navigation reference rectangle can start around there)
5930  if (want_focus)
5931  {
5932  FocusWindow(window);
5933  NavInitWindow(window, false);
5934  }
5935 
5936  // Title bar
5938  RenderWindowTitleBarContents(window, title_bar_rect, name, p_open);
5939 
5940  // Pressing CTRL+C while holding on a window copy its content to the clipboard
5941  // This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope.
5942  // Maybe we can support CTRL+C on every element?
5943  /*
5944  if (g.ActiveId == move_id)
5945  if (g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_C))
5946  LogToClipboard();
5947  */
5948 
5949  // We fill last item data based on Title Bar/Tab, in order for IsItemHovered() and IsItemActive() to be usable after Begin().
5950  // This is useful to allow creating context menus on title bar only, etc.
5951  window->DC.LastItemId = window->MoveId;
5952  window->DC.LastItemStatusFlags = IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0;
5953  window->DC.LastItemRect = title_bar_rect;
5954 #ifdef IMGUI_ENABLE_TEST_ENGINE
5955  if (!(window->Flags & ImGuiWindowFlags_NoTitleBar))
5957 #endif
5958  }
5959  else
5960  {
5961  // Append
5962  SetCurrentWindow(window);
5963  }
5964 
5965  PushClipRect(window->InnerClipRect.Min, window->InnerClipRect.Max, true);
5966 
5967  // Clear 'accessed' flag last thing (After PushClipRect which will set the flag. We want the flag to stay false when the default "Debug" window is unused)
5968  if (first_begin_of_the_frame)
5969  window->WriteAccessed = false;
5970 
5971  window->BeginCount++;
5972  g.NextWindowData.ClearFlags();
5973 
5975  {
5976  // Child window can be out of sight and have "negative" clip windows.
5977  // Mark them as collapsed so commands are skipped earlier (we can't manually collapse them because they have no title bar).
5979  if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0)
5980  if (window->OuterRectClipped.Min.x >= window->OuterRectClipped.Max.x || window->OuterRectClipped.Min.y >= window->OuterRectClipped.Max.y)
5981  window->HiddenFramesCanSkipItems = 1;
5982 
5983  // Hide along with parent or if parent is collapsed
5984  if (parent_window && (parent_window->Collapsed || parent_window->HiddenFramesCanSkipItems > 0))
5985  window->HiddenFramesCanSkipItems = 1;
5986  if (parent_window && (parent_window->Collapsed || parent_window->HiddenFramesCannotSkipItems > 0))
5987  window->HiddenFramesCannotSkipItems = 1;
5988  }
5989 
5990  // Don't render if style alpha is 0.0 at the time of Begin(). This is arbitrary and inconsistent but has been there for a long while (may remove at some point)
5991  if (style.Alpha <= 0.0f)
5992  window->HiddenFramesCanSkipItems = 1;
5993 
5994  // Update the Hidden flag
5995  window->Hidden = (window->HiddenFramesCanSkipItems > 0) || (window->HiddenFramesCannotSkipItems > 0);
5996 
5997  // Update the SkipItems flag, used to early out of all items functions (no layout required)
5998  bool skip_items = false;
5999  if (window->Collapsed || !window->Active || window->Hidden)
6000  if (window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && window->HiddenFramesCannotSkipItems <= 0)
6001  skip_items = true;
6002  window->SkipItems = skip_items;
6003 
6004  return !skip_items;
6005 }
6006 
6008 {
6009  ImGuiContext& g = *GImGui;
6010  ImGuiWindow* window = g.CurrentWindow;
6011 
6012  // Error checking: verify that user hasn't called End() too many times!
6013  if (g.CurrentWindowStack.Size <= 1 && g.WithinFrameScopeWithImplicitWindow)
6014  {
6015  IM_ASSERT_USER_ERROR(g.CurrentWindowStack.Size > 1, "Calling End() too many times!");
6016  return;
6017  }
6018  IM_ASSERT(g.CurrentWindowStack.Size > 0);
6019 
6020  // Error checking: verify that user doesn't directly call End() on a child window.
6021  if (window->Flags & ImGuiWindowFlags_ChildWindow)
6022  IM_ASSERT_USER_ERROR(g.WithinEndChild, "Must call EndChild() and not End()!");
6023 
6024  // Close anything that is open
6025  if (window->DC.CurrentColumns)
6026  EndColumns();
6027  PopClipRect(); // Inner window clip rectangle
6028 
6029  // Stop logging
6030  if (!(window->Flags & ImGuiWindowFlags_ChildWindow)) // FIXME: add more options for scope of logging
6031  LogFinish();
6032 
6033  // Pop from window stack
6034  g.CurrentWindowStack.pop_back();
6035  if (window->Flags & ImGuiWindowFlags_Popup)
6036  g.BeginPopupStack.pop_back();
6037  ErrorCheckBeginEndCompareStacksSize(window, false);
6038  SetCurrentWindow(g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back());
6039 }
6040 
6042 {
6043  ImGuiContext& g = *GImGui;
6044  if (g.WindowsFocusOrder.back() == window)
6045  return;
6046  for (int i = g.WindowsFocusOrder.Size - 2; i >= 0; i--) // We can ignore the top-most window
6047  if (g.WindowsFocusOrder[i] == window)
6048  {
6049  memmove(&g.WindowsFocusOrder[i], &g.WindowsFocusOrder[i + 1], (size_t)(g.WindowsFocusOrder.Size - i - 1) * sizeof(ImGuiWindow*));
6050  g.WindowsFocusOrder[g.WindowsFocusOrder.Size - 1] = window;
6051  break;
6052  }
6053 }
6054 
6056 {
6057  ImGuiContext& g = *GImGui;
6058  ImGuiWindow* current_front_window = g.Windows.back();
6059  if (current_front_window == window || current_front_window->RootWindow == window)
6060  return;
6061  for (int i = g.Windows.Size - 2; i >= 0; i--) // We can ignore the top-most window
6062  if (g.Windows[i] == window)
6063  {
6064  memmove(&g.Windows[i], &g.Windows[i + 1], (size_t)(g.Windows.Size - i - 1) * sizeof(ImGuiWindow*));
6065  g.Windows[g.Windows.Size - 1] = window;
6066  break;
6067  }
6068 }
6069 
6071 {
6072  ImGuiContext& g = *GImGui;
6073  if (g.Windows[0] == window)
6074  return;
6075  for (int i = 0; i < g.Windows.Size; i++)
6076  if (g.Windows[i] == window)
6077  {
6078  memmove(&g.Windows[1], &g.Windows[0], (size_t)i * sizeof(ImGuiWindow*));
6079  g.Windows[0] = window;
6080  break;
6081  }
6082 }
6083 
6084 // Moving window to front of display and set focus (which happens to be back of our sorted list)
6086 {
6087  ImGuiContext& g = *GImGui;
6088 
6089  if (g.NavWindow != window)
6090  {
6091  g.NavWindow = window;
6092  if (window && g.NavDisableMouseHover)
6093  g.NavMousePosDirty = true;
6094  g.NavInitRequest = false;
6095  g.NavId = window ? window->NavLastIds[0] : 0; // Restore NavId
6096  g.NavFocusScopeId = 0;
6097  g.NavIdIsAlive = false;
6098  g.NavLayer = ImGuiNavLayer_Main;
6099  //IMGUI_DEBUG_LOG("FocusWindow(\"%s\")\n", window ? window->Name : NULL);
6100  }
6101 
6102  // Close popups if any
6103  ClosePopupsOverWindow(window, false);
6104 
6105  // Passing NULL allow to disable keyboard focus
6106  if (!window)
6107  return;
6108 
6109  // Move the root window to the top of the pile
6110  IM_ASSERT(window->RootWindow != NULL);
6111  ImGuiWindow* focus_front_window = window->RootWindow; // NB: In docking branch this is window->RootWindowDockStop
6112  ImGuiWindow* display_front_window = window->RootWindow;
6113 
6114  // Steal focus on active widgets
6115  if (focus_front_window->Flags & ImGuiWindowFlags_Popup) // FIXME: This statement may be unnecessary? Need further testing before removing it..
6116  if (g.ActiveId != 0 && g.ActiveIdWindow && g.ActiveIdWindow->RootWindow != focus_front_window)
6117  ClearActiveID();
6118 
6119  // Bring to front
6120  BringWindowToFocusFront(focus_front_window);
6121  if (((window->Flags | display_front_window->Flags) & ImGuiWindowFlags_NoBringToFrontOnFocus) == 0)
6122  BringWindowToDisplayFront(display_front_window);
6123 }
6124 
6125 void ImGui::FocusTopMostWindowUnderOne(ImGuiWindow* under_this_window, ImGuiWindow* ignore_window)
6126 {
6127  ImGuiContext& g = *GImGui;
6128 
6129  int start_idx = g.WindowsFocusOrder.Size - 1;
6130  if (under_this_window != NULL)
6131  {
6132  int under_this_window_idx = FindWindowFocusIndex(under_this_window);
6133  if (under_this_window_idx != -1)
6134  start_idx = under_this_window_idx - 1;
6135  }
6136  for (int i = start_idx; i >= 0; i--)
6137  {
6138  // We may later decide to test for different NoXXXInputs based on the active navigation input (mouse vs nav) but that may feel more confusing to the user.
6139  ImGuiWindow* window = g.WindowsFocusOrder[i];
6140  if (window != ignore_window && window->WasActive && !(window->Flags & ImGuiWindowFlags_ChildWindow))
6142  {
6143  ImGuiWindow* focus_window = NavRestoreLastChildNavWindow(window);
6144  FocusWindow(focus_window);
6145  return;
6146  }
6147  }
6148  FocusWindow(NULL);
6149 }
6150 
6152 {
6153  ImGuiContext& g = *GImGui;
6154  IM_ASSERT(font && font->IsLoaded()); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ?
6155  IM_ASSERT(font->Scale > 0.0f);
6156  g.Font = font;
6157  g.FontBaseSize = ImMax(1.0f, g.IO.FontGlobalScale * g.Font->FontSize * g.Font->Scale);
6158  g.FontSize = g.CurrentWindow ? g.CurrentWindow->CalcFontSize() : 0.0f;
6159 
6160  ImFontAtlas* atlas = g.Font->ContainerAtlas;
6161  g.DrawListSharedData.TexUvWhitePixel = atlas->TexUvWhitePixel;
6162  g.DrawListSharedData.Font = g.Font;
6163  g.DrawListSharedData.FontSize = g.FontSize;
6164 }
6165 
6167 {
6168  ImGuiContext& g = *GImGui;
6169  if (!font)
6170  font = GetDefaultFont();
6171  SetCurrentFont(font);
6172  g.FontStack.push_back(font);
6173  g.CurrentWindow->DrawList->PushTextureID(font->ContainerAtlas->TexID);
6174 }
6175 
6177 {
6178  ImGuiContext& g = *GImGui;
6180  g.FontStack.pop_back();
6181  SetCurrentFont(g.FontStack.empty() ? GetDefaultFont() : g.FontStack.back());
6182 }
6183 
6185 {
6186  ImGuiWindow* window = GetCurrentWindow();
6187  if (enabled)
6188  window->DC.ItemFlags |= option;
6189  else
6190  window->DC.ItemFlags &= ~option;
6191  window->DC.ItemFlagsStack.push_back(window->DC.ItemFlags);
6192 }
6193 
6195 {
6196  ImGuiWindow* window = GetCurrentWindow();
6197  window->DC.ItemFlagsStack.pop_back();
6198  window->DC.ItemFlags = window->DC.ItemFlagsStack.empty() ? ImGuiItemFlags_Default_ : window->DC.ItemFlagsStack.back();
6199 }
6200 
6201 // FIXME: Look into renaming this once we have settled the new Focus/Activation/TabStop system.
6202 void ImGui::PushAllowKeyboardFocus(bool allow_keyboard_focus)
6203 {
6204  PushItemFlag(ImGuiItemFlags_NoTabStop, !allow_keyboard_focus);
6205 }
6206 
6208 {
6209  PopItemFlag();
6210 }
6211 
6212 void ImGui::PushButtonRepeat(bool repeat)
6213 {
6215 }
6216 
6218 {
6219  PopItemFlag();
6220 }
6221 
6222 void ImGui::PushTextWrapPos(float wrap_pos_x)
6223 {
6224  ImGuiWindow* window = GetCurrentWindow();
6225  window->DC.TextWrapPos = wrap_pos_x;
6226  window->DC.TextWrapPosStack.push_back(wrap_pos_x);
6227 }
6228 
6230 {
6231  ImGuiWindow* window = GetCurrentWindow();
6232  window->DC.TextWrapPosStack.pop_back();
6233  window->DC.TextWrapPos = window->DC.TextWrapPosStack.empty() ? -1.0f : window->DC.TextWrapPosStack.back();
6234 }
6235 
6236 bool ImGui::IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent)
6237 {
6238  if (window->RootWindow == potential_parent)
6239  return true;
6240  while (window != NULL)
6241  {
6242  if (window == potential_parent)
6243  return true;
6244  window = window->ParentWindow;
6245  }
6246  return false;
6247 }
6248 
6250 {
6251  IM_ASSERT((flags & ImGuiHoveredFlags_AllowWhenOverlapped) == 0); // Flags not supported by this function
6252  ImGuiContext& g = *GImGui;
6253 
6255  {
6256  if (g.HoveredWindow == NULL)
6257  return false;
6258  }
6259  else
6260  {
6262  {
6264  if (g.HoveredRootWindow != g.CurrentWindow->RootWindow)
6265  return false;
6266  break;
6268  if (g.HoveredWindow != g.CurrentWindow->RootWindow)
6269  return false;
6270  break;
6272  if (g.HoveredWindow == NULL || !IsWindowChildOf(g.HoveredWindow, g.CurrentWindow))
6273  return false;
6274  break;
6275  default:
6276  if (g.HoveredWindow != g.CurrentWindow)
6277  return false;
6278  break;
6279  }
6280  }
6281 
6282  if (!IsWindowContentHoverable(g.HoveredWindow, flags))
6283  return false;
6285  if (g.ActiveId != 0 && !g.ActiveIdAllowOverlap && g.ActiveId != g.HoveredWindow->MoveId)
6286  return false;
6287  return true;
6288 }
6289 
6291 {
6292  ImGuiContext& g = *GImGui;
6293 
6295  return g.NavWindow != NULL;
6296 
6297  IM_ASSERT(g.CurrentWindow); // Not inside a Begin()/End()
6299  {
6301  return g.NavWindow && g.NavWindow->RootWindow == g.CurrentWindow->RootWindow;
6303  return g.NavWindow == g.CurrentWindow->RootWindow;
6305  return g.NavWindow && IsWindowChildOf(g.NavWindow, g.CurrentWindow);
6306  default:
6307  return g.NavWindow == g.CurrentWindow;
6308  }
6309 }
6310 
6311 // Can we focus this window with CTRL+TAB (or PadMenu + PadFocusPrev/PadFocusNext)
6312 // Note that NoNavFocus makes the window not reachable with CTRL+TAB but it can still be focused with mouse or programmaticaly.
6313 // If you want a window to never be focused, you may use the e.g. NoInputs flag.
6315 {
6316  return window->Active && window == window->RootWindow && !(window->Flags & ImGuiWindowFlags_NoNavFocus);
6317 }
6318 
6320 {
6321  ImGuiWindow* window = GImGui->CurrentWindow;
6322  return window->Size.x;
6323 }
6324 
6326 {
6327  ImGuiWindow* window = GImGui->CurrentWindow;
6328  return window->Size.y;
6329 }
6330 
6332 {
6333  ImGuiContext& g = *GImGui;
6334  ImGuiWindow* window = g.CurrentWindow;
6335  return window->Pos;
6336 }
6337 
6338 void ImGui::SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond)
6339 {
6340  // Test condition (NB: bit 0 is always true) and clear flags for next time
6341  if (cond && (window->SetWindowPosAllowFlags & cond) == 0)
6342  return;
6343 
6344  IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags.
6346  window->SetWindowPosVal = ImVec2(FLT_MAX, FLT_MAX);
6347 
6348  // Set
6349  const ImVec2 old_pos = window->Pos;
6350  window->Pos = ImFloor(pos);
6351  ImVec2 offset = window->Pos - old_pos;
6352  window->DC.CursorPos += offset; // As we happen to move the window while it is being appended to (which is a bad idea - will smear) let's at least offset the cursor
6353  window->DC.CursorMaxPos += offset; // And more importantly we need to offset CursorMaxPos/CursorStartPos this so ContentSize calculation doesn't get affected.
6354  window->DC.CursorStartPos += offset;
6355 }
6356 
6357 void ImGui::SetWindowPos(const ImVec2& pos, ImGuiCond cond)
6358 {
6359  ImGuiWindow* window = GetCurrentWindowRead();
6360  SetWindowPos(window, pos, cond);
6361 }
6362 
6363 void ImGui::SetWindowPos(const char* name, const ImVec2& pos, ImGuiCond cond)
6364 {
6365  if (ImGuiWindow* window = FindWindowByName(name))
6366  SetWindowPos(window, pos, cond);
6367 }
6368 
6370 {
6371  ImGuiWindow* window = GetCurrentWindowRead();
6372  return window->Size;
6373 }
6374 
6376 {
6377  // Test condition (NB: bit 0 is always true) and clear flags for next time
6378  if (cond && (window->SetWindowSizeAllowFlags & cond) == 0)
6379  return;
6380 
6381  IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags.
6383 
6384  // Set
6385  if (size.x > 0.0f)
6386  {
6387  window->AutoFitFramesX = 0;
6388  window->SizeFull.x = IM_FLOOR(size.x);
6389  }
6390  else
6391  {
6392  window->AutoFitFramesX = 2;
6393  window->AutoFitOnlyGrows = false;
6394  }
6395  if (size.y > 0.0f)
6396  {
6397  window->AutoFitFramesY = 0;
6398  window->SizeFull.y = IM_FLOOR(size.y);
6399  }
6400  else
6401  {
6402  window->AutoFitFramesY = 2;
6403  window->AutoFitOnlyGrows = false;
6404  }
6405 }
6406 
6408 {
6410 }
6411 
6412 void ImGui::SetWindowSize(const char* name, const ImVec2& size, ImGuiCond cond)
6413 {
6414  if (ImGuiWindow* window = FindWindowByName(name))
6415  SetWindowSize(window, size, cond);
6416 }
6417 
6418 void ImGui::SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond)
6419 {
6420  // Test condition (NB: bit 0 is always true) and clear flags for next time
6421  if (cond && (window->SetWindowCollapsedAllowFlags & cond) == 0)
6422  return;
6424 
6425  // Set
6426  window->Collapsed = collapsed;
6427 }
6428 
6429 void ImGui::SetWindowCollapsed(bool collapsed, ImGuiCond cond)
6430 {
6431  SetWindowCollapsed(GImGui->CurrentWindow, collapsed, cond);
6432 }
6433 
6435 {
6436  ImGuiWindow* window = GetCurrentWindowRead();
6437  return window->Collapsed;
6438 }
6439 
6441 {
6442  ImGuiWindow* window = GetCurrentWindowRead();
6443  return window->Appearing;
6444 }
6445 
6446 void ImGui::SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond)
6447 {
6448  if (ImGuiWindow* window = FindWindowByName(name))
6449  SetWindowCollapsed(window, collapsed, cond);
6450 }
6451 
6453 {
6455 }
6456 
6457 void ImGui::SetWindowFocus(const char* name)
6458 {
6459  if (name)
6460  {
6461  if (ImGuiWindow* window = FindWindowByName(name))
6462  FocusWindow(window);
6463  }
6464  else
6465  {
6466  FocusWindow(NULL);
6467  }
6468 }
6469 
6470 void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pivot)
6471 {
6472  ImGuiContext& g = *GImGui;
6473  IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags.
6474  g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasPos;
6475  g.NextWindowData.PosVal = pos;
6476  g.NextWindowData.PosPivotVal = pivot;
6477  g.NextWindowData.PosCond = cond ? cond : ImGuiCond_Always;
6478 }
6479 
6481 {
6482  ImGuiContext& g = *GImGui;
6483  IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags.
6484  g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasSize;
6485  g.NextWindowData.SizeVal = size;
6486  g.NextWindowData.SizeCond = cond ? cond : ImGuiCond_Always;
6487 }
6488 
6489 void ImGui::SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback, void* custom_callback_user_data)
6490 {
6491  ImGuiContext& g = *GImGui;
6493  g.NextWindowData.SizeConstraintRect = ImRect(size_min, size_max);
6494  g.NextWindowData.SizeCallback = custom_callback;
6495  g.NextWindowData.SizeCallbackUserData = custom_callback_user_data;
6496 }
6497 
6498 // Content size = inner scrollable rectangle, padded with WindowPadding.
6499 // SetNextWindowContentSize(ImVec2(100,100) + ImGuiWindowFlags_AlwaysAutoResize will always allow submitting a 100x100 item.
6501 {
6502  ImGuiContext& g = *GImGui;
6504  g.NextWindowData.ContentSizeVal = size;
6505 }
6506 
6507 void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiCond cond)
6508 {
6509  ImGuiContext& g = *GImGui;
6510  IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags.
6511  g.NextWindowData.Flags |= ImGuiNextWindowDataFlags_HasCollapsed;
6512  g.NextWindowData.CollapsedVal = collapsed;
6513  g.NextWindowData.CollapsedCond = cond ? cond : ImGuiCond_Always;
6514 }
6515 
6517 {
6518  ImGuiContext& g = *GImGui;
6520 }
6521 
6523 {
6524  ImGuiContext& g = *GImGui;
6526  g.NextWindowData.BgAlphaVal = alpha;
6527 }
6528 
6530 {
6531  ImGuiWindow* window = GetCurrentWindow();
6532  return window->DrawList;
6533 }
6534 
6536 {
6537  return GImGui->Font;
6538 }
6539 
6541 {
6542  return GImGui->FontSize;
6543 }
6544 
6546 {
6548 }
6549 
6550 void ImGui::SetWindowFontScale(float scale)
6551 {
6552  ImGuiContext& g = *GImGui;
6553  ImGuiWindow* window = GetCurrentWindow();
6554  window->FontWindowScale = scale;
6555  g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize();
6556 }
6557 
6559 {
6560  ImGuiContext& g = *GImGui;
6562 }
6563 
6565 {
6566  ImGuiContext& g = *GImGui;
6567  ImGuiWindow* window = g.CurrentWindow;
6568  window->IDStack.push_back(window->DC.NavFocusScopeIdCurrent);
6569  window->DC.NavFocusScopeIdCurrent = id;
6570 }
6571 
6573 {
6574  ImGuiContext& g = *GImGui;
6575  ImGuiWindow* window = g.CurrentWindow;
6576  window->DC.NavFocusScopeIdCurrent = window->IDStack.back();
6577  window->IDStack.pop_back();
6578 }
6579 
6581 {
6582  IM_ASSERT(offset >= -1); // -1 is allowed but not below
6583  ImGuiContext& g = *GImGui;
6584  ImGuiWindow* window = g.CurrentWindow;
6585  g.FocusRequestNextWindow = window;
6586  g.FocusRequestNextCounterRegular = window->DC.FocusCounterRegular + 1 + offset;
6587  g.FocusRequestNextCounterTabStop = INT_MAX;
6588 }
6589 
6591 {
6592  ImGuiContext& g = *GImGui;
6593  ImGuiWindow* window = g.CurrentWindow;
6594  if (!window->Appearing)
6595  return;
6596  if (g.NavWindow == window->RootWindowForNav && (g.NavInitRequest || g.NavInitResultId != 0) && g.NavLayer == g.NavWindow->DC.NavLayerCurrent)
6597  {
6598  g.NavInitRequest = false;
6599  g.NavInitResultId = g.NavWindow->DC.LastItemId;
6600  g.NavInitResultRectRel = ImRect(g.NavWindow->DC.LastItemRect.Min - g.NavWindow->Pos, g.NavWindow->DC.LastItemRect.Max - g.NavWindow->Pos);
6602  if (!IsItemVisible())
6603  SetScrollHereY();
6604  }
6605 }
6606 
6608 {
6609  ImGuiWindow* window = GImGui->CurrentWindow;
6610  window->DC.StateStorage = tree ? tree : &window->StateStorage;
6611 }
6612 
6614 {
6615  ImGuiWindow* window = GImGui->CurrentWindow;
6616  return window->DC.StateStorage;
6617 }
6618 
6619 void ImGui::PushID(const char* str_id)
6620 {
6621  ImGuiWindow* window = GImGui->CurrentWindow;
6622  window->IDStack.push_back(window->GetIDNoKeepAlive(str_id));
6623 }
6624 
6625 void ImGui::PushID(const char* str_id_begin, const char* str_id_end)
6626 {
6627  ImGuiWindow* window = GImGui->CurrentWindow;
6628  window->IDStack.push_back(window->GetIDNoKeepAlive(str_id_begin, str_id_end));
6629 }
6630 
6631 void ImGui::PushID(const void* ptr_id)
6632 {
6633  ImGuiWindow* window = GImGui->CurrentWindow;
6634  window->IDStack.push_back(window->GetIDNoKeepAlive(ptr_id));
6635 }
6636 
6637 void ImGui::PushID(int int_id)
6638 {
6639  ImGuiWindow* window = GImGui->CurrentWindow;
6640  window->IDStack.push_back(window->GetIDNoKeepAlive(int_id));
6641 }
6642 
6643 // Push a given id value ignoring the ID stack as a seed.
6645 {
6646  ImGuiWindow* window = GImGui->CurrentWindow;
6647  window->IDStack.push_back(id);
6648 }
6649 
6651 {
6652  ImGuiWindow* window = GImGui->CurrentWindow;
6653  window->IDStack.pop_back();
6654 }
6655 
6656 ImGuiID ImGui::GetID(const char* str_id)
6657 {
6658  ImGuiWindow* window = GImGui->CurrentWindow;
6659  return window->GetID(str_id);
6660 }
6661 
6662 ImGuiID ImGui::GetID(const char* str_id_begin, const char* str_id_end)
6663 {
6664  ImGuiWindow* window = GImGui->CurrentWindow;
6665  return window->GetID(str_id_begin, str_id_end);
6666 }
6667 
6668 ImGuiID ImGui::GetID(const void* ptr_id)
6669 {
6670  ImGuiWindow* window = GImGui->CurrentWindow;
6671  return window->GetID(ptr_id);
6672 }
6673 
6675 {
6676  ImGuiWindow* window = GImGui->CurrentWindow;
6677  return window->ClipRect.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size));
6678 }
6679 
6680 bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max)
6681 {
6682  ImGuiWindow* window = GImGui->CurrentWindow;
6683  return window->ClipRect.Overlaps(ImRect(rect_min, rect_max));
6684 }
6685 
6686 
6687 //-----------------------------------------------------------------------------
6688 // [SECTION] ERROR CHECKING
6689 //-----------------------------------------------------------------------------
6690 
6691 // Helper function to verify ABI compatibility between caller code and compiled version of Dear ImGui.
6692 // Verify that the type sizes are matching between the calling file's compilation unit and imgui.cpp's compilation unit
6693 // If the user has inconsistent compilation settings, imgui configuration #define, packing pragma, etc. your user code
6694 // may see different structures than what imgui.cpp sees, which is problematic.
6695 // We usually require settings to be in imconfig.h to make sure that they are accessible to all compilation units involved with Dear ImGui.
6696 bool ImGui::DebugCheckVersionAndDataLayout(const char* version, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_vert, size_t sz_idx)
6697 {
6698  bool error = false;
6699  if (strcmp(version, IMGUI_VERSION) != 0) { error = true; IM_ASSERT(strcmp(version, IMGUI_VERSION) == 0 && "Mismatched version string!"); }
6700  if (sz_io != sizeof(ImGuiIO)) { error = true; IM_ASSERT(sz_io == sizeof(ImGuiIO) && "Mismatched struct layout!"); }
6701  if (sz_style != sizeof(ImGuiStyle)) { error = true; IM_ASSERT(sz_style == sizeof(ImGuiStyle) && "Mismatched struct layout!"); }
6702  if (sz_vec2 != sizeof(ImVec2)) { error = true; IM_ASSERT(sz_vec2 == sizeof(ImVec2) && "Mismatched struct layout!"); }
6703  if (sz_vec4 != sizeof(ImVec4)) { error = true; IM_ASSERT(sz_vec4 == sizeof(ImVec4) && "Mismatched struct layout!"); }
6704  if (sz_vert != sizeof(ImDrawVert)) { error = true; IM_ASSERT(sz_vert == sizeof(ImDrawVert) && "Mismatched struct layout!"); }
6705  if (sz_idx != sizeof(ImDrawIdx)) { error = true; IM_ASSERT(sz_idx == sizeof(ImDrawIdx) && "Mismatched struct layout!"); }
6706  return !error;
6707 }
6708 
6710 {
6711  ImGuiContext& g = *GImGui;
6712 
6713  // Check user data
6714  // (We pass an error message in the assert expression to make it visible to programmers who are not using a debugger, as most assert handlers display their argument)
6715  IM_ASSERT(g.Initialized);
6716  IM_ASSERT((g.IO.DeltaTime > 0.0f || g.FrameCount == 0) && "Need a positive DeltaTime!");
6717  IM_ASSERT((g.FrameCount == 0 || g.FrameCountEnded == g.FrameCount) && "Forgot to call Render() or EndFrame() at the end of the previous frame?");
6718  IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f && "Invalid DisplaySize value!");
6719  IM_ASSERT(g.IO.Fonts->Fonts.Size > 0 && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?");
6720  IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded() && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?");
6721  IM_ASSERT(g.Style.CurveTessellationTol > 0.0f && "Invalid style setting!");
6722  IM_ASSERT(g.Style.CircleSegmentMaxError > 0.0f && "Invalid style setting!");
6723  IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting. Alpha cannot be negative (allows us to avoid a few clamps in color computations)!");
6724  IM_ASSERT(g.Style.WindowMinSize.x >= 1.0f && g.Style.WindowMinSize.y >= 1.0f && "Invalid style setting.");
6725  IM_ASSERT(g.Style.WindowMenuButtonPosition == ImGuiDir_None || g.Style.WindowMenuButtonPosition == ImGuiDir_Left || g.Style.WindowMenuButtonPosition == ImGuiDir_Right);
6726  for (int n = 0; n < ImGuiKey_COUNT; n++)
6727  IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < IM_ARRAYSIZE(g.IO.KeysDown) && "io.KeyMap[] contains an out of bound value (need to be 0..512, or -1 for unmapped key)");
6728 
6729  // Perform simple check: required key mapping (we intentionally do NOT check all keys to not pressure user into setting up everything, but Space is required and was only recently added in 1.60 WIP)
6730  if (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard)
6731  IM_ASSERT(g.IO.KeyMap[ImGuiKey_Space] != -1 && "ImGuiKey_Space is not mapped, required for keyboard navigation.");
6732 
6733  // Perform simple check: the beta io.ConfigWindowsResizeFromEdges option requires back-end to honor mouse cursor changes and set the ImGuiBackendFlags_HasMouseCursors flag accordingly.
6734  if (g.IO.ConfigWindowsResizeFromEdges && !(g.IO.BackendFlags & ImGuiBackendFlags_HasMouseCursors))
6735  g.IO.ConfigWindowsResizeFromEdges = false;
6736 }
6737 
6739 {
6740  ImGuiContext& g = *GImGui;
6741 
6742  // Verify that io.KeyXXX fields haven't been tampered with. Key mods shoudl not be modified between NewFrame() and EndFrame()
6743  const ImGuiKeyModFlags expected_key_mod_flags = GetMergedKeyModFlags();
6744  IM_ASSERT(g.IO.KeyMods == expected_key_mod_flags && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods");
6745  IM_UNUSED(expected_key_mod_flags);
6746 
6747  // Report when there is a mismatch of Begin/BeginChild vs End/EndChild calls. Important: Remember that the Begin/BeginChild API requires you
6748  // to always call End/EndChild even if Begin/BeginChild returns false! (this is unfortunately inconsistent with most other Begin* API).
6749  if (g.CurrentWindowStack.Size != 1)
6750  {
6751  if (g.CurrentWindowStack.Size > 1)
6752  {
6753  IM_ASSERT_USER_ERROR(g.CurrentWindowStack.Size == 1, "Mismatched Begin/BeginChild vs End/EndChild calls: did you forget to call End/EndChild?");
6754  while (g.CurrentWindowStack.Size > 1)
6755  End();
6756  }
6757  else
6758  {
6759  IM_ASSERT_USER_ERROR(g.CurrentWindowStack.Size == 1, "Mismatched Begin/BeginChild vs End/EndChild calls: did you call End/EndChild too much?");
6760  }
6761  }
6762 }
6763 
6764 // Save and compare stack sizes on Begin()/End() to detect usage errors
6765 // Begin() calls this with write=true
6766 // End() calls this with write=false
6768 {
6769  ImGuiContext& g = *GImGui;
6770  short* p = &window->DC.StackSizesBackup[0];
6771 
6772  // Window stacks
6773  // NOT checking: DC.ItemWidth, DC.AllowKeyboardFocus, DC.ButtonRepeat, DC.TextWrapPos (per window) to allow user to conveniently push once and not pop (they are cleared on Begin)
6774  { int n = window->IDStack.Size; if (write) *p = (short)n; else IM_ASSERT(*p == n && "PushID/PopID or TreeNode/TreePop Mismatch!"); p++; } // Too few or too many PopID()/TreePop()
6775  { int n = window->DC.GroupStack.Size; if (write) *p = (short)n; else IM_ASSERT(*p == n && "BeginGroup/EndGroup Mismatch!"); p++; } // Too few or too many EndGroup()
6776 
6777  // Global stacks
6778  // For color, style and font stacks there is an incentive to use Push/Begin/Pop/.../End patterns, so we relax our checks a little to allow them.
6779  { int n = g.BeginPopupStack.Size; if (write) *p = (short)n; else IM_ASSERT(*p == n && "BeginMenu/EndMenu or BeginPopup/EndPopup Mismatch!"); p++; }// Too few or too many EndMenu()/EndPopup()
6780  { int n = g.ColorModifiers.Size; if (write) *p = (short)n; else IM_ASSERT(*p >= n && "PushStyleColor/PopStyleColor Mismatch!"); p++; } // Too few or too many PopStyleColor()
6781  { int n = g.StyleModifiers.Size; if (write) *p = (short)n; else IM_ASSERT(*p >= n && "PushStyleVar/PopStyleVar Mismatch!"); p++; } // Too few or too many PopStyleVar()
6782  { int n = g.FontStack.Size; if (write) *p = (short)n; else IM_ASSERT(*p >= n && "PushFont/PopFont Mismatch!"); p++; } // Too few or too many PopFont()
6784 }
6785 
6786 
6787 //-----------------------------------------------------------------------------
6788 // [SECTION] LAYOUT
6789 //-----------------------------------------------------------------------------
6790 // - ItemSize()
6791 // - ItemAdd()
6792 // - SameLine()
6793 // - GetCursorScreenPos()
6794 // - SetCursorScreenPos()
6795 // - GetCursorPos(), GetCursorPosX(), GetCursorPosY()
6796 // - SetCursorPos(), SetCursorPosX(), SetCursorPosY()
6797 // - GetCursorStartPos()
6798 // - Indent()
6799 // - Unindent()
6800 // - SetNextItemWidth()
6801 // - PushItemWidth()
6802 // - PushMultiItemsWidths()
6803 // - PopItemWidth()
6804 // - CalcItemWidth()
6805 // - CalcItemSize()
6806 // - GetTextLineHeight()
6807 // - GetTextLineHeightWithSpacing()
6808 // - GetFrameHeight()
6809 // - GetFrameHeightWithSpacing()
6810 // - GetContentRegionMax()
6811 // - GetContentRegionMaxAbs() [Internal]
6812 // - GetContentRegionAvail(),
6813 // - GetWindowContentRegionMin(), GetWindowContentRegionMax()
6814 // - GetWindowContentRegionWidth()
6815 // - BeginGroup()
6816 // - EndGroup()
6817 // Also see in imgui_widgets: tab bars, columns.
6818 //-----------------------------------------------------------------------------
6819 
6820 // Advance cursor given item size for layout.
6821 // Register minimum needed size so it can extend the bounding box used for auto-fit calculation.
6822 // See comments in ItemAdd() about how/why the size provided to ItemSize() vs ItemAdd() may often different.
6823 void ImGui::ItemSize(const ImVec2& size, float text_baseline_y)
6824 {
6825  ImGuiContext& g = *GImGui;
6826  ImGuiWindow* window = g.CurrentWindow;
6827  if (window->SkipItems)
6828  return;
6829 
6830  // We increase the height in this function to accommodate for baseline offset.
6831  // In theory we should be offsetting the starting position (window->DC.CursorPos), that will be the topic of a larger refactor,
6832  // but since ItemSize() is not yet an API that moves the cursor (to handle e.g. wrapping) enlarging the height has the same effect.
6833  const float offset_to_match_baseline_y = (text_baseline_y >= 0) ? ImMax(0.0f, window->DC.CurrLineTextBaseOffset - text_baseline_y) : 0.0f;
6834  const float line_height = ImMax(window->DC.CurrLineSize.y, size.y + offset_to_match_baseline_y);
6835 
6836  // Always align ourselves on pixel boundaries
6837  //if (g.IO.KeyAlt) window->DrawList->AddRect(window->DC.CursorPos, window->DC.CursorPos + ImVec2(size.x, line_height), IM_COL32(255,0,0,200)); // [DEBUG]
6838  window->DC.CursorPosPrevLine.x = window->DC.CursorPos.x + size.x;
6839  window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y;
6840  window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); // Next line
6841  window->DC.CursorPos.y = IM_FLOOR(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y); // Next line
6842  window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x);
6843  window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y - g.Style.ItemSpacing.y);
6844  //if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG]
6845 
6846  window->DC.PrevLineSize.y = line_height;
6847  window->DC.CurrLineSize.y = 0.0f;
6848  window->DC.PrevLineTextBaseOffset = ImMax(window->DC.CurrLineTextBaseOffset, text_baseline_y);
6849  window->DC.CurrLineTextBaseOffset = 0.0f;
6850 
6851  // Horizontal layout mode
6852  if (window->DC.LayoutType == ImGuiLayoutType_Horizontal)
6853  SameLine();
6854 }
6855 
6856 void ImGui::ItemSize(const ImRect& bb, float text_baseline_y)
6857 {
6858  ItemSize(bb.GetSize(), text_baseline_y);
6859 }
6860 
6861 // Declare item bounding box for clipping and interaction.
6862 // Note that the size can be different than the one provided to ItemSize(). Typically, widgets that spread over available surface
6863 // declare their minimum size requirement to ItemSize() and provide a larger region to ItemAdd() which is used drawing/interaction.
6864 bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg)
6865 {
6866  ImGuiContext& g = *GImGui;
6867  ImGuiWindow* window = g.CurrentWindow;
6868 
6869  if (id != 0)
6870  {
6871  // Navigation processing runs prior to clipping early-out
6872  // (a) So that NavInitRequest can be honored, for newly opened windows to select a default widget
6873  // (b) So that we can scroll up/down past clipped items. This adds a small O(N) cost to regular navigation requests
6874  // unfortunately, but it is still limited to one window. It may not scale very well for windows with ten of
6875  // thousands of item, but at least NavMoveRequest is only set on user interaction, aka maximum once a frame.
6876  // We could early out with "if (is_clipped && !g.NavInitRequest) return false;" but when we wouldn't be able
6877  // to reach unclipped widgets. This would work if user had explicit scrolling control (e.g. mapped on a stick).
6878  // We intentionally don't check if g.NavWindow != NULL because g.NavAnyRequest should only be set when it is non null.
6879  // If we crash on a NULL g.NavWindow we need to fix the bug elsewhere.
6880  window->DC.NavLayerActiveMaskNext |= window->DC.NavLayerCurrentMask;
6881  if (g.NavId == id || g.NavAnyRequest)
6882  if (g.NavWindow->RootWindowForNav == window->RootWindowForNav)
6883  if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened))
6884  NavProcessItem(window, nav_bb_arg ? *nav_bb_arg : bb, id);
6885 
6886  // [DEBUG] Item Picker tool, when enabling the "extended" version we perform the check in ItemAdd()
6887 #ifdef IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
6888  if (id == g.DebugItemPickerBreakId)
6889  {
6890  IM_DEBUG_BREAK();
6891  g.DebugItemPickerBreakId = 0;
6892  }
6893 #endif
6894  }
6895 
6896  window->DC.LastItemId = id;
6897  window->DC.LastItemRect = bb;
6899  g.NextItemData.Flags = ImGuiNextItemDataFlags_None;
6900 
6901 #ifdef IMGUI_ENABLE_TEST_ENGINE
6902  if (id != 0)
6903  IMGUI_TEST_ENGINE_ITEM_ADD(nav_bb_arg ? *nav_bb_arg : bb, id);
6904 #endif
6905 
6906  // Clipping test
6907  const bool is_clipped = IsClippedEx(bb, id, false);
6908  if (is_clipped)
6909  return false;
6910  //if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG]
6911 
6912  // We need to calculate this now to take account of the current clipping rectangle (as items like Selectable may change them)
6913  if (IsMouseHoveringRect(bb.Min, bb.Max))
6915  return true;
6916 }
6917 
6918 // Gets back to previous line and continue with horizontal layout
6919 // offset_from_start_x == 0 : follow right after previous item
6920 // offset_from_start_x != 0 : align to specified x position (relative to window/group left)
6921 // spacing_w < 0 : use default spacing if pos_x == 0, no spacing if pos_x != 0
6922 // spacing_w >= 0 : enforce spacing amount
6923 void ImGui::SameLine(float offset_from_start_x, float spacing_w)
6924 {
6925  ImGuiWindow* window = GetCurrentWindow();
6926  if (window->SkipItems)
6927  return;
6928 
6929  ImGuiContext& g = *GImGui;
6930  if (offset_from_start_x != 0.0f)
6931  {
6932  if (spacing_w < 0.0f) spacing_w = 0.0f;
6933  window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + offset_from_start_x + spacing_w + window->DC.GroupOffset.x + window->DC.ColumnsOffset.x;
6934  window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y;
6935  }
6936  else
6937  {
6938  if (spacing_w < 0.0f) spacing_w = g.Style.ItemSpacing.x;
6939  window->DC.CursorPos.x = window->DC.CursorPosPrevLine.x + spacing_w;
6940  window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y;
6941  }
6942  window->DC.CurrLineSize = window->DC.PrevLineSize;
6944 }
6945 
6947 {
6948  ImGuiWindow* window = GetCurrentWindowRead();
6949  return window->DC.CursorPos;
6950 }
6951 
6953 {
6954  ImGuiWindow* window = GetCurrentWindow();
6955  window->DC.CursorPos = pos;
6956  window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos);
6957 }
6958 
6959 // User generally sees positions in window coordinates. Internally we store CursorPos in absolute screen coordinates because it is more convenient.
6960 // Conversion happens as we pass the value to user, but it makes our naming convention confusing because GetCursorPos() == (DC.CursorPos - window.Pos). May want to rename 'DC.CursorPos'.
6962 {
6963  ImGuiWindow* window = GetCurrentWindowRead();
6964  return window->DC.CursorPos - window->Pos + window->Scroll;
6965 }
6966 
6968 {
6969  ImGuiWindow* window = GetCurrentWindowRead();
6970  return window->DC.CursorPos.x - window->Pos.x + window->Scroll.x;
6971 }
6972 
6974 {
6975  ImGuiWindow* window = GetCurrentWindowRead();
6976  return window->DC.CursorPos.y - window->Pos.y + window->Scroll.y;
6977 }
6978 
6979 void ImGui::SetCursorPos(const ImVec2& local_pos)
6980 {
6981  ImGuiWindow* window = GetCurrentWindow();
6982  window->DC.CursorPos = window->Pos - window->Scroll + local_pos;
6983  window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos);
6984 }
6985 
6987 {
6988  ImGuiWindow* window = GetCurrentWindow();
6989  window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + x;
6990  window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPos.x);
6991 }
6992 
6994 {
6995  ImGuiWindow* window = GetCurrentWindow();
6996  window->DC.CursorPos.y = window->Pos.y - window->Scroll.y + y;
6997  window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y);
6998 }
6999 
7001 {
7002  ImGuiWindow* window = GetCurrentWindowRead();
7003  return window->DC.CursorStartPos - window->Pos;
7004 }
7005 
7006 void ImGui::Indent(float indent_w)
7007 {
7008  ImGuiContext& g = *GImGui;
7009  ImGuiWindow* window = GetCurrentWindow();
7010  window->DC.Indent.x += (indent_w != 0.0f) ? indent_w : g.Style.IndentSpacing;
7011  window->DC.CursorPos.x = window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x;
7012 }
7013 
7014 void ImGui::Unindent(float indent_w)
7015 {
7016  ImGuiContext& g = *GImGui;
7017  ImGuiWindow* window = GetCurrentWindow();
7018  window->DC.Indent.x -= (indent_w != 0.0f) ? indent_w : g.Style.IndentSpacing;
7019  window->DC.CursorPos.x = window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x;
7020 }
7021 
7022 // Affect large frame+labels widgets only.
7023 void ImGui::SetNextItemWidth(float item_width)
7024 {
7025  ImGuiContext& g = *GImGui;
7027  g.NextItemData.Width = item_width;
7028 }
7029 
7030 void ImGui::PushItemWidth(float item_width)
7031 {
7032  ImGuiContext& g = *GImGui;
7033  ImGuiWindow* window = g.CurrentWindow;
7034  window->DC.ItemWidth = (item_width == 0.0f ? window->ItemWidthDefault : item_width);
7035  window->DC.ItemWidthStack.push_back(window->DC.ItemWidth);
7036  g.NextItemData.Flags &= ~ImGuiNextItemDataFlags_HasWidth;
7037 }
7038 
7039 void ImGui::PushMultiItemsWidths(int components, float w_full)
7040 {
7041  ImGuiContext& g = *GImGui;
7042  ImGuiWindow* window = g.CurrentWindow;
7043  const ImGuiStyle& style = g.Style;
7044  const float w_item_one = ImMax(1.0f, IM_FLOOR((w_full - (style.ItemInnerSpacing.x) * (components-1)) / (float)components));
7045  const float w_item_last = ImMax(1.0f, IM_FLOOR(w_full - (w_item_one + style.ItemInnerSpacing.x) * (components-1)));
7046  window->DC.ItemWidthStack.push_back(w_item_last);
7047  for (int i = 0; i < components-1; i++)
7048  window->DC.ItemWidthStack.push_back(w_item_one);
7049  window->DC.ItemWidth = window->DC.ItemWidthStack.back();
7050  g.NextItemData.Flags &= ~ImGuiNextItemDataFlags_HasWidth;
7051 }
7052 
7054 {
7055  ImGuiWindow* window = GetCurrentWindow();
7056  window->DC.ItemWidthStack.pop_back();
7057  window->DC.ItemWidth = window->DC.ItemWidthStack.empty() ? window->ItemWidthDefault : window->DC.ItemWidthStack.back();
7058 }
7059 
7060 // Calculate default item width given value passed to PushItemWidth() or SetNextItemWidth().
7061 // The SetNextItemWidth() data is generally cleared/consumed by ItemAdd() or NextItemData.ClearFlags()
7063 {
7064  ImGuiContext& g = *GImGui;
7065  ImGuiWindow* window = g.CurrentWindow;
7066  float w;
7067  if (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasWidth)
7068  w = g.NextItemData.Width;
7069  else
7070  w = window->DC.ItemWidth;
7071  if (w < 0.0f)
7072  {
7073  float region_max_x = GetContentRegionMaxAbs().x;
7074  w = ImMax(1.0f, region_max_x - window->DC.CursorPos.x + w);
7075  }
7076  w = IM_FLOOR(w);
7077  return w;
7078 }
7079 
7080 // [Internal] Calculate full item size given user provided 'size' parameter and default width/height. Default width is often == CalcItemWidth().
7081 // Those two functions CalcItemWidth vs CalcItemSize are awkwardly named because they are not fully symmetrical.
7082 // Note that only CalcItemWidth() is publicly exposed.
7083 // The 4.0f here may be changed to match CalcItemWidth() and/or BeginChild() (right now we have a mismatch which is harmless but undesirable)
7084 ImVec2 ImGui::CalcItemSize(ImVec2 size, float default_w, float default_h)
7085 {
7086  ImGuiWindow* window = GImGui->CurrentWindow;
7087 
7088  ImVec2 region_max;
7089  if (size.x < 0.0f || size.y < 0.0f)
7090  region_max = GetContentRegionMaxAbs();
7091 
7092  if (size.x == 0.0f)
7093  size.x = default_w;
7094  else if (size.x < 0.0f)
7095  size.x = ImMax(4.0f, region_max.x - window->DC.CursorPos.x + size.x);
7096 
7097  if (size.y == 0.0f)
7098  size.y = default_h;
7099  else if (size.y < 0.0f)
7100  size.y = ImMax(4.0f, region_max.y - window->DC.CursorPos.y + size.y);
7101 
7102  return size;
7103 }
7104 
7106 {
7107  ImGuiContext& g = *GImGui;
7108  return g.FontSize;
7109 }
7110 
7112 {
7113  ImGuiContext& g = *GImGui;
7114  return g.FontSize + g.Style.ItemSpacing.y;
7115 }
7116 
7118 {
7119  ImGuiContext& g = *GImGui;
7120  return g.FontSize + g.Style.FramePadding.y * 2.0f;
7121 }
7122 
7124 {
7125  ImGuiContext& g = *GImGui;
7126  return g.FontSize + g.Style.FramePadding.y * 2.0f + g.Style.ItemSpacing.y;
7127 }
7128 
7129 // FIXME: All the Contents Region function are messy or misleading. WE WILL AIM TO OBSOLETE ALL OF THEM WITH A NEW "WORK RECT" API. Thanks for your patience!
7130 
7131 // FIXME: This is in window space (not screen space!).
7133 {
7134  ImGuiContext& g = *GImGui;
7135  ImGuiWindow* window = g.CurrentWindow;
7136  ImVec2 mx = window->ContentRegionRect.Max - window->Pos;
7137  if (window->DC.CurrentColumns)
7138  mx.x = window->WorkRect.Max.x - window->Pos.x;
7139  return mx;
7140 }
7141 
7142 // [Internal] Absolute coordinate. Saner. This is not exposed until we finishing refactoring work rect features.
7144 {
7145  ImGuiContext& g = *GImGui;
7146  ImGuiWindow* window = g.CurrentWindow;
7147  ImVec2 mx = window->ContentRegionRect.Max;
7148  if (window->DC.CurrentColumns)
7149  mx.x = window->WorkRect.Max.x;
7150  return mx;
7151 }
7152 
7154 {
7155  ImGuiWindow* window = GImGui->CurrentWindow;
7156  return GetContentRegionMaxAbs() - window->DC.CursorPos;
7157 }
7158 
7159 // In window space (not screen space!)
7161 {
7162  ImGuiWindow* window = GImGui->CurrentWindow;
7163  return window->ContentRegionRect.Min - window->Pos;
7164 }
7165 
7167 {
7168  ImGuiWindow* window = GImGui->CurrentWindow;
7169  return window->ContentRegionRect.Max - window->Pos;
7170 }
7171 
7173 {
7174  ImGuiWindow* window = GImGui->CurrentWindow;
7175  return window->ContentRegionRect.GetWidth();
7176 }
7177 
7178 // Lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.)
7180 {
7181  ImGuiContext& g = *GImGui;
7182  ImGuiWindow* window = GetCurrentWindow();
7183 
7184  window->DC.GroupStack.resize(window->DC.GroupStack.Size + 1);
7185  ImGuiGroupData& group_data = window->DC.GroupStack.back();
7186  group_data.BackupCursorPos = window->DC.CursorPos;
7187  group_data.BackupCursorMaxPos = window->DC.CursorMaxPos;
7188  group_data.BackupIndent = window->DC.Indent;
7189  group_data.BackupGroupOffset = window->DC.GroupOffset;
7190  group_data.BackupCurrLineSize = window->DC.CurrLineSize;
7192  group_data.BackupActiveIdIsAlive = g.ActiveIdIsAlive;
7193  group_data.BackupActiveIdPreviousFrameIsAlive = g.ActiveIdPreviousFrameIsAlive;
7194  group_data.EmitItem = true;
7195 
7196  window->DC.GroupOffset.x = window->DC.CursorPos.x - window->Pos.x - window->DC.ColumnsOffset.x;
7197  window->DC.Indent = window->DC.GroupOffset;
7198  window->DC.CursorMaxPos = window->DC.CursorPos;
7199  window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
7200  if (g.LogEnabled)
7201  g.LogLinePosY = -FLT_MAX; // To enforce Log carriage return
7202 }
7203 
7205 {
7206  ImGuiContext& g = *GImGui;
7207  ImGuiWindow* window = GetCurrentWindow();
7208  IM_ASSERT(!window->DC.GroupStack.empty()); // Mismatched BeginGroup()/EndGroup() calls
7209 
7210  ImGuiGroupData& group_data = window->DC.GroupStack.back();
7211 
7212  ImRect group_bb(group_data.BackupCursorPos, ImMax(window->DC.CursorMaxPos, group_data.BackupCursorPos));
7213 
7214  window->DC.CursorPos = group_data.BackupCursorPos;
7215  window->DC.CursorMaxPos = ImMax(group_data.BackupCursorMaxPos, window->DC.CursorMaxPos);
7216  window->DC.Indent = group_data.BackupIndent;
7217  window->DC.GroupOffset = group_data.BackupGroupOffset;
7218  window->DC.CurrLineSize = group_data.BackupCurrLineSize;
7220  if (g.LogEnabled)
7221  g.LogLinePosY = -FLT_MAX; // To enforce Log carriage return
7222 
7223  if (!group_data.EmitItem)
7224  {
7225  window->DC.GroupStack.pop_back();
7226  return;
7227  }
7228 
7229  window->DC.CurrLineTextBaseOffset = ImMax(window->DC.PrevLineTextBaseOffset, group_data.BackupCurrLineTextBaseOffset); // FIXME: Incorrect, we should grab the base offset from the *first line* of the group but it is hard to obtain now.
7230  ItemSize(group_bb.GetSize());
7231  ItemAdd(group_bb, 0);
7232 
7233  // If the current ActiveId was declared within the boundary of our group, we copy it to LastItemId so IsItemActive(), IsItemDeactivated() etc. will be functional on the entire group.
7234  // It would be be neater if we replaced window.DC.LastItemId by e.g. 'bool LastItemIsActive', but would put a little more burden on individual widgets.
7235  // Also if you grep for LastItemId you'll notice it is only used in that context.
7236  // (The tests not symmetrical because ActiveIdIsAlive is an ID itself, in order to be able to handle ActiveId being overwritten during the frame.)
7237  const bool group_contains_curr_active_id = (group_data.BackupActiveIdIsAlive != g.ActiveId) && (g.ActiveIdIsAlive == g.ActiveId) && g.ActiveId;
7238  const bool group_contains_prev_active_id = !group_data.BackupActiveIdPreviousFrameIsAlive && g.ActiveIdPreviousFrameIsAlive;
7239  if (group_contains_curr_active_id)
7240  window->DC.LastItemId = g.ActiveId;
7241  else if (group_contains_prev_active_id)
7242  window->DC.LastItemId = g.ActiveIdPreviousFrame;
7243  window->DC.LastItemRect = group_bb;
7244 
7245  // Forward Edited flag
7246  if (group_contains_curr_active_id && g.ActiveIdHasBeenEditedThisFrame)
7248 
7249  // Forward Deactivated flag
7251  if (group_contains_prev_active_id && g.ActiveId != g.ActiveIdPreviousFrame)
7253 
7254  window->DC.GroupStack.pop_back();
7255  //window->DrawList->AddRect(group_bb.Min, group_bb.Max, IM_COL32(255,0,255,255)); // [Debug]
7256 }
7257 
7258 
7259 //-----------------------------------------------------------------------------
7260 // [SECTION] SCROLLING
7261 //-----------------------------------------------------------------------------
7262 
7263 static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window, bool snap_on_edges)
7264 {
7265  ImGuiContext& g = *GImGui;
7266  ImVec2 scroll = window->Scroll;
7267  if (window->ScrollTarget.x < FLT_MAX)
7268  {
7269  float cr_x = window->ScrollTargetCenterRatio.x;
7270  float target_x = window->ScrollTarget.x;
7271  if (snap_on_edges && cr_x <= 0.0f && target_x <= window->WindowPadding.x)
7272  target_x = 0.0f;
7273  else if (snap_on_edges && cr_x >= 1.0f && target_x >= window->ContentSize.x + window->WindowPadding.x + g.Style.ItemSpacing.x)
7274  target_x = window->ContentSize.x + window->WindowPadding.x * 2.0f;
7275  scroll.x = target_x - cr_x * (window->SizeFull.x - window->ScrollbarSizes.x);
7276  }
7277  if (window->ScrollTarget.y < FLT_MAX)
7278  {
7279  // 'snap_on_edges' allows for a discontinuity at the edge of scrolling limits to take account of WindowPadding so that scrolling to make the last item visible scroll far enough to see the padding.
7280  float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight();
7281  float cr_y = window->ScrollTargetCenterRatio.y;
7282  float target_y = window->ScrollTarget.y;
7283  if (snap_on_edges && cr_y <= 0.0f && target_y <= window->WindowPadding.y)
7284  target_y = 0.0f;
7285  if (snap_on_edges && cr_y >= 1.0f && target_y >= window->ContentSize.y + window->WindowPadding.y + g.Style.ItemSpacing.y)
7286  target_y = window->ContentSize.y + window->WindowPadding.y * 2.0f;
7287  scroll.y = target_y - cr_y * (window->SizeFull.y - window->ScrollbarSizes.y - decoration_up_height);
7288  }
7289  scroll.x = IM_FLOOR(ImMax(scroll.x, 0.0f));
7290  scroll.y = IM_FLOOR(ImMax(scroll.y, 0.0f));
7291  if (!window->Collapsed && !window->SkipItems)
7292  {
7293  scroll.x = ImMin(scroll.x, window->ScrollMax.x);
7294  scroll.y = ImMin(scroll.y, window->ScrollMax.y);
7295  }
7296  return scroll;
7297 }
7298 
7299 // Scroll to keep newly navigated item fully into view
7301 {
7302  ImGuiContext& g = *GImGui;
7303  ImRect window_rect(window->InnerRect.Min - ImVec2(1, 1), window->InnerRect.Max + ImVec2(1, 1));
7304  //GetForegroundDrawList(window)->AddRect(window_rect.Min, window_rect.Max, IM_COL32_WHITE); // [DEBUG]
7305 
7306  ImVec2 delta_scroll;
7307  if (!window_rect.Contains(item_rect))
7308  {
7309  if (window->ScrollbarX && item_rect.Min.x < window_rect.Min.x)
7310  SetScrollFromPosX(window, item_rect.Min.x - window->Pos.x + g.Style.ItemSpacing.x, 0.0f);
7311  else if (window->ScrollbarX && item_rect.Max.x >= window_rect.Max.x)
7312  SetScrollFromPosX(window, item_rect.Max.x - window->Pos.x + g.Style.ItemSpacing.x, 1.0f);
7313  if (item_rect.Min.y < window_rect.Min.y)
7314  SetScrollFromPosY(window, item_rect.Min.y - window->Pos.y - g.Style.ItemSpacing.y, 0.0f);
7315  else if (item_rect.Max.y >= window_rect.Max.y)
7316  SetScrollFromPosY(window, item_rect.Max.y - window->Pos.y + g.Style.ItemSpacing.y, 1.0f);
7317 
7318  ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window, false);
7319  delta_scroll = next_scroll - window->Scroll;
7320  }
7321 
7322  // Also scroll parent window to keep us into view if necessary
7323  if (window->Flags & ImGuiWindowFlags_ChildWindow)
7324  delta_scroll += ScrollToBringRectIntoView(window->ParentWindow, ImRect(item_rect.Min - delta_scroll, item_rect.Max - delta_scroll));
7325 
7326  return delta_scroll;
7327 }
7328 
7330 {
7331  ImGuiWindow* window = GImGui->CurrentWindow;
7332  return window->Scroll.x;
7333 }
7334 
7336 {
7337  ImGuiWindow* window = GImGui->CurrentWindow;
7338  return window->Scroll.y;
7339 }
7340 
7342 {
7343  ImGuiWindow* window = GImGui->CurrentWindow;
7344  return window->ScrollMax.x;
7345 }
7346 
7348 {
7349  ImGuiWindow* window = GImGui->CurrentWindow;
7350  return window->ScrollMax.y;
7351 }
7352 
7353 void ImGui::SetScrollX(float scroll_x)
7354 {
7355  ImGuiWindow* window = GetCurrentWindow();
7356  window->ScrollTarget.x = scroll_x;
7357  window->ScrollTargetCenterRatio.x = 0.0f;
7358 }
7359 
7360 void ImGui::SetScrollY(float scroll_y)
7361 {
7362  ImGuiWindow* window = GetCurrentWindow();
7363  window->ScrollTarget.y = scroll_y;
7364  window->ScrollTargetCenterRatio.y = 0.0f;
7365 }
7366 
7367 void ImGui::SetScrollX(ImGuiWindow* window, float new_scroll_x)
7368 {
7369  window->ScrollTarget.x = new_scroll_x;
7370  window->ScrollTargetCenterRatio.x = 0.0f;
7371 }
7372 
7373 void ImGui::SetScrollY(ImGuiWindow* window, float new_scroll_y)
7374 {
7375  window->ScrollTarget.y = new_scroll_y;
7376  window->ScrollTargetCenterRatio.y = 0.0f;
7377 }
7378 
7379 
7380 void ImGui::SetScrollFromPosX(ImGuiWindow* window, float local_x, float center_x_ratio)
7381 {
7382  // We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size
7383  IM_ASSERT(center_x_ratio >= 0.0f && center_x_ratio <= 1.0f);
7384  window->ScrollTarget.x = IM_FLOOR(local_x + window->Scroll.x);
7385  window->ScrollTargetCenterRatio.x = center_x_ratio;
7386 }
7387 
7388 void ImGui::SetScrollFromPosY(ImGuiWindow* window, float local_y, float center_y_ratio)
7389 {
7390  // We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size
7391  IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f);
7392  const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight();
7393  local_y -= decoration_up_height;
7394  window->ScrollTarget.y = IM_FLOOR(local_y + window->Scroll.y);
7395  window->ScrollTargetCenterRatio.y = center_y_ratio;
7396 }
7397 
7398 void ImGui::SetScrollFromPosX(float local_x, float center_x_ratio)
7399 {
7400  ImGuiContext& g = *GImGui;
7401  SetScrollFromPosX(g.CurrentWindow, local_x, center_x_ratio);
7402 }
7403 
7404 void ImGui::SetScrollFromPosY(float local_y, float center_y_ratio)
7405 {
7406  ImGuiContext& g = *GImGui;
7407  SetScrollFromPosY(g.CurrentWindow, local_y, center_y_ratio);
7408 }
7409 
7410 // center_x_ratio: 0.0f left of last item, 0.5f horizontal center of last item, 1.0f right of last item.
7411 void ImGui::SetScrollHereX(float center_x_ratio)
7412 {
7413  ImGuiContext& g = *GImGui;
7414  ImGuiWindow* window = g.CurrentWindow;
7415  float target_x = window->DC.LastItemRect.Min.x - window->Pos.x; // Left of last item, in window space
7416  float last_item_width = window->DC.LastItemRect.GetWidth();
7417  target_x += (last_item_width * center_x_ratio) + (g.Style.ItemSpacing.x * (center_x_ratio - 0.5f) * 2.0f); // Precisely aim before, in the middle or after the last item.
7418  SetScrollFromPosX(target_x, center_x_ratio);
7419 }
7420 
7421 // center_y_ratio: 0.0f top of last item, 0.5f vertical center of last item, 1.0f bottom of last item.
7422 void ImGui::SetScrollHereY(float center_y_ratio)
7423 {
7424  ImGuiContext& g = *GImGui;
7425  ImGuiWindow* window = g.CurrentWindow;
7426  float target_y = window->DC.CursorPosPrevLine.y - window->Pos.y; // Top of last item, in window space
7427  target_y += (window->DC.PrevLineSize.y * center_y_ratio) + (g.Style.ItemSpacing.y * (center_y_ratio - 0.5f) * 2.0f); // Precisely aim above, in the middle or below the last line.
7428  SetScrollFromPosY(target_y, center_y_ratio);
7429 }
7430 
7431 //-----------------------------------------------------------------------------
7432 // [SECTION] TOOLTIPS
7433 //-----------------------------------------------------------------------------
7434 
7436 {
7438 }
7439 
7441 {
7442  ImGuiContext& g = *GImGui;
7443 
7444  if (g.DragDropWithinSource || g.DragDropWithinTarget)
7445  {
7446  // The default tooltip position is a little offset to give space to see the context menu (it's also clamped within the current viewport/monitor)
7447  // In the context of a dragging tooltip we try to reduce that offset and we enforce following the cursor.
7448  // Whatever we do we want to call SetNextWindowPos() to enforce a tooltip position and disable clipping the tooltip without our display area, like regular tooltip do.
7449  //ImVec2 tooltip_pos = g.IO.MousePos - g.ActiveIdClickOffset - g.Style.WindowPadding;
7450  ImVec2 tooltip_pos = g.IO.MousePos + ImVec2(16 * g.Style.MouseCursorScale, 8 * g.Style.MouseCursorScale);
7451  SetNextWindowPos(tooltip_pos);
7452  SetNextWindowBgAlpha(g.Style.Colors[ImGuiCol_PopupBg].w * 0.60f);
7453  //PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * 0.60f); // This would be nice but e.g ColorButton with checkboard has issue with transparent colors :(
7455  }
7456 
7457  char window_name[16];
7458  ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", g.TooltipOverrideCount);
7459  if (tooltip_flags & ImGuiTooltipFlags_OverridePreviousTooltip)
7460  if (ImGuiWindow* window = FindWindowByName(window_name))
7461  if (window->Active)
7462  {
7463  // Hide previous tooltip from being displayed. We can't easily "reset" the content of a window so we create a new one.
7464  window->Hidden = true;
7465  window->HiddenFramesCanSkipItems = 1;
7466  ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", ++g.TooltipOverrideCount);
7467  }
7469  Begin(window_name, NULL, flags | extra_flags);
7470 }
7471 
7473 {
7474  IM_ASSERT(GetCurrentWindowRead()->Flags & ImGuiWindowFlags_Tooltip); // Mismatched BeginTooltip()/EndTooltip() calls
7475  End();
7476 }
7477 
7478 void ImGui::SetTooltipV(const char* fmt, va_list args)
7479 {
7481  TextV(fmt, args);
7482  EndTooltip();
7483 }
7484 
7485 void ImGui::SetTooltip(const char* fmt, ...)
7486 {
7487  va_list args;
7488  va_start(args, fmt);
7489  SetTooltipV(fmt, args);
7490  va_end(args);
7491 }
7492 
7493 //-----------------------------------------------------------------------------
7494 // [SECTION] POPUPS
7495 //-----------------------------------------------------------------------------
7496 
7498 {
7499  ImGuiContext& g = *GImGui;
7500  return g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].PopupId == id;
7501 }
7502 
7503 bool ImGui::IsPopupOpen(const char* str_id)
7504 {
7505  ImGuiContext& g = *GImGui;
7506  return g.OpenPopupStack.Size > g.BeginPopupStack.Size && g.OpenPopupStack[g.BeginPopupStack.Size].PopupId == g.CurrentWindow->GetID(str_id);
7507 }
7508 
7510 {
7511  ImGuiContext& g = *GImGui;
7512  for (int n = g.OpenPopupStack.Size-1; n >= 0; n--)
7513  if (ImGuiWindow* popup = g.OpenPopupStack.Data[n].Window)
7514  if (popup->Flags & ImGuiWindowFlags_Modal)
7515  return popup;
7516  return NULL;
7517 }
7518 
7519 void ImGui::OpenPopup(const char* str_id)
7520 {
7521  ImGuiContext& g = *GImGui;
7522  OpenPopupEx(g.CurrentWindow->GetID(str_id));
7523 }
7524 
7525 // Mark popup as open (toggle toward open state).
7526 // Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block.
7527 // Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level).
7528 // One open popup per level of the popup hierarchy (NB: when assigning we reset the Window member of ImGuiPopupRef to NULL)
7530 {
7531  ImGuiContext& g = *GImGui;
7532  ImGuiWindow* parent_window = g.CurrentWindow;
7533  int current_stack_size = g.BeginPopupStack.Size;
7534  ImGuiPopupData popup_ref; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack.
7535  popup_ref.PopupId = id;
7536  popup_ref.Window = NULL;
7537  popup_ref.SourceWindow = g.NavWindow;
7538  popup_ref.OpenFrameCount = g.FrameCount;
7539  popup_ref.OpenParentId = parent_window->IDStack.back();
7540  popup_ref.OpenPopupPos = NavCalcPreferredRefPos();
7541  popup_ref.OpenMousePos = IsMousePosValid(&g.IO.MousePos) ? g.IO.MousePos : popup_ref.OpenPopupPos;
7542 
7543  //IMGUI_DEBUG_LOG("OpenPopupEx(0x%08X)\n", g.FrameCount, id);
7544  if (g.OpenPopupStack.Size < current_stack_size + 1)
7545  {
7546  g.OpenPopupStack.push_back(popup_ref);
7547  }
7548  else
7549  {
7550  // Gently handle the user mistakenly calling OpenPopup() every frame. It is a programming mistake! However, if we were to run the regular code path, the ui
7551  // would become completely unusable because the popup will always be in hidden-while-calculating-size state _while_ claiming focus. Which would be a very confusing
7552  // situation for the programmer. Instead, we silently allow the popup to proceed, it will keep reappearing and the programming error will be more obvious to understand.
7553  if (g.OpenPopupStack[current_stack_size].PopupId == id && g.OpenPopupStack[current_stack_size].OpenFrameCount == g.FrameCount - 1)
7554  {
7555  g.OpenPopupStack[current_stack_size].OpenFrameCount = popup_ref.OpenFrameCount;
7556  }
7557  else
7558  {
7559  // Close child popups if any, then flag popup for open/reopen
7560  g.OpenPopupStack.resize(current_stack_size + 1);
7561  g.OpenPopupStack[current_stack_size] = popup_ref;
7562  }
7563 
7564  // When reopening a popup we first refocus its parent, otherwise if its parent is itself a popup it would get closed by ClosePopupsOverWindow().
7565  // This is equivalent to what ClosePopupToLevel() does.
7566  //if (g.OpenPopupStack[current_stack_size].PopupId == id)
7567  // FocusWindow(parent_window);
7568  }
7569 }
7570 
7571 void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup)
7572 {
7573  ImGuiContext& g = *GImGui;
7574  if (g.OpenPopupStack.empty())
7575  return;
7576 
7577  // When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it.
7578  // Don't close our own child popup windows.
7579  int popup_count_to_keep = 0;
7580  if (ref_window)
7581  {
7582  // Find the highest popup which is a descendant of the reference window (generally reference window = NavWindow)
7583  for (; popup_count_to_keep < g.OpenPopupStack.Size; popup_count_to_keep++)
7584  {
7585  ImGuiPopupData& popup = g.OpenPopupStack[popup_count_to_keep];
7586  if (!popup.Window)
7587  continue;
7588  IM_ASSERT((popup.Window->Flags & ImGuiWindowFlags_Popup) != 0);
7590  continue;
7591 
7592  // Trim the stack when popups are not direct descendant of the reference window (the reference window is often the NavWindow)
7593  bool popup_or_descendent_is_ref_window = false;
7594  for (int m = popup_count_to_keep; m < g.OpenPopupStack.Size && !popup_or_descendent_is_ref_window; m++)
7595  if (ImGuiWindow* popup_window = g.OpenPopupStack[m].Window)
7596  if (popup_window->RootWindow == ref_window->RootWindow)
7597  popup_or_descendent_is_ref_window = true;
7598  if (!popup_or_descendent_is_ref_window)
7599  break;
7600  }
7601  }
7602  if (popup_count_to_keep < g.OpenPopupStack.Size) // This test is not required but it allows to set a convenient breakpoint on the statement below
7603  {
7604  //IMGUI_DEBUG_LOG("ClosePopupsOverWindow(%s) -> ClosePopupToLevel(%d)\n", ref_window->Name, popup_count_to_keep);
7605  ClosePopupToLevel(popup_count_to_keep, restore_focus_to_window_under_popup);
7606  }
7607 }
7608 
7609 void ImGui::ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup)
7610 {
7611  ImGuiContext& g = *GImGui;
7612  IM_ASSERT(remaining >= 0 && remaining < g.OpenPopupStack.Size);
7613  ImGuiWindow* focus_window = g.OpenPopupStack[remaining].SourceWindow;
7614  ImGuiWindow* popup_window = g.OpenPopupStack[remaining].Window;
7615  g.OpenPopupStack.resize(remaining);
7616 
7617  if (restore_focus_to_window_under_popup)
7618  {
7619  if (focus_window && !focus_window->WasActive && popup_window)
7620  {
7621  // Fallback
7622  FocusTopMostWindowUnderOne(popup_window, NULL);
7623  }
7624  else
7625  {
7626  if (g.NavLayer == 0 && focus_window)
7627  focus_window = NavRestoreLastChildNavWindow(focus_window);
7628  FocusWindow(focus_window);
7629  }
7630  }
7631 }
7632 
7633 // Close the popup we have begin-ed into.
7635 {
7636  ImGuiContext& g = *GImGui;
7637  int popup_idx = g.BeginPopupStack.Size - 1;
7638  if (popup_idx < 0 || popup_idx >= g.OpenPopupStack.Size || g.BeginPopupStack[popup_idx].PopupId != g.OpenPopupStack[popup_idx].PopupId)
7639  return;
7640 
7641  // Closing a menu closes its top-most parent popup (unless a modal)
7642  while (popup_idx > 0)
7643  {
7644  ImGuiWindow* popup_window = g.OpenPopupStack[popup_idx].Window;
7645  ImGuiWindow* parent_popup_window = g.OpenPopupStack[popup_idx - 1].Window;
7646  bool close_parent = false;
7647  if (popup_window && (popup_window->Flags & ImGuiWindowFlags_ChildMenu))
7648  if (parent_popup_window == NULL || !(parent_popup_window->Flags & ImGuiWindowFlags_Modal))
7649  close_parent = true;
7650  if (!close_parent)
7651  break;
7652  popup_idx--;
7653  }
7654  //IMGUI_DEBUG_LOG("CloseCurrentPopup %d -> %d\n", g.BeginPopupStack.Size - 1, popup_idx);
7655  ClosePopupToLevel(popup_idx, true);
7656 
7657  // A common pattern is to close a popup when selecting a menu item/selectable that will open another window.
7658  // To improve this usage pattern, we avoid nav highlight for a single frame in the parent window.
7659  // Similarly, we could avoid mouse hover highlight in this window but it is less visually problematic.
7660  if (ImGuiWindow* window = g.NavWindow)
7661  window->DC.NavHideHighlightOneFrame = true;
7662 }
7663 
7665 {
7666  ImGuiContext& g = *GImGui;
7667  if (!IsPopupOpen(id))
7668  {
7669  g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values
7670  return false;
7671  }
7672 
7673  char name[20];
7675  ImFormatString(name, IM_ARRAYSIZE(name), "##Menu_%02d", g.BeginPopupStack.Size); // Recycle windows based on depth
7676  else
7677  ImFormatString(name, IM_ARRAYSIZE(name), "##Popup_%08x", id); // Not recycling, so we can close/open during the same frame
7678 
7680  bool is_open = Begin(name, NULL, flags);
7681  if (!is_open) // NB: Begin can return false when the popup is completely clipped (e.g. zero size display)
7682  EndPopup();
7683 
7684  return is_open;
7685 }
7686 
7687 bool ImGui::BeginPopup(const char* str_id, ImGuiWindowFlags flags)
7688 {
7689  ImGuiContext& g = *GImGui;
7690  if (g.OpenPopupStack.Size <= g.BeginPopupStack.Size) // Early out for performance
7691  {
7692  g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values
7693  return false;
7694  }
7696  return BeginPopupEx(g.CurrentWindow->GetID(str_id), flags);
7697 }
7698 
7699 // If 'p_open' is specified for a modal popup window, the popup will have a regular close button which will close the popup.
7700 // Note that popup visibility status is owned by Dear ImGui (and manipulated with e.g. OpenPopup) so the actual value of *p_open is meaningless here.
7701 bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags flags)
7702 {
7703  ImGuiContext& g = *GImGui;
7704  ImGuiWindow* window = g.CurrentWindow;
7705  const ImGuiID id = window->GetID(name);
7706  if (!IsPopupOpen(id))
7707  {
7708  g.NextWindowData.ClearFlags(); // We behave like Begin() and need to consume those values
7709  return false;
7710  }
7711 
7712  // Center modal windows by default
7713  // FIXME: Should test for (PosCond & window->SetWindowPosAllowFlags) with the upcoming window.
7714  if ((g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasPos) == 0)
7715  SetNextWindowPos(g.IO.DisplaySize * 0.5f, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f));
7716 
7718  const bool is_open = Begin(name, p_open, flags);
7719  if (!is_open || (p_open && !*p_open)) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display)
7720  {
7721  EndPopup();
7722  if (is_open)
7723  ClosePopupToLevel(g.BeginPopupStack.Size, true);
7724  return false;
7725  }
7726  return is_open;
7727 }
7728 
7730 {
7731  ImGuiContext& g = *GImGui;
7732  ImGuiWindow* window = g.CurrentWindow;
7733  IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginPopup()/EndPopup() calls
7734  IM_ASSERT(g.BeginPopupStack.Size > 0);
7735 
7736  // Make all menus and popups wrap around for now, may need to expose that policy.
7738 
7739  // Child-popups don't need to be layed out
7740  IM_ASSERT(g.WithinEndChild == false);
7741  if (window->Flags & ImGuiWindowFlags_ChildWindow)
7742  g.WithinEndChild = true;
7743  End();
7744  g.WithinEndChild = false;
7745 }
7746 
7747 bool ImGui::OpenPopupOnItemClick(const char* str_id, ImGuiMouseButton mouse_button)
7748 {
7749  ImGuiWindow* window = GImGui->CurrentWindow;
7751  {
7752  ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict!
7753  IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item)
7754  OpenPopupEx(id);
7755  return true;
7756  }
7757  return false;
7758 }
7759 
7760 // This is a helper to handle the simplest case of associating one named popup to one given widget.
7761 // You may want to handle this on user side if you have specific needs (e.g. tweaking IsItemHovered() parameters).
7762 // You can pass a NULL str_id to use the identifier of the last item.
7763 bool ImGui::BeginPopupContextItem(const char* str_id, ImGuiMouseButton mouse_button)
7764 {
7765  ImGuiWindow* window = GImGui->CurrentWindow;
7766  if (window->SkipItems)
7767  return false;
7768  ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict!
7769  IM_ASSERT(id != 0); // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item)
7771  OpenPopupEx(id);
7773 }
7774 
7775 bool ImGui::BeginPopupContextWindow(const char* str_id, ImGuiMouseButton mouse_button, bool also_over_items)
7776 {
7777  if (!str_id)
7778  str_id = "window_context";
7779  ImGuiID id = GImGui->CurrentWindow->GetID(str_id);
7781  if (also_over_items || !IsAnyItemHovered())
7782  OpenPopupEx(id);
7784 }
7785 
7786 bool ImGui::BeginPopupContextVoid(const char* str_id, ImGuiMouseButton mouse_button)
7787 {
7788  if (!str_id)
7789  str_id = "void_context";
7790  ImGuiID id = GImGui->CurrentWindow->GetID(str_id);
7792  OpenPopupEx(id);
7794 }
7795 
7796 // r_avoid = the rectangle to avoid (e.g. for tooltip it is a rectangle around the mouse cursor which we want to avoid. for popups it's a small point around the cursor.)
7797 // r_outer = the visible area rectangle, minus safe area padding. If our popup size won't fit because of safe area padding we ignore it.
7798 ImVec2 ImGui::FindBestWindowPosForPopupEx(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_outer, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy)
7799 {
7800  ImVec2 base_pos_clamped = ImClamp(ref_pos, r_outer.Min, r_outer.Max - size);
7801  //GetForegroundDrawList()->AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255,0,0,255));
7802  //GetForegroundDrawList()->AddRect(r_outer.Min, r_outer.Max, IM_COL32(0,255,0,255));
7803 
7804  // Combo Box policy (we want a connecting edge)
7805  if (policy == ImGuiPopupPositionPolicy_ComboBox)
7806  {
7807  const ImGuiDir dir_prefered_order[ImGuiDir_COUNT] = { ImGuiDir_Down, ImGuiDir_Right, ImGuiDir_Left, ImGuiDir_Up };
7808  for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_COUNT; n++)
7809  {
7810  const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n];
7811  if (n != -1 && dir == *last_dir) // Already tried this direction?
7812  continue;
7813  ImVec2 pos;
7814  if (dir == ImGuiDir_Down) pos = ImVec2(r_avoid.Min.x, r_avoid.Max.y); // Below, Toward Right (default)
7815  if (dir == ImGuiDir_Right) pos = ImVec2(r_avoid.Min.x, r_avoid.Min.y - size.y); // Above, Toward Right
7816  if (dir == ImGuiDir_Left) pos = ImVec2(r_avoid.Max.x - size.x, r_avoid.Max.y); // Below, Toward Left
7817  if (dir == ImGuiDir_Up) pos = ImVec2(r_avoid.Max.x - size.x, r_avoid.Min.y - size.y); // Above, Toward Left
7818  if (!r_outer.Contains(ImRect(pos, pos + size)))
7819  continue;
7820  *last_dir = dir;
7821  return pos;
7822  }
7823  }
7824 
7825  // Default popup policy
7826  const ImGuiDir dir_prefered_order[ImGuiDir_COUNT] = { ImGuiDir_Right, ImGuiDir_Down, ImGuiDir_Up, ImGuiDir_Left };
7827  for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_COUNT; n++)
7828  {
7829  const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n];
7830  if (n != -1 && dir == *last_dir) // Already tried this direction?
7831  continue;
7832  float avail_w = (dir == ImGuiDir_Left ? r_avoid.Min.x : r_outer.Max.x) - (dir == ImGuiDir_Right ? r_avoid.Max.x : r_outer.Min.x);
7833  float avail_h = (dir == ImGuiDir_Up ? r_avoid.Min.y : r_outer.Max.y) - (dir == ImGuiDir_Down ? r_avoid.Max.y : r_outer.Min.y);
7834  if (avail_w < size.x || avail_h < size.y)
7835  continue;
7836  ImVec2 pos;
7837  pos.x = (dir == ImGuiDir_Left) ? r_avoid.Min.x - size.x : (dir == ImGuiDir_Right) ? r_avoid.Max.x : base_pos_clamped.x;
7838  pos.y = (dir == ImGuiDir_Up) ? r_avoid.Min.y - size.y : (dir == ImGuiDir_Down) ? r_avoid.Max.y : base_pos_clamped.y;
7839  *last_dir = dir;
7840  return pos;
7841  }
7842 
7843  // Fallback, try to keep within display
7844  *last_dir = ImGuiDir_None;
7845  ImVec2 pos = ref_pos;
7846  pos.x = ImMax(ImMin(pos.x + size.x, r_outer.Max.x) - size.x, r_outer.Min.x);
7847  pos.y = ImMax(ImMin(pos.y + size.y, r_outer.Max.y) - size.y, r_outer.Min.y);
7848  return pos;
7849 }
7850 
7852 {
7853  IM_UNUSED(window);
7855  ImRect r_screen = GetViewportRect();
7856  r_screen.Expand(ImVec2((r_screen.GetWidth() > padding.x * 2) ? -padding.x : 0.0f, (r_screen.GetHeight() > padding.y * 2) ? -padding.y : 0.0f));
7857  return r_screen;
7858 }
7859 
7861 {
7862  ImGuiContext& g = *GImGui;
7863 
7864  ImRect r_outer = GetWindowAllowedExtentRect(window);
7865  if (window->Flags & ImGuiWindowFlags_ChildMenu)
7866  {
7867  // Child menus typically request _any_ position within the parent menu item, and then we move the new menu outside the parent bounds.
7868  // This is how we end up with child menus appearing (most-commonly) on the right of the parent menu.
7869  IM_ASSERT(g.CurrentWindow == window);
7870  ImGuiWindow* parent_window = g.CurrentWindowStack[g.CurrentWindowStack.Size - 2];
7871  float horizontal_overlap = g.Style.ItemInnerSpacing.x; // We want some overlap to convey the relative depth of each menu (currently the amount of overlap is hard-coded to style.ItemSpacing.x).
7872  ImRect r_avoid;
7873  if (parent_window->DC.MenuBarAppending)
7874  r_avoid = ImRect(-FLT_MAX, parent_window->ClipRect.Min.y, FLT_MAX, parent_window->ClipRect.Max.y); // Avoid parent menu-bar. If we wanted multi-line menu-bar, we may instead want to have the calling window setup e.g. a NextWindowData.PosConstraintAvoidRect field
7875  else
7876  r_avoid = ImRect(parent_window->Pos.x + horizontal_overlap, -FLT_MAX, parent_window->Pos.x + parent_window->Size.x - horizontal_overlap - parent_window->ScrollbarSizes.x, FLT_MAX);
7877  return FindBestWindowPosForPopupEx(window->Pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid);
7878  }
7879  if (window->Flags & ImGuiWindowFlags_Popup)
7880  {
7881  ImRect r_avoid = ImRect(window->Pos.x - 1, window->Pos.y - 1, window->Pos.x + 1, window->Pos.y + 1);
7882  return FindBestWindowPosForPopupEx(window->Pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid);
7883  }
7884  if (window->Flags & ImGuiWindowFlags_Tooltip)
7885  {
7886  // Position tooltip (always follows mouse)
7887  float sc = g.Style.MouseCursorScale;
7888  ImVec2 ref_pos = NavCalcPreferredRefPos();
7889  ImRect r_avoid;
7890  if (!g.NavDisableHighlight && g.NavDisableMouseHover && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos))
7891  r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8);
7892  else
7893  r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * sc, ref_pos.y + 24 * sc); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important.
7894  ImVec2 pos = FindBestWindowPosForPopupEx(ref_pos, window->Size, &window->AutoPosLastDirection, r_outer, r_avoid);
7895  if (window->AutoPosLastDirection == ImGuiDir_None)
7896  pos = ref_pos + ImVec2(2, 2); // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible.
7897  return pos;
7898  }
7899  IM_ASSERT(0);
7900  return window->Pos;
7901 }
7902 
7903 //-----------------------------------------------------------------------------
7904 // [SECTION] KEYBOARD/GAMEPAD NAVIGATION
7905 //-----------------------------------------------------------------------------
7906 
7907 // FIXME-NAV: The existence of SetNavID vs SetNavIDWithRectRel vs SetFocusID is incredibly messy and confusing,
7908 // and needs some explanation or serious refactoring.
7909 void ImGui::SetNavID(ImGuiID id, int nav_layer, ImGuiID focus_scope_id)
7910 {
7911  ImGuiContext& g = *GImGui;
7912  IM_ASSERT(g.NavWindow);
7913  IM_ASSERT(nav_layer == 0 || nav_layer == 1);
7914  g.NavId = id;
7915  g.NavFocusScopeId = focus_scope_id;
7916  g.NavWindow->NavLastIds[nav_layer] = id;
7917 }
7918 
7919 void ImGui::SetNavIDWithRectRel(ImGuiID id, int nav_layer, ImGuiID focus_scope_id, const ImRect& rect_rel)
7920 {
7921  ImGuiContext& g = *GImGui;
7922  SetNavID(id, nav_layer, focus_scope_id);
7923  g.NavWindow->NavRectRel[nav_layer] = rect_rel;
7924  g.NavMousePosDirty = true;
7925  g.NavDisableHighlight = false;
7926  g.NavDisableMouseHover = true;
7927 }
7928 
7930 {
7931  ImGuiContext& g = *GImGui;
7932  IM_ASSERT(id != 0);
7933 
7934  // Assume that SetFocusID() is called in the context where its window->DC.NavLayerCurrent and window->DC.NavFocusScopeIdCurrent are valid.
7935  // Note that window may be != g.CurrentWindow (e.g. SetFocusID call in InputTextEx for multi-line text)
7936  const ImGuiNavLayer nav_layer = window->DC.NavLayerCurrent;
7937  if (g.NavWindow != window)
7938  g.NavInitRequest = false;
7939  g.NavWindow = window;
7940  g.NavId = id;
7941  g.NavLayer = nav_layer;
7942  g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent;
7943  window->NavLastIds[nav_layer] = id;
7944  if (window->DC.LastItemId == id)
7945  window->NavRectRel[nav_layer] = ImRect(window->DC.LastItemRect.Min - window->Pos, window->DC.LastItemRect.Max - window->Pos);
7946 
7947  if (g.ActiveIdSource == ImGuiInputSource_Nav)
7948  g.NavDisableMouseHover = true;
7949  else
7950  g.NavDisableHighlight = true;
7951 }
7952 
7954 {
7955  if (ImFabs(dx) > ImFabs(dy))
7956  return (dx > 0.0f) ? ImGuiDir_Right : ImGuiDir_Left;
7957  return (dy > 0.0f) ? ImGuiDir_Down : ImGuiDir_Up;
7958 }
7959 
7960 static float inline NavScoreItemDistInterval(float a0, float a1, float b0, float b1)
7961 {
7962  if (a1 < b0)
7963  return a1 - b0;
7964  if (b1 < a0)
7965  return a0 - b1;
7966  return 0.0f;
7967 }
7968 
7969 static void inline NavClampRectToVisibleAreaForMoveDir(ImGuiDir move_dir, ImRect& r, const ImRect& clip_rect)
7970 {
7971  if (move_dir == ImGuiDir_Left || move_dir == ImGuiDir_Right)
7972  {
7973  r.Min.y = ImClamp(r.Min.y, clip_rect.Min.y, clip_rect.Max.y);
7974  r.Max.y = ImClamp(r.Max.y, clip_rect.Min.y, clip_rect.Max.y);
7975  }
7976  else
7977  {
7978  r.Min.x = ImClamp(r.Min.x, clip_rect.Min.x, clip_rect.Max.x);
7979  r.Max.x = ImClamp(r.Max.x, clip_rect.Min.x, clip_rect.Max.x);
7980  }
7981 }
7982 
7983 // Scoring function for directional navigation. Based on https://gist.github.com/rygorous/6981057
7985 {
7986  ImGuiContext& g = *GImGui;
7987  ImGuiWindow* window = g.CurrentWindow;
7988  if (g.NavLayer != window->DC.NavLayerCurrent)
7989  return false;
7990 
7991  const ImRect& curr = g.NavScoringRectScreen; // Current modified source rect (NB: we've applied Max.x = Min.x in NavUpdate() to inhibit the effect of having varied item width)
7992  g.NavScoringCount++;
7993 
7994  // When entering through a NavFlattened border, we consider child window items as fully clipped for scoring
7995  if (window->ParentWindow == g.NavWindow)
7996  {
7997  IM_ASSERT((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened);
7998  if (!window->ClipRect.Overlaps(cand))
7999  return false;
8000  cand.ClipWithFull(window->ClipRect); // This allows the scored item to not overlap other candidates in the parent window
8001  }
8002 
8003  // We perform scoring on items bounding box clipped by the current clipping rectangle on the other axis (clipping on our movement axis would give us equal scores for all clipped items)
8004  // For example, this ensure that items in one column are not reached when moving vertically from items in another column.
8005  NavClampRectToVisibleAreaForMoveDir(g.NavMoveClipDir, cand, window->ClipRect);
8006 
8007  // Compute distance between boxes
8008  // FIXME-NAV: Introducing biases for vertical navigation, needs to be removed.
8009  float dbx = NavScoreItemDistInterval(cand.Min.x, cand.Max.x, curr.Min.x, curr.Max.x);
8010  float dby = NavScoreItemDistInterval(ImLerp(cand.Min.y, cand.Max.y, 0.2f), ImLerp(cand.Min.y, cand.Max.y, 0.8f), ImLerp(curr.Min.y, curr.Max.y, 0.2f), ImLerp(curr.Min.y, curr.Max.y, 0.8f)); // Scale down on Y to keep using box-distance for vertically touching items
8011  if (dby != 0.0f && dbx != 0.0f)
8012  dbx = (dbx/1000.0f) + ((dbx > 0.0f) ? +1.0f : -1.0f);
8013  float dist_box = ImFabs(dbx) + ImFabs(dby);
8014 
8015  // Compute distance between centers (this is off by a factor of 2, but we only compare center distances with each other so it doesn't matter)
8016  float dcx = (cand.Min.x + cand.Max.x) - (curr.Min.x + curr.Max.x);
8017  float dcy = (cand.Min.y + cand.Max.y) - (curr.Min.y + curr.Max.y);
8018  float dist_center = ImFabs(dcx) + ImFabs(dcy); // L1 metric (need this for our connectedness guarantee)
8019 
8020  // Determine which quadrant of 'curr' our candidate item 'cand' lies in based on distance
8021  ImGuiDir quadrant;
8022  float dax = 0.0f, day = 0.0f, dist_axial = 0.0f;
8023  if (dbx != 0.0f || dby != 0.0f)
8024  {
8025  // For non-overlapping boxes, use distance between boxes
8026  dax = dbx;
8027  day = dby;
8028  dist_axial = dist_box;
8029  quadrant = ImGetDirQuadrantFromDelta(dbx, dby);
8030  }
8031  else if (dcx != 0.0f || dcy != 0.0f)
8032  {
8033  // For overlapping boxes with different centers, use distance between centers
8034  dax = dcx;
8035  day = dcy;
8036  dist_axial = dist_center;
8037  quadrant = ImGetDirQuadrantFromDelta(dcx, dcy);
8038  }
8039  else
8040  {
8041  // Degenerate case: two overlapping buttons with same center, break ties arbitrarily (note that LastItemId here is really the _previous_ item order, but it doesn't matter)
8042  quadrant = (window->DC.LastItemId < g.NavId) ? ImGuiDir_Left : ImGuiDir_Right;
8043  }
8044 
8045 #if IMGUI_DEBUG_NAV_SCORING
8046  char buf[128];
8047  if (IsMouseHoveringRect(cand.Min, cand.Max))
8048  {
8049  ImFormatString(buf, IM_ARRAYSIZE(buf), "dbox (%.2f,%.2f->%.4f)\ndcen (%.2f,%.2f->%.4f)\nd (%.2f,%.2f->%.4f)\nnav %c, quadrant %c", dbx, dby, dist_box, dcx, dcy, dist_center, dax, day, dist_axial, "WENS"[g.NavMoveDir], "WENS"[quadrant]);
8050  ImDrawList* draw_list = GetForegroundDrawList(window);
8051  draw_list->AddRect(curr.Min, curr.Max, IM_COL32(255,200,0,100));
8052  draw_list->AddRect(cand.Min, cand.Max, IM_COL32(255,255,0,200));
8053  draw_list->AddRectFilled(cand.Max - ImVec2(4,4), cand.Max + CalcTextSize(buf) + ImVec2(4,4), IM_COL32(40,0,0,150));
8054  draw_list->AddText(g.IO.FontDefault, 13.0f, cand.Max, ~0U, buf);
8055  }
8056  else if (g.IO.KeyCtrl) // Hold to preview score in matching quadrant. Press C to rotate.
8057  {
8058  if (IsKeyPressedMap(ImGuiKey_C)) { g.NavMoveDirLast = (ImGuiDir)((g.NavMoveDirLast + 1) & 3); g.IO.KeysDownDuration[g.IO.KeyMap[ImGuiKey_C]] = 0.01f; }
8059  if (quadrant == g.NavMoveDir)
8060  {
8061  ImFormatString(buf, IM_ARRAYSIZE(buf), "%.0f/%.0f", dist_box, dist_center);
8062  ImDrawList* draw_list = GetForegroundDrawList(window);
8063  draw_list->AddRectFilled(cand.Min, cand.Max, IM_COL32(255, 0, 0, 200));
8064  draw_list->AddText(g.IO.FontDefault, 13.0f, cand.Min, IM_COL32(255, 255, 255, 255), buf);
8065  }
8066  }
8067  #endif
8068 
8069  // Is it in the quadrant we're interesting in moving to?
8070  bool new_best = false;
8071  if (quadrant == g.NavMoveDir)
8072  {
8073  // Does it beat the current best candidate?
8074  if (dist_box < result->DistBox)
8075  {
8076  result->DistBox = dist_box;
8077  result->DistCenter = dist_center;
8078  return true;
8079  }
8080  if (dist_box == result->DistBox)
8081  {
8082  // Try using distance between center points to break ties
8083  if (dist_center < result->DistCenter)
8084  {
8085  result->DistCenter = dist_center;
8086  new_best = true;
8087  }
8088  else if (dist_center == result->DistCenter)
8089  {
8090  // Still tied! we need to be extra-careful to make sure everything gets linked properly. We consistently break ties by symbolically moving "later" items
8091  // (with higher index) to the right/downwards by an infinitesimal amount since we the current "best" button already (so it must have a lower index),
8092  // this is fairly easy. This rule ensures that all buttons with dx==dy==0 will end up being linked in order of appearance along the x axis.
8093  if (((g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) ? dby : dbx) < 0.0f) // moving bj to the right/down decreases distance
8094  new_best = true;
8095  }
8096  }
8097  }
8098 
8099  // Axial check: if 'curr' has no link at all in some direction and 'cand' lies roughly in that direction, add a tentative link. This will only be kept if no "real" matches
8100  // are found, so it only augments the graph produced by the above method using extra links. (important, since it doesn't guarantee strong connectedness)
8101  // This is just to avoid buttons having no links in a particular direction when there's a suitable neighbor. you get good graphs without this too.
8102  // 2017/09/29: FIXME: This now currently only enabled inside menu bars, ideally we'd disable it everywhere. Menus in particular need to catch failure. For general navigation it feels awkward.
8103  // Disabling it may lead to disconnected graphs when nodes are very spaced out on different axis. Perhaps consider offering this as an option?
8104  if (result->DistBox == FLT_MAX && dist_axial < result->DistAxial) // Check axial match
8105  if (g.NavLayer == 1 && !(g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu))
8106  if ((g.NavMoveDir == ImGuiDir_Left && dax < 0.0f) || (g.NavMoveDir == ImGuiDir_Right && dax > 0.0f) || (g.NavMoveDir == ImGuiDir_Up && day < 0.0f) || (g.NavMoveDir == ImGuiDir_Down && day > 0.0f))
8107  {
8108  result->DistAxial = dist_axial;
8109  new_best = true;
8110  }
8111 
8112  return new_best;
8113 }
8114 
8115 // We get there when either NavId == id, or when g.NavAnyRequest is set (which is updated by NavUpdateAnyRequestFlag above)
8116 static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, const ImGuiID id)
8117 {
8118  ImGuiContext& g = *GImGui;
8119  //if (!g.IO.NavActive) // [2017/10/06] Removed this possibly redundant test but I am not sure of all the side-effects yet. Some of the feature here will need to work regardless of using a _NoNavInputs flag.
8120  // return;
8121 
8122  const ImGuiItemFlags item_flags = window->DC.ItemFlags;
8123  const ImRect nav_bb_rel(nav_bb.Min - window->Pos, nav_bb.Max - window->Pos);
8124 
8125  // Process Init Request
8126  if (g.NavInitRequest && g.NavLayer == window->DC.NavLayerCurrent)
8127  {
8128  // Even if 'ImGuiItemFlags_NoNavDefaultFocus' is on (typically collapse/close button) we record the first ResultId so they can be used as a fallback
8129  if (!(item_flags & ImGuiItemFlags_NoNavDefaultFocus) || g.NavInitResultId == 0)
8130  {
8131  g.NavInitResultId = id;
8132  g.NavInitResultRectRel = nav_bb_rel;
8133  }
8134  if (!(item_flags & ImGuiItemFlags_NoNavDefaultFocus))
8135  {
8136  g.NavInitRequest = false; // Found a match, clear request
8138  }
8139  }
8140 
8141  // Process Move Request (scoring for navigation)
8142  // FIXME-NAV: Consider policy for double scoring (scoring from NavScoringRectScreen + scoring from a rect wrapped according to current wrapping policy)
8143  if ((g.NavId != id || (g.NavMoveRequestFlags & ImGuiNavMoveFlags_AllowCurrentNavId)) && !(item_flags & (ImGuiItemFlags_Disabled|ImGuiItemFlags_NoNav)))
8144  {
8145  ImGuiNavMoveResult* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther;
8147  // [DEBUG] Score all items in NavWindow at all times
8148  if (!g.NavMoveRequest)
8149  g.NavMoveDir = g.NavMoveDirLast;
8150  bool new_best = NavScoreItem(result, nav_bb) && g.NavMoveRequest;
8151 #else
8152  bool new_best = g.NavMoveRequest && NavScoreItem(result, nav_bb);
8153 #endif
8154  if (new_best)
8155  {
8156  result->Window = window;
8157  result->ID = id;
8158  result->FocusScopeId = window->DC.NavFocusScopeIdCurrent;
8159  result->RectRel = nav_bb_rel;
8160  }
8161 
8162  // Features like PageUp/PageDown need to maintain a separate score for the visible set of items.
8163  const float VISIBLE_RATIO = 0.70f;
8164  if ((g.NavMoveRequestFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet) && window->ClipRect.Overlaps(nav_bb))
8165  if (ImClamp(nav_bb.Max.y, window->ClipRect.Min.y, window->ClipRect.Max.y) - ImClamp(nav_bb.Min.y, window->ClipRect.Min.y, window->ClipRect.Max.y) >= (nav_bb.Max.y - nav_bb.Min.y) * VISIBLE_RATIO)
8166  if (NavScoreItem(&g.NavMoveResultLocalVisibleSet, nav_bb))
8167  {
8168  result = &g.NavMoveResultLocalVisibleSet;
8169  result->Window = window;
8170  result->ID = id;
8171  result->FocusScopeId = window->DC.NavFocusScopeIdCurrent;
8172  result->RectRel = nav_bb_rel;
8173  }
8174  }
8175 
8176  // Update window-relative bounding box of navigated item
8177  if (g.NavId == id)
8178  {
8179  g.NavWindow = window; // Always refresh g.NavWindow, because some operations such as FocusItem() don't have a window.
8180  g.NavLayer = window->DC.NavLayerCurrent;
8181  g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent;
8182  g.NavIdIsAlive = true;
8183  g.NavIdTabCounter = window->DC.FocusCounterTabStop;
8184  window->NavRectRel[window->DC.NavLayerCurrent] = nav_bb_rel; // Store item bounding box (relative to window position)
8185  }
8186 }
8187 
8189 {
8190  ImGuiContext& g = *GImGui;
8191  return g.NavMoveRequest && g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0;
8192 }
8193 
8195 {
8196  ImGuiContext& g = *GImGui;
8197  g.NavMoveRequest = false;
8199 }
8200 
8201 void ImGui::NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, const ImRect& bb_rel, ImGuiNavMoveFlags move_flags)
8202 {
8203  ImGuiContext& g = *GImGui;
8204  IM_ASSERT(g.NavMoveRequestForward == ImGuiNavForward_None);
8206  g.NavMoveDir = move_dir;
8207  g.NavMoveClipDir = clip_dir;
8208  g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued;
8209  g.NavMoveRequestFlags = move_flags;
8210  g.NavWindow->NavRectRel[g.NavLayer] = bb_rel;
8211 }
8212 
8214 {
8215  ImGuiContext& g = *GImGui;
8216  if (g.NavWindow != window || !NavMoveRequestButNoResultYet() || g.NavMoveRequestForward != ImGuiNavForward_None || g.NavLayer != 0)
8217  return;
8218  IM_ASSERT(move_flags != 0); // No points calling this with no wrapping
8219  ImRect bb_rel = window->NavRectRel[0];
8220 
8221  ImGuiDir clip_dir = g.NavMoveDir;
8222  if (g.NavMoveDir == ImGuiDir_Left && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX)))
8223  {
8224  bb_rel.Min.x = bb_rel.Max.x = ImMax(window->SizeFull.x, window->ContentSize.x + window->WindowPadding.x * 2.0f) - window->Scroll.x;
8225  if (move_flags & ImGuiNavMoveFlags_WrapX) { bb_rel.TranslateY(-bb_rel.GetHeight()); clip_dir = ImGuiDir_Up; }
8226  NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags);
8227  }
8228  if (g.NavMoveDir == ImGuiDir_Right && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX)))
8229  {
8230  bb_rel.Min.x = bb_rel.Max.x = -window->Scroll.x;
8231  if (move_flags & ImGuiNavMoveFlags_WrapX) { bb_rel.TranslateY(+bb_rel.GetHeight()); clip_dir = ImGuiDir_Down; }
8232  NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags);
8233  }
8234  if (g.NavMoveDir == ImGuiDir_Up && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
8235  {
8236  bb_rel.Min.y = bb_rel.Max.y = ImMax(window->SizeFull.y, window->ContentSize.y + window->WindowPadding.y * 2.0f) - window->Scroll.y;
8237  if (move_flags & ImGuiNavMoveFlags_WrapY) { bb_rel.TranslateX(-bb_rel.GetWidth()); clip_dir = ImGuiDir_Left; }
8238  NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags);
8239  }
8240  if (g.NavMoveDir == ImGuiDir_Down && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
8241  {
8242  bb_rel.Min.y = bb_rel.Max.y = -window->Scroll.y;
8243  if (move_flags & ImGuiNavMoveFlags_WrapY) { bb_rel.TranslateX(+bb_rel.GetWidth()); clip_dir = ImGuiDir_Right; }
8244  NavMoveRequestForward(g.NavMoveDir, clip_dir, bb_rel, move_flags);
8245  }
8246 }
8247 
8248 // FIXME: This could be replaced by updating a frame number in each window when (window == NavWindow) and (NavLayer == 0).
8249 // This way we could find the last focused window among our children. It would be much less confusing this way?
8251 {
8252  ImGuiWindow* parent_window = nav_window;
8253  while (parent_window && (parent_window->Flags & ImGuiWindowFlags_ChildWindow) != 0 && (parent_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0)
8254  parent_window = parent_window->ParentWindow;
8255  if (parent_window && parent_window != nav_window)
8256  parent_window->NavLastChildNavWindow = nav_window;
8257 }
8258 
8259 // Restore the last focused child.
8260 // Call when we are expected to land on the Main Layer (0) after FocusWindow()
8262 {
8263  return window->NavLastChildNavWindow ? window->NavLastChildNavWindow : window;
8264 }
8265 
8267 {
8268  ImGuiContext& g = *GImGui;
8269  g.NavLayer = layer;
8270  if (layer == 0)
8271  g.NavWindow = ImGui::NavRestoreLastChildNavWindow(g.NavWindow);
8272  ImGuiWindow* window = g.NavWindow;
8273  if (layer == 0 && window->NavLastIds[0] != 0)
8274  ImGui::SetNavIDWithRectRel(window->NavLastIds[0], layer, 0, window->NavRectRel[0]);
8275  else
8276  ImGui::NavInitWindow(window, true);
8277 }
8278 
8280 {
8281  ImGuiContext& g = *GImGui;
8282  g.NavAnyRequest = g.NavMoveRequest || g.NavInitRequest || (IMGUI_DEBUG_NAV_SCORING && g.NavWindow != NULL);
8283  if (g.NavAnyRequest)
8284  IM_ASSERT(g.NavWindow != NULL);
8285 }
8286 
8287 // This needs to be called before we submit any widget (aka in or before Begin)
8288 void ImGui::NavInitWindow(ImGuiWindow* window, bool force_reinit)
8289 {
8290  ImGuiContext& g = *GImGui;
8291  IM_ASSERT(window == g.NavWindow);
8292  bool init_for_nav = false;
8293  if (!(window->Flags & ImGuiWindowFlags_NoNavInputs))
8294  if (!(window->Flags & ImGuiWindowFlags_ChildWindow) || (window->Flags & ImGuiWindowFlags_Popup) || (window->NavLastIds[0] == 0) || force_reinit)
8295  init_for_nav = true;
8296  //IMGUI_DEBUG_LOG("[Nav] NavInitWindow() init_for_nav=%d, window=\"%s\", layer=%d\n", init_for_nav, window->Name, g.NavLayer);
8297  if (init_for_nav)
8298  {
8299  SetNavID(0, g.NavLayer, 0);
8300  g.NavInitRequest = true;
8301  g.NavInitRequestFromMove = false;
8302  g.NavInitResultId = 0;
8303  g.NavInitResultRectRel = ImRect();
8305  }
8306  else
8307  {
8308  g.NavId = window->NavLastIds[0];
8309  g.NavFocusScopeId = 0;
8310  }
8311 }
8312 
8314 {
8315  ImGuiContext& g = *GImGui;
8316  if (g.NavDisableHighlight || !g.NavDisableMouseHover || !g.NavWindow)
8317  {
8318  // Mouse (we need a fallback in case the mouse becomes invalid after being used)
8319  if (IsMousePosValid(&g.IO.MousePos))
8320  return g.IO.MousePos;
8321  return g.LastValidMousePos;
8322  }
8323  else
8324  {
8325  // When navigation is active and mouse is disabled, decide on an arbitrary position around the bottom left of the currently navigated item.
8326  const ImRect& rect_rel = g.NavWindow->NavRectRel[g.NavLayer];
8327  ImVec2 pos = g.NavWindow->Pos + ImVec2(rect_rel.Min.x + ImMin(g.Style.FramePadding.x * 4, rect_rel.GetWidth()), rect_rel.Max.y - ImMin(g.Style.FramePadding.y, rect_rel.GetHeight()));
8328  ImRect visible_rect = GetViewportRect();
8329  return ImFloor(ImClamp(pos, visible_rect.Min, visible_rect.Max)); // ImFloor() is important because non-integer mouse position application in back-end might be lossy and result in undesirable non-zero delta.
8330  }
8331 }
8332 
8334 {
8335  ImGuiContext& g = *GImGui;
8337  return g.IO.NavInputs[n]; // Instant, read analog input (0.0f..1.0f, as provided by user)
8338 
8339  const float t = g.IO.NavInputsDownDuration[n];
8340  if (t < 0.0f && mode == ImGuiInputReadMode_Released) // Return 1.0f when just released, no repeat, ignore analog input.
8341  return (g.IO.NavInputsDownDurationPrev[n] >= 0.0f ? 1.0f : 0.0f);
8342  if (t < 0.0f)
8343  return 0.0f;
8344  if (mode == ImGuiInputReadMode_Pressed) // Return 1.0f when just pressed, no repeat, ignore analog input.
8345  return (t == 0.0f) ? 1.0f : 0.0f;
8347  return (float)CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay * 0.72f, g.IO.KeyRepeatRate * 0.80f);
8349  return (float)CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay * 1.25f, g.IO.KeyRepeatRate * 2.00f);
8351  return (float)CalcTypematicRepeatAmount(t - g.IO.DeltaTime, t, g.IO.KeyRepeatDelay * 0.72f, g.IO.KeyRepeatRate * 0.30f);
8352  return 0.0f;
8353 }
8354 
8355 ImVec2 ImGui::GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor, float fast_factor)
8356 {
8357  ImVec2 delta(0.0f, 0.0f);
8358  if (dir_sources & ImGuiNavDirSourceFlags_Keyboard)
8360  if (dir_sources & ImGuiNavDirSourceFlags_PadDPad)
8362  if (dir_sources & ImGuiNavDirSourceFlags_PadLStick)
8364  if (slow_factor != 0.0f && IsNavInputDown(ImGuiNavInput_TweakSlow))
8365  delta *= slow_factor;
8366  if (fast_factor != 0.0f && IsNavInputDown(ImGuiNavInput_TweakFast))
8367  delta *= fast_factor;
8368  return delta;
8369 }
8370 
8371 static void ImGui::NavUpdate()
8372 {
8373  ImGuiContext& g = *GImGui;
8374  g.IO.WantSetMousePos = false;
8375 #if 0
8376  if (g.NavScoringCount > 0) IMGUI_DEBUG_LOG("NavScoringCount %d for '%s' layer %d (Init:%d, Move:%d)\n", g.FrameCount, g.NavScoringCount, g.NavWindow ? g.NavWindow->Name : "NULL", g.NavLayer, g.NavInitRequest || g.NavInitResultId != 0, g.NavMoveRequest);
8377 #endif
8378 
8379  // Set input source as Gamepad when buttons are pressed (as some features differs when used with Gamepad vs Keyboard)
8380  // (do it before we map Keyboard input!)
8381  bool nav_keyboard_active = (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) != 0;
8382  bool nav_gamepad_active = (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (g.IO.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0;
8383  if (nav_gamepad_active)
8384  if (g.IO.NavInputs[ImGuiNavInput_Activate] > 0.0f || g.IO.NavInputs[ImGuiNavInput_Input] > 0.0f || g.IO.NavInputs[ImGuiNavInput_Cancel] > 0.0f || g.IO.NavInputs[ImGuiNavInput_Menu] > 0.0f)
8385  g.NavInputSource = ImGuiInputSource_NavGamepad;
8386 
8387  // Update Keyboard->Nav inputs mapping
8388  if (nav_keyboard_active)
8389  {
8390  #define NAV_MAP_KEY(_KEY, _NAV_INPUT) do { if (IsKeyDown(g.IO.KeyMap[_KEY])) { g.IO.NavInputs[_NAV_INPUT] = 1.0f; g.NavInputSource = ImGuiInputSource_NavKeyboard; } } while (0)
8398  if (g.IO.KeyCtrl)
8399  g.IO.NavInputs[ImGuiNavInput_TweakSlow] = 1.0f;
8400  if (g.IO.KeyShift)
8401  g.IO.NavInputs[ImGuiNavInput_TweakFast] = 1.0f;
8402  if (g.IO.KeyAlt && !g.IO.KeyCtrl) // AltGR is Alt+Ctrl, also even on keyboards without AltGR we don't want Alt+Ctrl to open menu.
8403  g.IO.NavInputs[ImGuiNavInput_KeyMenu_] = 1.0f;
8404  #undef NAV_MAP_KEY
8405  }
8406  memcpy(g.IO.NavInputsDownDurationPrev, g.IO.NavInputsDownDuration, sizeof(g.IO.NavInputsDownDuration));
8407  for (int i = 0; i < IM_ARRAYSIZE(g.IO.NavInputs); i++)
8408  g.IO.NavInputsDownDuration[i] = (g.IO.NavInputs[i] > 0.0f) ? (g.IO.NavInputsDownDuration[i] < 0.0f ? 0.0f : g.IO.NavInputsDownDuration[i] + g.IO.DeltaTime) : -1.0f;
8409 
8410  // Process navigation init request (select first/default focus)
8411  // In very rare cases g.NavWindow may be null (e.g. clearing focus after requesting an init request, which does happen when releasing Alt while clicking on void)
8412  if (g.NavInitResultId != 0 && (!g.NavDisableHighlight || g.NavInitRequestFromMove) && g.NavWindow)
8413  {
8414  // Apply result from previous navigation init request (will typically select the first item, unless SetItemDefaultFocus() has been called)
8415  //IMGUI_DEBUG_LOG("[Nav] Apply NavInitRequest result: 0x%08X Layer %d in \"%s\"\n", g.NavInitResultId, g.NavLayer, g.NavWindow->Name);
8416  if (g.NavInitRequestFromMove)
8417  SetNavIDWithRectRel(g.NavInitResultId, g.NavLayer, 0, g.NavInitResultRectRel);
8418  else
8419  SetNavID(g.NavInitResultId, g.NavLayer, 0);
8420  g.NavWindow->NavRectRel[g.NavLayer] = g.NavInitResultRectRel;
8421  }
8422  g.NavInitRequest = false;
8423  g.NavInitRequestFromMove = false;
8424  g.NavInitResultId = 0;
8425  g.NavJustMovedToId = 0;
8426 
8427  // Process navigation move request
8428  if (g.NavMoveRequest)
8430 
8431  // When a forwarded move request failed, we restore the highlight that we disabled during the forward frame
8432  if (g.NavMoveRequestForward == ImGuiNavForward_ForwardActive)
8433  {
8434  IM_ASSERT(g.NavMoveRequest);
8435  if (g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0)
8436  g.NavDisableHighlight = false;
8437  g.NavMoveRequestForward = ImGuiNavForward_None;
8438  }
8439 
8440  // Apply application mouse position movement, after we had a chance to process move request result.
8441  if (g.NavMousePosDirty && g.NavIdIsAlive)
8442  {
8443  // Set mouse position given our knowledge of the navigated item position from last frame
8444  if ((g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) && (g.IO.BackendFlags & ImGuiBackendFlags_HasSetMousePos))
8445  {
8446  if (!g.NavDisableHighlight && g.NavDisableMouseHover && g.NavWindow)
8447  {
8448  g.IO.MousePos = g.IO.MousePosPrev = NavCalcPreferredRefPos();
8449  g.IO.WantSetMousePos = true;
8450  }
8451  }
8452  g.NavMousePosDirty = false;
8453  }
8454  g.NavIdIsAlive = false;
8455  g.NavJustTabbedId = 0;
8456  IM_ASSERT(g.NavLayer == 0 || g.NavLayer == 1);
8457 
8458  // Store our return window (for returning from Layer 1 to Layer 0) and clear it as soon as we step back in our own Layer 0
8459  if (g.NavWindow)
8461  if (g.NavWindow && g.NavWindow->NavLastChildNavWindow != NULL && g.NavLayer == 0)
8462  g.NavWindow->NavLastChildNavWindow = NULL;
8463 
8464  // Update CTRL+TAB and Windowing features (hold Square to move/resize/etc.)
8466 
8467  // Set output flags for user application
8468  g.IO.NavActive = (nav_keyboard_active || nav_gamepad_active) && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs);
8469  g.IO.NavVisible = (g.IO.NavActive && g.NavId != 0 && !g.NavDisableHighlight) || (g.NavWindowingTarget != NULL);
8470 
8471  // Process NavCancel input (to close a popup, get back to parent, clear focus)
8473  {
8474  if (g.ActiveId != 0)
8475  {
8477  ClearActiveID();
8478  }
8479  else if (g.NavWindow && (g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow) && !(g.NavWindow->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->ParentWindow)
8480  {
8481  // Exit child window
8482  ImGuiWindow* child_window = g.NavWindow;
8483  ImGuiWindow* parent_window = g.NavWindow->ParentWindow;
8484  IM_ASSERT(child_window->ChildId != 0);
8485  FocusWindow(parent_window);
8486  SetNavID(child_window->ChildId, 0, 0);
8487  // Reassigning with same value, we're being explicit here.
8488  g.NavIdIsAlive = false; // -V1048
8489  if (g.NavDisableMouseHover)
8490  g.NavMousePosDirty = true;
8491  }
8492  else if (g.OpenPopupStack.Size > 0)
8493  {
8494  // Close open popup/menu
8495  if (!(g.OpenPopupStack.back().Window->Flags & ImGuiWindowFlags_Modal))
8496  ClosePopupToLevel(g.OpenPopupStack.Size - 1, true);
8497  }
8498  else if (g.NavLayer != 0)
8499  {
8500  // Leave the "menu" layer
8502  }
8503  else
8504  {
8505  // Clear NavLastId for popups but keep it for regular child window so we can leave one and come back where we were
8506  if (g.NavWindow && ((g.NavWindow->Flags & ImGuiWindowFlags_Popup) || !(g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow)))
8507  g.NavWindow->NavLastIds[0] = 0;
8508  g.NavId = g.NavFocusScopeId = 0;
8509  }
8510  }
8511 
8512  // Process manual activation request
8513  g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = 0;
8514  if (g.NavId != 0 && !g.NavDisableHighlight && !g.NavWindowingTarget && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
8515  {
8516  bool activate_down = IsNavInputDown(ImGuiNavInput_Activate);
8517  bool activate_pressed = activate_down && IsNavInputTest(ImGuiNavInput_Activate, ImGuiInputReadMode_Pressed);
8518  if (g.ActiveId == 0 && activate_pressed)
8519  g.NavActivateId = g.NavId;
8520  if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && activate_down)
8521  g.NavActivateDownId = g.NavId;
8522  if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && activate_pressed)
8523  g.NavActivatePressedId = g.NavId;
8524  if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && IsNavInputTest(ImGuiNavInput_Input, ImGuiInputReadMode_Pressed))
8525  g.NavInputId = g.NavId;
8526  }
8527  if (g.NavWindow && (g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
8528  g.NavDisableHighlight = true;
8529  if (g.NavActivateId != 0)
8530  IM_ASSERT(g.NavActivateDownId == g.NavActivateId);
8531  g.NavMoveRequest = false;
8532 
8533  // Process programmatic activation request
8534  if (g.NavNextActivateId != 0)
8535  g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = g.NavNextActivateId;
8536  g.NavNextActivateId = 0;
8537 
8538  // Initiate directional inputs request
8539  if (g.NavMoveRequestForward == ImGuiNavForward_None)
8540  {
8541  g.NavMoveDir = ImGuiDir_None;
8542  g.NavMoveRequestFlags = ImGuiNavMoveFlags_None;
8543  if (g.NavWindow && !g.NavWindowingTarget && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
8544  {
8550  }
8551  g.NavMoveClipDir = g.NavMoveDir;
8552  }
8553  else
8554  {
8555  // Forwarding previous request (which has been modified, e.g. wrap around menus rewrite the requests with a starting rectangle at the other side of the window)
8556  // (Preserve g.NavMoveRequestFlags, g.NavMoveClipDir which were set by the NavMoveRequestForward() function)
8557  IM_ASSERT(g.NavMoveDir != ImGuiDir_None && g.NavMoveClipDir != ImGuiDir_None);
8558  IM_ASSERT(g.NavMoveRequestForward == ImGuiNavForward_ForwardQueued);
8559  g.NavMoveRequestForward = ImGuiNavForward_ForwardActive;
8560  }
8561 
8562  // Update PageUp/PageDown/Home/End scroll
8563  // FIXME-NAV: Consider enabling those keys even without the master ImGuiConfigFlags_NavEnableKeyboard flag?
8564  float nav_scoring_rect_offset_y = 0.0f;
8565  if (nav_keyboard_active)
8566  nav_scoring_rect_offset_y = NavUpdatePageUpPageDown();
8567 
8568  // If we initiate a movement request and have no current NavId, we initiate a InitDefautRequest that will be used as a fallback if the direction fails to find a match
8569  if (g.NavMoveDir != ImGuiDir_None)
8570  {
8571  g.NavMoveRequest = true;
8572  g.NavMoveDirLast = g.NavMoveDir;
8573  }
8574  if (g.NavMoveRequest && g.NavId == 0)
8575  {
8576  //IMGUI_DEBUG_LOG("[Nav] NavInitRequest from move, window \"%s\", layer=%d\n", g.NavWindow->Name, g.NavLayer);
8577  g.NavInitRequest = g.NavInitRequestFromMove = true;
8578  // Reassigning with same value, we're being explicit here.
8579  g.NavInitResultId = 0; // -V1048
8580  g.NavDisableHighlight = false;
8581  }
8583 
8584  // Scrolling
8585  if (g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.NavWindowingTarget)
8586  {
8587  // *Fallback* manual-scroll with Nav directional keys when window has no navigable item
8588  ImGuiWindow* window = g.NavWindow;
8589  const float scroll_speed = IM_ROUND(window->CalcFontSize() * 100 * g.IO.DeltaTime); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported.
8590  if (window->DC.NavLayerActiveMask == 0x00 && window->DC.NavHasScroll && g.NavMoveRequest)
8591  {
8592  if (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right)
8593  SetScrollX(window, ImFloor(window->Scroll.x + ((g.NavMoveDir == ImGuiDir_Left) ? -1.0f : +1.0f) * scroll_speed));
8594  if (g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down)
8595  SetScrollY(window, ImFloor(window->Scroll.y + ((g.NavMoveDir == ImGuiDir_Up) ? -1.0f : +1.0f) * scroll_speed));
8596  }
8597 
8598  // *Normal* Manual scroll with NavScrollXXX keys
8599  // Next movement request will clamp the NavId reference rectangle to the visible area, so navigation will resume within those bounds.
8601  if (scroll_dir.x != 0.0f && window->ScrollbarX)
8602  {
8603  SetScrollX(window, ImFloor(window->Scroll.x + scroll_dir.x * scroll_speed));
8604  g.NavMoveFromClampedRefRect = true;
8605  }
8606  if (scroll_dir.y != 0.0f)
8607  {
8608  SetScrollY(window, ImFloor(window->Scroll.y + scroll_dir.y * scroll_speed));
8609  g.NavMoveFromClampedRefRect = true;
8610  }
8611  }
8612 
8613  // Reset search results
8614  g.NavMoveResultLocal.Clear();
8615  g.NavMoveResultLocalVisibleSet.Clear();
8616  g.NavMoveResultOther.Clear();
8617 
8618  // When we have manually scrolled (without using navigation) and NavId becomes out of bounds, we project its bounding box to the visible area to restart navigation within visible items
8619  if (g.NavMoveRequest && g.NavMoveFromClampedRefRect && g.NavLayer == 0)
8620  {
8621  ImGuiWindow* window = g.NavWindow;
8622  ImRect window_rect_rel(window->InnerRect.Min - window->Pos - ImVec2(1,1), window->InnerRect.Max - window->Pos + ImVec2(1,1));
8623  if (!window_rect_rel.Contains(window->NavRectRel[g.NavLayer]))
8624  {
8625  float pad = window->CalcFontSize() * 0.5f;
8626  window_rect_rel.Expand(ImVec2(-ImMin(window_rect_rel.GetWidth(), pad), -ImMin(window_rect_rel.GetHeight(), pad))); // Terrible approximation for the intent of starting navigation from first fully visible item
8627  window->NavRectRel[g.NavLayer].ClipWith(window_rect_rel);
8628  g.NavId = g.NavFocusScopeId = 0;
8629  }
8630  g.NavMoveFromClampedRefRect = false;
8631  }
8632 
8633  // For scoring we use a single segment on the left side our current item bounding box (not touching the edge to avoid box overlap with zero-spaced items)
8634  ImRect nav_rect_rel = (g.NavWindow && !g.NavWindow->NavRectRel[g.NavLayer].IsInverted()) ? g.NavWindow->NavRectRel[g.NavLayer] : ImRect(0,0,0,0);
8635  g.NavScoringRectScreen = g.NavWindow ? ImRect(g.NavWindow->Pos + nav_rect_rel.Min, g.NavWindow->Pos + nav_rect_rel.Max) : GetViewportRect();
8636  g.NavScoringRectScreen.TranslateY(nav_scoring_rect_offset_y);
8637  g.NavScoringRectScreen.Min.x = ImMin(g.NavScoringRectScreen.Min.x + 1.0f, g.NavScoringRectScreen.Max.x);
8638  g.NavScoringRectScreen.Max.x = g.NavScoringRectScreen.Min.x;
8639  IM_ASSERT(!g.NavScoringRectScreen.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allows us to remove extraneous ImFabs() calls in NavScoreItem().
8640  //GetForegroundDrawList()->AddRect(g.NavScoringRectScreen.Min, g.NavScoringRectScreen.Max, IM_COL32(255,200,0,255)); // [DEBUG]
8641  g.NavScoringCount = 0;
8642 #if IMGUI_DEBUG_NAV_RECTS
8643  if (g.NavWindow)
8644  {
8645  ImDrawList* draw_list = GetForegroundDrawList(g.NavWindow);
8646  if (1) { for (int layer = 0; layer < 2; layer++) draw_list->AddRect(g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Min, g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Max, IM_COL32(255,200,0,255)); } // [DEBUG]
8647  if (1) { ImU32 col = (!g.NavWindow->Hidden) ? IM_COL32(255,0,255,255) : IM_COL32(255,0,0,255); ImVec2 p = NavCalcPreferredRefPos(); char buf[32]; ImFormatString(buf, 32, "%d", g.NavLayer); draw_list->AddCircleFilled(p, 3.0f, col); draw_list->AddText(NULL, 13.0f, p + ImVec2(8,-4), col, buf); }
8648  }
8649 #endif
8650 }
8651 
8652 // Apply result from previous frame navigation directional move request
8654 {
8655  ImGuiContext& g = *GImGui;
8656  if (g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0)
8657  {
8658  // In a situation when there is no results but NavId != 0, re-enable the Navigation highlight (because g.NavId is not considered as a possible result)
8659  if (g.NavId != 0)
8660  {
8661  g.NavDisableHighlight = false;
8662  g.NavDisableMouseHover = true;
8663  }
8664  return;
8665  }
8666 
8667  // Select which result to use
8668  ImGuiNavMoveResult* result = (g.NavMoveResultLocal.ID != 0) ? &g.NavMoveResultLocal : &g.NavMoveResultOther;
8669 
8670  // PageUp/PageDown behavior first jumps to the bottom/top mostly visible item, _otherwise_ use the result from the previous/next page.
8671  if (g.NavMoveRequestFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet)
8672  if (g.NavMoveResultLocalVisibleSet.ID != 0 && g.NavMoveResultLocalVisibleSet.ID != g.NavId)
8673  result = &g.NavMoveResultLocalVisibleSet;
8674 
8675  // Maybe entering a flattened child from the outside? In this case solve the tie using the regular scoring rules.
8676  if (result != &g.NavMoveResultOther && g.NavMoveResultOther.ID != 0 && g.NavMoveResultOther.Window->ParentWindow == g.NavWindow)
8677  if ((g.NavMoveResultOther.DistBox < result->DistBox) || (g.NavMoveResultOther.DistBox == result->DistBox && g.NavMoveResultOther.DistCenter < result->DistCenter))
8678  result = &g.NavMoveResultOther;
8679  IM_ASSERT(g.NavWindow && result->Window);
8680 
8681  // Scroll to keep newly navigated item fully into view.
8682  if (g.NavLayer == 0)
8683  {
8684  ImVec2 delta_scroll;
8685  if (g.NavMoveRequestFlags & ImGuiNavMoveFlags_ScrollToEdge)
8686  {
8687  float scroll_target = (g.NavMoveDir == ImGuiDir_Up) ? result->Window->ScrollMax.y : 0.0f;
8688  delta_scroll.y = result->Window->Scroll.y - scroll_target;
8689  SetScrollY(result->Window, scroll_target);
8690  }
8691  else
8692  {
8693  ImRect rect_abs = ImRect(result->RectRel.Min + result->Window->Pos, result->RectRel.Max + result->Window->Pos);
8694  delta_scroll = ScrollToBringRectIntoView(result->Window, rect_abs);
8695  }
8696 
8697  // Offset our result position so mouse position can be applied immediately after in NavUpdate()
8698  result->RectRel.TranslateX(-delta_scroll.x);
8699  result->RectRel.TranslateY(-delta_scroll.y);
8700  }
8701 
8702  ClearActiveID();
8703  g.NavWindow = result->Window;
8704  if (g.NavId != result->ID)
8705  {
8706  // Don't set NavJustMovedToId if just landed on the same spot (which may happen with ImGuiNavMoveFlags_AllowCurrentNavId)
8707  g.NavJustMovedToId = result->ID;
8708  g.NavJustMovedToFocusScopeId = result->FocusScopeId;
8709 
8710  }
8711  SetNavIDWithRectRel(result->ID, g.NavLayer, result->FocusScopeId, result->RectRel);
8712  g.NavMoveFromClampedRefRect = false;
8713 }
8714 
8715 // Handle PageUp/PageDown/Home/End keys
8717 {
8718  ImGuiContext& g = *GImGui;
8719  if (g.NavMoveDir != ImGuiDir_None || g.NavWindow == NULL)
8720  return 0.0f;
8721  if ((g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) || g.NavWindowingTarget != NULL || g.NavLayer != 0)
8722  return 0.0f;
8723 
8724  ImGuiWindow* window = g.NavWindow;
8725  const bool page_up_held = IsKeyDown(g.IO.KeyMap[ImGuiKey_PageUp]) && !IsActiveIdUsingKey(ImGuiKey_PageUp);
8726  const bool page_down_held = IsKeyDown(g.IO.KeyMap[ImGuiKey_PageDown]) && !IsActiveIdUsingKey(ImGuiKey_PageDown);
8727  const bool home_pressed = IsKeyPressed(g.IO.KeyMap[ImGuiKey_Home]) && !IsActiveIdUsingKey(ImGuiKey_Home);
8728  const bool end_pressed = IsKeyPressed(g.IO.KeyMap[ImGuiKey_End]) && !IsActiveIdUsingKey(ImGuiKey_End);
8729  if (page_up_held != page_down_held || home_pressed != end_pressed) // If either (not both) are pressed
8730  {
8731  if (window->DC.NavLayerActiveMask == 0x00 && window->DC.NavHasScroll)
8732  {
8733  // Fallback manual-scroll when window has no navigable item
8734  if (IsKeyPressed(g.IO.KeyMap[ImGuiKey_PageUp], true))
8735  SetScrollY(window, window->Scroll.y - window->InnerRect.GetHeight());
8736  else if (IsKeyPressed(g.IO.KeyMap[ImGuiKey_PageDown], true))
8737  SetScrollY(window, window->Scroll.y + window->InnerRect.GetHeight());
8738  else if (home_pressed)
8739  SetScrollY(window, 0.0f);
8740  else if (end_pressed)
8741  SetScrollY(window, window->ScrollMax.y);
8742  }
8743  else
8744  {
8745  ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer];
8746  const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->CalcFontSize() * 1.0f + nav_rect_rel.GetHeight());
8747  float nav_scoring_rect_offset_y = 0.0f;
8748  if (IsKeyPressed(g.IO.KeyMap[ImGuiKey_PageUp], true))
8749  {
8750  nav_scoring_rect_offset_y = -page_offset_y;
8751  g.NavMoveDir = ImGuiDir_Down; // Because our scoring rect is offset up, we request the down direction (so we can always land on the last item)
8752  g.NavMoveClipDir = ImGuiDir_Up;
8754  }
8755  else if (IsKeyPressed(g.IO.KeyMap[ImGuiKey_PageDown], true))
8756  {
8757  nav_scoring_rect_offset_y = +page_offset_y;
8758  g.NavMoveDir = ImGuiDir_Up; // Because our scoring rect is offset down, we request the up direction (so we can always land on the last item)
8759  g.NavMoveClipDir = ImGuiDir_Down;
8761  }
8762  else if (home_pressed)
8763  {
8764  // FIXME-NAV: handling of Home/End is assuming that the top/bottom most item will be visible with Scroll.y == 0/ScrollMax.y
8765  // Scrolling will be handled via the ImGuiNavMoveFlags_ScrollToEdge flag, we don't scroll immediately to avoid scrolling happening before nav result.
8766  // Preserve current horizontal position if we have any.
8767  nav_rect_rel.Min.y = nav_rect_rel.Max.y = -window->Scroll.y;
8768  if (nav_rect_rel.IsInverted())
8769  nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f;
8770  g.NavMoveDir = ImGuiDir_Down;
8772  }
8773  else if (end_pressed)
8774  {
8775  nav_rect_rel.Min.y = nav_rect_rel.Max.y = window->ScrollMax.y + window->SizeFull.y - window->Scroll.y;
8776  if (nav_rect_rel.IsInverted())
8777  nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f;
8778  g.NavMoveDir = ImGuiDir_Up;
8780  }
8781  return nav_scoring_rect_offset_y;
8782  }
8783  }
8784  return 0.0f;
8785 }
8786 
8787 static int ImGui::FindWindowFocusIndex(ImGuiWindow* window) // FIXME-OPT O(N)
8788 {
8789  ImGuiContext& g = *GImGui;
8790  for (int i = g.WindowsFocusOrder.Size-1; i >= 0; i--)
8791  if (g.WindowsFocusOrder[i] == window)
8792  return i;
8793  return -1;
8794 }
8795 
8796 static ImGuiWindow* FindWindowNavFocusable(int i_start, int i_stop, int dir) // FIXME-OPT O(N)
8797 {
8798  ImGuiContext& g = *GImGui;
8799  for (int i = i_start; i >= 0 && i < g.WindowsFocusOrder.Size && i != i_stop; i += dir)
8800  if (ImGui::IsWindowNavFocusable(g.WindowsFocusOrder[i]))
8801  return g.WindowsFocusOrder[i];
8802  return NULL;
8803 }
8804 
8805 static void NavUpdateWindowingHighlightWindow(int focus_change_dir)
8806 {
8807  ImGuiContext& g = *GImGui;
8808  IM_ASSERT(g.NavWindowingTarget);
8809  if (g.NavWindowingTarget->Flags & ImGuiWindowFlags_Modal)
8810  return;
8811 
8812  const int i_current = ImGui::FindWindowFocusIndex(g.NavWindowingTarget);
8813  ImGuiWindow* window_target = FindWindowNavFocusable(i_current + focus_change_dir, -INT_MAX, focus_change_dir);
8814  if (!window_target)
8815  window_target = FindWindowNavFocusable((focus_change_dir < 0) ? (g.WindowsFocusOrder.Size - 1) : 0, i_current, focus_change_dir);
8816  if (window_target) // Don't reset windowing target if there's a single window in the list
8817  g.NavWindowingTarget = g.NavWindowingTargetAnim = window_target;
8818  g.NavWindowingToggleLayer = false;
8819 }
8820 
8821 // Windowing management mode
8822 // Keyboard: CTRL+Tab (change focus/move/resize), Alt (toggle menu layer)
8823 // Gamepad: Hold Menu/Square (change focus/move/resize), Tap Menu/Square (toggle menu layer)
8825 {
8826  ImGuiContext& g = *GImGui;
8827  ImGuiWindow* apply_focus_window = NULL;
8828  bool apply_toggle_layer = false;
8829 
8830  ImGuiWindow* modal_window = GetTopMostPopupModal();
8831  if (modal_window != NULL)
8832  {
8833  g.NavWindowingTarget = NULL;
8834  return;
8835  }
8836 
8837  // Fade out
8838  if (g.NavWindowingTargetAnim && g.NavWindowingTarget == NULL)
8839  {
8840  g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha - g.IO.DeltaTime * 10.0f, 0.0f);
8841  if (g.DimBgRatio <= 0.0f && g.NavWindowingHighlightAlpha <= 0.0f)
8842  g.NavWindowingTargetAnim = NULL;
8843  }
8844 
8845  // Start CTRL-TAB or Square+L/R window selection
8846  bool start_windowing_with_gamepad = !g.NavWindowingTarget && IsNavInputTest(ImGuiNavInput_Menu, ImGuiInputReadMode_Pressed);
8847  bool start_windowing_with_keyboard = !g.NavWindowingTarget && g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab) && (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard);
8848  if (start_windowing_with_gamepad || start_windowing_with_keyboard)
8849  if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1))
8850  {
8851  g.NavWindowingTarget = g.NavWindowingTargetAnim = window->RootWindow; // FIXME-DOCK: Will need to use RootWindowDockStop
8852  g.NavWindowingTimer = g.NavWindowingHighlightAlpha = 0.0f;
8853  g.NavWindowingToggleLayer = start_windowing_with_keyboard ? false : true;
8854  g.NavInputSource = start_windowing_with_keyboard ? ImGuiInputSource_NavKeyboard : ImGuiInputSource_NavGamepad;
8855  }
8856 
8857  // Gamepad update
8858  g.NavWindowingTimer += g.IO.DeltaTime;
8859  if (g.NavWindowingTarget && g.NavInputSource == ImGuiInputSource_NavGamepad)
8860  {
8861  // Highlight only appears after a brief time holding the button, so that a fast tap on PadMenu (to toggle NavLayer) doesn't add visual noise
8862  g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingTimer - NAV_WINDOWING_HIGHLIGHT_DELAY) / 0.05f));
8863 
8864  // Select window to focus
8866  if (focus_change_dir != 0)
8867  {
8868  NavUpdateWindowingHighlightWindow(focus_change_dir);
8869  g.NavWindowingHighlightAlpha = 1.0f;
8870  }
8871 
8872  // Single press toggles NavLayer, long press with L/R apply actual focus on release (until then the window was merely rendered top-most)
8874  {
8875  g.NavWindowingToggleLayer &= (g.NavWindowingHighlightAlpha < 1.0f); // Once button was held long enough we don't consider it a tap-to-toggle-layer press anymore.
8876  if (g.NavWindowingToggleLayer && g.NavWindow)
8877  apply_toggle_layer = true;
8878  else if (!g.NavWindowingToggleLayer)
8879  apply_focus_window = g.NavWindowingTarget;
8880  g.NavWindowingTarget = NULL;
8881  }
8882  }
8883 
8884  // Keyboard: Focus
8885  if (g.NavWindowingTarget && g.NavInputSource == ImGuiInputSource_NavKeyboard)
8886  {
8887  // Visuals only appears after a brief time after pressing TAB the first time, so that a fast CTRL+TAB doesn't add visual noise
8888  g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingTimer - NAV_WINDOWING_HIGHLIGHT_DELAY) / 0.05f)); // 1.0f
8889  if (IsKeyPressedMap(ImGuiKey_Tab, true))
8890  NavUpdateWindowingHighlightWindow(g.IO.KeyShift ? +1 : -1);
8891  if (!g.IO.KeyCtrl)
8892  apply_focus_window = g.NavWindowingTarget;
8893  }
8894 
8895  // Keyboard: Press and Release ALT to toggle menu layer
8896  // FIXME: We lack an explicit IO variable for "is the imgui window focused", so compare mouse validity to detect the common case of back-end clearing releases all keys on ALT-TAB
8898  g.NavWindowingToggleLayer = true;
8899  if ((g.ActiveId == 0 || g.ActiveIdAllowOverlap) && g.NavWindowingToggleLayer && IsNavInputTest(ImGuiNavInput_KeyMenu_, ImGuiInputReadMode_Released))
8900  if (IsMousePosValid(&g.IO.MousePos) == IsMousePosValid(&g.IO.MousePosPrev))
8901  apply_toggle_layer = true;
8902 
8903  // Move window
8904  if (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoMove))
8905  {
8906  ImVec2 move_delta;
8907  if (g.NavInputSource == ImGuiInputSource_NavKeyboard && !g.IO.KeyShift)
8909  if (g.NavInputSource == ImGuiInputSource_NavGamepad)
8911  if (move_delta.x != 0.0f || move_delta.y != 0.0f)
8912  {
8913  const float NAV_MOVE_SPEED = 800.0f;
8914  const float move_speed = ImFloor(NAV_MOVE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y)); // FIXME: Doesn't code variable framerate very well
8915  SetWindowPos(g.NavWindowingTarget->RootWindow, g.NavWindowingTarget->RootWindow->Pos + move_delta * move_speed, ImGuiCond_Always);
8916  g.NavDisableMouseHover = true;
8917  MarkIniSettingsDirty(g.NavWindowingTarget);
8918  }
8919  }
8920 
8921  // Apply final focus
8922  if (apply_focus_window && (g.NavWindow == NULL || apply_focus_window != g.NavWindow->RootWindow))
8923  {
8924  ClearActiveID();
8925  g.NavDisableHighlight = false;
8926  g.NavDisableMouseHover = true;
8927  apply_focus_window = NavRestoreLastChildNavWindow(apply_focus_window);
8928  ClosePopupsOverWindow(apply_focus_window, false);
8929  FocusWindow(apply_focus_window);
8930  if (apply_focus_window->NavLastIds[0] == 0)
8931  NavInitWindow(apply_focus_window, false);
8932 
8933  // If the window only has a menu layer, select it directly
8934  if (apply_focus_window->DC.NavLayerActiveMask == (1 << ImGuiNavLayer_Menu))
8935  g.NavLayer = ImGuiNavLayer_Menu;
8936  }
8937  if (apply_focus_window)
8938  g.NavWindowingTarget = NULL;
8939 
8940  // Apply menu/layer toggle
8941  if (apply_toggle_layer && g.NavWindow)
8942  {
8943  // Move to parent menu if necessary
8944  ImGuiWindow* new_nav_window = g.NavWindow;
8945  while (new_nav_window->ParentWindow
8946  && (new_nav_window->DC.NavLayerActiveMask & (1 << ImGuiNavLayer_Menu)) == 0
8947  && (new_nav_window->Flags & ImGuiWindowFlags_ChildWindow) != 0
8948  && (new_nav_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0)
8949  new_nav_window = new_nav_window->ParentWindow;
8950  if (new_nav_window != g.NavWindow)
8951  {
8952  ImGuiWindow* old_nav_window = g.NavWindow;
8953  FocusWindow(new_nav_window);
8954  new_nav_window->NavLastChildNavWindow = old_nav_window;
8955  }
8956  g.NavDisableHighlight = false;
8957  g.NavDisableMouseHover = true;
8958 
8959  // When entering a regular menu bar with the Alt key, we always reinitialize the navigation ID.
8960  const ImGuiNavLayer new_nav_layer = (g.NavWindow->DC.NavLayerActiveMask & (1 << ImGuiNavLayer_Menu)) ? (ImGuiNavLayer)((int)g.NavLayer ^ 1) : ImGuiNavLayer_Main;
8961  NavRestoreLayer(new_nav_layer);
8962  }
8963 }
8964 
8965 // Window has already passed the IsWindowNavFocusable()
8967 {
8968  if (window->Flags & ImGuiWindowFlags_Popup)
8969  return "(Popup)";
8970  if ((window->Flags & ImGuiWindowFlags_MenuBar) && strcmp(window->Name, "##MainMenuBar") == 0)
8971  return "(Main menu bar)";
8972  return "(Untitled)";
8973 }
8974 
8975 // Overlay displayed when using CTRL+TAB. Called by EndFrame().
8977 {
8978  ImGuiContext& g = *GImGui;
8979  IM_ASSERT(g.NavWindowingTarget != NULL);
8980 
8981  if (g.NavWindowingTimer < NAV_WINDOWING_LIST_APPEAR_DELAY)
8982  return;
8983 
8984  if (g.NavWindowingList == NULL)
8985  g.NavWindowingList = FindWindowByName("###NavWindowingList");
8986  SetNextWindowSizeConstraints(ImVec2(g.IO.DisplaySize.x * 0.20f, g.IO.DisplaySize.y * 0.20f), ImVec2(FLT_MAX, FLT_MAX));
8987  SetNextWindowPos(g.IO.DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
8988  PushStyleVar(ImGuiStyleVar_WindowPadding, g.Style.WindowPadding * 2.0f);
8990  for (int n = g.WindowsFocusOrder.Size - 1; n >= 0; n--)
8991  {
8992  ImGuiWindow* window = g.WindowsFocusOrder[n];
8993  if (!IsWindowNavFocusable(window))
8994  continue;
8995  const char* label = window->Name;
8998  Selectable(label, g.NavWindowingTarget == window);
8999  }
9000  End();
9001  PopStyleVar();
9002 }
9003 
9004 //-----------------------------------------------------------------------------
9005 // [SECTION] DRAG AND DROP
9006 //-----------------------------------------------------------------------------
9007 
9009 {
9010  ImGuiContext& g = *GImGui;
9011  g.DragDropActive = false;
9012  g.DragDropPayload.Clear();
9013  g.DragDropAcceptFlags = ImGuiDragDropFlags_None;
9014  g.DragDropAcceptIdCurr = g.DragDropAcceptIdPrev = 0;
9015  g.DragDropAcceptIdCurrRectSurface = FLT_MAX;
9016  g.DragDropAcceptFrameCount = -1;
9017 
9018  g.DragDropPayloadBufHeap.clear();
9019  memset(&g.DragDropPayloadBufLocal, 0, sizeof(g.DragDropPayloadBufLocal));
9020 }
9021 
9022 // Call when current ID is active.
9023 // When this returns true you need to: a) call SetDragDropPayload() exactly once, b) you may render the payload visual/description, c) call EndDragDropSource()
9025 {
9026  ImGuiContext& g = *GImGui;
9027  ImGuiWindow* window = g.CurrentWindow;
9028 
9029  bool source_drag_active = false;
9030  ImGuiID source_id = 0;
9031  ImGuiID source_parent_id = 0;
9032  ImGuiMouseButton mouse_button = ImGuiMouseButton_Left;
9034  {
9035  source_id = window->DC.LastItemId;
9036  if (source_id != 0 && g.ActiveId != source_id) // Early out for most common case
9037  return false;
9038  if (g.IO.MouseDown[mouse_button] == false)
9039  return false;
9040 
9041  if (source_id == 0)
9042  {
9043  // If you want to use BeginDragDropSource() on an item with no unique identifier for interaction, such as Text() or Image(), you need to:
9044  // A) Read the explanation below, B) Use the ImGuiDragDropFlags_SourceAllowNullID flag, C) Swallow your programmer pride.
9046  {
9047  IM_ASSERT(0);
9048  return false;
9049  }
9050 
9051  // Early out
9052  if ((window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect) == 0 && (g.ActiveId == 0 || g.ActiveIdWindow != window))
9053  return false;
9054 
9055  // Magic fallback (=somehow reprehensible) to handle items with no assigned ID, e.g. Text(), Image()
9056  // We build a throwaway ID based on current ID stack + relative AABB of items in window.
9057  // THE IDENTIFIER WON'T SURVIVE ANY REPOSITIONING OF THE WIDGET, so if your widget moves your dragging operation will be canceled.
9058  // We don't need to maintain/call ClearActiveID() as releasing the button will early out this function and trigger !ActiveIdIsAlive.
9059  source_id = window->DC.LastItemId = window->GetIDFromRectangle(window->DC.LastItemRect);
9060  bool is_hovered = ItemHoverable(window->DC.LastItemRect, source_id);
9061  if (is_hovered && g.IO.MouseClicked[mouse_button])
9062  {
9063  SetActiveID(source_id, window);
9064  FocusWindow(window);
9065  }
9066  if (g.ActiveId == source_id) // Allow the underlying widget to display/return hovered during the mouse release frame, else we would get a flicker.
9067  g.ActiveIdAllowOverlap = is_hovered;
9068  }
9069  else
9070  {
9071  g.ActiveIdAllowOverlap = false;
9072  }
9073  if (g.ActiveId != source_id)
9074  return false;
9075  source_parent_id = window->IDStack.back();
9076  source_drag_active = IsMouseDragging(mouse_button);
9077 
9078  // Disable navigation and key inputs while dragging
9079  g.ActiveIdUsingNavDirMask = ~(ImU32)0;
9080  g.ActiveIdUsingNavInputMask = ~(ImU32)0;
9081  g.ActiveIdUsingKeyInputMask = ~(ImU64)0;
9082  }
9083  else
9084  {
9085  window = NULL;
9086  source_id = ImHashStr("#SourceExtern");
9087  source_drag_active = true;
9088  }
9089 
9090  if (source_drag_active)
9091  {
9092  if (!g.DragDropActive)
9093  {
9094  IM_ASSERT(source_id != 0);
9095  ClearDragDrop();
9096  ImGuiPayload& payload = g.DragDropPayload;
9097  payload.SourceId = source_id;
9098  payload.SourceParentId = source_parent_id;
9099  g.DragDropActive = true;
9100  g.DragDropSourceFlags = flags;
9101  g.DragDropMouseButton = mouse_button;
9102  }
9103  g.DragDropSourceFrameCount = g.FrameCount;
9104  g.DragDropWithinSource = true;
9105 
9107  {
9108  // Target can request the Source to not display its tooltip (we use a dedicated flag to make this request explicit)
9109  // We unfortunately can't just modify the source flags and skip the call to BeginTooltip, as caller may be emitting contents.
9110  BeginTooltip();
9111  if (g.DragDropAcceptIdPrev && (g.DragDropAcceptFlags & ImGuiDragDropFlags_AcceptNoPreviewTooltip))
9112  {
9113  ImGuiWindow* tooltip_window = g.CurrentWindow;
9114  tooltip_window->SkipItems = true;
9115  tooltip_window->HiddenFramesCanSkipItems = 1;
9116  }
9117  }
9118 
9121 
9122  return true;
9123  }
9124  return false;
9125 }
9126 
9128 {
9129  ImGuiContext& g = *GImGui;
9130  IM_ASSERT(g.DragDropActive);
9131  IM_ASSERT(g.DragDropWithinSource && "Not after a BeginDragDropSource()?");
9132 
9133  if (!(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoPreviewTooltip))
9134  EndTooltip();
9135 
9136  // Discard the drag if have not called SetDragDropPayload()
9137  if (g.DragDropPayload.DataFrameCount == -1)
9138  ClearDragDrop();
9139  g.DragDropWithinSource = false;
9140 }
9141 
9142 // Use 'cond' to choose to submit payload on drag start or every frame
9143 bool ImGui::SetDragDropPayload(const char* type, const void* data, size_t data_size, ImGuiCond cond)
9144 {
9145  ImGuiContext& g = *GImGui;
9146  ImGuiPayload& payload = g.DragDropPayload;
9147  if (cond == 0)
9148  cond = ImGuiCond_Always;
9149 
9150  IM_ASSERT(type != NULL);
9151  IM_ASSERT(strlen(type) < IM_ARRAYSIZE(payload.DataType) && "Payload type can be at most 32 characters long");
9152  IM_ASSERT((data != NULL && data_size > 0) || (data == NULL && data_size == 0));
9153  IM_ASSERT(cond == ImGuiCond_Always || cond == ImGuiCond_Once);
9154  IM_ASSERT(payload.SourceId != 0); // Not called between BeginDragDropSource() and EndDragDropSource()
9155 
9156  if (cond == ImGuiCond_Always || payload.DataFrameCount == -1)
9157  {
9158  // Copy payload
9159  ImStrncpy(payload.DataType, type, IM_ARRAYSIZE(payload.DataType));
9160  g.DragDropPayloadBufHeap.resize(0);
9161  if (data_size > sizeof(g.DragDropPayloadBufLocal))
9162  {
9163  // Store in heap
9164  g.DragDropPayloadBufHeap.resize((int)data_size);
9165  payload.Data = g.DragDropPayloadBufHeap.Data;
9166  memcpy(payload.Data, data, data_size);
9167  }
9168  else if (data_size > 0)
9169  {
9170  // Store locally
9171  memset(&g.DragDropPayloadBufLocal, 0, sizeof(g.DragDropPayloadBufLocal));
9172  payload.Data = g.DragDropPayloadBufLocal;
9173  memcpy(payload.Data, data, data_size);
9174  }
9175  else
9176  {
9177  payload.Data = NULL;
9178  }
9179  payload.DataSize = (int)data_size;
9180  }
9181  payload.DataFrameCount = g.FrameCount;
9182 
9183  return (g.DragDropAcceptFrameCount == g.FrameCount) || (g.DragDropAcceptFrameCount == g.FrameCount - 1);
9184 }
9185 
9187 {
9188  ImGuiContext& g = *GImGui;
9189  if (!g.DragDropActive)
9190  return false;
9191 
9192  ImGuiWindow* window = g.CurrentWindow;
9193  if (g.HoveredWindow == NULL || window->RootWindow != g.HoveredWindow->RootWindow)
9194  return false;
9195  IM_ASSERT(id != 0);
9196  if (!IsMouseHoveringRect(bb.Min, bb.Max) || (id == g.DragDropPayload.SourceId))
9197  return false;
9198  if (window->SkipItems)
9199  return false;
9200 
9201  IM_ASSERT(g.DragDropWithinTarget == false);
9202  g.DragDropTargetRect = bb;
9203  g.DragDropTargetId = id;
9204  g.DragDropWithinTarget = true;
9205  return true;
9206 }
9207 
9208 // We don't use BeginDragDropTargetCustom() and duplicate its code because:
9209 // 1) we use LastItemRectHoveredRect which handles items that pushes a temporarily clip rectangle in their code. Calling BeginDragDropTargetCustom(LastItemRect) would not handle them.
9210 // 2) and it's faster. as this code may be very frequently called, we want to early out as fast as we can.
9211 // Also note how the HoveredWindow test is positioned differently in both functions (in both functions we optimize for the cheapest early out case)
9213 {
9214  ImGuiContext& g = *GImGui;
9215  if (!g.DragDropActive)
9216  return false;
9217 
9218  ImGuiWindow* window = g.CurrentWindow;
9220  return false;
9221  if (g.HoveredWindow == NULL || window->RootWindow != g.HoveredWindow->RootWindow)
9222  return false;
9223 
9224  const ImRect& display_rect = (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HasDisplayRect) ? window->DC.LastItemDisplayRect : window->DC.LastItemRect;
9225  ImGuiID id = window->DC.LastItemId;
9226  if (id == 0)
9227  id = window->GetIDFromRectangle(display_rect);
9228  if (g.DragDropPayload.SourceId == id)
9229  return false;
9230 
9231  IM_ASSERT(g.DragDropWithinTarget == false);
9232  g.DragDropTargetRect = display_rect;
9233  g.DragDropTargetId = id;
9234  g.DragDropWithinTarget = true;
9235  return true;
9236 }
9237 
9239 {
9240  ImGuiContext& g = *GImGui;
9241  return g.DragDropActive && g.DragDropAcceptIdPrev != 0;
9242 }
9243 
9245 {
9246  ImGuiContext& g = *GImGui;
9247  ImGuiWindow* window = g.CurrentWindow;
9248  ImGuiPayload& payload = g.DragDropPayload;
9249  IM_ASSERT(g.DragDropActive); // Not called between BeginDragDropTarget() and EndDragDropTarget() ?
9250  IM_ASSERT(payload.DataFrameCount != -1); // Forgot to call EndDragDropTarget() ?
9251  if (type != NULL && !payload.IsDataType(type))
9252  return NULL;
9253 
9254  // Accept smallest drag target bounding box, this allows us to nest drag targets conveniently without ordering constraints.
9255  // NB: We currently accept NULL id as target. However, overlapping targets requires a unique ID to function!
9256  const bool was_accepted_previously = (g.DragDropAcceptIdPrev == g.DragDropTargetId);
9257  ImRect r = g.DragDropTargetRect;
9258  float r_surface = r.GetWidth() * r.GetHeight();
9259  if (r_surface < g.DragDropAcceptIdCurrRectSurface)
9260  {
9261  g.DragDropAcceptFlags = flags;
9262  g.DragDropAcceptIdCurr = g.DragDropTargetId;
9263  g.DragDropAcceptIdCurrRectSurface = r_surface;
9264  }
9265 
9266  // Render default drop visuals
9267  payload.Preview = was_accepted_previously;
9268  flags |= (g.DragDropSourceFlags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect); // Source can also inhibit the preview (useful for external sources that lives for 1 frame)
9270  {
9271  // FIXME-DRAG: Settle on a proper default visuals for drop target.
9272  r.Expand(3.5f);
9273  bool push_clip_rect = !window->ClipRect.Contains(r);
9274  if (push_clip_rect) window->DrawList->PushClipRect(r.Min-ImVec2(1,1), r.Max+ImVec2(1,1));
9275  window->DrawList->AddRect(r.Min, r.Max, GetColorU32(ImGuiCol_DragDropTarget), 0.0f, ~0, 2.0f);
9276  if (push_clip_rect) window->DrawList->PopClipRect();
9277  }
9278 
9279  g.DragDropAcceptFrameCount = g.FrameCount;
9280  payload.Delivery = was_accepted_previously && !IsMouseDown(g.DragDropMouseButton); // For extern drag sources affecting os window focus, it's easier to just test !IsMouseDown() instead of IsMouseReleased()
9282  return NULL;
9283 
9284  return &payload;
9285 }
9286 
9288 {
9289  ImGuiContext& g = *GImGui;
9290  return g.DragDropActive ? &g.DragDropPayload : NULL;
9291 }
9292 
9293 // We don't really use/need this now, but added it for the sake of consistency and because we might need it later.
9295 {
9296  ImGuiContext& g = *GImGui;
9297  IM_ASSERT(g.DragDropActive);
9298  IM_ASSERT(g.DragDropWithinTarget);
9299  g.DragDropWithinTarget = false;
9300 }
9301 
9302 //-----------------------------------------------------------------------------
9303 // [SECTION] LOGGING/CAPTURING
9304 //-----------------------------------------------------------------------------
9305 // All text output from the interface can be captured into tty/file/clipboard.
9306 // By default, tree nodes are automatically opened during logging.
9307 //-----------------------------------------------------------------------------
9308 
9309 // Pass text data straight to log (without being displayed)
9310 void ImGui::LogText(const char* fmt, ...)
9311 {
9312  ImGuiContext& g = *GImGui;
9313  if (!g.LogEnabled)
9314  return;
9315 
9316  va_list args;
9317  va_start(args, fmt);
9318  if (g.LogFile)
9319  {
9320  g.LogBuffer.Buf.resize(0);
9321  g.LogBuffer.appendfv(fmt, args);
9322  ImFileWrite(g.LogBuffer.c_str(), sizeof(char), (ImU64)g.LogBuffer.size(), g.LogFile);
9323  }
9324  else
9325  {
9326  g.LogBuffer.appendfv(fmt, args);
9327  }
9328  va_end(args);
9329 }
9330 
9331 // Internal version that takes a position to decide on newline placement and pad items according to their depth.
9332 // We split text into individual lines to add current tree level padding
9333 void ImGui::LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end)
9334 {
9335  ImGuiContext& g = *GImGui;
9336  ImGuiWindow* window = g.CurrentWindow;
9337 
9338  if (!text_end)
9339  text_end = FindRenderedTextEnd(text, text_end);
9340 
9341  const bool log_new_line = ref_pos && (ref_pos->y > g.LogLinePosY + 1);
9342  if (ref_pos)
9343  g.LogLinePosY = ref_pos->y;
9344  if (log_new_line)
9345  g.LogLineFirstItem = true;
9346 
9347  const char* text_remaining = text;
9348  if (g.LogDepthRef > window->DC.TreeDepth) // Re-adjust padding if we have popped out of our starting depth
9349  g.LogDepthRef = window->DC.TreeDepth;
9350  const int tree_depth = (window->DC.TreeDepth - g.LogDepthRef);
9351  for (;;)
9352  {
9353  // Split the string. Each new line (after a '\n') is followed by spacing corresponding to the current depth of our log entry.
9354  // We don't add a trailing \n to allow a subsequent item on the same line to be captured.
9355  const char* line_start = text_remaining;
9356  const char* line_end = ImStreolRange(line_start, text_end);
9357  const bool is_first_line = (line_start == text);
9358  const bool is_last_line = (line_end == text_end);
9359  if (!is_last_line || (line_start != line_end))
9360  {
9361  const int char_count = (int)(line_end - line_start);
9362  if (log_new_line || !is_first_line)
9363  LogText(IM_NEWLINE "%*s%.*s", tree_depth * 4, "", char_count, line_start);
9364  else if (g.LogLineFirstItem)
9365  LogText("%*s%.*s", tree_depth * 4, "", char_count, line_start);
9366  else
9367  LogText(" %.*s", char_count, line_start);
9368  g.LogLineFirstItem = false;
9369  }
9370  else if (log_new_line)
9371  {
9372  // An empty "" string at a different Y position should output a carriage return.
9374  break;
9375  }
9376 
9377  if (is_last_line)
9378  break;
9379  text_remaining = line_end + 1;
9380  }
9381 }
9382 
9383 // Start logging/capturing text output
9384 void ImGui::LogBegin(ImGuiLogType type, int auto_open_depth)
9385 {
9386  ImGuiContext& g = *GImGui;
9387  ImGuiWindow* window = g.CurrentWindow;
9388  IM_ASSERT(g.LogEnabled == false);
9389  IM_ASSERT(g.LogFile == NULL);
9390  IM_ASSERT(g.LogBuffer.empty());
9391  g.LogEnabled = true;
9392  g.LogType = type;
9393  g.LogDepthRef = window->DC.TreeDepth;
9394  g.LogDepthToExpand = ((auto_open_depth >= 0) ? auto_open_depth : g.LogDepthToExpandDefault);
9395  g.LogLinePosY = FLT_MAX;
9396  g.LogLineFirstItem = true;
9397 }
9398 
9399 void ImGui::LogToTTY(int auto_open_depth)
9400 {
9401  ImGuiContext& g = *GImGui;
9402  if (g.LogEnabled)
9403  return;
9404  IM_UNUSED(auto_open_depth);
9405 #ifndef IMGUI_DISABLE_TTY_FUNCTIONS
9406  LogBegin(ImGuiLogType_TTY, auto_open_depth);
9407  g.LogFile = stdout;
9408 #endif
9409 }
9410 
9411 // Start logging/capturing text output to given file
9412 void ImGui::LogToFile(int auto_open_depth, const char* filename)
9413 {
9414  ImGuiContext& g = *GImGui;
9415  if (g.LogEnabled)
9416  return;
9417 
9418  // FIXME: We could probably open the file in text mode "at", however note that clipboard/buffer logging will still
9419  // be subject to outputting OS-incompatible carriage return if within strings the user doesn't use IM_NEWLINE.
9420  // By opening the file in binary mode "ab" we have consistent output everywhere.
9421  if (!filename)
9422  filename = g.IO.LogFilename;
9423  if (!filename || !filename[0])
9424  return;
9425  ImFileHandle f = ImFileOpen(filename, "ab");
9426  if (!f)
9427  {
9428  IM_ASSERT(0);
9429  return;
9430  }
9431 
9432  LogBegin(ImGuiLogType_File, auto_open_depth);
9433  g.LogFile = f;
9434 }
9435 
9436 // Start logging/capturing text output to clipboard
9437 void ImGui::LogToClipboard(int auto_open_depth)
9438 {
9439  ImGuiContext& g = *GImGui;
9440  if (g.LogEnabled)
9441  return;
9442  LogBegin(ImGuiLogType_Clipboard, auto_open_depth);
9443 }
9444 
9445 void ImGui::LogToBuffer(int auto_open_depth)
9446 {
9447  ImGuiContext& g = *GImGui;
9448  if (g.LogEnabled)
9449  return;
9450  LogBegin(ImGuiLogType_Buffer, auto_open_depth);
9451 }
9452 
9454 {
9455  ImGuiContext& g = *GImGui;
9456  if (!g.LogEnabled)
9457  return;
9458 
9460  switch (g.LogType)
9461  {
9462  case ImGuiLogType_TTY:
9463 #ifndef IMGUI_DISABLE_TTY_FUNCTIONS
9464  fflush(g.LogFile);
9465 #endif
9466  break;
9467  case ImGuiLogType_File:
9468  ImFileClose(g.LogFile);
9469  break;
9470  case ImGuiLogType_Buffer:
9471  break;
9473  if (!g.LogBuffer.empty())
9474  SetClipboardText(g.LogBuffer.begin());
9475  break;
9476  case ImGuiLogType_None:
9477  IM_ASSERT(0);
9478  break;
9479  }
9480 
9481  g.LogEnabled = false;
9482  g.LogType = ImGuiLogType_None;
9483  g.LogFile = NULL;
9484  g.LogBuffer.clear();
9485 }
9486 
9487 // Helper to display logging buttons
9488 // FIXME-OBSOLETE: We should probably obsolete this and let the user have their own helper (this is one of the oldest function alive!)
9490 {
9491  ImGuiContext& g = *GImGui;
9492 
9493  PushID("LogButtons");
9494 #ifndef IMGUI_DISABLE_TTY_FUNCTIONS
9495  const bool log_to_tty = Button("Log To TTY"); SameLine();
9496 #else
9497  const bool log_to_tty = false;
9498 #endif
9499  const bool log_to_file = Button("Log To File"); SameLine();
9500  const bool log_to_clipboard = Button("Log To Clipboard"); SameLine();
9501  PushAllowKeyboardFocus(false);
9502  SetNextItemWidth(80.0f);
9503  SliderInt("Default Depth", &g.LogDepthToExpandDefault, 0, 9, NULL);
9505  PopID();
9506 
9507  // Start logging at the end of the function so that the buttons don't appear in the log
9508  if (log_to_tty)
9509  LogToTTY();
9510  if (log_to_file)
9511  LogToFile();
9512  if (log_to_clipboard)
9513  LogToClipboard();
9514 }
9515 
9516 //-----------------------------------------------------------------------------
9517 // [SECTION] SETTINGS
9518 //-----------------------------------------------------------------------------
9519 
9520 // Called by NewFrame()
9522 {
9523  // Load settings on first frame (if not explicitly loaded manually before)
9524  ImGuiContext& g = *GImGui;
9525  if (!g.SettingsLoaded)
9526  {
9527  IM_ASSERT(g.SettingsWindows.empty());
9528  if (g.IO.IniFilename)
9529  LoadIniSettingsFromDisk(g.IO.IniFilename);
9530  g.SettingsLoaded = true;
9531  }
9532 
9533  // Save settings (with a delay after the last modification, so we don't spam disk too much)
9534  if (g.SettingsDirtyTimer > 0.0f)
9535  {
9536  g.SettingsDirtyTimer -= g.IO.DeltaTime;
9537  if (g.SettingsDirtyTimer <= 0.0f)
9538  {
9539  if (g.IO.IniFilename != NULL)
9540  SaveIniSettingsToDisk(g.IO.IniFilename);
9541  else
9542  g.IO.WantSaveIniSettings = true; // Let user know they can call SaveIniSettingsToMemory(). user will need to clear io.WantSaveIniSettings themselves.
9543  g.SettingsDirtyTimer = 0.0f;
9544  }
9545  }
9546 }
9547 
9549 {
9550  ImGuiContext& g = *GImGui;
9551  if (g.SettingsDirtyTimer <= 0.0f)
9552  g.SettingsDirtyTimer = g.IO.IniSavingRate;
9553 }
9554 
9556 {
9557  ImGuiContext& g = *GImGui;
9558  if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings))
9559  if (g.SettingsDirtyTimer <= 0.0f)
9560  g.SettingsDirtyTimer = g.IO.IniSavingRate;
9561 }
9562 
9564 {
9565  ImGuiContext& g = *GImGui;
9566 
9567 #if !IMGUI_DEBUG_INI_SETTINGS
9568  // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID()
9569  // Preserve the full string when IMGUI_DEBUG_INI_SETTINGS is set to make .ini inspection easier.
9570  if (const char* p = strstr(name, "###"))
9571  name = p;
9572 #endif
9573  const size_t name_len = strlen(name);
9574 
9575  // Allocate chunk
9576  const size_t chunk_size = sizeof(ImGuiWindowSettings) + name_len + 1;
9577  ImGuiWindowSettings* settings = g.SettingsWindows.alloc_chunk(chunk_size);
9579  settings->ID = ImHashStr(name, name_len);
9580  memcpy(settings->GetName(), name, name_len + 1); // Store with zero terminator
9581 
9582  return settings;
9583 }
9584 
9586 {
9587  ImGuiContext& g = *GImGui;
9588  for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings))
9589  if (settings->ID == id)
9590  return settings;
9591  return NULL;
9592 }
9593 
9595 {
9597  return settings;
9598  return CreateNewWindowSettings(name);
9599 }
9600 
9601 void ImGui::LoadIniSettingsFromDisk(const char* ini_filename)
9602 {
9603  size_t file_data_size = 0;
9604  char* file_data = (char*)ImFileLoadToMemory(ini_filename, "rb", &file_data_size);
9605  if (!file_data)
9606  return;
9607  LoadIniSettingsFromMemory(file_data, (size_t)file_data_size);
9608  IM_FREE(file_data);
9609 }
9610 
9612 {
9613  ImGuiContext& g = *GImGui;
9614  const ImGuiID type_hash = ImHashStr(type_name);
9615  for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++)
9616  if (g.SettingsHandlers[handler_n].TypeHash == type_hash)
9617  return &g.SettingsHandlers[handler_n];
9618  return NULL;
9619 }
9620 
9621 // Zero-tolerance, no error reporting, cheap .ini parsing
9622 void ImGui::LoadIniSettingsFromMemory(const char* ini_data, size_t ini_size)
9623 {
9624  ImGuiContext& g = *GImGui;
9625  IM_ASSERT(g.Initialized);
9626  IM_ASSERT(g.SettingsLoaded == false && g.FrameCount == 0);
9627 
9628  // For user convenience, we allow passing a non zero-terminated string (hence the ini_size parameter).
9629  // For our convenience and to make the code simpler, we'll also write zero-terminators within the buffer. So let's create a writable copy..
9630  if (ini_size == 0)
9631  ini_size = strlen(ini_data);
9632  char* buf = (char*)IM_ALLOC(ini_size + 1);
9633  char* buf_end = buf + ini_size;
9634  memcpy(buf, ini_data, ini_size);
9635  buf[ini_size] = 0;
9636 
9637  void* entry_data = NULL;
9638  ImGuiSettingsHandler* entry_handler = NULL;
9639 
9640  char* line_end = NULL;
9641  for (char* line = buf; line < buf_end; line = line_end + 1)
9642  {
9643  // Skip new lines markers, then find end of the line
9644  while (*line == '\n' || *line == '\r')
9645  line++;
9646  line_end = line;
9647  while (line_end < buf_end && *line_end != '\n' && *line_end != '\r')
9648  line_end++;
9649  line_end[0] = 0;
9650  if (line[0] == ';')
9651  continue;
9652  if (line[0] == '[' && line_end > line && line_end[-1] == ']')
9653  {
9654  // Parse "[Type][Name]". Note that 'Name' can itself contains [] characters, which is acceptable with the current format and parsing code.
9655  line_end[-1] = 0;
9656  const char* name_end = line_end - 1;
9657  const char* type_start = line + 1;
9658  char* type_end = (char*)(void*)ImStrchrRange(type_start, name_end, ']');
9659  const char* name_start = type_end ? ImStrchrRange(type_end + 1, name_end, '[') : NULL;
9660  if (!type_end || !name_start)
9661  continue;
9662  *type_end = 0; // Overwrite first ']'
9663  name_start++; // Skip second '['
9664  entry_handler = FindSettingsHandler(type_start);
9665  entry_data = entry_handler ? entry_handler->ReadOpenFn(&g, entry_handler, name_start) : NULL;
9666  }
9667  else if (entry_handler != NULL && entry_data != NULL)
9668  {
9669  // Let type handler parse the line
9670  entry_handler->ReadLineFn(&g, entry_handler, entry_data, line);
9671  }
9672  }
9673  IM_FREE(buf);
9674  g.SettingsLoaded = true;
9675 }
9676 
9677 void ImGui::SaveIniSettingsToDisk(const char* ini_filename)
9678 {
9679  ImGuiContext& g = *GImGui;
9680  g.SettingsDirtyTimer = 0.0f;
9681  if (!ini_filename)
9682  return;
9683 
9684  size_t ini_data_size = 0;
9685  const char* ini_data = SaveIniSettingsToMemory(&ini_data_size);
9686  ImFileHandle f = ImFileOpen(ini_filename, "wt");
9687  if (!f)
9688  return;
9689  ImFileWrite(ini_data, sizeof(char), ini_data_size, f);
9690  ImFileClose(f);
9691 }
9692 
9693 // Call registered handlers (e.g. SettingsHandlerWindow_WriteAll() + custom handlers) to write their stuff into a text buffer
9694 const char* ImGui::SaveIniSettingsToMemory(size_t* out_size)
9695 {
9696  ImGuiContext& g = *GImGui;
9697  g.SettingsDirtyTimer = 0.0f;
9698  g.SettingsIniData.Buf.resize(0);
9699  g.SettingsIniData.Buf.push_back(0);
9700  for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++)
9701  {
9702  ImGuiSettingsHandler* handler = &g.SettingsHandlers[handler_n];
9703  handler->WriteAllFn(&g, handler, &g.SettingsIniData);
9704  }
9705  if (out_size)
9706  *out_size = (size_t)g.SettingsIniData.size();
9707  return g.SettingsIniData.c_str();
9708 }
9709 
9711 {
9713  if (!settings)
9715  return (void*)settings;
9716 }
9717 
9718 static void WindowSettingsHandler_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line)
9719 {
9720  ImGuiWindowSettings* settings = (ImGuiWindowSettings*)entry;
9721  int x, y;
9722  int i;
9723  if (sscanf(line, "Pos=%i,%i", &x, &y) == 2) settings->Pos = ImVec2ih((short)x, (short)y);
9724  else if (sscanf(line, "Size=%i,%i", &x, &y) == 2) settings->Size = ImVec2ih((short)x, (short)y);
9725  else if (sscanf(line, "Collapsed=%d", &i) == 1) settings->Collapsed = (i != 0);
9726 }
9727 
9729 {
9730  // Gather data from windows that were active during this session
9731  // (if a window wasn't opened in this session we preserve its settings)
9732  ImGuiContext& g = *ctx;
9733  for (int i = 0; i != g.Windows.Size; i++)
9734  {
9735  ImGuiWindow* window = g.Windows[i];
9737  continue;
9738 
9739  ImGuiWindowSettings* settings = (window->SettingsOffset != -1) ? g.SettingsWindows.ptr_from_offset(window->SettingsOffset) : ImGui::FindWindowSettings(window->ID);
9740  if (!settings)
9741  {
9742  settings = ImGui::CreateNewWindowSettings(window->Name);
9743  window->SettingsOffset = g.SettingsWindows.offset_from_ptr(settings);
9744  }
9745  IM_ASSERT(settings->ID == window->ID);
9746  settings->Pos = ImVec2ih((short)window->Pos.x, (short)window->Pos.y);
9747  settings->Size = ImVec2ih((short)window->SizeFull.x, (short)window->SizeFull.y);
9748  settings->Collapsed = window->Collapsed;
9749  }
9750 
9751  // Write to text buffer
9752  buf->reserve(buf->size() + g.SettingsWindows.size() * 6); // ballpark reserve
9753  for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings))
9754  {
9755  const char* settings_name = settings->GetName();
9756  buf->appendf("[%s][%s]\n", handler->TypeName, settings_name);
9757  buf->appendf("Pos=%d,%d\n", settings->Pos.x, settings->Pos.y);
9758  buf->appendf("Size=%d,%d\n", settings->Size.x, settings->Size.y);
9759  buf->appendf("Collapsed=%d\n", settings->Collapsed);
9760  buf->append("\n");
9761  }
9762 }
9763 
9764 
9765 //-----------------------------------------------------------------------------
9766 // [SECTION] VIEWPORTS, PLATFORM WINDOWS
9767 //-----------------------------------------------------------------------------
9768 
9769 // (this section is filled in the 'docking' branch)
9770 
9771 
9772 //-----------------------------------------------------------------------------
9773 // [SECTION] DOCKING
9774 //-----------------------------------------------------------------------------
9775 
9776 // (this section is filled in the 'docking' branch)
9777 
9778 
9779 //-----------------------------------------------------------------------------
9780 // [SECTION] PLATFORM DEPENDENT HELPERS
9781 //-----------------------------------------------------------------------------
9782 
9783 #if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS)
9784 
9785 #ifdef _MSC_VER
9786 #pragma comment(lib, "user32")
9787 #pragma comment(lib, "kernel32")
9788 #endif
9789 
9790 // Win32 clipboard implementation
9791 static const char* GetClipboardTextFn_DefaultImpl(void*)
9792 {
9793  static ImVector<char> buf_local;
9794  buf_local.clear();
9795  if (!::OpenClipboard(NULL))
9796  return NULL;
9797  HANDLE wbuf_handle = ::GetClipboardData(CF_UNICODETEXT);
9798  if (wbuf_handle == NULL)
9799  {
9800  ::CloseClipboard();
9801  return NULL;
9802  }
9803  if (const WCHAR* wbuf_global = (const WCHAR*)::GlobalLock(wbuf_handle))
9804  {
9805  int buf_len = ::WideCharToMultiByte(CP_UTF8, 0, wbuf_global, -1, NULL, 0, NULL, NULL);
9806  buf_local.resize(buf_len);
9807  ::WideCharToMultiByte(CP_UTF8, 0, wbuf_global, -1, buf_local.Data, buf_len, NULL, NULL);
9808  }
9809  ::GlobalUnlock(wbuf_handle);
9810  ::CloseClipboard();
9811  return buf_local.Data;
9812 }
9813 
9814 static void SetClipboardTextFn_DefaultImpl(void*, const char* text)
9815 {
9816  if (!::OpenClipboard(NULL))
9817  return;
9818  const int wbuf_length = ::MultiByteToWideChar(CP_UTF8, 0, text, -1, NULL, 0);
9819  HGLOBAL wbuf_handle = ::GlobalAlloc(GMEM_MOVEABLE, (SIZE_T)wbuf_length * sizeof(WCHAR));
9820  if (wbuf_handle == NULL)
9821  {
9822  ::CloseClipboard();
9823  return;
9824  }
9825  WCHAR* wbuf_global = (WCHAR*)::GlobalLock(wbuf_handle);
9826  ::MultiByteToWideChar(CP_UTF8, 0, text, -1, wbuf_global, wbuf_length);
9827  ::GlobalUnlock(wbuf_handle);
9828  ::EmptyClipboard();
9829  if (::SetClipboardData(CF_UNICODETEXT, wbuf_handle) == NULL)
9830  ::GlobalFree(wbuf_handle);
9831  ::CloseClipboard();
9832 }
9833 
9834 #elif defined(__APPLE__) && TARGET_OS_OSX && defined(IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS)
9835 
9836 #include <Carbon/Carbon.h> // Use old API to avoid need for separate .mm file
9837 static PasteboardRef main_clipboard = 0;
9838 
9839 // OSX clipboard implementation
9840 // If you enable this you will need to add '-framework ApplicationServices' to your linker command-line!
9841 static void SetClipboardTextFn_DefaultImpl(void*, const char* text)
9842 {
9843  if (!main_clipboard)
9844  PasteboardCreate(kPasteboardClipboard, &main_clipboard);
9845  PasteboardClear(main_clipboard);
9846  CFDataRef cf_data = CFDataCreate(kCFAllocatorDefault, (const UInt8*)text, strlen(text));
9847  if (cf_data)
9848  {
9849  PasteboardPutItemFlavor(main_clipboard, (PasteboardItemID)1, CFSTR("public.utf8-plain-text"), cf_data, 0);
9850  CFRelease(cf_data);
9851  }
9852 }
9853 
9854 static const char* GetClipboardTextFn_DefaultImpl(void*)
9855 {
9856  if (!main_clipboard)
9857  PasteboardCreate(kPasteboardClipboard, &main_clipboard);
9858  PasteboardSynchronize(main_clipboard);
9859 
9860  ItemCount item_count = 0;
9861  PasteboardGetItemCount(main_clipboard, &item_count);
9862  for (ItemCount i = 0; i < item_count; i++)
9863  {
9864  PasteboardItemID item_id = 0;
9865  PasteboardGetItemIdentifier(main_clipboard, i + 1, &item_id);
9866  CFArrayRef flavor_type_array = 0;
9867  PasteboardCopyItemFlavors(main_clipboard, item_id, &flavor_type_array);
9868  for (CFIndex j = 0, nj = CFArrayGetCount(flavor_type_array); j < nj; j++)
9869  {
9870  CFDataRef cf_data;
9871  if (PasteboardCopyItemFlavorData(main_clipboard, item_id, CFSTR("public.utf8-plain-text"), &cf_data) == noErr)
9872  {
9873  static ImVector<char> clipboard_text;
9874  int length = (int)CFDataGetLength(cf_data);
9875  clipboard_text.resize(length + 1);
9876  CFDataGetBytes(cf_data, CFRangeMake(0, length), (UInt8*)clipboard_text.Data);
9877  clipboard_text[length] = 0;
9878  CFRelease(cf_data);
9879  return clipboard_text.Data;
9880  }
9881  }
9882  }
9883  return NULL;
9884 }
9885 
9886 #else
9887 
9888 // Local Dear ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers.
9889 static const char* GetClipboardTextFn_DefaultImpl(void*)
9890 {
9891  ImGuiContext& g = *GImGui;
9892  return g.PrivateClipboard.empty() ? NULL : g.PrivateClipboard.begin();
9893 }
9894 
9895 static void SetClipboardTextFn_DefaultImpl(void*, const char* text)
9896 {
9897  ImGuiContext& g = *GImGui;
9899  const char* text_end = text + strlen(text);
9900  g.PrivateClipboard.resize((int)(text_end - text) + 1);
9901  memcpy(&g.PrivateClipboard[0], text, (size_t)(text_end - text));
9902  g.PrivateClipboard[(int)(text_end - text)] = 0;
9903 }
9904 
9905 #endif
9906 
9907 // Win32 API IME support (for Asian languages, etc.)
9908 #if defined(_WIN32) && !defined(__GNUC__) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS)
9909 
9910 #include <imm.h>
9911 #ifdef _MSC_VER
9912 #pragma comment(lib, "imm32")
9913 #endif
9914 
9915 static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y)
9916 {
9917  // Notify OS Input Method Editor of text input position
9918  ImGuiIO& io = ImGui::GetIO();
9919  if (HWND hwnd = (HWND)io.ImeWindowHandle)
9920  if (HIMC himc = ::ImmGetContext(hwnd))
9921  {
9922  COMPOSITIONFORM cf;
9923  cf.ptCurrentPos.x = x;
9924  cf.ptCurrentPos.y = y;
9925  cf.dwStyle = CFS_FORCE_POSITION;
9926  ::ImmSetCompositionWindow(himc, &cf);
9927  ::ImmReleaseContext(hwnd, himc);
9928  }
9929 }
9930 
9931 #else
9932 
9933 static void ImeSetInputScreenPosFn_DefaultImpl(int, int) {}
9934 
9935 #endif
9936 
9937 //-----------------------------------------------------------------------------
9938 // [SECTION] METRICS/DEBUG WINDOW
9939 //-----------------------------------------------------------------------------
9940 
9941 #ifndef IMGUI_DISABLE_METRICS_WINDOW
9942 // Avoid naming collision with imgui_demo.cpp's HelpMarker() for unity builds.
9943 static void MetricsHelpMarker(const char* desc)
9944 {
9945  ImGui::TextDisabled("(?)");
9946  if (ImGui::IsItemHovered())
9947  {
9953  }
9954 }
9955 
9956 void ImGui::ShowMetricsWindow(bool* p_open)
9957 {
9958  if (!ImGui::Begin("Dear ImGui Metrics", p_open))
9959  {
9960  ImGui::End();
9961  return;
9962  }
9963 
9964  // Debugging enums
9965  enum { WRT_OuterRect, WRT_OuterRectClipped, WRT_InnerRect, WRT_InnerClipRect, WRT_WorkRect, WRT_Content, WRT_ContentRegionRect, WRT_Count }; // Windows Rect Type
9966  const char* wrt_rects_names[WRT_Count] = { "OuterRect", "OuterRectClipped", "InnerRect", "InnerClipRect", "WorkRect", "Content", "ContentRegionRect" };
9967  enum { TRT_OuterRect, TRT_WorkRect, TRT_HostClipRect, TRT_InnerClipRect, TRT_BackgroundClipRect, TRT_ColumnsRect, TRT_ColumnsClipRect, TRT_ColumnsContentHeadersUsed, TRT_ColumnsContentHeadersDesired, TRT_ColumnsContentRowsFrozen, TRT_ColumnsContentRowsUnfrozen, TRT_Count }; // Tables Rect Type
9968  const char* trt_rects_names[TRT_Count] = { "OuterRect", "WorkRect", "HostClipRect", "InnerClipRect", "BackgroundClipRect", "ColumnsRect", "ColumnsClipRect", "ColumnsContentHeadersUsed", "ColumnsContentHeadersDesired", "ColumnsContentRowsFrozen", "ColumnsContentRowsUnfrozen" };
9969 
9970  // State
9971  static bool show_windows_rects = false;
9972  static int show_windows_rect_type = WRT_WorkRect;
9973  static bool show_windows_begin_order = false;
9974  static bool show_tables_rects = false;
9975  static int show_tables_rect_type = TRT_WorkRect;
9976  static bool show_drawcmd_details = true;
9977 
9978  // Basic info
9979  ImGuiContext& g = *GImGui;
9980  ImGuiIO& io = ImGui::GetIO();
9981  ImGui::Text("Dear ImGui %s", ImGui::GetVersion());
9982  ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
9983  ImGui::Text("%d vertices, %d indices (%d triangles)", io.MetricsRenderVertices, io.MetricsRenderIndices, io.MetricsRenderIndices / 3);
9984  ImGui::Text("%d active windows (%d visible)", io.MetricsActiveWindows, io.MetricsRenderWindows);
9985  ImGui::Text("%d active allocations", io.MetricsActiveAllocations);
9986  ImGui::Separator();
9987 
9988  // Helper functions to display common structures:
9989  // - NodeDrawList()
9990  // - NodeColumns()
9991  // - NodeWindow()
9992  // - NodeWindows()
9993  // - NodeTabBar()
9994  // - NodeStorage()
9995  struct Funcs
9996  {
9997  static ImRect GetWindowRect(ImGuiWindow* window, int rect_type)
9998  {
9999  if (rect_type == WRT_OuterRect) { return window->Rect(); }
10000  else if (rect_type == WRT_OuterRectClipped) { return window->OuterRectClipped; }
10001  else if (rect_type == WRT_InnerRect) { return window->InnerRect; }
10002  else if (rect_type == WRT_InnerClipRect) { return window->InnerClipRect; }
10003  else if (rect_type == WRT_WorkRect) { return window->WorkRect; }
10004  else if (rect_type == WRT_Content) { ImVec2 min = window->InnerRect.Min - window->Scroll + window->WindowPadding; return ImRect(min, min + window->ContentSize); }
10005  else if (rect_type == WRT_ContentRegionRect) { return window->ContentRegionRect; }
10006  IM_ASSERT(0);
10007  return ImRect();
10008  }
10009 
10010  static void NodeDrawList(ImGuiWindow* window, ImDrawList* draw_list, const char* label)
10011  {
10012  bool node_open = ImGui::TreeNode(draw_list, "%s: '%s' %d vtx, %d indices, %d cmds", label, draw_list->_OwnerName ? draw_list->_OwnerName : "", draw_list->VtxBuffer.Size, draw_list->IdxBuffer.Size, draw_list->CmdBuffer.Size);
10013  if (draw_list == ImGui::GetWindowDrawList())
10014  {
10015  ImGui::SameLine();
10016  ImGui::TextColored(ImVec4(1.0f,0.4f,0.4f,1.0f), "CURRENTLY APPENDING"); // Can't display stats for active draw list! (we don't have the data double-buffered)
10017  if (node_open) ImGui::TreePop();
10018  return;
10019  }
10020 
10021  ImDrawList* fg_draw_list = GetForegroundDrawList(window); // Render additional visuals into the top-most draw list
10022  if (window && IsItemHovered())
10023  fg_draw_list->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255));
10024  if (!node_open)
10025  return;
10026 
10027  if (window && !window->WasActive)
10028  ImGui::TextDisabled("Warning: owning Window is inactive. This DrawList is not being rendered!");
10029 
10030  unsigned int elem_offset = 0;
10031  for (const ImDrawCmd* pcmd = draw_list->CmdBuffer.begin(); pcmd < draw_list->CmdBuffer.end(); elem_offset += pcmd->ElemCount, pcmd++)
10032  {
10033  if (pcmd->UserCallback == NULL && pcmd->ElemCount == 0)
10034  continue;
10035  if (pcmd->UserCallback)
10036  {
10037  ImGui::BulletText("Callback %p, user_data %p", pcmd->UserCallback, pcmd->UserCallbackData);
10038  continue;
10039  }
10040 
10041  ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL;
10042  char buf[300];
10043  ImFormatString(buf, IM_ARRAYSIZE(buf), "DrawCmd: %4d triangles, Tex 0x%p, ClipRect (%4.0f,%4.0f)-(%4.0f,%4.0f)",
10044  pcmd->ElemCount/3, (void*)(intptr_t)pcmd->TextureId,
10045  pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w);
10046  bool pcmd_node_open = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "%s", buf);
10047  if (show_drawcmd_details && fg_draw_list && ImGui::IsItemHovered())
10048  {
10049  ImRect clip_rect = pcmd->ClipRect;
10050  ImRect vtxs_rect(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX);
10051  for (unsigned int i = elem_offset; i < elem_offset + (int)pcmd->ElemCount; i++)
10052  vtxs_rect.Add(draw_list->VtxBuffer[idx_buffer ? idx_buffer[i] : i].pos);
10053  fg_draw_list->AddRect(ImFloor(clip_rect.Min), ImFloor(clip_rect.Max), IM_COL32(255,0,255,255));
10054  fg_draw_list->AddRect(ImFloor(vtxs_rect.Min), ImFloor(vtxs_rect.Max), IM_COL32(255,255,0,255));
10055  }
10056  if (!pcmd_node_open)
10057  continue;
10058 
10059  // Calculate approximate coverage area (touched pixel count)
10060  // This will be in pixels squared as long there's no post-scaling happening to the renderer output.
10061  float total_area = 0.0f;
10062  for (unsigned int base_idx = elem_offset; base_idx < (elem_offset + pcmd->ElemCount); base_idx += 3)
10063  {
10064  ImVec2 triangle[3];
10065  for (int n = 0; n < 3; n++)
10066  triangle[n] = draw_list->VtxBuffer[idx_buffer ? idx_buffer[base_idx + n] : (base_idx + n)].pos;
10067  total_area += ImTriangleArea(triangle[0], triangle[1], triangle[2]);
10068  }
10069 
10070  // Display vertex information summary. Hover to get all triangles drawn in wire-frame
10071  ImFormatString(buf, IM_ARRAYSIZE(buf), "Mesh: ElemCount: %d, VtxOffset: +%d, IdxOffset: +%d, Area: ~%0.f px", pcmd->ElemCount, pcmd->VtxOffset, pcmd->IdxOffset, total_area);
10073  if (fg_draw_list && ImGui::IsItemHovered() && show_drawcmd_details)
10074  {
10075  // Draw wire-frame version of everything
10076  ImDrawListFlags backup_flags = fg_draw_list->Flags;
10077  fg_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines is more readable for very large and thin triangles.
10078  ImRect clip_rect = pcmd->ClipRect;
10079  fg_draw_list->AddRect(ImFloor(clip_rect.Min), ImFloor(clip_rect.Max), IM_COL32(255, 0, 255, 255));
10080  for (unsigned int base_idx = elem_offset; base_idx < (elem_offset + pcmd->ElemCount); base_idx += 3)
10081  {
10082  ImVec2 triangle[3];
10083  for (int n = 0; n < 3; n++)
10084  triangle[n] = draw_list->VtxBuffer[idx_buffer ? idx_buffer[base_idx + n] : (base_idx + n)].pos;
10085  fg_draw_list->AddPolyline(triangle, 3, IM_COL32(255, 255, 0, 255), true, 1.0f);
10086  }
10087  fg_draw_list->Flags = backup_flags;
10088  }
10089 
10090  // Display individual triangles/vertices. Hover on to get the corresponding triangle highlighted.
10091  ImGuiListClipper clipper(pcmd->ElemCount/3); // Manually coarse clip our print out of individual vertices to save CPU, only items that may be visible.
10092  while (clipper.Step())
10093  for (int prim = clipper.DisplayStart, idx_i = elem_offset + clipper.DisplayStart*3; prim < clipper.DisplayEnd; prim++)
10094  {
10095  char *buf_p = buf, *buf_end = buf + IM_ARRAYSIZE(buf);
10096  ImVec2 triangle[3];
10097  for (int n = 0; n < 3; n++, idx_i++)
10098  {
10099  ImDrawVert& v = draw_list->VtxBuffer[idx_buffer ? idx_buffer[idx_i] : idx_i];
10100  triangle[n] = v.pos;
10101  buf_p += ImFormatString(buf_p, buf_end - buf_p, "%s %04d: pos (%8.2f,%8.2f), uv (%.6f,%.6f), col %08X\n",
10102  (n == 0) ? "Vert:" : " ", idx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col);
10103  }
10104 
10105  ImGui::Selectable(buf, false);
10106  if (fg_draw_list && ImGui::IsItemHovered())
10107  {
10108  ImDrawListFlags backup_flags = fg_draw_list->Flags;
10109  fg_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines is more readable for very large and thin triangles.
10110  fg_draw_list->AddPolyline(triangle, 3, IM_COL32(255,255,0,255), true, 1.0f);
10111  fg_draw_list->Flags = backup_flags;
10112  }
10113  }
10114  ImGui::TreePop();
10115  }
10116  ImGui::TreePop();
10117  }
10118 
10119  static void NodeColumns(const ImGuiColumns* columns)
10120  {
10121  if (!ImGui::TreeNode((void*)(uintptr_t)columns->ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns->ID, columns->Count, columns->Flags))
10122  return;
10123  ImGui::BulletText("Width: %.1f (MinX: %.1f, MaxX: %.1f)", columns->OffMaxX - columns->OffMinX, columns->OffMinX, columns->OffMaxX);
10124  for (int column_n = 0; column_n < columns->Columns.Size; column_n++)
10125  ImGui::BulletText("Column %02d: OffsetNorm %.3f (= %.1f px)", column_n, columns->Columns[column_n].OffsetNorm, GetColumnOffsetFromNorm(columns, columns->Columns[column_n].OffsetNorm));
10126  ImGui::TreePop();
10127  }
10128 
10129  static void NodeWindows(ImVector<ImGuiWindow*>& windows, const char* label)
10130  {
10131  if (!ImGui::TreeNode(label, "%s (%d)", label, windows.Size))
10132  return;
10133  for (int i = 0; i < windows.Size; i++)
10134  {
10135  ImGui::PushID(windows[i]);
10136  Funcs::NodeWindow(windows[i], "Window");
10137  ImGui::PopID();
10138  }
10139  ImGui::TreePop();
10140  }
10141 
10142  static void NodeWindow(ImGuiWindow* window, const char* label)
10143  {
10144  if (window == NULL)
10145  {
10146  ImGui::BulletText("%s: NULL", label);
10147  return;
10148  }
10149  bool open = ImGui::TreeNode(label, "%s '%s', %d @ 0x%p", label, window->Name, (window->Active || window->WasActive), window);
10150  if (ImGui::IsItemHovered() && window->WasActive)
10151  ImGui::GetForegroundDrawList()->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255));
10152  if (!open)
10153  return;
10154  ImGuiWindowFlags flags = window->Flags;
10155  NodeDrawList(window, window->DrawList, "DrawList");
10156  ImGui::BulletText("Pos: (%.1f,%.1f), Size: (%.1f,%.1f), ContentSize (%.1f,%.1f)", window->Pos.x, window->Pos.y, window->Size.x, window->Size.y, window->ContentSize.x, window->ContentSize.y);
10157  ImGui::BulletText("Flags: 0x%08X (%s%s%s%s%s%s%s%s%s..)", flags,
10158  (flags & ImGuiWindowFlags_ChildWindow) ? "Child " : "", (flags & ImGuiWindowFlags_Tooltip) ? "Tooltip " : "", (flags & ImGuiWindowFlags_Popup) ? "Popup " : "",
10159  (flags & ImGuiWindowFlags_Modal) ? "Modal " : "", (flags & ImGuiWindowFlags_ChildMenu) ? "ChildMenu " : "", (flags & ImGuiWindowFlags_NoSavedSettings) ? "NoSavedSettings " : "",
10160  (flags & ImGuiWindowFlags_NoMouseInputs)? "NoMouseInputs":"", (flags & ImGuiWindowFlags_NoNavInputs) ? "NoNavInputs" : "", (flags & ImGuiWindowFlags_AlwaysAutoResize) ? "AlwaysAutoResize" : "");
10161  ImGui::BulletText("Scroll: (%.2f/%.2f,%.2f/%.2f) Scrollbar:%s%s", window->Scroll.x, window->ScrollMax.x, window->Scroll.y, window->ScrollMax.y, window->ScrollbarX ? "X" : "", window->ScrollbarY ? "Y" : "");
10162  ImGui::BulletText("Active: %d/%d, WriteAccessed: %d, BeginOrderWithinContext: %d", window->Active, window->WasActive, window->WriteAccessed, (window->Active || window->WasActive) ? window->BeginOrderWithinContext : -1);
10163  ImGui::BulletText("Appearing: %d, Hidden: %d (CanSkip %d Cannot %d), SkipItems: %d", window->Appearing, window->Hidden, window->HiddenFramesCanSkipItems, window->HiddenFramesCannotSkipItems, window->SkipItems);
10164  ImGui::BulletText("NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X", window->NavLastIds[0], window->NavLastIds[1], window->DC.NavLayerActiveMask);
10165  ImGui::BulletText("NavLastChildNavWindow: %s", window->NavLastChildNavWindow ? window->NavLastChildNavWindow->Name : "NULL");
10166  if (!window->NavRectRel[0].IsInverted())
10167  ImGui::BulletText("NavRectRel[0]: (%.1f,%.1f)(%.1f,%.1f)", window->NavRectRel[0].Min.x, window->NavRectRel[0].Min.y, window->NavRectRel[0].Max.x, window->NavRectRel[0].Max.y);
10168  else
10169  ImGui::BulletText("NavRectRel[0]: <None>");
10170  if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow");
10171  if (window->ParentWindow != NULL) NodeWindow(window->ParentWindow, "ParentWindow");
10172  if (window->DC.ChildWindows.Size > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows");
10173  if (window->ColumnsStorage.Size > 0 && ImGui::TreeNode("Columns", "Columns sets (%d)", window->ColumnsStorage.Size))
10174  {
10175  for (int n = 0; n < window->ColumnsStorage.Size; n++)
10176  NodeColumns(&window->ColumnsStorage[n]);
10177  ImGui::TreePop();
10178  }
10179  NodeStorage(&window->StateStorage, "Storage");
10180  ImGui::TreePop();
10181  }
10182 
10183  static void NodeTabBar(ImGuiTabBar* tab_bar)
10184  {
10185  // Standalone tab bars (not associated to docking/windows functionality) currently hold no discernible strings.
10186  char buf[256];
10187  char* p = buf;
10188  const char* buf_end = buf + IM_ARRAYSIZE(buf);
10189  p += ImFormatString(p, buf_end - p, "TabBar (%d tabs)%s", tab_bar->Tabs.Size, (tab_bar->PrevFrameVisible < ImGui::GetFrameCount() - 2) ? " *Inactive*" : "");
10190  if (ImGui::TreeNode(tab_bar, "%s", buf))
10191  {
10192  for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++)
10193  {
10194  const ImGuiTabItem* tab = &tab_bar->Tabs[tab_n];
10195  ImGui::PushID(tab);
10196  if (ImGui::SmallButton("<")) { TabBarQueueChangeTabOrder(tab_bar, tab, -1); } ImGui::SameLine(0, 2);
10197  if (ImGui::SmallButton(">")) { TabBarQueueChangeTabOrder(tab_bar, tab, +1); } ImGui::SameLine();
10198  ImGui::Text("%02d%c Tab 0x%08X '%s'", tab_n, (tab->ID == tab_bar->SelectedTabId) ? '*' : ' ', tab->ID, (tab->NameOffset != -1) ? tab_bar->GetTabName(tab) : "");
10199  ImGui::PopID();
10200  }
10201  ImGui::TreePop();
10202  }
10203  }
10204 
10205  static void NodeStorage(ImGuiStorage* storage, const char* label)
10206  {
10207  if (!ImGui::TreeNode(label, "%s: %d entries, %d bytes", label, storage->Data.Size, storage->Data.size_in_bytes()))
10208  return;
10209  for (int n = 0; n < storage->Data.Size; n++)
10210  {
10211  const ImGuiStorage::ImGuiStoragePair& p = storage->Data[n];
10212  ImGui::BulletText("Key 0x%08X Value { i: %d }", p.key, p.val_i); // Important: we currently don't store a type, real value may not be integer.
10213  }
10214  ImGui::TreePop();
10215  }
10216  };
10217 
10218  Funcs::NodeWindows(g.Windows, "Windows");
10219  //Funcs::NodeWindows(g.WindowsFocusOrder, "WindowsFocusOrder");
10220  if (ImGui::TreeNode("DrawLists", "Active DrawLists (%d)", g.DrawDataBuilder.Layers[0].Size))
10221  {
10222  for (int i = 0; i < g.DrawDataBuilder.Layers[0].Size; i++)
10223  Funcs::NodeDrawList(NULL, g.DrawDataBuilder.Layers[0][i], "DrawList");
10224  ImGui::TreePop();
10225  }
10226 
10227  // Details for Popups
10228  if (ImGui::TreeNode("Popups", "Popups (%d)", g.OpenPopupStack.Size))
10229  {
10230  for (int i = 0; i < g.OpenPopupStack.Size; i++)
10231  {
10232  ImGuiWindow* window = g.OpenPopupStack[i].Window;
10233  ImGui::BulletText("PopupID: %08x, Window: '%s'%s%s", g.OpenPopupStack[i].PopupId, window ? window->Name : "NULL", window && (window->Flags & ImGuiWindowFlags_ChildWindow) ? " ChildWindow" : "", window && (window->Flags & ImGuiWindowFlags_ChildMenu) ? " ChildMenu" : "");
10234  }
10235  ImGui::TreePop();
10236  }
10237 
10238  // Details for TabBars
10239  if (ImGui::TreeNode("TabBars", "Tab Bars (%d)", g.TabBars.GetSize()))
10240  {
10241  for (int n = 0; n < g.TabBars.GetSize(); n++)
10242  Funcs::NodeTabBar(g.TabBars.GetByIndex(n));
10243  ImGui::TreePop();
10244  }
10245 
10246  // Details for Tables
10247  IM_UNUSED(trt_rects_names);
10248  IM_UNUSED(show_tables_rects);
10249  IM_UNUSED(show_tables_rect_type);
10250 #ifdef IMGUI_HAS_TABLE
10251  if (ImGui::TreeNode("Tables", "Tables (%d)", g.Tables.GetSize()))
10252  {
10253  for (int n = 0; n < g.Tables.GetSize(); n++)
10254  Funcs::NodeTable(g.Tables.GetByIndex(n));
10255  ImGui::TreePop();
10256  }
10257 #endif // #define IMGUI_HAS_TABLE
10258 
10259  // Details for Docking
10260 #ifdef IMGUI_HAS_DOCK
10261  if (ImGui::TreeNode("Docking"))
10262  {
10263  ImGui::TreePop();
10264  }
10265 #endif // #define IMGUI_HAS_DOCK
10266 
10267  // Misc Details
10268  if (ImGui::TreeNode("Internal state"))
10269  {
10270  const char* input_source_names[] = { "None", "Mouse", "Nav", "NavKeyboard", "NavGamepad" }; IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT);
10271  ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL");
10272  ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL");
10273  ImGui::Text("HoveredId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d", g.HoveredId, g.HoveredIdPreviousFrame, g.HoveredIdTimer, g.HoveredIdAllowOverlap); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not
10274  ImGui::Text("ActiveId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d, Source: %s", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer, g.ActiveIdAllowOverlap, input_source_names[g.ActiveIdSource]);
10275  ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL");
10276  ImGui::Text("MovingWindow: '%s'", g.MovingWindow ? g.MovingWindow->Name : "NULL");
10277  ImGui::Text("NavWindow: '%s'", g.NavWindow ? g.NavWindow->Name : "NULL");
10278  ImGui::Text("NavId: 0x%08X, NavLayer: %d", g.NavId, g.NavLayer);
10279  ImGui::Text("NavInputSource: %s", input_source_names[g.NavInputSource]);
10280  ImGui::Text("NavActive: %d, NavVisible: %d", g.IO.NavActive, g.IO.NavVisible);
10281  ImGui::Text("NavActivateId: 0x%08X, NavInputId: 0x%08X", g.NavActivateId, g.NavInputId);
10282  ImGui::Text("NavDisableHighlight: %d, NavDisableMouseHover: %d", g.NavDisableHighlight, g.NavDisableMouseHover);
10283  ImGui::Text("NavWindowingTarget: '%s'", g.NavWindowingTarget ? g.NavWindowingTarget->Name : "NULL");
10284  ImGui::Text("DragDrop: %d, SourceId = 0x%08X, Payload \"%s\" (%d bytes)", g.DragDropActive, g.DragDropPayload.SourceId, g.DragDropPayload.DataType, g.DragDropPayload.DataSize);
10285  ImGui::TreePop();
10286  }
10287 
10288  // Tools
10289  if (ImGui::TreeNode("Tools"))
10290  {
10291  // The Item Picker tool is super useful to visually select an item and break into the call-stack of where it was submitted.
10292  if (ImGui::Button("Item Picker.."))
10294  ImGui::SameLine();
10295  MetricsHelpMarker("Will call the IM_DEBUG_BREAK() macro to break in debugger.\nWarning: If you don't have a debugger attached, this will probably crash.");
10296 
10297  ImGui::Checkbox("Show windows begin order", &show_windows_begin_order);
10298  ImGui::Checkbox("Show windows rectangles", &show_windows_rects);
10299  ImGui::SameLine();
10301  show_windows_rects |= ImGui::Combo("##show_windows_rect_type", &show_windows_rect_type, wrt_rects_names, WRT_Count, WRT_Count);
10302  if (show_windows_rects && g.NavWindow)
10303  {
10304  ImGui::BulletText("'%s':", g.NavWindow->Name);
10305  ImGui::Indent();
10306  for (int rect_n = 0; rect_n < WRT_Count; rect_n++)
10307  {
10308  ImRect r = Funcs::GetWindowRect(g.NavWindow, rect_n);
10309  ImGui::Text("(%6.1f,%6.1f) (%6.1f,%6.1f) Size (%6.1f,%6.1f) %s", r.Min.x, r.Min.y, r.Max.x, r.Max.y, r.GetWidth(), r.GetHeight(), wrt_rects_names[rect_n]);
10310  }
10311  ImGui::Unindent();
10312  }
10313  ImGui::Checkbox("Show details when hovering ImDrawCmd node", &show_drawcmd_details);
10314  ImGui::TreePop();
10315  }
10316 
10317  // Overlay: Display windows Rectangles and Begin Order
10318  if (show_windows_rects || show_windows_begin_order)
10319  {
10320  for (int n = 0; n < g.Windows.Size; n++)
10321  {
10322  ImGuiWindow* window = g.Windows[n];
10323  if (!window->WasActive)
10324  continue;
10325  ImDrawList* draw_list = GetForegroundDrawList(window);
10326  if (show_windows_rects)
10327  {
10328  ImRect r = Funcs::GetWindowRect(window, show_windows_rect_type);
10329  draw_list->AddRect(r.Min, r.Max, IM_COL32(255, 0, 128, 255));
10330  }
10331  if (show_windows_begin_order && !(window->Flags & ImGuiWindowFlags_ChildWindow))
10332  {
10333  char buf[32];
10335  float font_size = ImGui::GetFontSize();
10336  draw_list->AddRectFilled(window->Pos, window->Pos + ImVec2(font_size, font_size), IM_COL32(200, 100, 100, 255));
10337  draw_list->AddText(window->Pos, IM_COL32(255, 255, 255, 255), buf);
10338  }
10339  }
10340  }
10341 
10342 #ifdef IMGUI_HAS_TABLE
10343  // Overlay: Display Tables Rectangles
10344  if (show_tables_rects)
10345  {
10346  for (int table_n = 0; table_n < g.Tables.GetSize(); table_n++)
10347  {
10348  ImGuiTable* table = g.Tables.GetByIndex(table_n);
10349  }
10350  }
10351 #endif // #define IMGUI_HAS_TABLE
10352 
10353 #ifdef IMGUI_HAS_DOCK
10354  // Overlay: Display Docking info
10355  if (show_docking_nodes && g.IO.KeyCtrl)
10356  {
10357  }
10358 #endif // #define IMGUI_HAS_DOCK
10359 
10360  ImGui::End();
10361 }
10362 
10363 #else
10364 
10365 void ImGui::ShowMetricsWindow(bool*) { }
10366 
10367 #endif
10368 
10369 //-----------------------------------------------------------------------------
10370 
10371 // Include imgui_user.inl at the end of imgui.cpp to access private data/functions that aren't exposed.
10372 // Prefer just including imgui_internal.h from your code rather than using this define. If a declaration is missing from imgui_internal.h add it or request it on the github.
10373 #ifdef IMGUI_INCLUDE_IMGUI_USER_INL
10374 #include "imgui_user.inl"
10375 #endif
10376 
10377 //-----------------------------------------------------------------------------
10378 
10379 #endif // #ifndef IMGUI_DISABLE
ImWchar16
unsigned short ImWchar16
Definition: imgui.h:180
MetricsHelpMarker
static void MetricsHelpMarker(const char *desc)
Definition: imgui.cpp:9943
ImGuiIO::KeyMap
int KeyMap[ImGuiKey_COUNT]
Definition: imgui.h:1430
IMGUI_CDECL
#define IMGUI_CDECL
Definition: imgui_internal.h:192
ImGuiCol_DragDropTarget
@ ImGuiCol_DragDropTarget
Definition: imgui.h:1129
ImGuiGroupData::BackupCurrLineTextBaseOffset
float BackupCurrLineTextBaseOffset
Definition: imgui_internal.h:751
ImGui::GetCursorStartPos
IMGUI_API ImVec2 GetCursorStartPos()
Definition: imgui.cpp:7000
ImGuiMouseCursor_ResizeEW
@ ImGuiMouseCursor_ResizeEW
Definition: imgui.h:1249
ImGui::LogButtons
IMGUI_API void LogButtons()
Definition: imgui.cpp:9489
ImGui::ClosePopupToLevel
IMGUI_API void ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup)
Definition: imgui.cpp:7609
ImGui::NavUpdateWindowing
static void NavUpdateWindowing()
Definition: imgui.cpp:8824
ImGuiAxis_Y
@ ImGuiAxis_Y
Definition: imgui_internal.h:586
ImGui::GetTopMostPopupModal
IMGUI_API ImGuiWindow * GetTopMostPopupModal()
Definition: imgui.cpp:7509
ImGuiDataType_Float
@ ImGuiDataType_Float
Definition: imgui.h:968
ImGui::CalcWindowExpectedSize
IMGUI_API ImVec2 CalcWindowExpectedSize(ImGuiWindow *window)
Definition: imgui.cpp:4969
ImGui::LoadIniSettingsFromDisk
IMGUI_API void LoadIniSettingsFromDisk(const char *ini_filename)
Definition: imgui.cpp:9601
ImGuiCond_Once
@ ImGuiCond_Once
Definition: imgui.h:1268
ImGuiNextWindowDataFlags_HasSizeConstraint
@ ImGuiNextWindowDataFlags_HasSizeConstraint
Definition: imgui_internal.h:949
table
upb_strtable table
Definition: php/ext/google/protobuf/protobuf.h:1065
ImStrSkipBlank
const char * ImStrSkipBlank(const char *str)
Definition: imgui.cpp:1412
SetupDrawData
static void SetupDrawData(ImVector< ImDrawList * > *draw_lists, ImDrawData *draw_data)
Definition: imgui.cpp:4110
ImGuiWindow::WasActive
bool WasActive
Definition: imgui_internal.h:1479
ImIsPowerOfTwo
static bool ImIsPowerOfTwo(int v)
Definition: imgui_internal.h:225
ImDrawList::_IdxWritePtr
ImDrawIdx * _IdxWritePtr
Definition: imgui.h:1975
ImGuiLogType_Clipboard
@ ImGuiLogType_Clipboard
Definition: imgui_internal.h:578
ImGuiIO::KeysDownDuration
float KeysDownDuration[512]
Definition: imgui.h:1538
ImVector::begin
T * begin()
Definition: imgui.h:1326
ImGuiNavMoveFlags
int ImGuiNavMoveFlags
Definition: imgui_internal.h:110
ImGuiWindow::WindowRounding
float WindowRounding
Definition: imgui_internal.h:1467
ImGui::UpdateTabFocus
static void UpdateTabFocus()
Definition: imgui.cpp:3585
ImGuiLogType
ImGuiLogType
Definition: imgui_internal.h:572
ImGuiDragDropFlags
int ImGuiDragDropFlags
Definition: imgui.h:159
ImGuiWindow::GetIDFromRectangle
ImGuiID GetIDFromRectangle(const ImRect &r_abs)
Definition: imgui.cpp:2922
ImGui::CaptureKeyboardFromApp
IMGUI_API void CaptureKeyboardFromApp(bool want_capture_keyboard_value=true)
Definition: imgui.cpp:4553
ImDrawData::FramebufferScale
ImVec2 FramebufferScale
Definition: imgui.h:2077
ImGuiCol_TextDisabled
@ ImGuiCol_TextDisabled
Definition: imgui.h:1087
ImGuiContext::NavMoveRequest
bool NavMoveRequest
Definition: imgui_internal.h:1117
ImGuiWindow::ResizeBorderHeld
signed char ResizeBorderHeld
Definition: imgui_internal.h:1488
ImGui::PopButtonRepeat
IMGUI_API void PopButtonRepeat()
Definition: imgui.cpp:6217
ImGui::PushItemWidth
IMGUI_API void PushItemWidth(float item_width)
Definition: imgui.cpp:7030
ImGui::PopFocusScope
IMGUI_API void PopFocusScope()
Definition: imgui.cpp:6572
ImGui::EndDragDropSource
IMGUI_API void EndDragDropSource()
Definition: imgui.cpp:9127
ImGuiCol_TitleBgActive
@ ImGuiCol_TitleBgActive
Definition: imgui.h:1097
ImGui::SetNextWindowSizeConstraints
IMGUI_API void SetNextWindowSizeConstraints(const ImVec2 &size_min, const ImVec2 &size_max, ImGuiSizeCallback custom_callback=NULL, void *custom_callback_data=NULL)
Definition: imgui.cpp:6489
ImGuiNavMoveResult::RectRel
ImRect RectRel
Definition: imgui_internal.h:936
ImGuiColumns::OffMinX
float OffMinX
Definition: imgui_internal.h:863
ImGui::BeginPopup
IMGUI_API bool BeginPopup(const char *str_id, ImGuiWindowFlags flags=0)
Definition: imgui.cpp:7687
name
GLuint const GLchar * name
Definition: glcorearb.h:3055
ImGui::TextColored
IMGUI_API void TextColored(const ImVec4 &col, const char *fmt,...) IM_FMTARGS(2)
Definition: imgui_widgets.cpp:266
ImRect::ClipWithFull
void ClipWithFull(const ImRect &r)
Definition: imgui_internal.h:713
ImGuiWindow::BeginCount
short BeginCount
Definition: imgui_internal.h:1489
ImGuiDir_None
@ ImGuiDir_None
Definition: imgui.h:976
LowerBound
static ImGuiStorage::ImGuiStoragePair * LowerBound(ImVector< ImGuiStorage::ImGuiStoragePair > &data, ImGuiID key)
Definition: imgui.cpp:1886
ImGui::BeginPopupContextWindow
IMGUI_API bool BeginPopupContextWindow(const char *str_id=NULL, ImGuiMouseButton mouse_button=1, bool also_over_items=true)
Definition: imgui.cpp:7775
ImGui::BeginPopupContextVoid
IMGUI_API bool BeginPopupContextVoid(const char *str_id=NULL, ImGuiMouseButton mouse_button=1)
Definition: imgui.cpp:7786
ImGuiContext::FontSize
float FontSize
Definition: imgui_internal.h:1025
ImGuiWindow::WindowPadding
ImVec2 WindowPadding
Definition: imgui_internal.h:1466
ImVec2ih
Definition: imgui_internal.h:674
ImStrchrRange
const char * ImStrchrRange(const char *str, const char *str_end, char c)
Definition: imgui.cpp:1346
ImGuiNavMoveResult
Definition: imgui_internal.h:928
ImGui::PushItemFlag
IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled)
Definition: imgui.cpp:6184
ImGui::IsWindowFocused
IMGUI_API bool IsWindowFocused(ImGuiFocusedFlags flags=0)
Definition: imgui.cpp:6290
ImDrawIdx
unsigned short ImDrawIdx
Definition: imgui.h:1888
ImGui::GetFontTexUvWhitePixel
IMGUI_API ImVec2 GetFontTexUvWhitePixel()
Definition: imgui.cpp:6545
ImGuiItemFlags_Disabled
@ ImGuiItemFlags_Disabled
Definition: imgui_internal.h:523
ImDrawDataBuilder::FlattenIntoSingleLayer
IMGUI_API void FlattenIntoSingleLayer()
Definition: imgui.cpp:4092
ImGuiStyleMod::VarIdx
ImGuiStyleVar VarIdx
Definition: imgui_internal.h:736
ImGuiResizeGripDef::AngleMax12
int AngleMax12
Definition: imgui.cpp:5004
GImAllocatorAllocFunc
static void *(* GImAllocatorAllocFunc)(size_t size, void *user_data)
Definition: imgui.cpp:989
ImGuiListClipper
Definition: imgui.h:1785
ImGuiWindowFlags_NoScrollbar
@ ImGuiWindowFlags_NoScrollbar
Definition: imgui.h:772
ImGui::IsWindowAppearing
IMGUI_API bool IsWindowAppearing()
Definition: imgui.cpp:6440
ImGui::CollapseButton
IMGUI_API bool CollapseButton(ImGuiID id, const ImVec2 &pos)
Definition: imgui_widgets.cpp:785
ImGuiWindowTempData::CurrentColumns
ImGuiColumns * CurrentColumns
Definition: imgui_internal.h:1402
ImGui::GetScrollY
IMGUI_API float GetScrollY()
Definition: imgui.cpp:7335
ImGui::SetCurrentFont
IMGUI_API void SetCurrentFont(ImFont *font)
Definition: imgui.cpp:6151
ImGuiNavDirSourceFlags_PadLStick
@ ImGuiNavDirSourceFlags_PadLStick
Definition: imgui_internal.h:630
ImGuiTabBar::SelectedTabId
ImGuiID SelectedTabId
Definition: imgui_internal.h:1612
ImGui::IsWindowHovered
IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags=0)
Definition: imgui.cpp:6249
ImBezierCalc
ImVec2 ImBezierCalc(const ImVec2 &p1, const ImVec2 &p2, const ImVec2 &p3, const ImVec2 &p4, float t)
Definition: imgui_draw.cpp:935
ImGuiWindowTempData::GroupOffset
ImVec1 GroupOffset
Definition: imgui_internal.h:1377
ImGuiKey
int ImGuiKey
Definition: imgui.h:147
ImGui::GetDragDropPayload
const IMGUI_API ImGuiPayload * GetDragDropPayload()
Definition: imgui.cpp:9287
ImGui::UpdateMouseMovingWindowNewFrame
IMGUI_API void UpdateMouseMovingWindowNewFrame()
Definition: imgui.cpp:3347
K
#define K(t)
Definition: sha1.c:43
ImGui::SetCursorPosX
IMGUI_API void SetCursorPosX(float local_x)
Definition: imgui.cpp:6986
IM_COL32_R_SHIFT
#define IM_COL32_R_SHIFT
Definition: imgui.h:1814
ImGui::ColorConvertRGBtoHSV
IMGUI_API void ColorConvertRGBtoHSV(float r, float g, float b, float &out_h, float &out_s, float &out_v)
Definition: imgui.cpp:1831
ImGuiInputSource_Mouse
@ ImGuiInputSource_Mouse
Definition: imgui_internal.h:598
ImGuiStyle::MouseCursorScale
float MouseCursorScale
Definition: imgui.h:1397
ImDrawData::DisplayPos
ImVec2 DisplayPos
Definition: imgui.h:2075
ImGuiIO::Fonts
ImFontAtlas * Fonts
Definition: imgui.h:1435
ImGuiDir
int ImGuiDir
Definition: imgui.h:146
NavUpdateWindowingHighlightWindow
static void NavUpdateWindowingHighlightWindow(int focus_change_dir)
Definition: imgui.cpp:8805
ImGuiNextItemData::Flags
ImGuiNextItemDataFlags Flags
Definition: imgui_internal.h:985
ImGuiWindow::MenuBarRect
ImRect MenuBarRect() const
Definition: imgui_internal.h:1558
GetMergedKeyModFlags
static ImGuiKeyModFlags GetMergedKeyModFlags()
Definition: imgui.cpp:3680
ImGuiContext::ActiveIdIsJustActivated
bool ActiveIdIsJustActivated
Definition: imgui_internal.h:1060
ImDrawList::IdxBuffer
ImVector< ImDrawIdx > IdxBuffer
Definition: imgui.h:1965
ImGui::GetID
IMGUI_API ImGuiID GetID(const char *str_id)
Definition: imgui.cpp:6656
ImGuiNavLayer_Main
@ ImGuiNavLayer_Main
Definition: imgui_internal.h:654
ClampWindowRect
static void ClampWindowRect(ImGuiWindow *window, const ImRect &rect, const ImVec2 &padding)
Definition: imgui.cpp:5162
ImGuiIO::KeysDownDurationPrev
float KeysDownDurationPrev[512]
Definition: imgui.h:1539
ImDrawListFlags_AntiAliasedFill
@ ImDrawListFlags_AntiAliasedFill
Definition: imgui.h:1949
ImFont::FontSize
float FontSize
Definition: imgui.h:2277
ImGuiHoveredFlags_ChildWindows
@ ImGuiHoveredFlags_ChildWindows
Definition: imgui.h:923
ImClamp
static T ImClamp(T v, T mn, T mx)
Definition: imgui_internal.h:322
ImGui::GetWindowContentRegionMin
IMGUI_API ImVec2 GetWindowContentRegionMin()
Definition: imgui.cpp:7160
GetResizeBorderRect
static ImRect GetResizeBorderRect(ImGuiWindow *window, int border_n, float perp_padding, float thickness)
Definition: imgui.cpp:5015
ImFabs
#define ImFabs(X)
Definition: imgui_internal.h:305
ImGuiNavLayer_Menu
@ ImGuiNavLayer_Menu
Definition: imgui_internal.h:655
ImFontAtlas::TexID
ImTextureID TexID
Definition: imgui.h:2247
ImGuiPopupData::Window
ImGuiWindow * Window
Definition: imgui_internal.h:835
ImGuiWindowTempData::ItemFlags
ImGuiItemFlags ItemFlags
Definition: imgui_internal.h:1410
ImGuiWindowTempData::NavHasScroll
bool NavHasScroll
Definition: imgui_internal.h:1392
ImGuiKey_PageUp
@ ImGuiKey_PageUp
Definition: imgui.h:992
CreateNewWindow
static ImGuiWindow * CreateNewWindow(const char *name, ImVec2 size, ImGuiWindowFlags flags)
Definition: imgui.cpp:4837
IMGUI_DEBUG_NAV_SCORING
#define IMGUI_DEBUG_NAV_SCORING
Definition: imgui.cpp:885
ImRect::Expand
void Expand(const float amount)
Definition: imgui_internal.h:707
ImTextStrToUtf8
int ImTextStrToUtf8(char *buf, int buf_size, const ImWchar *in_text, const ImWchar *in_text_end)
Definition: imgui.cpp:1765
FreeWrapper
static void FreeWrapper(void *ptr, void *user_data)
Definition: imgui.cpp:983
ImDrawData::CmdListsCount
int CmdListsCount
Definition: imgui.h:2072
ImGuiWindow::ImGuiWindow
ImGuiWindow(ImGuiContext *context, const char *name)
Definition: imgui.cpp:2805
end
GLuint GLuint end
Definition: glcorearb.h:2858
ImGetDirQuadrantFromDelta
ImGuiDir ImGetDirQuadrantFromDelta(float dx, float dy)
Definition: imgui.cpp:7953
ImStrlenW
int ImStrlenW(const ImWchar *str)
Definition: imgui.cpp:1352
ImGuiLogType_Buffer
@ ImGuiLogType_Buffer
Definition: imgui_internal.h:577
ImGuiDir_COUNT
@ ImGuiDir_COUNT
Definition: imgui.h:981
ImGuiNextItemDataFlags_None
@ ImGuiNextItemDataFlags_None
Definition: imgui_internal.h:978
WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER
static const float WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER
Definition: imgui.cpp:896
ImGuiNavInput_FocusNext
@ ImGuiNavInput_FocusNext
Definition: imgui.h:1042
ImGuiContext::WindowsById
ImGuiStorage WindowsById
Definition: imgui_internal.h:1041
ImGuiButtonFlags_NoNavFocus
@ ImGuiButtonFlags_NoNavFocus
Definition: imgui_internal.h:454
ImGuiContext::Font
ImFont * Font
Definition: imgui_internal.h:1024
ImU64
unsigned long long ImU64
Definition: imgui.h:204
ImGuiWindowTempData::MenuColumns
ImGuiMenuColumns MenuColumns
Definition: imgui_internal.h:1397
ImGui::GetTextLineHeightWithSpacing
IMGUI_API float GetTextLineHeightWithSpacing()
Definition: imgui.cpp:7111
NULL
NULL
Definition: test_security_zap.cpp:405
ImGuiDragDropFlags_AcceptBeforeDelivery
@ ImGuiDragDropFlags_AcceptBeforeDelivery
Definition: imgui.h:947
g
GLboolean GLboolean g
Definition: glcorearb.h:3228
ImGuiStorage::ImGuiStoragePair
Definition: imgui.h:1732
IMGUI_VERSION
#define IMGUI_VERSION
Definition: imgui.h:62
ChildWindowComparer
static int IMGUI_CDECL ChildWindowComparer(const void *lhs, const void *rhs)
Definition: imgui.cpp:4001
src
GLenum src
Definition: glcorearb.h:3364
ImGuiNavDirSourceFlags_Keyboard
@ ImGuiNavDirSourceFlags_Keyboard
Definition: imgui_internal.h:628
ImGuiContext::Style
ImGuiStyle Style
Definition: imgui_internal.h:1023
ImGui::PushStyleColor
IMGUI_API void PushStyleColor(ImGuiCol idx, ImU32 col)
Definition: imgui.cpp:2378
ImGuiCol_ResizeGrip
@ ImGuiCol_ResizeGrip
Definition: imgui.h:1116
ImGuiCol_Separator
@ ImGuiCol_Separator
Definition: imgui.h:1113
ImGuiContext::DragDropActive
bool DragDropActive
Definition: imgui_internal.h:1152
ImGuiStorage::Data
ImVector< ImGuiStoragePair > Data
Definition: imgui.h:1741
ImGuiMouseButton_COUNT
@ ImGuiMouseButton_COUNT
Definition: imgui.h:1237
ImGuiCond
int ImGuiCond
Definition: imgui.h:144
ImGuiWindowFlags_NoBringToFrontOnFocus
@ ImGuiWindowFlags_NoBringToFrontOnFocus
Definition: imgui.h:782
ImGuiConfigFlags_NavEnableGamepad
@ ImGuiConfigFlags_NavEnableGamepad
Definition: imgui.h:1062
ImGuiCol_SliderGrab
@ ImGuiCol_SliderGrab
Definition: imgui.h:1105
IM_NEW
#define IM_NEW(_TYPE)
Definition: imgui.h:1286
ImBezierClosestPointCasteljau
ImVec2 ImBezierClosestPointCasteljau(const ImVec2 &p1, const ImVec2 &p2, const ImVec2 &p3, const ImVec2 &p4, const ImVec2 &p, float tess_tol)
Definition: imgui.cpp:1239
versiongenerate.file_data
string file_data
Definition: versiongenerate.py:84
ImGuiCol_PlotHistogram
@ ImGuiCol_PlotHistogram
Definition: imgui.h:1126
GImAllocatorFreeFunc
static void(* GImAllocatorFreeFunc)(void *ptr, void *user_data)
Definition: imgui.cpp:990
ImGuiStyleMod::BackupFloat
float BackupFloat[2]
Definition: imgui_internal.h:737
ImVec4::z
float z
Definition: imgui.h:223
ImGuiContext::OpenPopupStack
ImVector< ImGuiPopupData > OpenPopupStack
Definition: imgui_internal.h:1087
ImGui::SetNextWindowPos
IMGUI_API void SetNextWindowPos(const ImVec2 &pos, ImGuiCond cond=0, const ImVec2 &pivot=ImVec2(0, 0))
Definition: imgui.cpp:6470
ImGuiCol
int ImGuiCol
Definition: imgui.h:137
ImGuiWindow::Flags
ImGuiWindowFlags Flags
Definition: imgui_internal.h:1460
ImGuiTooltipFlags_OverridePreviousTooltip
@ ImGuiTooltipFlags_OverridePreviousTooltip
Definition: imgui_internal.h:561
ImGuiSettingsHandler::TypeHash
ImGuiID TypeHash
Definition: imgui_internal.h:822
length
GLenum GLuint GLenum GLsizei length
Definition: glcorearb.h:2695
ImGuiCol_HeaderHovered
@ ImGuiCol_HeaderHovered
Definition: imgui.h:1111
ImGuiNavMoveFlags_AllowCurrentNavId
@ ImGuiNavMoveFlags_AllowCurrentNavId
Definition: imgui_internal.h:640
ImRect::Min
ImVec2 Min
Definition: imgui_internal.h:686
ImGuiNavInput
int ImGuiNavInput
Definition: imgui.h:148
ImGui::GetCursorScreenPos
IMGUI_API ImVec2 GetCursorScreenPos()
Definition: imgui.cpp:6946
ImGui::FindWindowByName
IMGUI_API ImGuiWindow * FindWindowByName(const char *name)
Definition: imgui.cpp:4831
ImGuiIO::MouseDownDuration
float MouseDownDuration[5]
Definition: imgui.h:1534
ImGui::GetFrameHeightWithSpacing
IMGUI_API float GetFrameHeightWithSpacing()
Definition: imgui.cpp:7123
ImGui::GetClipboardText
const IMGUI_API char * GetClipboardText()
Definition: imgui.cpp:3226
ImGuiListClipper::DisplayEnd
int DisplayEnd
Definition: imgui.h:1787
ImGuiNavInput_TweakSlow
@ ImGuiNavInput_TweakSlow
Definition: imgui.h:1043
ImGui::GetDrawData
IMGUI_API ImDrawData * GetDrawData()
Definition: imgui.cpp:3293
ImDrawData::Valid
bool Valid
Definition: imgui.h:2070
ImGuiIO::FontGlobalScale
float FontGlobalScale
Definition: imgui.h:1436
ImGuiColorMod::Col
ImGuiCol Col
Definition: imgui_internal.h:729
ImGui::IsItemEdited
IMGUI_API bool IsItemEdited()
Definition: imgui.cpp:4652
ImGuiWindow::NavLastIds
ImGuiID NavLastIds[ImGuiNavLayer_COUNT]
Definition: imgui_internal.h:1533
ImGuiInputSource_Nav
@ ImGuiInputSource_Nav
Definition: imgui_internal.h:599
ImDrawList::PushClipRect
IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect=false)
Definition: imgui_draw.cpp:493
ImGuiCol_TextSelectedBg
@ ImGuiCol_TextSelectedBg
Definition: imgui.h:1128
ImGui::GcAwakeTransientWindowBuffers
IMGUI_API void GcAwakeTransientWindowBuffers(ImGuiWindow *window)
Definition: imgui.cpp:2959
ImGuiWindow::RootWindow
ImGuiWindow * RootWindow
Definition: imgui_internal.h:1528
ImGui::Button
IMGUI_API bool Button(const char *label, const ImVec2 &size=ImVec2(0, 0))
Definition: imgui_widgets.cpp:678
ImGuiNextWindowDataFlags_HasCollapsed
@ ImGuiNextWindowDataFlags_HasCollapsed
Definition: imgui_internal.h:948
ImGuiWindowFlags_NoBackground
@ ImGuiWindowFlags_NoBackground
Definition: imgui.h:776
ImGuiIO::ConfigWindowsMoveFromTitleBarOnly
bool ConfigWindowsMoveFromTitleBarOnly
Definition: imgui.h:1446
ImGui::LogToTTY
IMGUI_API void LogToTTY(int auto_open_depth=-1)
Definition: imgui.cpp:9399
ImGui::MarkItemEdited
IMGUI_API void MarkItemEdited(ImGuiID id)
Definition: imgui.cpp:3030
ImGui::GetItemRectMin
IMGUI_API ImVec2 GetItemRectMin()
Definition: imgui.cpp:4668
ImGui::IsItemActive
IMGUI_API bool IsItemActive()
Definition: imgui.cpp:4563
ImGuiContext::ActiveId
ImGuiID ActiveId
Definition: imgui_internal.h:1057
WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER
static const float WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER
Definition: imgui.cpp:895
ImGuiNavInput_TweakFast
@ ImGuiNavInput_TweakFast
Definition: imgui.h:1044
ImGuiWindow::AutoFitFramesY
ImS8 AutoFitFramesY
Definition: imgui_internal.h:1493
ImGuiWindowFlags
int ImGuiWindowFlags
Definition: imgui.h:168
ImRect::TranslateY
void TranslateY(float dy)
Definition: imgui_internal.h:711
ImGui::BeginDragDropTargetCustom
IMGUI_API bool BeginDragDropTargetCustom(const ImRect &bb, ImGuiID id)
Definition: imgui.cpp:9186
ImGuiContext::WantCaptureMouseNextFrame
int WantCaptureMouseNextFrame
Definition: imgui_internal.h:1223
s
XmlRpcServer s
ImGuiIO::DisplayFramebufferScale
ImVec2 DisplayFramebufferScale
Definition: imgui.h:1439
ImFont::ContainerAtlas
ImFontAtlas * ContainerAtlas
Definition: imgui.h:2286
ImGuiContext::FrameCount
int FrameCount
Definition: imgui_internal.h:1029
ImGuiTabBar::PrevFrameVisible
int PrevFrameVisible
Definition: imgui_internal.h:1616
ImGuiCol_ResizeGripHovered
@ ImGuiCol_ResizeGripHovered
Definition: imgui.h:1117
ImGui::CalcItemSize
IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_w, float default_h)
Definition: imgui.cpp:7084
ImGui::IsMouseDown
IMGUI_API bool IsMouseDown(ImGuiMouseButton button)
Definition: imgui.cpp:4426
ImGuiWindowTempData::NavLayerActiveMaskNext
int NavLayerActiveMaskNext
Definition: imgui_internal.h:1389
ImFormatString
int ImFormatString(char *buf, size_t buf_size, const char *fmt,...)
Definition: imgui.cpp:1437
mode
GLenum mode
Definition: glcorearb.h:2764
ImGuiNavMoveFlags_WrapY
@ ImGuiNavMoveFlags_WrapY
Definition: imgui_internal.h:639
ImGui::IsItemDeactivatedAfterEdit
IMGUI_API bool IsItemDeactivatedAfterEdit()
Definition: imgui.cpp:4595
ImGui::SetNextItemWidth
IMGUI_API void SetNextItemWidth(float item_width)
Definition: imgui.cpp:7023
ImGui::GetKeyPressedAmount
IMGUI_API int GetKeyPressedAmount(int key_index, float repeat_delay, float rate)
Definition: imgui.cpp:4394
ImGui::IsItemToggledOpen
IMGUI_API bool IsItemToggledOpen()
Definition: imgui.cpp:4616
ImGuiNavInput_Activate
@ ImGuiNavInput_Activate
Definition: imgui.h:1029
ImGuiPayload::SourceId
ImGuiID SourceId
Definition: imgui.h:1605
ImDrawList::PopTextureID
IMGUI_API void PopTextureID()
Definition: imgui_draw.cpp:529
IM_COL32_B_SHIFT
#define IM_COL32_B_SHIFT
Definition: imgui.h:1816
ImGuiContext::NavAnyRequest
bool NavAnyRequest
Definition: imgui_internal.h:1111
ImGuiPopupData::PopupId
ImGuiID PopupId
Definition: imgui_internal.h:834
ImGuiTextFilter::InputBuf
char InputBuf[256]
Definition: imgui.h:1695
ImGuiTextFilter::ImGuiTextRange
Definition: imgui.h:1685
ImGui::CalcTypematicRepeatAmount
IMGUI_API int CalcTypematicRepeatAmount(float t0, float t1, float repeat_delay, float repeat_rate)
Definition: imgui.cpp:4380
ImGuiWindowTempData::NavLayerCurrent
ImGuiNavLayer NavLayerCurrent
Definition: imgui_internal.h:1386
ImGuiTextFilter::ImGuiTextFilter
IMGUI_API ImGuiTextFilter(const char *default_filter="")
Definition: imgui.cpp:2034
ImGuiPopupData
Definition: imgui_internal.h:832
ImDrawData::CmdLists
ImDrawList ** CmdLists
Definition: imgui.h:2071
ImGui::GetVersion
const IMGUI_API char * GetVersion()
Definition: imgui.cpp:3239
ImGuiStorage::BuildSortByKey
IMGUI_API void BuildSortByKey()
Definition: imgui.cpp:1909
ImGuiTextFilter::Draw
IMGUI_API bool Draw(const char *label="Filter (inc,-exc)", float width=0.0f)
Definition: imgui.cpp:2048
ImGuiWindow::SetWindowSizeAllowFlags
ImGuiCond SetWindowSizeAllowFlags
Definition: imgui_internal.h:1500
IsWindowActiveAndVisible
static bool IsWindowActiveAndVisible(ImGuiWindow *window)
Definition: imgui.cpp:3437
ImGui::ErrorCheckBeginEndCompareStacksSize
static void ErrorCheckBeginEndCompareStacksSize(ImGuiWindow *window, bool write)
Definition: imgui.cpp:6767
ImGuiStyleVar_ChildRounding
@ ImGuiStyleVar_ChildRounding
Definition: imgui.h:1159
ImGui::PopStyleColor
IMGUI_API void PopStyleColor(int count=1)
Definition: imgui.cpp:2398
label
GLuint GLsizei const GLchar * label
Definition: glcorearb.h:4316
ImGuiNavInput_Cancel
@ ImGuiNavInput_Cancel
Definition: imgui.h:1030
ImGui::ItemHoverable
IMGUI_API bool ItemHoverable(const ImRect &bb, ImGuiID id)
Definition: imgui.cpp:3107
ImGuiWindowTempData::ColumnsOffset
ImVec1 ColumnsOffset
Definition: imgui_internal.h:1376
ImGui::SetKeyboardFocusHere
IMGUI_API void SetKeyboardFocusHere(int offset=0)
Definition: imgui.cpp:6580
ImGuiNavMoveFlags_AlsoScoreVisibleSet
@ ImGuiNavMoveFlags_AlsoScoreVisibleSet
Definition: imgui_internal.h:641
ImGuiKey_Enter
@ ImGuiKey_Enter
Definition: imgui.h:1000
ImGuiWindow::SetWindowPosPivot
ImVec2 SetWindowPosPivot
Definition: imgui_internal.h:1503
ImGuiIO::KeyRepeatRate
float KeyRepeatRate
Definition: imgui.h:1432
ImGuiWindowTempData::PrevLineTextBaseOffset
float PrevLineTextBaseOffset
Definition: imgui_internal.h:1374
ImGui::SetNextWindowBgAlpha
IMGUI_API void SetNextWindowBgAlpha(float alpha)
Definition: imgui.cpp:6522
ImGui::LogToClipboard
IMGUI_API void LogToClipboard(int auto_open_depth=-1)
Definition: imgui.cpp:9437
ImGui::PushAllowKeyboardFocus
IMGUI_API void PushAllowKeyboardFocus(bool allow_keyboard_focus)
Definition: imgui.cpp:6202
ImHashStr
ImU32 ImHashStr(const char *data_p, size_t data_size, ImU32 seed)
Definition: imgui.cpp:1513
ImGui::SetScrollY
IMGUI_API void SetScrollY(float scroll_y)
Definition: imgui.cpp:7360
ImGuiWindowTempData::LastItemDisplayRect
ImRect LastItemDisplayRect
Definition: imgui_internal.h:1383
GetFallbackWindowNameForWindowingList
static const char * GetFallbackWindowNameForWindowingList(ImGuiWindow *window)
Definition: imgui.cpp:8966
ImFont::IsLoaded
bool IsLoaded() const
Definition: imgui.h:2303
ImGuiContext::SettingsDirtyTimer
float SettingsDirtyTimer
Definition: imgui_internal.h:1199
ImVec1::x
float x
Definition: imgui_internal.h:668
ImGuiStorage::GetVoidPtr
IMGUI_API void * GetVoidPtr(ImGuiID key) const
Definition: imgui.cpp:1946
ImDrawList::AddRectFilled
IMGUI_API void AddRectFilled(const ImVec2 &p_min, const ImVec2 &p_max, ImU32 col, float rounding=0.0f, ImDrawCornerFlags rounding_corners=ImDrawCornerFlags_All)
Definition: imgui_draw.cpp:1033
ImGui::IsAnyItemHovered
IMGUI_API bool IsAnyItemHovered()
Definition: imgui.cpp:4628
ImGuiContext::NavWindow
ImGuiWindow * NavWindow
Definition: imgui_internal.h:1091
ImGuiPayload::Data
void * Data
Definition: imgui.h:1601
ImGui::Render
IMGUI_API void Render()
Definition: imgui.cpp:4222
desc
#define desc
Definition: extension_set.h:342
ImGuiContext::WheelingWindowTimer
float WheelingWindowTimer
Definition: imgui_internal.h:1049
ImGuiListClipper::DisplayStart
int DisplayStart
Definition: imgui.h:1787
ImGui::LogText
IMGUI_API void LogText(const char *fmt,...) IM_FMTARGS(1)
Definition: imgui.cpp:9310
ImFloor
static float ImFloor(float f)
Definition: imgui_internal.h:338
ImGuiContext::NextWindowData
ImGuiNextWindowData NextWindowData
Definition: imgui_internal.h:1080
ImGuiIO::IniFilename
const char * IniFilename
Definition: imgui.h:1425
ImGuiStorage::GetBool
IMGUI_API bool GetBool(ImGuiID key, bool default_val=false) const
Definition: imgui.cpp:1933
ImGui::FindWindowByID
IMGUI_API ImGuiWindow * FindWindowByID(ImGuiID id)
Definition: imgui.cpp:4825
ImGuiWindowFlags_NoMouseInputs
@ ImGuiWindowFlags_NoMouseInputs
Definition: imgui.h:778
ImGuiWindow::ParentWindow
ImGuiWindow * ParentWindow
Definition: imgui_internal.h:1527
ImDrawList
Definition: imgui.h:1961
IM_UNICODE_CODEPOINT_INVALID
#define IM_UNICODE_CODEPOINT_INVALID
Definition: imgui.h:1658
ImRect::IsInverted
bool IsInverted() const
Definition: imgui_internal.h:715
ImGuiKey_RightArrow
@ ImGuiKey_RightArrow
Definition: imgui.h:989
ImGuiNavMoveFlags_ScrollToEdge
@ ImGuiNavMoveFlags_ScrollToEdge
Definition: imgui_internal.h:642
ImGui::GetKeyIndex
IMGUI_API int GetKeyIndex(ImGuiKey imgui_key)
Definition: imgui.cpp:4358
ImGuiIO::ImeWindowHandle
void * ImeWindowHandle
Definition: imgui.h:1470
ImGuiTooltipFlags
int ImGuiTooltipFlags
Definition: imgui_internal.h:116
ImDrawList::PushTextureID
IMGUI_API void PushTextureID(ImTextureID texture_id)
Definition: imgui_draw.cpp:523
ImGui::DebugCheckVersionAndDataLayout
IMGUI_API bool DebugCheckVersionAndDataLayout(const char *version_str, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_drawvert, size_t sz_drawidx)
Definition: imgui.cpp:6696
ImGui::RenderMouseCursor
IMGUI_API void RenderMouseCursor(ImDrawList *draw_list, ImVec2 pos, float scale, ImGuiMouseCursor mouse_cursor, ImU32 col_fill, ImU32 col_border, ImU32 col_shadow)
Definition: imgui_draw.cpp:3230
ImGui::IsMouseHoveringRect
IMGUI_API bool IsMouseHoveringRect(const ImVec2 &r_min, const ImVec2 &r_max, bool clip=true)
Definition: imgui.cpp:4342
ImStrdupcpy
char * ImStrdupcpy(char *dst, size_t *p_dst_size, const char *src)
Definition: imgui.cpp:1332
ImGuiContext::NavNextActivateId
ImGuiID NavNextActivateId
Definition: imgui_internal.h:1101
ImRect::GetSize
ImVec2 GetSize() const
Definition: imgui_internal.h:695
AddWindowToSortBuffer
static void AddWindowToSortBuffer(ImVector< ImGuiWindow * > *out_sorted_windows, ImGuiWindow *window)
Definition: imgui.cpp:4012
ImGuiStyle::CurveTessellationTol
float CurveTessellationTol
Definition: imgui.h:1400
ImGuiWindow::HasCloseButton
bool HasCloseButton
Definition: imgui_internal.h:1487
ImDrawCornerFlags_All
@ ImDrawCornerFlags_All
Definition: imgui.h:1942
ImGuiWindow::Collapsed
bool Collapsed
Definition: imgui_internal.h:1481
ImTriangleClosestPoint
ImVec2 ImTriangleClosestPoint(const ImVec2 &a, const ImVec2 &b, const ImVec2 &c, const ImVec2 &p)
Definition: imgui.cpp:1281
ImGuiContext::BackgroundDrawList
ImDrawList BackgroundDrawList
Definition: imgui_internal.h:1147
ImGuiInputReadMode_Repeat
@ ImGuiInputReadMode_Repeat
Definition: imgui_internal.h:611
imgui.h
GetWindowBgColorIdxFromFlags
static ImGuiCol GetWindowBgColorIdxFromFlags(ImGuiWindowFlags flags)
Definition: imgui.cpp:4977
ImModPositive
static int ImModPositive(int a, int b)
Definition: imgui_internal.h:340
ImGui::UpdateMouseWheel
static void UpdateMouseWheel()
Definition: imgui.cpp:3509
ImGuiIO::BackendLanguageUserData
void * BackendLanguageUserData
Definition: imgui.h:1459
ImGuiAxis_X
@ ImGuiAxis_X
Definition: imgui_internal.h:585
ImStricmp
int ImStricmp(const char *str1, const char *str2)
Definition: imgui.cpp:1302
NavRestoreLayer
static void NavRestoreLayer(ImGuiNavLayer layer)
Definition: imgui.cpp:8266
ImGuiPayload::Delivery
bool Delivery
Definition: imgui.h:1610
ImGui::PushFont
IMGUI_API void PushFont(ImFont *font)
Definition: imgui.cpp:6166
ImDrawList::ClearFreeMemory
IMGUI_API void ClearFreeMemory()
Definition: imgui_draw.cpp:395
ImDrawList::_Data
const ImDrawListSharedData * _Data
Definition: imgui.h:1970
ImGuiWindowTempData::StateStorage
ImGuiStorage * StateStorage
Definition: imgui_internal.h:1401
ImGuiIO::NavInputs
float NavInputs[ImGuiNavInput_COUNT]
Definition: imgui.h:1494
ImGuiWindowTempData::TextWrapPosStack
ImVector< float > TextWrapPosStack
Definition: imgui_internal.h:1415
ImGuiWindowSettings::Pos
ImVec2ih Pos
Definition: imgui_internal.h:811
NAV_WINDOWING_LIST_APPEAR_DELAY
static const float NAV_WINDOWING_LIST_APPEAR_DELAY
Definition: imgui.cpp:891
ImGuiWindowTempData::CursorStartPos
ImVec2 CursorStartPos
Definition: imgui_internal.h:1369
ImS8
signed char ImS8
Definition: imgui.h:189
ImGuiWindow::SetWindowCollapsedAllowFlags
ImGuiCond SetWindowCollapsedAllowFlags
Definition: imgui_internal.h:1501
ImGui::Unindent
IMGUI_API void Unindent(float indent_w=0.0f)
Definition: imgui.cpp:7014
ImGui::Text
IMGUI_API void Text(const char *fmt,...) IM_FMTARGS(1)
Definition: imgui_widgets.cpp:247
if
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END if(!upb_strtable_init(&intern->table, UPB_CTYPE_UINT64))
Definition: php/ext/google/protobuf/map.c:232
ImDrawList::PopClipRect
IMGUI_API void PopClipRect()
Definition: imgui_draw.cpp:516
ImFontAtlas::Locked
bool Locked
Definition: imgui.h:2245
ImGuiWindowFlags_Popup
@ ImGuiWindowFlags_Popup
Definition: imgui.h:797
ImGuiCol_Button
@ ImGuiCol_Button
Definition: imgui.h:1107
ImGuiID
unsigned int ImGuiID
Definition: imgui.h:174
ImGui::GetWindowContentRegionMax
IMGUI_API ImVec2 GetWindowContentRegionMax()
Definition: imgui.cpp:7166
ImGuiNavHighlightFlags
int ImGuiNavHighlightFlags
Definition: imgui_internal.h:108
ImGuiKey_Space
@ ImGuiKey_Space
Definition: imgui.h:999
ImGuiCol_ScrollbarGrabHovered
@ ImGuiCol_ScrollbarGrabHovered
Definition: imgui.h:1102
ImGuiStyle::Alpha
float Alpha
Definition: imgui.h:1367
ImTextCountUtf8BytesFromStr
int ImTextCountUtf8BytesFromStr(const ImWchar *in_text, const ImWchar *in_text_end)
Definition: imgui.cpp:1781
ImGuiNavLayer
ImGuiNavLayer
Definition: imgui_internal.h:652
ImGui::NavMoveRequestCancel
IMGUI_API void NavMoveRequestCancel()
Definition: imgui.cpp:8194
ImVector< ImDrawList * >
ImGui::SameLine
IMGUI_API void SameLine(float offset_from_start_x=0.0f, float spacing=-1.0f)
Definition: imgui.cpp:6923
ImGuiWindowTempData::NavFocusScopeIdCurrent
ImGuiID NavFocusScopeIdCurrent
Definition: imgui_internal.h:1390
ImGui::Selectable
IMGUI_API bool Selectable(const char *label, bool selected=false, ImGuiSelectableFlags flags=0, const ImVec2 &size=ImVec2(0, 0))
Definition: imgui_widgets.cpp:5572
ImGuiWindowFlags_AlwaysVerticalScrollbar
@ ImGuiWindowFlags_AlwaysVerticalScrollbar
Definition: imgui.h:783
ImGuiIO::FontAllowUserScaling
bool FontAllowUserScaling
Definition: imgui.h:1437
ImGuiWindowFlags_AlwaysAutoResize
@ ImGuiWindowFlags_AlwaysAutoResize
Definition: imgui.h:775
ImFontGlyph
Definition: imgui.h:2120
SetClipboardTextFn_DefaultImpl
static void SetClipboardTextFn_DefaultImpl(void *user_data, const char *text)
Definition: imgui.cpp:9895
ImGui::IsDragDropPayloadBeingAccepted
IMGUI_API bool IsDragDropPayloadBeingAccepted()
Definition: imgui.cpp:9238
ImGuiTabBar
Definition: imgui_internal.h:1608
ImGuiKeyModFlags_None
@ ImGuiKeyModFlags_None
Definition: imgui.h:1015
IM_COL32_G_SHIFT
#define IM_COL32_G_SHIFT
Definition: imgui.h:1815
ImGui::GetDefaultFont
ImFont * GetDefaultFont()
Definition: imgui_internal.h:1678
y
GLint y
Definition: glcorearb.h:2768
ImGuiIO::ClipboardUserData
void * ClipboardUserData
Definition: imgui.h:1465
ImGui::SmallButton
IMGUI_API bool SmallButton(const char *label)
Definition: imgui_widgets.cpp:684
ImGuiCol_Header
@ ImGuiCol_Header
Definition: imgui.h:1110
NAV_WINDOWING_HIGHLIGHT_DELAY
static const float NAV_WINDOWING_HIGHLIGHT_DELAY
Definition: imgui.cpp:890
ImGui::FocusableItemRegister
IMGUI_API bool FocusableItemRegister(ImGuiWindow *window, ImGuiID id)
Definition: imgui.cpp:3152
ImGuiIO::GetClipboardTextFn
const char *(* GetClipboardTextFn)(void *user_data)
Definition: imgui.h:1463
ImGui::GetColumnOffsetFromNorm
IMGUI_API float GetColumnOffsetFromNorm(const ImGuiColumns *columns, float offset_norm)
Definition: imgui_widgets.cpp:7329
ImGuiPayload::DataSize
int DataSize
Definition: imgui.h:1602
conformance_python.stdout
stdout
Definition: conformance_python.py:50
ImGuiNextWindowData::ClearFlags
void ClearFlags()
Definition: imgui_internal.h:973
ImGui::ClearActiveID
IMGUI_API void ClearActiveID()
Definition: imgui.cpp:3001
ImGuiIO::InputQueueSurrogate
ImWchar16 InputQueueSurrogate
Definition: imgui.h:1542
ImGui::GetWindowSize
IMGUI_API ImVec2 GetWindowSize()
Definition: imgui.cpp:6369
ImGui::SetScrollHereY
IMGUI_API void SetScrollHereY(float center_y_ratio=0.5f)
Definition: imgui.cpp:7422
alpha
GLfloat GLfloat GLfloat alpha
Definition: glcorearb.h:2777
ImGuiContext::NavId
ImGuiID NavId
Definition: imgui_internal.h:1092
ImGuiPayload::SourceParentId
ImGuiID SourceParentId
Definition: imgui.h:1606
ImGui::RenderText
IMGUI_API void RenderText(ImVec2 pos, const char *text, const char *text_end=NULL, bool hide_text_after_hash=true)
Definition: imgui.cpp:2574
ImFontAtlas
Definition: imgui.h:2182
ImVec2
Definition: imgui.h:208
ImGuiContext::FocusTabPressed
bool FocusTabPressed
Definition: imgui_internal.h:1141
ImGui::BringWindowToDisplayFront
IMGUI_API void BringWindowToDisplayFront(ImGuiWindow *window)
Definition: imgui.cpp:6055
ImGui::FocusTopMostWindowUnderOne
IMGUI_API void FocusTopMostWindowUnderOne(ImGuiWindow *under_this_window, ImGuiWindow *ignore_window)
Definition: imgui.cpp:6125
ImGuiStorage::ImGuiStoragePair::key
ImGuiID key
Definition: imgui.h:1734
ImGuiKey_End
@ ImGuiKey_End
Definition: imgui.h:995
ImGui::GetIO
IMGUI_API ImGuiIO & GetIO()
Definition: imgui.cpp:3286
x
GLint GLenum GLint x
Definition: glcorearb.h:2834
ImGuiIO::MouseDrawCursor
bool MouseDrawCursor
Definition: imgui.h:1442
dummy
ReturnVal dummy
Definition: register_benchmark_test.cc:68
ImGuiHoveredFlags_AnyWindow
@ ImGuiHoveredFlags_AnyWindow
Definition: imgui.h:925
ImTriangleContainsPoint
bool ImTriangleContainsPoint(const ImVec2 &a, const ImVec2 &b, const ImVec2 &c, const ImVec2 &p)
Definition: imgui.cpp:1262
ImGui::RenderTextClipped
IMGUI_API void RenderTextClipped(const ImVec2 &pos_min, const ImVec2 &pos_max, const char *text, const char *text_end, const ImVec2 *text_size_if_known, const ImVec2 &align=ImVec2(0, 0), const ImRect *clip_rect=NULL)
Definition: imgui.cpp:2646
ImGuiColumns::Columns
ImVector< ImGuiColumnData > Columns
Definition: imgui_internal.h:869
IM_UNUSED
#define IM_UNUSED(_VAR)
Definition: imgui.h:89
ImGuiContext::NavDisableHighlight
bool NavDisableHighlight
Definition: imgui_internal.h:1109
ImRect::Max
ImVec2 Max
Definition: imgui_internal.h:687
ImGuiWindowFlags_MenuBar
@ ImGuiWindowFlags_MenuBar
Definition: imgui.h:779
ImGuiPopupPositionPolicy_ComboBox
@ ImGuiPopupPositionPolicy_ComboBox
Definition: imgui_internal.h:662
ImGuiWindowTempData::CursorPos
ImVec2 CursorPos
Definition: imgui_internal.h:1367
ImGuiTextBuffer::appendf
IMGUI_API void appendf(const char *fmt,...) IM_FMTARGS(2)
Definition: imgui.cpp:2165
ImGui::IsItemVisible
IMGUI_API bool IsItemVisible()
Definition: imgui.cpp:4646
ImGuiCol_HeaderActive
@ ImGuiCol_HeaderActive
Definition: imgui.h:1112
AddDrawListToDrawData
static void AddDrawListToDrawData(ImVector< ImDrawList * > *out_list, ImDrawList *draw_list)
Definition: imgui.cpp:4029
ImFont::FindGlyph
const IMGUI_API ImFontGlyph * FindGlyph(ImWchar c) const
Definition: imgui_draw.cpp:2752
ImGui::RenderNavHighlight
IMGUI_API void RenderNavHighlight(const ImRect &bb, ImGuiID id, ImGuiNavHighlightFlags flags=ImGuiNavHighlightFlags_TypeDefault)
Definition: imgui.cpp:2768
ImGui::PushTextWrapPos
IMGUI_API void PushTextWrapPos(float wrap_local_pos_x=0.0f)
Definition: imgui.cpp:6222
ImRect::Overlaps
bool Overlaps(const ImRect &r) const
Definition: imgui_internal.h:704
ImGuiFocusedFlags_AnyWindow
@ ImGuiFocusedFlags_AnyWindow
Definition: imgui.h:913
ImGuiWindowFlags_NoSavedSettings
@ ImGuiWindowFlags_NoSavedSettings
Definition: imgui.h:777
ImGuiResizeGripDef::CornerPosN
ImVec2 CornerPosN
Definition: imgui.cpp:5002
ImGui::RenderWindowOuterBorders
static void RenderWindowOuterBorders(ImGuiWindow *window)
Definition: imgui.cpp:5169
error
Definition: cJSON.c:88
ImGui::BeginDragDropSource
IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags=0)
Definition: imgui.cpp:9024
ImGuiIO::KeyRepeatDelay
float KeyRepeatDelay
Definition: imgui.h:1431
ImGuiWindowTempData::NavLayerActiveMask
int NavLayerActiveMask
Definition: imgui_internal.h:1388
ImGui::GetMouseCursor
IMGUI_API ImGuiMouseCursor GetMouseCursor()
Definition: imgui.cpp:4543
ImGuiIO::MouseDragThreshold
float MouseDragThreshold
Definition: imgui.h:1429
ImGuiStorage::GetBoolRef
IMGUI_API bool * GetBoolRef(ImGuiID key, bool default_val=false)
Definition: imgui.cpp:1963
ImGuiWindow::SizeFull
ImVec2 SizeFull
Definition: imgui_internal.h:1463
ImGuiIO::AddInputCharacter
IMGUI_API void AddInputCharacter(unsigned int c)
Definition: imgui.cpp:1130
ImGui::UpdateDebugToolItemPicker
static void UpdateDebugToolItemPicker()
Definition: imgui.cpp:3870
ImVector::Capacity
int Capacity
Definition: imgui.h:1304
ImTextStrFromUtf8
int ImTextStrFromUtf8(ImWchar *buf, int buf_size, const char *in_text, const char *in_text_end, const char **in_text_remaining)
Definition: imgui.cpp:1681
ImGuiWindowTempData::GroupStack
ImVector< ImGuiGroupData > GroupStack
Definition: imgui_internal.h:1416
ImGuiWindowTempData::NavHideHighlightOneFrame
bool NavHideHighlightOneFrame
Definition: imgui_internal.h:1391
ImFileGetSize
ImU64 ImFileGetSize(ImFileHandle f)
Definition: imgui.cpp:1567
ImGuiContext::PrivateClipboard
ImVector< char > PrivateClipboard
Definition: imgui_internal.h:1190
ImGui::SetMouseCursor
IMGUI_API void SetMouseCursor(ImGuiMouseCursor cursor_type)
Definition: imgui.cpp:4548
ImGui::LogFinish
IMGUI_API void LogFinish()
Definition: imgui.cpp:9453
ImMin
static T ImMin(T lhs, T rhs)
Definition: imgui_internal.h:320
ImGui::PushFocusScope
IMGUI_API void PushFocusScope(ImGuiID id)
Definition: imgui.cpp:6564
ImGui::GetWindowWidth
IMGUI_API float GetWindowWidth()
Definition: imgui.cpp:6319
idx
static uint32_t idx(tarjan *t, const upb_refcounted *r)
Definition: ruby/ext/google/protobuf_c/upb.c:5925
ImGuiWindowFlags_ChildMenu
@ ImGuiWindowFlags_ChildMenu
Definition: imgui.h:799
ImDrawList::CmdBuffer
ImVector< ImDrawCmd > CmdBuffer
Definition: imgui.h:1964
ImGui::NavRestoreLastChildNavWindow
static ImGuiWindow * NavRestoreLastChildNavWindow(ImGuiWindow *window)
Definition: imgui.cpp:8261
ImGuiStyleVarInfo::GetVarPtr
void * GetVarPtr(ImGuiStyle *style) const
Definition: imgui.cpp:2415
ImGuiInputSource_NavGamepad
@ ImGuiInputSource_NavGamepad
Definition: imgui_internal.h:601
GCrc32LookupTable
static const ImU32 GCrc32LookupTable[256]
Definition: imgui.cpp:1474
ImGui::IsNavInputTest
bool IsNavInputTest(ImGuiNavInput n, ImGuiInputReadMode rm)
Definition: imgui_internal.h:1779
ImGuiWindow::AutoFitOnlyGrows
bool AutoFitOnlyGrows
Definition: imgui_internal.h:1495
ImGuiTabBar::Tabs
ImVector< ImGuiTabItem > Tabs
Definition: imgui_internal.h:1610
ImStrdup
char * ImStrdup(const char *str)
Definition: imgui.cpp:1325
ImGuiStyleVar_ChildBorderSize
@ ImGuiStyleVar_ChildBorderSize
Definition: imgui.h:1160
ImGuiNavMoveFlags_None
@ ImGuiNavMoveFlags_None
Definition: imgui_internal.h:635
ImGuiWindow::~ImGuiWindow
~ImGuiWindow()
Definition: imgui.cpp:2871
flags
GLbitfield flags
Definition: glcorearb.h:3585
ImGuiWindowSettings::Size
ImVec2ih Size
Definition: imgui_internal.h:812
ImRect::TranslateX
void TranslateX(float dx)
Definition: imgui_internal.h:710
ImGuiStyle::ChildBorderSize
float ChildBorderSize
Definition: imgui.h:1375
ImGui::GetMouseDragDelta
IMGUI_API ImVec2 GetMouseDragDelta(ImGuiMouseButton button=0, float lock_threshold=-1.0f)
Definition: imgui.cpp:4522
ImGuiIO::WantSetMousePos
bool WantSetMousePos
Definition: imgui.h:1509
ImGui::GetCurrentWindow
ImGuiWindow * GetCurrentWindow()
Definition: imgui_internal.h:1657
ImGuiHoveredFlags_AllowWhenBlockedByPopup
@ ImGuiHoveredFlags_AllowWhenBlockedByPopup
Definition: imgui.h:926
ImGui::BeginChildEx
IMGUI_API bool BeginChildEx(const char *name, ImGuiID id, const ImVec2 &size_arg, bool border, ImGuiWindowFlags flags)
Definition: imgui.cpp:4692
ImDrawCmd
Definition: imgui.h:1871
imgui_internal.h
ImGuiGroupData::BackupCurrLineSize
ImVec2 BackupCurrLineSize
Definition: imgui_internal.h:750
ImGuiStyle::ItemSpacing
ImVec2 ItemSpacing
Definition: imgui.h:1381
ImGuiStyle::SelectableTextAlign
ImVec2 SelectableTextAlign
Definition: imgui.h:1394
IM_DELETE
void IM_DELETE(T *p)
Definition: imgui.h:1287
ImDrawList::AddText
IMGUI_API void AddText(const ImVec2 &pos, ImU32 col, const char *text_begin, const char *text_end=NULL)
Definition: imgui_draw.cpp:1235
NavClampRectToVisibleAreaForMoveDir
static void NavClampRectToVisibleAreaForMoveDir(ImGuiDir move_dir, ImRect &r, const ImRect &clip_rect)
Definition: imgui.cpp:7969
ImFileLoadToMemory
void * ImFileLoadToMemory(const char *filename, const char *mode, size_t *out_file_size, int padding_bytes)
Definition: imgui.cpp:1575
ImGuiTextFilter::ImGuiTextRange::split
IMGUI_API void split(char separator, ImVector< ImGuiTextRange > *out) const
Definition: imgui.cpp:2058
ImGui::GetHoveredID
IMGUI_API ImGuiID GetHoveredID()
Definition: imgui.cpp:3015
ImDrawListSharedData::FontSize
float FontSize
Definition: imgui_internal.h:905
b
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:3228
ImGuiStyle::FrameRounding
float FrameRounding
Definition: imgui.h:1379
ImGuiConfigFlags_None
@ ImGuiConfigFlags_None
Definition: imgui.h:1060
ImGuiNavInput_LStickLeft
@ ImGuiNavInput_LStickLeft
Definition: imgui.h:1037
ImGuiStyle::ColorButtonPosition
ImGuiDir ColorButtonPosition
Definition: imgui.h:1392
ImGuiCol_ScrollbarGrab
@ ImGuiCol_ScrollbarGrab
Definition: imgui.h:1101
ImGui::IsItemClicked
IMGUI_API bool IsItemClicked(ImGuiMouseButton mouse_button=0)
Definition: imgui.cpp:4611
ImGuiKey_Home
@ ImGuiKey_Home
Definition: imgui.h:994
ImGui::IsPopupOpen
IMGUI_API bool IsPopupOpen(const char *str_id)
Definition: imgui.cpp:7503
ImGuiItemFlags_NoNavDefaultFocus
@ ImGuiItemFlags_NoNavDefaultFocus
Definition: imgui_internal.h:525
ImGuiCol_PlotLinesHovered
@ ImGuiCol_PlotLinesHovered
Definition: imgui.h:1125
ImAlphaBlendColors
IMGUI_API ImU32 ImAlphaBlendColors(ImU32 col_a, ImU32 col_b)
Definition: imgui.cpp:1800
ImGuiInputReadMode_RepeatFast
@ ImGuiInputReadMode_RepeatFast
Definition: imgui_internal.h:613
ImGuiResizeGripDef::AngleMin12
int AngleMin12
Definition: imgui.cpp:5004
ImGui::IsItemHovered
IMGUI_API bool IsItemHovered(ImGuiHoveredFlags flags=0)
Definition: imgui.cpp:3065
ImGuiWindowTempData::LastItemStatusFlags
ImGuiItemStatusFlags LastItemStatusFlags
Definition: imgui_internal.h:1381
ImGui::SetStateStorage
IMGUI_API void SetStateStorage(ImGuiStorage *storage)
Definition: imgui.cpp:6607
ImGui::Separator
IMGUI_API void Separator()
Definition: imgui_widgets.cpp:1311
ImDrawCmd::UserCallback
ImDrawCallback UserCallback
Definition: imgui.h:1878
ImGuiKey_COUNT
@ ImGuiKey_COUNT
Definition: imgui.h:1009
ImGui::CalcWrapWidthForPos
IMGUI_API float CalcWrapWidthForPos(const ImVec2 &pos, float wrap_pos_x)
Definition: imgui.cpp:3195
ImGuiHoveredFlags
int ImGuiHoveredFlags
Definition: imgui.h:161
ImGuiCol_FrameBgActive
@ ImGuiCol_FrameBgActive
Definition: imgui.h:1095
ImSaturate
static float ImSaturate(float f)
Definition: imgui_internal.h:334
ImGuiPayload
Definition: imgui.h:1598
ImGui::BeginGroup
IMGUI_API void BeginGroup()
Definition: imgui.cpp:7179
ImTextCountUtf8BytesFromChar
int ImTextCountUtf8BytesFromChar(const char *in_text, const char *in_text_end)
Definition: imgui.cpp:1750
ImGui::SetCursorPos
IMGUI_API void SetCursorPos(const ImVec2 &local_pos)
Definition: imgui.cpp:6979
ImGuiBackendFlags_HasMouseCursors
@ ImGuiBackendFlags_HasMouseCursors
Definition: imgui.h:1078
enabled
GLenum GLenum GLsizei const GLuint GLboolean enabled
Definition: glcorearb.h:4174
CalcResizePosSizeFromAnyCorner
static void CalcResizePosSizeFromAnyCorner(ImGuiWindow *window, const ImVec2 &corner_target, const ImVec2 &corner_norm, ImVec2 *out_pos, ImVec2 *out_size)
Definition: imgui.cpp:4986
ImGui::FindBestWindowPosForPopupEx
IMGUI_API ImVec2 FindBestWindowPosForPopupEx(const ImVec2 &ref_pos, const ImVec2 &size, ImGuiDir *last_dir, const ImRect &r_outer, const ImRect &r_avoid, ImGuiPopupPositionPolicy policy=ImGuiPopupPositionPolicy_Default)
Definition: imgui.cpp:7798
ImGuiWindow::SkipItems
bool SkipItems
Definition: imgui_internal.h:1483
ImGuiWindow::ItemWidthDefault
float ItemWidthDefault
Definition: imgui_internal.h:1519
ImGui::SaveIniSettingsToDisk
IMGUI_API void SaveIniSettingsToDisk(const char *ini_filename)
Definition: imgui.cpp:9677
ImGui::GetScrollX
IMGUI_API float GetScrollX()
Definition: imgui.cpp:7329
ImGuiIO::MouseDown
bool MouseDown[5]
Definition: imgui.h:1486
ImGuiWindowFlags_AlwaysUseWindowPadding
@ ImGuiWindowFlags_AlwaysUseWindowPadding
Definition: imgui.h:785
ImGui::CalcListClipping
IMGUI_API void CalcListClipping(int items_count, float items_height, int *out_items_display_start, int *out_items_display_end)
Definition: imgui.cpp:2209
ImGuiContext::IO
ImGuiIO IO
Definition: imgui_internal.h:1022
CalcWindowSizeAfterConstraint
static ImVec2 CalcWindowSizeAfterConstraint(ImGuiWindow *window, ImVec2 new_size)
Definition: imgui.cpp:4887
ImGuiNextWindowDataFlags_HasPos
@ ImGuiNextWindowDataFlags_HasPos
Definition: imgui_internal.h:945
ImGuiIO::UserData
void * UserData
Definition: imgui.h:1433
ImGui::FindWindowFocusIndex
static int FindWindowFocusIndex(ImGuiWindow *window)
Definition: imgui.cpp:8787
ImGuiIO::MetricsRenderIndices
int MetricsRenderIndices
Definition: imgui.h:1515
ImGuiWindowTempData::PrevLineSize
ImVec2 PrevLineSize
Definition: imgui_internal.h:1372
ImGuiTextFilter::PassFilter
IMGUI_API bool PassFilter(const char *text, const char *text_end=NULL) const
Definition: imgui.cpp:2097
ImGuiWindow::FontWindowScale
float FontWindowScale
Definition: imgui_internal.h:1522
ImGuiColumns::Flags
ImGuiColumnsFlags Flags
Definition: imgui_internal.h:858
ImGui::End
IMGUI_API void End()
Definition: imgui.cpp:6007
ImGuiTextBuffer
Definition: imgui.h:1702
ImGuiTooltipFlags_None
@ ImGuiTooltipFlags_None
Definition: imgui_internal.h:560
ImGui::IsKeyPressed
IMGUI_API bool IsKeyPressed(int user_key_index, bool repeat=true)
Definition: imgui.cpp:4404
ImGui::IsClippedEx
IMGUI_API bool IsClippedEx(const ImRect &bb, ImGuiID id, bool clip_even_when_logged)
Definition: imgui.cpp:3140
ImVec4::y
float y
Definition: imgui.h:223
ImGuiWindow::SetWindowPosVal
ImVec2 SetWindowPosVal
Definition: imgui_internal.h:1502
ImDrawList::AddCircleFilled
IMGUI_API void AddCircleFilled(const ImVec2 &center, float radius, ImU32 col, int num_segments=12)
Definition: imgui_draw.cpp:1141
ImGuiStyle::ItemInnerSpacing
ImVec2 ItemInnerSpacing
Definition: imgui.h:1382
ImGuiIO::ConfigInputTextCursorBlink
bool ConfigInputTextCursorBlink
Definition: imgui.h:1444
ImGui::Combo
IMGUI_API bool Combo(const char *label, int *current_item, const char *const items[], int items_count, int popup_max_height_in_items=-1)
Definition: imgui_widgets.cpp:1628
ImGui::SetWindowFontScale
IMGUI_API void SetWindowFontScale(float scale)
Definition: imgui.cpp:6550
ImGuiNavMoveResult::FocusScopeId
ImGuiID FocusScopeId
Definition: imgui_internal.h:932
ImGuiKeyModFlags
int ImGuiKeyModFlags
Definition: imgui.h:163
ImRect::GetBR
ImVec2 GetBR() const
Definition: imgui_internal.h:701
ImGui::GetBackgroundDrawList
IMGUI_API ImDrawList * GetBackgroundDrawList()
Definition: imgui.cpp:3309
GImGui
ImGuiContext * GImGui
Definition: imgui.cpp:975
ImGui::ClosePopupsOverWindow
IMGUI_API void ClosePopupsOverWindow(ImGuiWindow *ref_window, bool restore_focus_to_window_under_popup)
Definition: imgui.cpp:7571
ImGuiWindowTempData::TextWrapPos
float TextWrapPos
Definition: imgui_internal.h:1412
ImGuiTextFilter::Build
IMGUI_API void Build()
Definition: imgui.cpp:2076
ImDrawListSharedData::TexUvWhitePixel
ImVec2 TexUvWhitePixel
Definition: imgui_internal.h:903
ImGuiHoveredFlags_AllowWhenDisabled
@ ImGuiHoveredFlags_AllowWhenDisabled
Definition: imgui.h:930
ImGui::NavScoreItem
static bool NavScoreItem(ImGuiNavMoveResult *result, ImRect cand)
Definition: imgui.cpp:7984
ImGuiPopupPositionPolicy
ImGuiPopupPositionPolicy
Definition: imgui_internal.h:659
ImGui::GcCompactTransientWindowBuffers
IMGUI_API void GcCompactTransientWindowBuffers(ImGuiWindow *window)
Definition: imgui.cpp:2945
ImGui::ColorConvertHSVtoRGB
IMGUI_API void ColorConvertHSVtoRGB(float h, float s, float v, float &out_r, float &out_g, float &out_b)
Definition: imgui.cpp:1853
ImGuiIO::MouseClicked
bool MouseClicked[5]
Definition: imgui.h:1529
ImGuiWindow::Scroll
ImVec2 Scroll
Definition: imgui_internal.h:1472
ImVector::Data
T * Data
Definition: imgui.h:1305
ImGui::SetNextWindowFocus
IMGUI_API void SetNextWindowFocus()
Definition: imgui.cpp:6516
ImGuiNavMoveFlags_WrapX
@ ImGuiNavMoveFlags_WrapX
Definition: imgui_internal.h:638
IM_COL32_A_MASK
#define IM_COL32_A_MASK
Definition: imgui.h:1818
ImGui::SetItemAllowOverlap
IMGUI_API void SetItemAllowOverlap()
Definition: imgui.cpp:4659
ImGuiWindow::TitleBarHeight
float TitleBarHeight() const
Definition: imgui_internal.h:1555
ImGuiSizeCallbackData
Definition: imgui.h:1589
CalcNextScrollFromScrollTargetAndClamp
static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow *window, bool snap_on_edges)
Definition: imgui.cpp:7263
ImGuiWindow::ID
ImGuiID ID
Definition: imgui_internal.h:1459
ImStrbolW
const ImWchar * ImStrbolW(const ImWchar *buf_mid_line, const ImWchar *buf_begin)
Definition: imgui.cpp:1367
ImGuiWindowTempData::TreeDepth
int TreeDepth
Definition: imgui_internal.h:1398
ImGuiItemStatusFlags_None
@ ImGuiItemStatusFlags_None
Definition: imgui_internal.h:534
ImGuiNavInput_KeyMenu_
@ ImGuiNavInput_KeyMenu_
Definition: imgui.h:1048
ImGuiIO::LogFilename
const char * LogFilename
Definition: imgui.h:1426
ImGuiCol_TabActive
@ ImGuiCol_TabActive
Definition: imgui.h:1121
ImGuiTabItem::NameOffset
int NameOffset
Definition: imgui_internal.h:1599
IMGUI_TEST_ENGINE_ITEM_ADD
#define IMGUI_TEST_ENGINE_ITEM_ADD(_BB, _ID)
Definition: imgui_internal.h:1934
ImGuiIO::AddInputCharactersUTF8
IMGUI_API void AddInputCharactersUTF8(const char *str)
Definition: imgui.cpp:1161
ImVector::clear
void clear()
Definition: imgui.h:1325
ImGuiSettingsHandler::ReadOpenFn
void *(* ReadOpenFn)(ImGuiContext *ctx, ImGuiSettingsHandler *handler, const char *name)
Definition: imgui_internal.h:823
ImGuiStyleVarInfo::Count
ImU32 Count
Definition: imgui.cpp:2413
ImGui::SetItemDefaultFocus
IMGUI_API void SetItemDefaultFocus()
Definition: imgui.cpp:6590
ImGui::BeginPopupContextItem
IMGUI_API bool BeginPopupContextItem(const char *str_id=NULL, ImGuiMouseButton mouse_button=1)
Definition: imgui.cpp:7763
ImGuiIO::ConfigMacOSXBehaviors
bool ConfigMacOSXBehaviors
Definition: imgui.h:1443
ImGuiNavDirSourceFlags_PadDPad
@ ImGuiNavDirSourceFlags_PadDPad
Definition: imgui_internal.h:629
ImGuiIO::IniSavingRate
float IniSavingRate
Definition: imgui.h:1424
border
GLint GLint GLsizei GLint border
Definition: glcorearb.h:2773
ImGui::SetTooltipV
IMGUI_API void SetTooltipV(const char *fmt, va_list args) IM_FMTLIST(1)
Definition: imgui.cpp:7478
ImFont::Scale
float Scale
Definition: imgui.h:2292
ImGuiDataType
int ImGuiDataType
Definition: imgui.h:145
ImGui::SetScrollX
IMGUI_API void SetScrollX(float scroll_x)
Definition: imgui.cpp:7353
ImGuiWindowTempData::CursorMaxPos
ImVec2 CursorMaxPos
Definition: imgui_internal.h:1370
ImGuiMouseButton
int ImGuiMouseButton
Definition: imgui.h:149
offset
GLintptr offset
Definition: glcorearb.h:2944
ImGuiInputSource_COUNT
@ ImGuiInputSource_COUNT
Definition: imgui_internal.h:602
ImGuiIO::ConfigFlags
ImGuiConfigFlags ConfigFlags
Definition: imgui.h:1420
ImGui::SetNavIDWithRectRel
IMGUI_API void SetNavIDWithRectRel(ImGuiID id, int nav_layer, ImGuiID focus_scope_id, const ImRect &rect_rel)
Definition: imgui.cpp:7919
ImGuiItemFlags
int ImGuiItemFlags
Definition: imgui_internal.h:106
ImGuiNavForward_ForwardActive
@ ImGuiNavForward_ForwardActive
Definition: imgui_internal.h:649
ImGuiNavMoveFlags_LoopX
@ ImGuiNavMoveFlags_LoopX
Definition: imgui_internal.h:636
ImGuiKeyModFlags_Shift
@ ImGuiKeyModFlags_Shift
Definition: imgui.h:1017
ImGuiNavMoveFlags_LoopY
@ ImGuiNavMoveFlags_LoopY
Definition: imgui_internal.h:637
ImGuiNavInput_FocusPrev
@ ImGuiNavInput_FocusPrev
Definition: imgui.h:1041
ImGuiContext::WantCaptureKeyboardNextFrame
int WantCaptureKeyboardNextFrame
Definition: imgui_internal.h:1224
id
GLenum GLuint id
Definition: glcorearb.h:2695
ImGuiNavInput_DpadLeft
@ ImGuiNavInput_DpadLeft
Definition: imgui.h:1033
ImGui::GetContentRegionMaxAbs
IMGUI_API ImVec2 GetContentRegionMaxAbs()
Definition: imgui.cpp:7143
ImFileOpen
ImFileHandle ImFileOpen(const char *filename, const char *mode)
Definition: imgui.cpp:1548
AddRootWindowToDrawData
static void AddRootWindowToDrawData(ImGuiWindow *window)
Definition: imgui.cpp:4085
va_copy
#define va_copy(dest, src)
Definition: imgui.cpp:2141
start
GLuint start
Definition: glcorearb.h:2858
ImGuiKey_DownArrow
@ ImGuiKey_DownArrow
Definition: imgui.h:991
ImGuiIO::MouseDownDurationPrev
float MouseDownDurationPrev[5]
Definition: imgui.h:1535
ImGui::UpdateWindowParentAndRootLinks
IMGUI_API void UpdateWindowParentAndRootLinks(ImGuiWindow *window, ImGuiWindowFlags flags, ImGuiWindow *parent_window)
Definition: imgui.cpp:5375
ImGui::BeginChild
IMGUI_API bool BeginChild(const char *str_id, const ImVec2 &size=ImVec2(0, 0), bool border=false, ImGuiWindowFlags flags=0)
Definition: imgui.cpp:4743
ImGuiHoveredFlags_RootWindow
@ ImGuiHoveredFlags_RootWindow
Definition: imgui.h:924
ImGui::IsMouseDragPastThreshold
IMGUI_API bool IsMouseDragPastThreshold(ImGuiMouseButton button, float lock_threshold=-1.0f)
Definition: imgui.cpp:4466
ImGuiStyle::CircleSegmentMaxError
float CircleSegmentMaxError
Definition: imgui.h:1401
ImGuiStorage::GetVoidPtrRef
IMGUI_API void ** GetVoidPtrRef(ImGuiID key, void *default_val=NULL)
Definition: imgui.cpp:1976
ImDrawData
Definition: imgui.h:2068
ImGuiIO::Framerate
float Framerate
Definition: imgui.h:1513
ImGuiContext::NextItemData
ImGuiNextItemData NextItemData
Definition: imgui_internal.h:1081
ImGuiContext::BeginPopupStack
ImVector< ImGuiPopupData > BeginPopupStack
Definition: imgui_internal.h:1088
ImGui::SetFocusID
IMGUI_API void SetFocusID(ImGuiID id, ImGuiWindow *window)
Definition: imgui.cpp:7929
ImGuiNavInput_DpadDown
@ ImGuiNavInput_DpadDown
Definition: imgui.h:1036
ImGuiWindow::DrawList
ImDrawList * DrawList
Definition: imgui_internal.h:1525
ImGuiLogType_File
@ ImGuiLogType_File
Definition: imgui_internal.h:576
ImFileClose
bool ImFileClose(ImFileHandle f)
Definition: imgui.cpp:1566
update_failure_list.str
str
Definition: update_failure_list.py:41
ImGuiBackendFlags_HasSetMousePos
@ ImGuiBackendFlags_HasSetMousePos
Definition: imgui.h:1079
ImVector::Size
int Size
Definition: imgui.h:1303
ImDrawVert
Definition: imgui.h:1893
ImStrncpy
void ImStrncpy(char *dst, const char *src, size_t count)
Definition: imgui.cpp:1316
ImVec2::x
float x
Definition: imgui.h:210
ImGuiContext::Time
double Time
Definition: imgui_internal.h:1028
ImStristr
const char * ImStristr(const char *haystack, const char *haystack_end, const char *needle, const char *needle_end)
Definition: imgui.cpp:1374
ImGui::ItemAdd
IMGUI_API bool ItemAdd(const ImRect &bb, ImGuiID id, const ImRect *nav_bb=NULL)
Definition: imgui.cpp:6864
ImGuiNavMoveResult::Window
ImGuiWindow * Window
Definition: imgui_internal.h:930
ImGuiColumns::ID
ImGuiID ID
Definition: imgui_internal.h:857
ImGui::GetScrollMaxX
IMGUI_API float GetScrollMaxX()
Definition: imgui.cpp:7341
ImGuiStyle
Definition: imgui.h:1365
ImGuiDir_Up
@ ImGuiDir_Up
Definition: imgui.h:979
ImGui::FindWindowSettings
IMGUI_API ImGuiWindowSettings * FindWindowSettings(ImGuiID id)
Definition: imgui.cpp:9585
ImTriangleBarycentricCoords
void ImTriangleBarycentricCoords(const ImVec2 &a, const ImVec2 &b, const ImVec2 &c, const ImVec2 &p, float &out_u, float &out_v, float &out_w)
Definition: imgui.cpp:1270
ImGuiDragDropFlags_SourceNoDisableHover
@ ImGuiDragDropFlags_SourceNoDisableHover
Definition: imgui.h:941
ImGui::GetWindowAllowedExtentRect
IMGUI_API ImRect GetWindowAllowedExtentRect(ImGuiWindow *window)
Definition: imgui.cpp:7851
ImGuiItemStatusFlags_ToggledSelection
@ ImGuiItemStatusFlags_ToggledSelection
Definition: imgui_internal.h:538
ImGui::ErrorCheckEndFrameSanityChecks
static void ErrorCheckEndFrameSanityChecks()
Definition: imgui.cpp:6738
ImGui::PopItemFlag
IMGUI_API void PopItemFlag()
Definition: imgui.cpp:6194
ImRect::Add
void Add(const ImVec2 &p)
Definition: imgui_internal.h:705
ImVector::push_back
void push_back(const T &v)
Definition: imgui.h:1343
ImGuiCol_SeparatorActive
@ ImGuiCol_SeparatorActive
Definition: imgui.h:1115
ImGuiStyle::ColumnsMinSpacing
float ColumnsMinSpacing
Definition: imgui.h:1385
ImGuiTextFilter::ImGuiTextRange::b
const char * b
Definition: imgui.h:1687
ImHashData
ImU32 ImHashData(const void *data_p, size_t data_size, ImU32 seed)
Definition: imgui.cpp:1497
ImGui::UpdateSettings
static void UpdateSettings()
Definition: imgui.cpp:9521
ImGuiWindow::ScrollbarSizes
ImVec2 ScrollbarSizes
Definition: imgui_internal.h:1476
ImGui::MemAlloc
IMGUI_API void * MemAlloc(size_t size)
Definition: imgui.cpp:3210
ImGuiTextFilter::Filters
ImVector< ImGuiTextRange > Filters
Definition: imgui.h:1696
WindowSettingsHandler_ReadLine
static void WindowSettingsHandler_ReadLine(ImGuiContext *, ImGuiSettingsHandler *, void *entry, const char *line)
Definition: imgui.cpp:9718
ImGuiWindow::Active
bool Active
Definition: imgui_internal.h:1478
ImGui::TextDisabled
IMGUI_API void TextDisabled(const char *fmt,...) IM_FMTARGS(1)
Definition: imgui_widgets.cpp:281
ImGui::LogRenderedText
IMGUI_API void LogRenderedText(const ImVec2 *ref_pos, const char *text, const char *text_end=NULL)
Definition: imgui.cpp:9333
ImGuiCol_ChildBg
@ ImGuiCol_ChildBg
Definition: imgui.h:1089
ImGuiWindowTempData::NavLayerCurrentMask
int NavLayerCurrentMask
Definition: imgui_internal.h:1387
testing::internal::fmt
GTEST_API_ const char * fmt
Definition: gtest.h:1835
ImGui::PushID
IMGUI_API void PushID(const char *str_id)
Definition: imgui.cpp:6619
ImGui::GetCursorPosX
IMGUI_API float GetCursorPosX()
Definition: imgui.cpp:6967
MallocWrapper
static void * MallocWrapper(size_t size, void *user_data)
Definition: imgui.cpp:982
ImGuiInputReadMode
ImGuiInputReadMode
Definition: imgui_internal.h:606
ImGui::CalcItemWidth
IMGUI_API float CalcItemWidth()
Definition: imgui.cpp:7062
ImGuiLayoutType_Vertical
@ ImGuiLayoutType_Vertical
Definition: imgui_internal.h:569
p
const char * p
Definition: gmock-matchers_test.cc:3863
ImGui::GetStyleColorVec4
const IMGUI_API ImVec4 & GetStyleColorVec4(ImGuiCol idx)
Definition: imgui.cpp:2361
ImGui::SetTooltip
IMGUI_API void SetTooltip(const char *fmt,...) IM_FMTARGS(1)
Definition: imgui.cpp:7485
ImGui::ScrollToBringRectIntoView
IMGUI_API ImVec2 ScrollToBringRectIntoView(ImGuiWindow *window, const ImRect &item_rect)
Definition: imgui.cpp:7300
ImGui::UpdateHoveredWindowAndCaptureFlags
IMGUI_API void UpdateHoveredWindowAndCaptureFlags()
Definition: imgui.cpp:3622
ImGuiStorage::GetInt
IMGUI_API int GetInt(ImGuiID key, int default_val=0) const
Definition: imgui.cpp:1925
ImGuiIO::MousePosPrev
ImVec2 MousePosPrev
Definition: imgui.h:1526
ImGui::TreePop
IMGUI_API void TreePop()
Definition: imgui_widgets.cpp:5479
ImGuiCol_Text
@ ImGuiCol_Text
Definition: imgui.h:1086
ImGuiNavInput_KeyUp_
@ ImGuiNavInput_KeyUp_
Definition: imgui.h:1051
ImGuiWindow::InnerClipRect
ImRect InnerClipRect
Definition: imgui_internal.h:1512
ImGui::GetNavInputAmount2d
IMGUI_API ImVec2 GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor=0.0f, float fast_factor=0.0f)
Definition: imgui.cpp:8355
ImGuiStyle::DisplaySafeAreaPadding
ImVec2 DisplaySafeAreaPadding
Definition: imgui.h:1396
ImDrawList::Clear
IMGUI_API void Clear()
Definition: imgui_draw.cpp:379
ImGui::NavProcessItem
static void NavProcessItem(ImGuiWindow *window, const ImRect &nav_bb, ImGuiID id)
Definition: imgui.cpp:8116
ImGuiNavForward_None
@ ImGuiNavForward_None
Definition: imgui_internal.h:647
googletest-filter-unittest.child
child
Definition: googletest-filter-unittest.py:62
IM_ROUND
#define IM_ROUND(_VAL)
Definition: imgui_internal.h:186
ImGui::DestroyContext
IMGUI_API void DestroyContext(ImGuiContext *ctx=NULL)
Definition: imgui.cpp:3276
ImGui::EndGroup
IMGUI_API void EndGroup()
Definition: imgui.cpp:7204
ImGuiStorage::GetFloat
IMGUI_API float GetFloat(ImGuiID key, float default_val=0.0f) const
Definition: imgui.cpp:1938
IM_ALLOC
#define IM_ALLOC(_SIZE)
Definition: imgui.h:1283
ImGui::IsWindowNavFocusable
IMGUI_API bool IsWindowNavFocusable(ImGuiWindow *window)
Definition: imgui.cpp:6314
IM_OFFSETOF
#define IM_OFFSETOF(_TYPE, _MEMBER)
Definition: imgui.h:93
ImGui::OpenPopupOnItemClick
IMGUI_API bool OpenPopupOnItemClick(const char *str_id=NULL, ImGuiMouseButton mouse_button=1)
Definition: imgui.cpp:7747
ImGui::IsWindowCollapsed
IMGUI_API bool IsWindowCollapsed()
Definition: imgui.cpp:6434
ImGuiContext::DrawData
ImDrawData DrawData
Definition: imgui_internal.h:1144
ImTriangleArea
float ImTriangleArea(const ImVec2 &a, const ImVec2 &b, const ImVec2 &c)
Definition: imgui_internal.h:354
ImGuiWindowTempData::LayoutType
ImGuiLayoutType LayoutType
Definition: imgui_internal.h:1403
size
#define size
Definition: glcorearb.h:2944
ImGuiColumns::OffMaxX
float OffMaxX
Definition: imgui_internal.h:863
ImGui::PopID
IMGUI_API void PopID()
Definition: imgui.cpp:6650
ImGuiCol_ButtonHovered
@ ImGuiCol_ButtonHovered
Definition: imgui.h:1108
ImTextCountCharsFromUtf8
int ImTextCountCharsFromUtf8(const char *in_text, const char *in_text_end)
Definition: imgui.cpp:1699
ImGuiKey_LeftArrow
@ ImGuiKey_LeftArrow
Definition: imgui.h:988
ImGuiInputSource_NavKeyboard
@ ImGuiInputSource_NavKeyboard
Definition: imgui_internal.h:600
IM_ARRAYSIZE
#define IM_ARRAYSIZE(_ARR)
Definition: imgui.h:88
ImGuiPopupData::OpenPopupPos
ImVec2 OpenPopupPos
Definition: imgui_internal.h:839
ImGuiCol_TabUnfocused
@ ImGuiCol_TabUnfocused
Definition: imgui.h:1122
ImGui::TreeNode
IMGUI_API bool TreeNode(const char *label)
Definition: imgui_widgets.cpp:5148
ImGui::EndFrame
IMGUI_API void EndFrame()
Definition: imgui.cpp:4143
ImGui::UpdateWindowManualResize
static bool UpdateWindowManualResize(ImGuiWindow *window, const ImVec2 &size_auto_fit, int *border_held, int resize_grip_count, ImU32 resize_grip_col[4])
Definition: imgui.cpp:5040
ImGui::SetHoveredID
IMGUI_API void SetHoveredID(ImGuiID id)
Definition: imgui.cpp:3006
ImGuiGroupData::BackupActiveIdIsAlive
ImGuiID BackupActiveIdIsAlive
Definition: imgui_internal.h:752
ImGui::BeginPopupEx
IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags)
Definition: imgui.cpp:7664
ImGui::BeginDragDropTarget
IMGUI_API bool BeginDragDropTarget()
Definition: imgui.cpp:9212
ImGui::GetStateStorage
IMGUI_API ImGuiStorage * GetStateStorage()
Definition: imgui.cpp:6613
ImDrawDataBuilder::Layers
ImVector< ImDrawList * > Layers[2]
Definition: imgui_internal.h:921
ImGuiWindow::HiddenFramesCannotSkipItems
int HiddenFramesCannotSkipItems
Definition: imgui_internal.h:1498
ImGui::SaveIniSettingsToMemory
const IMGUI_API char * SaveIniSettingsToMemory(size_t *out_ini_size=NULL)
Definition: imgui.cpp:9694
ImGui::IsKeyReleased
IMGUI_API bool IsKeyReleased(int user_key_index)
Definition: imgui.cpp:4418
ImGui::ActivateItem
IMGUI_API void ActivateItem(ImGuiID id)
Definition: imgui.cpp:6558
ImGuiTextBuffer::append
IMGUI_API void append(const char *str, const char *str_end=NULL)
Definition: imgui.cpp:2147
ImVector::reserve
void reserve(int new_capacity)
Definition: imgui.h:1340
ImGui::FindRenderedTextEnd
const IMGUI_API char * FindRenderedTextEnd(const char *text, const char *text_end=NULL)
Definition: imgui.cpp:2561
ImGuiCol_PlotHistogramHovered
@ ImGuiCol_PlotHistogramHovered
Definition: imgui.h:1127
ImRect
Definition: imgui_internal.h:684
sc
void * sc
Definition: test_channel.cpp:9
ImGui::SetActiveID
IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow *window)
Definition: imgui.cpp:2969
ImGuiWindowFlags_Tooltip
@ ImGuiWindowFlags_Tooltip
Definition: imgui.h:796
ImGuiPopupData::SourceWindow
ImGuiWindow * SourceWindow
Definition: imgui_internal.h:836
ImGuiWindow::MemoryDrawListIdxCapacity
int MemoryDrawListIdxCapacity
Definition: imgui_internal.h:1537
ImGuiWindowSettings::Collapsed
bool Collapsed
Definition: imgui_internal.h:813
ImGuiHoveredFlags_AllowWhenOverlapped
@ ImGuiHoveredFlags_AllowWhenOverlapped
Definition: imgui.h:929
ImGuiDragDropFlags_SourceAllowNullID
@ ImGuiDragDropFlags_SourceAllowNullID
Definition: imgui.h:943
ImGuiStyle::ImGuiStyle
IMGUI_API ImGuiStyle()
Definition: imgui.cpp:997
ImGuiStyle::ChildRounding
float ChildRounding
Definition: imgui.h:1374
ImGuiNextWindowDataFlags_HasSize
@ ImGuiNextWindowDataFlags_HasSize
Definition: imgui_internal.h:946
ImGui::IsActiveIdUsingKey
bool IsActiveIdUsingKey(ImGuiKey key)
Definition: imgui_internal.h:1775
ImGui::ColorConvertU32ToFloat4
IMGUI_API ImVec4 ColorConvertU32ToFloat4(ImU32 in)
Definition: imgui.cpp:1809
ImGuiIO::ImGuiIO
IMGUI_API ImGuiIO()
Definition: imgui.cpp:1065
d
d
ImGuiCol_Border
@ ImGuiCol_Border
Definition: imgui.h:1091
ImGuiSettingsHandler
Definition: imgui_internal.h:819
ImGui::IsKeyPressedMap
bool IsKeyPressedMap(ImGuiKey key, bool repeat=true)
Definition: imgui_internal.h:1777
ImGuiWindowFlags_NoFocusOnAppearing
@ ImGuiWindowFlags_NoFocusOnAppearing
Definition: imgui.h:781
GetViewportRect
static ImRect GetViewportRect()
Definition: imgui.cpp:4686
ImGui::ErrorCheckNewFrameSanityChecks
static void ErrorCheckNewFrameSanityChecks()
Definition: imgui.cpp:6709
ImGuiCol_ButtonActive
@ ImGuiCol_ButtonActive
Definition: imgui.h:1109
ImGuiWindowFlags_HorizontalScrollbar
@ ImGuiWindowFlags_HorizontalScrollbar
Definition: imgui.h:780
ImGui::NavSaveLastChildNavWindowIntoParent
static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow *nav_window)
Definition: imgui.cpp:8250
ImGuiItemStatusFlags_HoveredRect
@ ImGuiItemStatusFlags_HoveredRect
Definition: imgui_internal.h:535
ImGui::Checkbox
IMGUI_API bool Checkbox(const char *label, bool *v)
Definition: imgui_widgets.cpp:1008
ImGuiWindow::NavRectRel
ImRect NavRectRel[ImGuiNavLayer_COUNT]
Definition: imgui_internal.h:1534
ImGui::AcceptDragDropPayload
const IMGUI_API ImGuiPayload * AcceptDragDropPayload(const char *type, ImGuiDragDropFlags flags=0)
Definition: imgui.cpp:9244
ImGuiWindowFlags_ChildWindow
@ ImGuiWindowFlags_ChildWindow
Definition: imgui.h:795
ImDrawData::TotalVtxCount
int TotalVtxCount
Definition: imgui.h:2074
ImGuiNavForward_ForwardQueued
@ ImGuiNavForward_ForwardQueued
Definition: imgui_internal.h:648
WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS
static const float WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS
Definition: imgui.cpp:894
ImGuiContext::HoveredIdAllowOverlap
bool HoveredIdAllowOverlap
Definition: imgui_internal.h:1053
ImRect::GetWidth
float GetWidth() const
Definition: imgui_internal.h:696
ImGuiIO::ImeSetInputScreenPosFn
void(* ImeSetInputScreenPosFn)(int x, int y)
Definition: imgui.h:1469
ImGui::NavUpdate
static void NavUpdate()
Definition: imgui.cpp:8371
ImGui::IsMousePosValid
IMGUI_API bool IsMousePosValid(const ImVec2 *mouse_pos=NULL)
Definition: imgui.cpp:4500
ImGuiDir_Left
@ ImGuiDir_Left
Definition: imgui.h:977
ImDrawList::_VtxCurrentIdx
unsigned int _VtxCurrentIdx
Definition: imgui.h:1973
ImGui::CreateContext
IMGUI_API ImGuiContext * CreateContext(ImFontAtlas *shared_font_atlas=NULL)
Definition: imgui.cpp:3267
ImGui::GetFrameCount
IMGUI_API int GetFrameCount()
Definition: imgui.cpp:3304
ImGui::StartMouseMovingWindow
IMGUI_API void StartMouseMovingWindow(ImGuiWindow *window)
Definition: imgui.cpp:3324
ImGuiTextBuffer::EmptyString
static IMGUI_API char EmptyString[1]
Definition: imgui.h:1705
ImVec4::x
float x
Definition: imgui.h:223
ImGuiCol_PlotLines
@ ImGuiCol_PlotLines
Definition: imgui.h:1124
ImGuiInputReadMode_Pressed
@ ImGuiInputReadMode_Pressed
Definition: imgui_internal.h:609
ImGuiSettingsHandler::ReadLineFn
void(* ReadLineFn)(ImGuiContext *ctx, ImGuiSettingsHandler *handler, void *entry, const char *line)
Definition: imgui_internal.h:824
ImMax
static T ImMax(T lhs, T rhs)
Definition: imgui_internal.h:321
ImGui::LoadIniSettingsFromMemory
IMGUI_API void LoadIniSettingsFromMemory(const char *ini_data, size_t ini_size=0)
Definition: imgui.cpp:9622
ImGuiCol_TabHovered
@ ImGuiCol_TabHovered
Definition: imgui.h:1120
buf
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glcorearb.h:4175
ImGuiWindow::TitleBarRect
ImRect TitleBarRect() const
Definition: imgui_internal.h:1556
ImGui::GetMousePos
IMGUI_API ImVec2 GetMousePos()
Definition: imgui.cpp:4484
key
const SETUP_TEARDOWN_TESTCONTEXT char * key
Definition: test_wss_transport.cpp:10
ImGuiNextWindowDataFlags_HasFocus
@ ImGuiNextWindowDataFlags_HasFocus
Definition: imgui_internal.h:950
ImGuiContext
Definition: imgui_internal.h:1018
ImU32
unsigned int ImU32
Definition: imgui.h:194
ImGui::IsActiveIdUsingNavInput
bool IsActiveIdUsingNavInput(ImGuiNavInput input)
Definition: imgui_internal.h:1774
ImFont::CalcTextSizeA
IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char *text_begin, const char *text_end=NULL, const char **remaining=NULL) const
Definition: imgui_draw.cpp:2871
ImGuiNextItemDataFlags_HasWidth
@ ImGuiNextItemDataFlags_HasWidth
Definition: imgui_internal.h:979
SetCurrentWindow
static void SetCurrentWindow(ImGuiWindow *window)
Definition: imgui.cpp:2931
ImRect::Contains
bool Contains(const ImVec2 &p) const
Definition: imgui_internal.h:702
ImGui::FocusableItemUnregister
IMGUI_API void FocusableItemUnregister(ImGuiWindow *window)
Definition: imgui.cpp:3189
ImGuiIO::ConfigWindowsMemoryCompactTimer
float ConfigWindowsMemoryCompactTimer
Definition: imgui.h:1447
ImGui::CreateNewWindowSettings
IMGUI_API ImGuiWindowSettings * CreateNewWindowSettings(const char *name)
Definition: imgui.cpp:9563
ImGuiCol_TabUnfocusedActive
@ ImGuiCol_TabUnfocusedActive
Definition: imgui.h:1123
ImFontGlyph::X1
float X1
Definition: imgui.h:2125
SetWindowConditionAllowFlags
static void SetWindowConditionAllowFlags(ImGuiWindow *window, ImGuiCond flags, bool enabled)
Definition: imgui.cpp:4818
ImGui::IsAnyItemActive
IMGUI_API bool IsAnyItemActive()
Definition: imgui.cpp:4634
ImGuiWindowTempData::ChildWindows
ImVector< ImGuiWindow * > ChildWindows
Definition: imgui_internal.h:1400
ImGui::SetNextWindowSize
IMGUI_API void SetNextWindowSize(const ImVec2 &size, ImGuiCond cond=0)
Definition: imgui.cpp:6480
ImGuiBackendFlags_RendererHasVtxOffset
@ ImGuiBackendFlags_RendererHasVtxOffset
Definition: imgui.h:1080
ImTextCharToUtf8
static int ImTextCharToUtf8(char *buf, int buf_size, unsigned int c)
Definition: imgui.cpp:1714
ImGuiNavInput_LStickUp
@ ImGuiNavInput_LStickUp
Definition: imgui.h:1039
ImGuiWindow::ClipRect
ImRect ClipRect
Definition: imgui_internal.h:1514
WindowSettingsHandler_WriteAll
static void WindowSettingsHandler_WriteAll(ImGuiContext *, ImGuiSettingsHandler *, ImGuiTextBuffer *buf)
Definition: imgui.cpp:9728
ImGuiCol_MenuBarBg
@ ImGuiCol_MenuBarBg
Definition: imgui.h:1099
ImGui::SetCursorScreenPos
IMGUI_API void SetCursorScreenPos(const ImVec2 &pos)
Definition: imgui.cpp:6952
ImGuiIO::FontDefault
ImFont * FontDefault
Definition: imgui.h:1438
ImGuiCol_WindowBg
@ ImGuiCol_WindowBg
Definition: imgui.h:1088
ImGuiDragDropFlags_SourceNoPreviewTooltip
@ ImGuiDragDropFlags_SourceNoPreviewTooltip
Definition: imgui.h:940
ImGuiCol_ScrollbarGrabActive
@ ImGuiCol_ScrollbarGrabActive
Definition: imgui.h:1103
ImRect::GetBL
ImVec2 GetBL() const
Definition: imgui_internal.h:700
ImGuiWindow::Pos
ImVec2 Pos
Definition: imgui_internal.h:1461
ImGuiDragDropFlags_SourceAutoExpirePayload
@ ImGuiDragDropFlags_SourceAutoExpirePayload
Definition: imgui.h:945
ImDrawList::_OwnerName
const char * _OwnerName
Definition: imgui.h:1971
ImGui::SetNextWindowCollapsed
IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond=0)
Definition: imgui.cpp:6507
ImGui::GetContentRegionAvail
IMGUI_API ImVec2 GetContentRegionAvail()
Definition: imgui.cpp:7153
ImGuiWindow::InnerRect
ImRect InnerRect
Definition: imgui_internal.h:1511
ImStrnicmp
int ImStrnicmp(const char *str1, const char *str2, size_t count)
Definition: imgui.cpp:1309
ImGuiListClipper::Step
IMGUI_API bool Step()
Definition: imgui.cpp:2295
ImGuiStyle::WindowMinSize
ImVec2 WindowMinSize
Definition: imgui.h:1371
layer
GLenum GLuint GLint GLint layer
Definition: glcorearb.h:3469
IM_NEWLINE
#define IM_NEWLINE
Definition: imgui_demo.cpp:113
ImGuiPayload::Preview
bool Preview
Definition: imgui.h:1609
ImGuiWindow::ContentSizeExplicit
ImVec2 ContentSizeExplicit
Definition: imgui_internal.h:1465
ImGui::GetForegroundDrawList
IMGUI_API ImDrawList * GetForegroundDrawList()
Definition: imgui.cpp:3314
ImGuiGroupData
Definition: imgui_internal.h:744
ImDrawList::AddLine
IMGUI_API void AddLine(const ImVec2 &p1, const ImVec2 &p2, ImU32 col, float thickness=1.0f)
Definition: imgui_draw.cpp:1011
ImGui::ClearDragDrop
IMGUI_API void ClearDragDrop()
Definition: imgui.cpp:9008
ImGui::GetFontSize
IMGUI_API float GetFontSize()
Definition: imgui.cpp:6540
ImGui::ColorConvertFloat4ToU32
IMGUI_API ImU32 ColorConvertFloat4ToU32(const ImVec4 &in)
Definition: imgui.cpp:1819
ImGuiKey_PageDown
@ ImGuiKey_PageDown
Definition: imgui.h:993
void
typedef void(APIENTRY *GLDEBUGPROCARB)(GLenum source
n
GLdouble n
Definition: glcorearb.h:4153
ImGuiContext::ForegroundDrawList
ImDrawList ForegroundDrawList
Definition: imgui_internal.h:1148
ImGuiResizeGripDef::InnerDir
ImVec2 InnerDir
Definition: imgui.cpp:5003
ImGuiContext::MouseCursor
ImGuiMouseCursor MouseCursor
Definition: imgui_internal.h:1149
ImGui::RenderFrameBorder
IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding=0.0f)
Definition: imgui.cpp:2756
ImGuiWindowTempData::FocusCounterTabStop
int FocusCounterTabStop
Definition: imgui_internal.h:1406
ImGuiKey_C
@ ImGuiKey_C
Definition: imgui.h:1004
ImDrawList::Flags
ImDrawListFlags Flags
Definition: imgui.h:1967
ImGuiWindow::DC
ImGuiWindowTempData DC
Definition: imgui_internal.h:1506
ImDrawList::VtxBuffer
ImVector< ImDrawVert > VtxBuffer
Definition: imgui.h:1966
i
int i
Definition: gmock-matchers_test.cc:764
ImGui::PopStyleVar
IMGUI_API void PopStyleVar(int count=1)
Definition: imgui.cpp:2480
ImGuiStorage::SetFloat
IMGUI_API void SetFloat(ImGuiID key, float val)
Definition: imgui.cpp:2001
ImGuiWindow::PopupId
ImGuiID PopupId
Definition: imgui_internal.h:1492
ImGuiWindowTempData::StackSizesBackup
short StackSizesBackup[6]
Definition: imgui_internal.h:1417
ImGuiKeyModFlags_Alt
@ ImGuiKeyModFlags_Alt
Definition: imgui.h:1018
ImGuiWindow
Definition: imgui_internal.h:1456
ImFormatStringV
int ImFormatStringV(char *buf, size_t buf_size, const char *fmt, va_list args)
Definition: imgui.cpp:1455
ImGuiItemStatusFlags_Edited
@ ImGuiItemStatusFlags_Edited
Definition: imgui_internal.h:537
ImGuiIO::NavInputsDownDuration
float NavInputsDownDuration[ImGuiNavInput_COUNT]
Definition: imgui.h:1540
ImGuiItemFlags_NoNav
@ ImGuiItemFlags_NoNav
Definition: imgui_internal.h:524
ImGui::DebugStartItemPicker
void DebugStartItemPicker()
Definition: imgui_internal.h:1897
ImGuiStyle::WindowTitleAlign
ImVec2 WindowTitleAlign
Definition: imgui.h:1372
ImGuiKey_Escape
@ ImGuiKey_Escape
Definition: imgui.h:1001
ImGuiPopupData::OpenMousePos
ImVec2 OpenMousePos
Definition: imgui_internal.h:840
ImGuiStyle::GrabMinSize
float GrabMinSize
Definition: imgui.h:1388
ImGui::CalcTextSize
IMGUI_API ImVec2 CalcTextSize(const char *text, const char *text_end=NULL, bool hide_text_after_double_hash=false, float wrap_width=-1.0f)
Definition: imgui.cpp:4274
ImGui::SetAllocatorFunctions
IMGUI_API void SetAllocatorFunctions(void *(*alloc_func)(size_t sz, void *user_data), void(*free_func)(void *ptr, void *user_data), void *user_data=NULL)
Definition: imgui.cpp:3260
ImGui::GetWindowHeight
IMGUI_API float GetWindowHeight()
Definition: imgui.cpp:6325
ImGuiWindowTempData::MenuBarOffset
ImVec2 MenuBarOffset
Definition: imgui_internal.h:1396
ImGui::Scrollbar
IMGUI_API void Scrollbar(ImGuiAxis axis)
Definition: imgui_widgets.cpp:912
ImGui::IsMouseClicked
IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, bool repeat=false)
Definition: imgui.cpp:4433
ImGuiMouseCursor_ResizeNWSE
@ ImGuiMouseCursor_ResizeNWSE
Definition: imgui.h:1251
ImDrawCornerFlags_Top
@ ImDrawCornerFlags_Top
Definition: imgui.h:1938
ImGui::TextV
IMGUI_API void TextV(const char *fmt, va_list args) IM_FMTLIST(1)
Definition: imgui_widgets.cpp:255
ImGuiFocusedFlags
int ImGuiFocusedFlags
Definition: imgui.h:160
ImGuiWindowTempData::FocusCounterRegular
int FocusCounterRegular
Definition: imgui_internal.h:1405
IM_COL32_BLACK
#define IM_COL32_BLACK
Definition: imgui.h:1822
IM_FLOOR
#define IM_FLOOR(_VAL)
Definition: imgui_internal.h:185
type
GLenum type
Definition: glcorearb.h:2695
ImGuiWindowSettings::ID
ImGuiID ID
Definition: imgui_internal.h:810
WindowSettingsHandler_ReadOpen
static void * WindowSettingsHandler_ReadOpen(ImGuiContext *, ImGuiSettingsHandler *, const char *name)
Definition: imgui.cpp:9710
ImGuiWindow::WorkRect
ImRect WorkRect
Definition: imgui_internal.h:1513
ImGuiStyle::GrabRounding
float GrabRounding
Definition: imgui.h:1389
ImGuiMouseButton_Left
@ ImGuiMouseButton_Left
Definition: imgui.h:1234
ImGui::GetWindowPos
IMGUI_API ImVec2 GetWindowPos()
Definition: imgui.cpp:6331
ImGuiIO::BackendPlatformName
const char * BackendPlatformName
Definition: imgui.h:1455
v1
GLfloat GLfloat v1
Definition: glcorearb.h:3086
ImGuiIO::InputQueueCharacters
ImVector< ImWchar > InputQueueCharacters
Definition: imgui.h:1543
ImGui::MarkIniSettingsDirty
IMGUI_API void MarkIniSettingsDirty()
Definition: imgui.cpp:9548
ImSwap
static void ImSwap(T &a, T &b)
Definition: imgui_internal.h:324
ImGui::IsMouseReleased
IMGUI_API bool IsMouseReleased(ImGuiMouseButton button)
Definition: imgui.cpp:4451
ImGui::InputText
IMGUI_API bool InputText(const char *label, char *buf, size_t buf_size, ImGuiInputTextFlags flags=0, ImGuiInputTextCallback callback=NULL, void *user_data=NULL)
Definition: imgui_widgets.cpp:3110
ImGuiIO::MetricsActiveAllocations
int MetricsActiveAllocations
Definition: imgui.h:1518
ImGui::EndTooltip
IMGUI_API void EndTooltip()
Definition: imgui.cpp:7472
ImGuiCond_Always
@ ImGuiCond_Always
Definition: imgui.h:1267
ImGuiIO::MousePos
ImVec2 MousePos
Definition: imgui.h:1485
ImGui::NavMoveRequestTryWrapping
IMGUI_API void NavMoveRequestTryWrapping(ImGuiWindow *window, ImGuiNavMoveFlags move_flags)
Definition: imgui.cpp:8213
ImGuiFocusedFlags_RootWindow
@ ImGuiFocusedFlags_RootWindow
Definition: imgui.h:912
ImGuiHoveredFlags_None
@ ImGuiHoveredFlags_None
Definition: imgui.h:922
ImDrawList::PathArcTo
IMGUI_API void PathArcTo(const ImVec2 &center, float radius, float a_min, float a_max, int num_segments=10)
Definition: imgui_draw.cpp:917
ImGui::PopClipRect
IMGUI_API void PopClipRect()
Definition: imgui.cpp:4135
IsWindowContentHoverable
static bool IsWindowContentHoverable(ImGuiWindow *window, ImGuiHoveredFlags flags)
Definition: imgui.cpp:3043
IM_COL32_A_SHIFT
#define IM_COL32_A_SHIFT
Definition: imgui.h:1817
ImGuiWindow::ContentSize
ImVec2 ContentSize
Definition: imgui_internal.h:1464
ImGui::RenderTextClippedEx
IMGUI_API void RenderTextClippedEx(ImDrawList *draw_list, const ImVec2 &pos_min, const ImVec2 &pos_max, const char *text, const char *text_end, const ImVec2 *text_size_if_known, const ImVec2 &align=ImVec2(0, 0), const ImRect *clip_rect=NULL)
Definition: imgui.cpp:2618
ImGuiStyle::AntiAliasedLines
bool AntiAliasedLines
Definition: imgui.h:1398
ImGuiStyle::ScaleAllSizes
IMGUI_API void ScaleAllSizes(float scale_factor)
Definition: imgui.cpp:1041
ImGuiHoveredFlags_AllowWhenBlockedByActiveItem
@ ImGuiHoveredFlags_AllowWhenBlockedByActiveItem
Definition: imgui.h:928
ImGuiNavMoveResult::DistCenter
float DistCenter
Definition: imgui_internal.h:934
ImGuiConfigFlags_NavEnableKeyboard
@ ImGuiConfigFlags_NavEnableKeyboard
Definition: imgui.h:1061
ImGuiWindow::MemoryCompacted
bool MemoryCompacted
Definition: imgui_internal.h:1536
ImGuiWindow::MemoryDrawListVtxCapacity
int MemoryDrawListVtxCapacity
Definition: imgui_internal.h:1538
ImGui::RenderFrame
IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border=true, float rounding=0.0f)
Definition: imgui.cpp:2743
ImGuiDir_Down
@ ImGuiDir_Down
Definition: imgui.h:980
ImGui::Indent
IMGUI_API void Indent(float indent_w=0.0f)
Definition: imgui.cpp:7006
ImGui::NavUpdateWindowingOverlay
static void NavUpdateWindowingOverlay()
Definition: imgui.cpp:8976
len
int len
Definition: php/ext/google/protobuf/map.c:206
ImGuiCond_Appearing
@ ImGuiCond_Appearing
Definition: imgui.h:1270
ImDrawListFlags_AllowVtxOffset
@ ImDrawListFlags_AllowVtxOffset
Definition: imgui.h:1950
ImGui::TextUnformatted
IMGUI_API void TextUnformatted(const char *text, const char *text_end=NULL)
Definition: imgui_widgets.cpp:242
ImGuiStyle::IndentSpacing
float IndentSpacing
Definition: imgui.h:1384
ImGui::PopAllowKeyboardFocus
IMGUI_API void PopAllowKeyboardFocus()
Definition: imgui.cpp:6207
ImGui::ResetMouseDragDelta
IMGUI_API void ResetMouseDragDelta(ImGuiMouseButton button=0)
Definition: imgui.cpp:4535
ImGuiNavHighlightFlags_TypeThin
@ ImGuiNavHighlightFlags_TypeThin
Definition: imgui_internal.h:620
ImGuiMouseCursor_Hand
@ ImGuiMouseCursor_Hand
Definition: imgui.h:1252
ImGuiWindow::NameBufLen
int NameBufLen
Definition: imgui_internal.h:1469
ImGui::PushButtonRepeat
IMGUI_API void PushButtonRepeat(bool repeat)
Definition: imgui.cpp:6212
v
const GLdouble * v
Definition: glcorearb.h:3106
ImGuiColumns::Count
int Count
Definition: imgui_internal.h:862
ImGuiWindowFlags_None
@ ImGuiWindowFlags_None
Definition: imgui.h:768
ImGui::IsItemActivated
IMGUI_API bool IsItemActivated()
Definition: imgui.cpp:4574
ImGuiNavMoveResult::DistBox
float DistBox
Definition: imgui_internal.h:933
ImGui::IsWindowChildOf
IMGUI_API bool IsWindowChildOf(ImGuiWindow *window, ImGuiWindow *potential_parent)
Definition: imgui.cpp:6236
ImGui::GetWindowResizeID
IMGUI_API ImGuiID GetWindowResizeID(ImGuiWindow *window, int n)
Definition: imgui.cpp:5029
ImGuiNavInput_KeyDown_
@ ImGuiNavInput_KeyDown_
Definition: imgui.h:1052
ImGuiStorage::SetBool
IMGUI_API void SetBool(ImGuiID key, bool val)
Definition: imgui.cpp:1996
ImGuiWindow::MoveId
ImGuiID MoveId
Definition: imgui_internal.h:1470
ImGui::BeginTooltip
IMGUI_API void BeginTooltip()
Definition: imgui.cpp:7435
ImGuiStorage::GetIntRef
IMGUI_API int * GetIntRef(ImGuiID key, int default_val=0)
Definition: imgui.cpp:1955
ImGui::SetWindowCollapsed
IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiCond cond=0)
Definition: imgui.cpp:6429
ImGuiContext::DebugItemPickerBreakId
ImGuiID DebugItemPickerBreakId
Definition: imgui_internal.h:1217
ImGuiTextFilter::ImGuiTextRange::ImGuiTextRange
ImGuiTextRange()
Definition: imgui.h:1690
ImGuiStyle::ScrollbarRounding
float ScrollbarRounding
Definition: imgui.h:1387
FindWindowNavFocusable
static ImGuiWindow * FindWindowNavFocusable(int i_start, int i_stop, int dir)
Definition: imgui.cpp:8796
ImGui::SetDragDropPayload
IMGUI_API bool SetDragDropPayload(const char *type, const void *data, size_t sz, ImGuiCond cond=0)
Definition: imgui.cpp:9143
ImGui::PopItemWidth
IMGUI_API void PopItemWidth()
Definition: imgui.cpp:7053
ImGuiWindow::WindowBorderSize
float WindowBorderSize
Definition: imgui_internal.h:1468
ImGuiConfigFlags_NavNoCaptureKeyboard
@ ImGuiConfigFlags_NavNoCaptureKeyboard
Definition: imgui.h:1064
ImGuiWindow::ScrollbarX
bool ScrollbarX
Definition: imgui_internal.h:1477
ImGuiNavHighlightFlags_NoRounding
@ ImGuiNavHighlightFlags_NoRounding
Definition: imgui_internal.h:622
ImGui::GetDrawListSharedData
IMGUI_API ImDrawListSharedData * GetDrawListSharedData()
Definition: imgui.cpp:3319
ImGui::IsMouseDoubleClicked
IMGUI_API bool IsMouseDoubleClicked(ImGuiMouseButton button)
Definition: imgui.cpp:4458
ImGuiWindow::OuterRectClipped
ImRect OuterRectClipped
Definition: imgui_internal.h:1510
ImGuiStyle::DisplayWindowPadding
ImVec2 DisplayWindowPadding
Definition: imgui.h:1395
ImGuiColorMod::BackupValue
ImVec4 BackupValue
Definition: imgui_internal.h:730
ImGuiStorage::SetAllInt
IMGUI_API void SetAllInt(int val)
Definition: imgui.cpp:2023
ImGuiStyle::FrameBorderSize
float FrameBorderSize
Definition: imgui.h:1380
IM_COL32_WHITE
#define IM_COL32_WHITE
Definition: imgui.h:1821
ImGuiWindowFlags_NoMove
@ ImGuiWindowFlags_NoMove
Definition: imgui.h:771
ImGuiTextFilter::ImGuiTextRange::e
const char * e
Definition: imgui.h:1688
ImGuiNextWindowData::Flags
ImGuiNextWindowDataFlags Flags
Definition: imgui_internal.h:957
ImGuiWindowTempData::MenuBarAppending
bool MenuBarAppending
Definition: imgui_internal.h:1395
ImGuiWindow::CalcFontSize
float CalcFontSize() const
Definition: imgui_internal.h:1554
ImGuiWindow::ColumnsStorage
ImVector< ImGuiColumns > ColumnsStorage
Definition: imgui_internal.h:1521
ImGui::GetTextLineHeight
IMGUI_API float GetTextLineHeight()
Definition: imgui.cpp:7105
ImGui::NewFrame
IMGUI_API void NewFrame()
Definition: imgui.cpp:3691
ImGui::NavMoveRequestButNoResultYet
IMGUI_API bool NavMoveRequestButNoResultYet()
Definition: imgui.cpp:8188
ImGuiIO::ConfigWindowsResizeFromEdges
bool ConfigWindowsResizeFromEdges
Definition: imgui.h:1445
ImGuiNavDirSourceFlags
int ImGuiNavDirSourceFlags
Definition: imgui_internal.h:109
IM_PLACEMENT_NEW
#define IM_PLACEMENT_NEW(_PTR)
Definition: imgui.h:1285
ImGuiNavHighlightFlags_TypeDefault
@ ImGuiNavHighlightFlags_TypeDefault
Definition: imgui_internal.h:619
ImGuiCol_Tab
@ ImGuiCol_Tab
Definition: imgui.h:1119
ImGuiInputReadMode_Released
@ ImGuiInputReadMode_Released
Definition: imgui_internal.h:610
ImWchar
ImWchar16 ImWchar
Definition: imgui.h:185
ImGuiStyle::PopupBorderSize
float PopupBorderSize
Definition: imgui.h:1377
ImGui::NavMoveRequestForward
IMGUI_API void NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, const ImRect &bb_rel, ImGuiNavMoveFlags move_flags)
Definition: imgui.cpp:8201
ImLerp
static T ImLerp(T a, T b, float t)
Definition: imgui_internal.h:323
ImGui::EndColumns
IMGUI_API void EndColumns()
Definition: imgui_widgets.cpp:7621
ImGuiWindowTempData::TreeJumpToParentOnPopMask
ImU32 TreeJumpToParentOnPopMask
Definition: imgui_internal.h:1399
ImGuiIO::DisplaySize
ImVec2 DisplaySize
Definition: imgui.h:1422
ImGuiWindowFlags_NoNavInputs
@ ImGuiWindowFlags_NoNavInputs
Definition: imgui.h:786
ImGuiIO::MouseDoubleClickTime
float MouseDoubleClickTime
Definition: imgui.h:1427
ImGuiTextFilter::CountGrep
int CountGrep
Definition: imgui.h:1697
ImFmod
#define ImFmod(X, Y)
Definition: imgui_internal.h:307
ImGuiStyleVarInfo::Type
ImGuiDataType Type
Definition: imgui.cpp:2412
ImRect::GetHeight
float GetHeight() const
Definition: imgui_internal.h:697
ImGuiStorage::SetInt
IMGUI_API void SetInt(ImGuiID key, int val)
Definition: imgui.cpp:1985
ImGui::IsNavInputDown
bool IsNavInputDown(ImGuiNavInput n)
Definition: imgui_internal.h:1778
size
GLsizeiptr size
Definition: glcorearb.h:2943
ImGuiGroupData::BackupIndent
ImVec1 BackupIndent
Definition: imgui_internal.h:748
v0
GLfloat v0
Definition: glcorearb.h:3085
ImGui::PopTextWrapPos
IMGUI_API void PopTextWrapPos()
Definition: imgui.cpp:6229
ImGuiStyle::Colors
ImVec4 Colors[ImGuiCol_COUNT]
Definition: imgui.h:1402
ImGui::NavUpdateAnyRequestFlag
static void NavUpdateAnyRequestFlag()
Definition: imgui.cpp:8279
ImDrawList::PathLineTo
void PathLineTo(const ImVec2 &pos)
Definition: imgui.h:2025
ImGuiCol_NavHighlight
@ ImGuiCol_NavHighlight
Definition: imgui.h:1130
ImGuiNavInput_KeyRight_
@ ImGuiNavInput_KeyRight_
Definition: imgui.h:1050
ImDrawListSharedData
Definition: imgui_internal.h:901
ImGuiWindow::Size
ImVec2 Size
Definition: imgui_internal.h:1462
ImVector::resize
void resize(int new_size)
Definition: imgui.h:1337
ImGui::GetNavInputAmount
IMGUI_API float GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode)
Definition: imgui.cpp:8333
ImGui::GetCursorPosY
IMGUI_API float GetCursorPosY()
Definition: imgui.cpp:6973
ImQsort
#define ImQsort
Definition: imgui_internal.h:214
ImGuiWindowFlags_NoNavFocus
@ ImGuiWindowFlags_NoNavFocus
Definition: imgui.h:787
ImGui::GetWindowDrawList
IMGUI_API ImDrawList * GetWindowDrawList()
Definition: imgui.cpp:6529
ImGui::Begin
IMGUI_API bool Begin(const char *name, bool *p_open=NULL, ImGuiWindowFlags flags=0)
Definition: imgui.cpp:5397
ImGui::NavUpdatePageUpPageDown
static float NavUpdatePageUpPageDown()
Definition: imgui.cpp:8716
ImGui::RenderWindowDecorations
static void RenderWindowDecorations(ImGuiWindow *window, const ImRect &title_bar_rect, bool title_bar_is_highlight, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size)
Definition: imgui.cpp:5208
ImGuiInputReadMode_RepeatSlow
@ ImGuiInputReadMode_RepeatSlow
Definition: imgui_internal.h:612
ImLineClosestPoint
ImVec2 ImLineClosestPoint(const ImVec2 &a, const ImVec2 &b, const ImVec2 &p)
Definition: imgui.cpp:1249
pad
int pad
Definition: statusor_test.cc:47
ImGuiWindow::SetWindowPosAllowFlags
ImGuiCond SetWindowPosAllowFlags
Definition: imgui_internal.h:1499
ImDrawListSharedData::Font
ImFont * Font
Definition: imgui_internal.h:904
ImGuiCol_NavWindowingDimBg
@ ImGuiCol_NavWindowingDimBg
Definition: imgui.h:1132
ImGuiWindow::ScrollbarY
bool ScrollbarY
Definition: imgui_internal.h:1477
name_len
static size_t name_len(const char *name_)
Definition: mechanism.cpp:104
ImGuiNavHighlightFlags_AlwaysDraw
@ ImGuiNavHighlightFlags_AlwaysDraw
Definition: imgui_internal.h:621
ImGuiWindowFlags_UnsavedDocument
@ ImGuiWindowFlags_UnsavedDocument
Definition: imgui.h:788
ImGuiCol_ModalWindowDimBg
@ ImGuiCol_ModalWindowDimBg
Definition: imgui.h:1133
ImGui::GetTime
IMGUI_API double GetTime()
Definition: imgui.cpp:3299
ImGuiWindow::BeginOrderWithinParent
short BeginOrderWithinParent
Definition: imgui_internal.h:1490
ImGuiCol_PopupBg
@ ImGuiCol_PopupBg
Definition: imgui.h:1090
ImGui::ItemSize
IMGUI_API void ItemSize(const ImVec2 &size, float text_baseline_y=-1.0f)
Definition: imgui.cpp:6823
ImGui::PushMultiItemsWidths
IMGUI_API void PushMultiItemsWidths(int components, float width_full)
Definition: imgui.cpp:7039
ImGui::SetWindowFocus
IMGUI_API void SetWindowFocus()
Definition: imgui.cpp:6452
ImGuiContext::WindowsFocusOrder
ImVector< ImGuiWindow * > WindowsFocusOrder
Definition: imgui_internal.h:1038
ImGui::BeginTooltipEx
IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, ImGuiTooltipFlags tooltip_flags)
Definition: imgui.cpp:7440
ImGuiItemStatusFlags_HasDeactivated
@ ImGuiItemStatusFlags_HasDeactivated
Definition: imgui_internal.h:540
ImVec4::w
float w
Definition: imgui.h:223
ImGuiColumns
Definition: imgui_internal.h:855
ImGui::IsMouseDragging
IMGUI_API bool IsMouseDragging(ImGuiMouseButton button, float lock_threshold=-1.0f)
Definition: imgui.cpp:4475
m
const upb_json_parsermethod * m
Definition: ruby/ext/google/protobuf_c/upb.h:10501
ImGuiListClipper::Begin
IMGUI_API void Begin(int items_count, float items_height=-1.0f)
Definition: imgui.cpp:2265
ImGuiWindow::AutoFitFramesX
ImS8 AutoFitFramesX
Definition: imgui_internal.h:1493
ImBezierClosestPoint
ImVec2 ImBezierClosestPoint(const ImVec2 &p1, const ImVec2 &p2, const ImVec2 &p3, const ImVec2 &p4, const ImVec2 &p, int num_segments)
Definition: imgui.cpp:1181
ImGuiWindow::MenuBarHeight
float MenuBarHeight() const
Definition: imgui_internal.h:1557
ImGuiMouseCursor_ResizeNESW
@ ImGuiMouseCursor_ResizeNESW
Definition: imgui.h:1250
ImGui::IsItemFocused
IMGUI_API bool IsItemFocused()
Definition: imgui.cpp:4601
ImGuiContext::HoveredId
ImGuiID HoveredId
Definition: imgui_internal.h:1052
ImGuiStyle::WindowPadding
ImVec2 WindowPadding
Definition: imgui.h:1368
ImGuiDragDropFlags_SourceExtern
@ ImGuiDragDropFlags_SourceExtern
Definition: imgui.h:944
ImGui::LogToFile
IMGUI_API void LogToFile(int auto_open_depth=-1, const char *filename=NULL)
Definition: imgui.cpp:9412
ImGui::GetItemRectSize
IMGUI_API ImVec2 GetItemRectSize()
Definition: imgui.cpp:4680
ImGuiIO::BackendRendererName
const char * BackendRendererName
Definition: imgui.h:1456
ImGuiWindow::RootWindowForNav
ImGuiWindow * RootWindowForNav
Definition: imgui_internal.h:1530
ImGuiTabBar::GetTabName
const char * GetTabName(const ImGuiTabItem *tab) const
Definition: imgui_internal.h:1637
ImGuiWindow::WantCollapseToggle
bool WantCollapseToggle
Definition: imgui_internal.h:1482
ImGuiItemStatusFlags_Deactivated
@ ImGuiItemStatusFlags_Deactivated
Definition: imgui_internal.h:541
ImGui::Initialize
IMGUI_API void Initialize(ImGuiContext *context)
Definition: imgui.cpp:3894
ImGui::ButtonBehavior
IMGUI_API bool ButtonBehavior(const ImRect &bb, ImGuiID id, bool *out_hovered, bool *out_held, ImGuiButtonFlags flags=0)
Definition: imgui_widgets.cpp:459
ImGui::PushStyleVar
IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val)
Definition: imgui.cpp:2452
r
GLboolean r
Definition: glcorearb.h:3228
ImGui::RenderWindowTitleBarContents
static void RenderWindowTitleBarContents(ImGuiWindow *window, const ImRect &title_bar_rect, const char *name, bool *p_open)
Definition: imgui.cpp:5291
ImGuiPayload::DataFrameCount
int DataFrameCount
Definition: imgui.h:1607
ImVector::empty
bool empty() const
Definition: imgui.h:1318
ImGuiStorage
Definition: imgui.h:1729
ImGui::NavInitWindow
IMGUI_API void NavInitWindow(ImGuiWindow *window, bool force_reinit)
Definition: imgui.cpp:8288
ImGuiWindowSettings
Definition: imgui_internal.h:808
ImGuiCol_SliderGrabActive
@ ImGuiCol_SliderGrabActive
Definition: imgui.h:1106
ImGuiNavMoveResult::ID
ImGuiID ID
Definition: imgui_internal.h:931
StartLockWheelingWindow
static void StartLockWheelingWindow(ImGuiWindow *window)
Definition: imgui.cpp:3499
ImGuiPopupData::OpenFrameCount
int OpenFrameCount
Definition: imgui_internal.h:837
ImStreolRange
const char * ImStreolRange(const char *str, const char *str_end)
Definition: imgui.cpp:1361
ImGuiBackendFlags_None
@ ImGuiBackendFlags_None
Definition: imgui.h:1076
ImGui::IsAnyMouseDown
IMGUI_API bool IsAnyMouseDown()
Definition: imgui.cpp:4510
ImGuiKeyModFlags_Super
@ ImGuiKeyModFlags_Super
Definition: imgui.h:1019
HANDLE
void * HANDLE
Definition: wepoll.c:70
ImGuiKeyModFlags_Ctrl
@ ImGuiKeyModFlags_Ctrl
Definition: imgui.h:1016
ImGuiNavInput_Menu
@ ImGuiNavInput_Menu
Definition: imgui.h:1032
ImGui::IsActiveIdUsingNavDir
bool IsActiveIdUsingNavDir(ImGuiDir dir)
Definition: imgui_internal.h:1773
dst
GLenum GLenum dst
Definition: glcorearb.h:3364
ImGuiStyle::TouchExtraPadding
ImVec2 TouchExtraPadding
Definition: imgui.h:1383
ImGuiItemFlags_ButtonRepeat
@ ImGuiItemFlags_ButtonRepeat
Definition: imgui_internal.h:522
ImGuiNavInput_Input
@ ImGuiNavInput_Input
Definition: imgui.h:1031
ImGui::SetWindowSize
IMGUI_API void SetWindowSize(const ImVec2 &size, ImGuiCond cond=0)
Definition: imgui.cpp:6407
ImGuiStyle::TabBorderSize
float TabBorderSize
Definition: imgui.h:1391
ImGuiWindow::IDStack
ImVector< ImGuiID > IDStack
Definition: imgui_internal.h:1505
ImGuiWindow::Name
char * Name
Definition: imgui_internal.h:1458
first
GLint first
Definition: glcorearb.h:2830
ImGui::SetWindowPos
IMGUI_API void SetWindowPos(const ImVec2 &pos, ImGuiCond cond=0)
Definition: imgui.cpp:6357
capture
static int capture(class zmq::socket_base_t *capture_, zmq::msg_t *msg_, int more_=0)
Definition: proxy.cpp:58
ImGuiWindow::Rect
ImRect Rect() const
Definition: imgui_internal.h:1553
ImGui::FindBestWindowPosForPopup
IMGUI_API ImVec2 FindBestWindowPosForPopup(ImGuiWindow *window)
Definition: imgui.cpp:7860
ImGuiItemStatusFlags_HasDisplayRect
@ ImGuiItemStatusFlags_HasDisplayRect
Definition: imgui_internal.h:536
ImGuiWindow::AutoFitChildAxises
ImS8 AutoFitChildAxises
Definition: imgui_internal.h:1494
IM_DEBUG_BREAK
#define IM_DEBUG_BREAK()
Definition: imgui_internal.h:1918
ImGui::CaptureMouseFromApp
IMGUI_API void CaptureMouseFromApp(bool want_capture_mouse_value=true)
Definition: imgui.cpp:4558
ImGui::MemFree
IMGUI_API void MemFree(void *ptr)
Definition: imgui.cpp:3218
ImGuiGroupData::BackupCursorMaxPos
ImVec2 BackupCursorMaxPos
Definition: imgui_internal.h:747
ImGui::SetCursorPosY
IMGUI_API void SetCursorPosY(float local_y)
Definition: imgui.cpp:6993
ImGui::BringWindowToDisplayBack
IMGUI_API void BringWindowToDisplayBack(ImGuiWindow *window)
Definition: imgui.cpp:6070
ImGuiStyle::WindowMenuButtonPosition
ImGuiDir WindowMenuButtonPosition
Definition: imgui.h:1373
handler
void * handler
Definition: test_security_curve.cpp:27
ImGuiWindowFlags_NoCollapse
@ ImGuiWindowFlags_NoCollapse
Definition: imgui.h:774
CalcWindowContentSize
static ImVec2 CalcWindowContentSize(ImGuiWindow *window)
Definition: imgui.cpp:4920
ImGuiWindow::LastFrameActive
int LastFrameActive
Definition: imgui_internal.h:1517
ImGuiCol_FrameBg
@ ImGuiCol_FrameBg
Definition: imgui.h:1093
ImGui::TabBarQueueChangeTabOrder
IMGUI_API void TabBarQueueChangeTabOrder(ImGuiTabBar *tab_bar, const ImGuiTabItem *tab, int dir)
Definition: imgui_widgets.cpp:6842
ImGuiIO
Definition: imgui.h:1414
IM_ASSERT_USER_ERROR
#define IM_ASSERT_USER_ERROR(_EXP, _MSG)
Definition: imgui_internal.h:172
ImFont
Definition: imgui.h:2272
ImDrawList::AddPolyline
IMGUI_API void AddPolyline(const ImVec2 *points, int num_points, ImU32 col, bool closed, float thickness)
Definition: imgui_draw.cpp:625
ImFont::RenderChar
IMGUI_API void RenderChar(ImDrawList *draw_list, float size, ImVec2 pos, ImU32 col, ImWchar c) const
Definition: imgui_draw.cpp:2965
ImGui::SetNextWindowContentSize
IMGUI_API void SetNextWindowContentSize(const ImVec2 &size)
Definition: imgui.cpp:6500
ImGuiContext::NavLayer
ImGuiNavLayer NavLayer
Definition: imgui_internal.h:1105
ImGuiConfigFlags_NoMouse
@ ImGuiConfigFlags_NoMouse
Definition: imgui.h:1065
ImGui::SetCurrentContext
IMGUI_API void SetCurrentContext(ImGuiContext *ctx)
Definition: imgui.cpp:3251
ImGuiButtonFlags_FlattenChildren
@ ImGuiButtonFlags_FlattenChildren
Definition: imgui_internal.h:447
ImGuiItemFlags_NoTabStop
@ ImGuiItemFlags_NoTabStop
Definition: imgui_internal.h:521
ImGuiMenuColumns::Update
void Update(int count, float spacing, bool clear)
Definition: imgui_widgets.cpp:6044
tree
Definition: wepoll.c:502
GStyleVarInfo
static const ImGuiStyleVarInfo GStyleVarInfo[]
Definition: imgui.cpp:2418
ImGui::GetCursorPos
IMGUI_API ImVec2 GetCursorPos()
Definition: imgui.cpp:6961
ImGuiWindowTempData::Indent
ImVec1 Indent
Definition: imgui_internal.h:1375
ImGuiWindowFlags_Modal
@ ImGuiWindowFlags_Modal
Definition: imgui.h:798
ImGuiTextBuffer::appendfv
IMGUI_API void appendfv(const char *fmt, va_list args) IM_FMTLIST(2)
Definition: imgui.cpp:2174
ImGuiWindow::RootWindowForTitleBarHighlight
ImGuiWindow * RootWindowForTitleBarHighlight
Definition: imgui_internal.h:1529
ImGuiStyle::FramePadding
ImVec2 FramePadding
Definition: imgui.h:1378
ImFontAtlas::TexUvWhitePixel
ImVec2 TexUvWhitePixel
Definition: imgui.h:2258
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: glcorearb.h:2879
ImCharIsBlankA
static bool ImCharIsBlankA(char c)
Definition: imgui_internal.h:247
ImGui::FocusWindow
IMGUI_API void FocusWindow(ImGuiWindow *window)
Definition: imgui.cpp:6085
ImGuiStyle::WindowBorderSize
float WindowBorderSize
Definition: imgui.h:1370
ImGuiSettingsHandler::TypeName
const char * TypeName
Definition: imgui_internal.h:821
GImAllocatorUserData
static void * GImAllocatorUserData
Definition: imgui.cpp:991
ImeSetInputScreenPosFn_DefaultImpl
static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y)
Definition: imgui.cpp:9933
ImGuiStyle::TabRounding
float TabRounding
Definition: imgui.h:1390
ImGuiStyle::PopupRounding
float PopupRounding
Definition: imgui.h:1376
ImGuiNextWindowDataFlags_HasBgAlpha
@ ImGuiNextWindowDataFlags_HasBgAlpha
Definition: imgui_internal.h:951
BezierClosestPointCasteljauStep
static void BezierClosestPointCasteljauStep(const ImVec2 &p, ImVec2 &p_closest, ImVec2 &p_last, float &p_closest_dist2, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level)
Definition: imgui.cpp:1204
ImGuiIO::BackendPlatformUserData
void * BackendPlatformUserData
Definition: imgui.h:1457
ImGuiContext::WheelingWindow
ImGuiWindow * WheelingWindow
Definition: imgui_internal.h:1047
ImDrawData::TotalIdxCount
int TotalIdxCount
Definition: imgui.h:2073
ImGuiLogType_None
@ ImGuiLogType_None
Definition: imgui_internal.h:574
ImVec4
Definition: imgui.h:221
ImGuiItemStatusFlags_ToggledOpen
@ ImGuiItemStatusFlags_ToggledOpen
Definition: imgui_internal.h:539
ImGuiIO::MouseDoubleClickMaxDist
float MouseDoubleClickMaxDist
Definition: imgui.h:1428
ImGuiPayload::DataType
char DataType[32+1]
Definition: imgui.h:1608
ImGuiStyleVar_WindowPadding
@ ImGuiStyleVar_WindowPadding
Definition: imgui.h:1154
ImGuiGroupData::BackupActiveIdPreviousFrameIsAlive
bool BackupActiveIdPreviousFrameIsAlive
Definition: imgui_internal.h:753
ImGuiStyleVar_COUNT
@ ImGuiStyleVar_COUNT
Definition: imgui.h:1176
true
#define true
Definition: cJSON.c:65
ImGuiWindow::GetIDNoKeepAlive
ImGuiID GetIDNoKeepAlive(const char *str, const char *str_end=NULL)
Definition: imgui.cpp:2903
ImGui::GetItemRectMax
IMGUI_API ImVec2 GetItemRectMax()
Definition: imgui.cpp:4674
ImGui::RenderTextWrapped
IMGUI_API void RenderTextWrapped(ImVec2 pos, const char *text, const char *text_end, float wrap_width)
Definition: imgui.cpp:2600
ImGui::FindOrCreateWindowSettings
IMGUI_API ImGuiWindowSettings * FindOrCreateWindowSettings(const char *name)
Definition: imgui.cpp:9594
ImStrTrimBlanks
void ImStrTrimBlanks(char *buf)
Definition: imgui.cpp:1397
ImGuiIO::RenderDrawListsFn
void(* RenderDrawListsFn)(ImDrawData *data)
Definition: imgui.h:1475
ImGui::LogToBuffer
IMGUI_API void LogToBuffer(int auto_open_depth=-1)
Definition: imgui.cpp:9445
GetClipboardTextFn_DefaultImpl
static const char * GetClipboardTextFn_DefaultImpl(void *user_data)
Definition: imgui.cpp:9889
ImGuiWindow::HiddenFramesCanSkipItems
int HiddenFramesCanSkipItems
Definition: imgui_internal.h:1497
ImDrawList::_ClipRectStack
ImVector< ImVec4 > _ClipRectStack
Definition: imgui.h:1976
ImGui::SetScrollHereX
IMGUI_API void SetScrollHereX(float center_x_ratio=0.5f)
Definition: imgui.cpp:7411
ImGuiNavInput_LStickDown
@ ImGuiNavInput_LStickDown
Definition: imgui.h:1040
ImDrawListFlags_None
@ ImDrawListFlags_None
Definition: imgui.h:1947
IM_ASSERT
#define IM_ASSERT(_EXPR)
Definition: imgui.h:79
ImGui::IsAnyItemFocused
IMGUI_API bool IsAnyItemFocused()
Definition: imgui.cpp:4640
ImDrawCornerFlags_Bot
@ ImDrawCornerFlags_Bot
Definition: imgui.h:1939
val
GLuint GLfloat * val
Definition: glcorearb.h:3604
IMGUI_API
#define IMGUI_API
Definition: imgui.h:70
CalcWindowAutoFitSize
static ImVec2 CalcWindowAutoFitSize(ImGuiWindow *window, const ImVec2 &size_contents)
Definition: imgui.cpp:4934
ImDrawList::_VtxWritePtr
ImDrawVert * _VtxWritePtr
Definition: imgui.h:1974
ImGuiWindowTempData::CursorPosPrevLine
ImVec2 CursorPosPrevLine
Definition: imgui_internal.h:1368
resize_grip_def
static const ImGuiResizeGripDef resize_grip_def[4]
Definition: imgui.cpp:5007
ImGuiKey_UpArrow
@ ImGuiKey_UpArrow
Definition: imgui.h:990
ImGui::SetClipboardText
IMGUI_API void SetClipboardText(const char *text)
Definition: imgui.cpp:3232
ImGui::GetFrameHeight
IMGUI_API float GetFrameHeight()
Definition: imgui.cpp:7117
ImGui::IsItemToggledSelection
IMGUI_API bool IsItemToggledSelection()
Definition: imgui.cpp:4622
ImGui::CloseCurrentPopup
IMGUI_API void CloseCurrentPopup()
Definition: imgui.cpp:7634
IM_F32_TO_INT8_SAT
#define IM_F32_TO_INT8_SAT(_VAL)
Definition: imgui_internal.h:184
ImGuiConfigFlags_NavEnableSetMousePos
@ ImGuiConfigFlags_NavEnableSetMousePos
Definition: imgui.h:1063
ImGuiGroupData::BackupGroupOffset
ImVec1 BackupGroupOffset
Definition: imgui_internal.h:749
IM_PI
#define IM_PI
Definition: imgui_internal.h:176
NAV_MAP_KEY
#define NAV_MAP_KEY(_KEY, _NAV_INPUT)
ImGuiWindow::DrawListInst
ImDrawList DrawListInst
Definition: imgui_internal.h:1526
ImGuiCol_ResizeGripActive
@ ImGuiCol_ResizeGripActive
Definition: imgui.h:1118
ImGui::IsRectVisible
IMGUI_API bool IsRectVisible(const ImVec2 &size)
Definition: imgui.cpp:6674
ImGuiWindowFlags_NoTitleBar
@ ImGuiWindowFlags_NoTitleBar
Definition: imgui.h:769
ImDrawData::DisplaySize
ImVec2 DisplaySize
Definition: imgui.h:2076
f
GLfloat f
Definition: glcorearb.h:3964
ImGuiCol_BorderShadow
@ ImGuiCol_BorderShadow
Definition: imgui.h:1092
IM_UNICODE_CODEPOINT_MAX
#define IM_UNICODE_CODEPOINT_MAX
Definition: imgui.h:1662
ImGui::GetStyle
IMGUI_API ImGuiStyle & GetStyle()
Definition: imgui.cpp:2339
ImGuiColorMod
Definition: imgui_internal.h:727
ImGuiNavInput_KeyLeft_
@ ImGuiNavInput_KeyLeft_
Definition: imgui.h:1049
ImGuiWindowFlags_NoScrollWithMouse
@ ImGuiWindowFlags_NoScrollWithMouse
Definition: imgui.h:773
ImGui
Definition: imgui.cpp:922
ImGuiWindowFlags_AlwaysHorizontalScrollbar
@ ImGuiWindowFlags_AlwaysHorizontalScrollbar
Definition: imgui.h:784
ImFileHandle
FILE * ImFileHandle
Definition: imgui_internal.h:291
ImGuiWindowTempData::LastItemId
ImGuiID LastItemId
Definition: imgui_internal.h:1380
ImGui::FindSettingsHandler
IMGUI_API ImGuiSettingsHandler * FindSettingsHandler(const char *type_name)
Definition: imgui.cpp:9611
ImGuiWindow::Hidden
bool Hidden
Definition: imgui_internal.h:1485
ImGuiCol_TitleBg
@ ImGuiCol_TitleBg
Definition: imgui.h:1096
ImGuiWindowTempData::ItemWidthStack
ImVector< float > ItemWidthStack
Definition: imgui_internal.h:1414
ImGuiNavInput_LStickRight
@ ImGuiNavInput_LStickRight
Definition: imgui.h:1038
ImGui::PushClipRect
IMGUI_API void PushClipRect(const ImVec2 &clip_rect_min, const ImVec2 &clip_rect_max, bool intersect_with_current_clip_rect)
Definition: imgui.cpp:4128
ImGuiWindow::ChildId
ImGuiID ChildId
Definition: imgui_internal.h:1471
ImFont::EllipsisChar
ImWchar EllipsisChar
Definition: imgui.h:2290
ImGuiLayoutType_Horizontal
@ ImGuiLayoutType_Horizontal
Definition: imgui_internal.h:568
ImGuiCol_NavWindowingHighlight
@ ImGuiCol_NavWindowingHighlight
Definition: imgui.h:1131
ImGui::GetWindowContentRegionWidth
IMGUI_API float GetWindowContentRegionWidth()
Definition: imgui.cpp:7172
ImGuiCol_TitleBgCollapsed
@ ImGuiCol_TitleBgCollapsed
Definition: imgui.h:1098
ImGuiWindowFlags_NoResize
@ ImGuiWindowFlags_NoResize
Definition: imgui.h:770
ImGuiContext::ActiveIdIsAlive
ImGuiID ActiveIdIsAlive
Definition: imgui_internal.h:1058
ImRect::ClipWith
void ClipWith(const ImRect &r)
Definition: imgui_internal.h:712
ImGui::ShowMetricsWindow
IMGUI_API void ShowMetricsWindow(bool *p_open=NULL)
Definition: imgui.cpp:9956
ImGuiContext::CurrentWindow
ImGuiWindow * CurrentWindow
Definition: imgui_internal.h:1043
ImGui::EndChild
IMGUI_API void EndChild()
Definition: imgui.cpp:4755
ImGuiDragDropFlags_AcceptNoDrawDefaultRect
@ ImGuiDragDropFlags_AcceptNoDrawDefaultRect
Definition: imgui.h:948
ImGuiWindowTempData::ParentLayoutType
ImGuiLayoutType ParentLayoutType
Definition: imgui_internal.h:1404
ImGuiWindow::GetID
ImGuiID GetID(const char *str, const char *str_end=NULL)
Definition: imgui.cpp:2879
AddWindowToDrawData
static void AddWindowToDrawData(ImVector< ImDrawList * > *out_render_list, ImGuiWindow *window)
Definition: imgui.cpp:4071
ImDrawListFlags_AntiAliasedLines
@ ImDrawListFlags_AntiAliasedLines
Definition: imgui.h:1948
ImGui::NavCalcPreferredRefPos
static ImVec2 NavCalcPreferredRefPos()
Definition: imgui.cpp:8313
ImGuiIO::MetricsRenderVertices
int MetricsRenderVertices
Definition: imgui.h:1514
ImDrawListFlags
int ImDrawListFlags
Definition: imgui.h:153
ImGui::GetStyleColorName
const IMGUI_API char * GetStyleColorName(ImGuiCol idx)
Definition: imgui.cpp:2496
ImGui::GetContentRegionMax
IMGUI_API ImVec2 GetContentRegionMax()
Definition: imgui.cpp:7132
w
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:3126
ImGuiStyle::WindowRounding
float WindowRounding
Definition: imgui.h:1369
ImVector::pop_back
void pop_back()
Definition: imgui.h:1344
ImGuiIO::ClearInputCharacters
IMGUI_API void ClearInputCharacters()
Definition: imgui.cpp:1172
ImGuiDir_Right
@ ImGuiDir_Right
Definition: imgui.h:978
ImGuiWindowTempData::CurrLineTextBaseOffset
float CurrLineTextBaseOffset
Definition: imgui_internal.h:1373
version
static struct @0 version
ImFileWrite
ImU64 ImFileWrite(const void *data, ImU64 sz, ImU64 count, ImFileHandle f)
Definition: imgui.cpp:1569
ImGuiStyleMod
Definition: imgui_internal.h:734
ImGuiGroupData::EmitItem
bool EmitItem
Definition: imgui_internal.h:754
ImGuiIO::BackendRendererUserData
void * BackendRendererUserData
Definition: imgui.h:1458
ImGui::OpenPopup
IMGUI_API void OpenPopup(const char *str_id)
Definition: imgui.cpp:7519
ImGuiCol_ScrollbarBg
@ ImGuiCol_ScrollbarBg
Definition: imgui.h:1100
count
GLint GLsizei count
Definition: glcorearb.h:2830
ImGuiIO::DeltaTime
float DeltaTime
Definition: imgui.h:1423
false
#define false
Definition: cJSON.c:70
ImGui::SetScrollFromPosY
IMGUI_API void SetScrollFromPosY(float local_y, float center_y_ratio=0.5f)
Definition: imgui.cpp:7404
ImGuiWindow::StateStorage
ImGuiStorage StateStorage
Definition: imgui_internal.h:1520
ImGuiCol_FrameBgHovered
@ ImGuiCol_FrameBgHovered
Definition: imgui.h:1094
IM_FREE
#define IM_FREE(_PTR)
Definition: imgui.h:1284
GetStyleVarInfo
static const ImGuiStyleVarInfo * GetStyleVarInfo(ImGuiStyleVar idx)
Definition: imgui.cpp:2445
ImGuiWindow::LastTimeActive
float LastTimeActive
Definition: imgui_internal.h:1518
ImGui::OpenPopupEx
IMGUI_API void OpenPopupEx(ImGuiID id)
Definition: imgui.cpp:7529
ImFileRead
ImU64 ImFileRead(void *data, ImU64 sz, ImU64 count, ImFileHandle f)
Definition: imgui.cpp:1568
ImGuiMouseCursor
int ImGuiMouseCursor
Definition: imgui.h:150
ImGuiWindow::ContentRegionRect
ImRect ContentRegionRect
Definition: imgui_internal.h:1515
ImGui::EndDragDropTarget
IMGUI_API void EndDragDropTarget()
Definition: imgui.cpp:9294
ImGuiStyle::ScrollbarSize
float ScrollbarSize
Definition: imgui.h:1386
ImGui::SliderInt
IMGUI_API bool SliderInt(const char *label, int *v, int v_min, int v_max, const char *format="%d")
Definition: imgui_widgets.cpp:2682
ImLengthSqr
static float ImLengthSqr(const ImVec2 &lhs)
Definition: imgui_internal.h:335
ImGuiSizeCallback
void(* ImGuiSizeCallback)(ImGuiSizeCallbackData *data)
Definition: imgui.h:176
ImGuiContext::DrawListSharedData
ImDrawListSharedData DrawListSharedData
Definition: imgui_internal.h:1027
ImGui::StyleColorsDark
IMGUI_API void StyleColorsDark(ImGuiStyle *dst=NULL)
Definition: imgui_draw.cpp:178
ImGuiTabItem
Definition: imgui_internal.h:1593
ImGuiCol_SeparatorHovered
@ ImGuiCol_SeparatorHovered
Definition: imgui.h:1114
ImGuiGroupData::BackupCursorPos
ImVec2 BackupCursorPos
Definition: imgui_internal.h:746
ImGui::RenderTextEllipsis
IMGUI_API void RenderTextEllipsis(ImDrawList *draw_list, const ImVec2 &pos_min, const ImVec2 &pos_max, float clip_max_x, float ellipsis_max_x, const char *text, const char *text_end, const ImVec2 *text_size_if_known)
Definition: imgui.cpp:2665
ImGuiDragDropFlags_AcceptNoPreviewTooltip
@ ImGuiDragDropFlags_AcceptNoPreviewTooltip
Definition: imgui.h:949
ImGuiWindowTempData::CurrLineSize
ImVec2 CurrLineSize
Definition: imgui_internal.h:1371
ImGuiNavInput_DpadUp
@ ImGuiNavInput_DpadUp
Definition: imgui.h:1035
ImGui::CloseButton
IMGUI_API bool CloseButton(ImGuiID id, const ImVec2 &pos)
Definition: imgui_widgets.cpp:755
IM_COL32
#define IM_COL32(R, G, B, A)
Definition: imgui.h:1820
ImVector::back
T & back()
Definition: imgui.h:1332
ImGuiWindow::SettingsOffset
int SettingsOffset
Definition: imgui_internal.h:1523
a
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:3228
ImGuiMouseCursor_ResizeNS
@ ImGuiMouseCursor_ResizeNS
Definition: imgui.h:1248
SetCursorPosYAndSetupDummyPrevLine
static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height)
Definition: imgui.cpp:2247
ImGui::GetCurrentWindowRead
ImGuiWindow * GetCurrentWindowRead()
Definition: imgui_internal.h:1656
ImGuiWindow::NavLastChildNavWindow
ImGuiWindow * NavLastChildNavWindow
Definition: imgui_internal.h:1532
level
GLint level
Definition: glcorearb.h:2773
ImGui::BeginPopupModal
IMGUI_API bool BeginPopupModal(const char *name, bool *p_open=NULL, ImGuiWindowFlags flags=0)
Definition: imgui.cpp:7701
ImGuiInputReadMode_Down
@ ImGuiInputReadMode_Down
Definition: imgui_internal.h:608
ImGui::GetScrollMaxY
IMGUI_API float GetScrollMaxY()
Definition: imgui.cpp:7347
ImGui::Shutdown
IMGUI_API void Shutdown(ImGuiContext *context)
Definition: imgui.cpp:3930
ImGuiSettingsHandler::WriteAllFn
void(* WriteAllFn)(ImGuiContext *ctx, ImGuiSettingsHandler *handler, ImGuiTextBuffer *out_buf)
Definition: imgui_internal.h:825
ImGuiDragDropFlags_None
@ ImGuiDragDropFlags_None
Definition: imgui.h:938
ImGuiMouseCursor_Arrow
@ ImGuiMouseCursor_Arrow
Definition: imgui.h:1245
ImGuiStyleVarInfo::Offset
ImU32 Offset
Definition: imgui.cpp:2414
ImGuiIO::BackendFlags
ImGuiBackendFlags BackendFlags
Definition: imgui.h:1421
ImGuiPayload::IsDataType
bool IsDataType(const char *type) const
Definition: imgui.h:1614
ImGuiPopupData::OpenParentId
ImGuiID OpenParentId
Definition: imgui_internal.h:838
ImGuiStyleVar
int ImGuiStyleVar
Definition: imgui.h:151
ImGui::EndChildFrame
IMGUI_API void EndChildFrame()
Definition: imgui.cpp:4813
ImGui::SetScrollFromPosX
IMGUI_API void SetScrollFromPosX(float local_x, float center_x_ratio=0.5f)
Definition: imgui.cpp:7398
IMGUI_DEBUG_LOG
#define IMGUI_DEBUG_LOG(_FMT,...)
Definition: imgui_internal.h:150
ImGui::BringWindowToFocusFront
IMGUI_API void BringWindowToFocusFront(ImGuiWindow *window)
Definition: imgui.cpp:6041
ImGuiStorage::SetVoidPtr
IMGUI_API void SetVoidPtr(ImGuiID key, void *val)
Definition: imgui.cpp:2012
ImGuiIO::MetricsRenderWindows
int MetricsRenderWindows
Definition: imgui.h:1516
ImGui::GetColorU32
IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul=1.0f)
Definition: imgui.cpp:2345
ImTextCharFromUtf8
int ImTextCharFromUtf8(unsigned int *out_char, const char *in_text, const char *in_text_end)
Definition: imgui.cpp:1621
ImGui::IsKeyDown
IMGUI_API bool IsKeyDown(int user_key_index)
Definition: imgui.cpp:4367
ImGuiWindow::ScrollTargetCenterRatio
ImVec2 ScrollTargetCenterRatio
Definition: imgui_internal.h:1475
ImGuiCond_FirstUseEver
@ ImGuiCond_FirstUseEver
Definition: imgui.h:1269
ImGui::UpdateMouseMovingWindowEndFrame
IMGUI_API void UpdateMouseMovingWindowEndFrame()
Definition: imgui.cpp:3387
ImGuiWindowTempData::ItemWidth
float ItemWidth
Definition: imgui_internal.h:1411
FindHoveredWindow
static void FindHoveredWindow()
Definition: imgui.cpp:4300
ImGuiListClipper::End
IMGUI_API void End()
Definition: imgui.cpp:2284
ImGui::IsItemDeactivated
IMGUI_API bool IsItemDeactivated()
Definition: imgui.cpp:4586
ImGuiWindow::AutoPosLastDirection
ImGuiDir AutoPosLastDirection
Definition: imgui_internal.h:1496
it
MapIter it
Definition: php/ext/google/protobuf/map.c:205
ImGuiWindow::ScrollMax
ImVec2 ScrollMax
Definition: imgui_internal.h:1473
ImGuiBackendFlags_HasGamepad
@ ImGuiBackendFlags_HasGamepad
Definition: imgui.h:1077
ImDrawList::PathFillConvex
void PathFillConvex(ImU32 col)
Definition: imgui.h:2027
ImGuiWindow::Appearing
bool Appearing
Definition: imgui_internal.h:1484
ImGuiNavMoveResult::DistAxial
float DistAxial
Definition: imgui_internal.h:935
ImGui::GetCurrentContext
IMGUI_API ImGuiContext * GetCurrentContext()
Definition: imgui.cpp:3246
ImGuiWindow::IsFallbackWindow
bool IsFallbackWindow
Definition: imgui_internal.h:1486
ImGuiIO::MetricsActiveWindows
int MetricsActiveWindows
Definition: imgui.h:1517
ImGui::GetMousePosOnOpeningCurrentPopup
IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup()
Definition: imgui.cpp:4491
ImGuiWindow::WriteAccessed
bool WriteAccessed
Definition: imgui_internal.h:1480
ImGui::PopFont
IMGUI_API void PopFont()
Definition: imgui.cpp:6176
ImGui::EndPopup
IMGUI_API void EndPopup()
Definition: imgui.cpp:7729
ImGuiNavInput_DpadRight
@ ImGuiNavInput_DpadRight
Definition: imgui.h:1034
ImGuiIO::AddInputCharacterUTF16
IMGUI_API void AddInputCharacterUTF16(ImWchar16 c)
Definition: imgui.cpp:1137
ImGuiStyle::AntiAliasedFill
bool AntiAliasedFill
Definition: imgui.h:1399
ImGuiKey_Tab
@ ImGuiKey_Tab
Definition: imgui.h:987
ImGuiWindowSettings::GetName
char * GetName()
Definition: imgui_internal.h:816
ImGui::KeepAliveID
IMGUI_API void KeepAliveID(ImGuiID id)
Definition: imgui.cpp:3021
ImGuiNextWindowDataFlags_HasContentSize
@ ImGuiNextWindowDataFlags_HasContentSize
Definition: imgui_internal.h:947
ImDrawList::PathArcToFast
IMGUI_API void PathArcToFast(const ImVec2 &center, float radius, int a_min_of_12, int a_max_of_12)
Definition: imgui_draw.cpp:894
ImGui::BulletText
IMGUI_API void BulletText(const char *fmt,...) IM_FMTARGS(1)
Definition: imgui_widgets.cpp:349
ImGui::LogBegin
IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth)
Definition: imgui.cpp:9384
ImDrawList::AddRect
IMGUI_API void AddRect(const ImVec2 &p_min, const ImVec2 &p_max, ImU32 col, float rounding=0.0f, ImDrawCornerFlags rounding_corners=ImDrawCornerFlags_All, float thickness=1.0f)
Definition: imgui_draw.cpp:1022
ImGuiTabItem::ID
ImGuiID ID
Definition: imgui_internal.h:1595
ImGuiResizeGripDef
Definition: imgui.cpp:5000
ImGuiItemFlags_Default_
@ ImGuiItemFlags_Default_
Definition: imgui_internal.h:528
ImGuiWindowTempData::ItemFlagsStack
ImVector< ImGuiItemFlags > ItemFlagsStack
Definition: imgui_internal.h:1413
ImGui::PushOverrideID
IMGUI_API void PushOverrideID(ImGuiID id)
Definition: imgui.cpp:6644
v2
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:3087
ImGuiWindow::ScrollTarget
ImVec2 ScrollTarget
Definition: imgui_internal.h:1474
ImGuiStyleVarInfo
Definition: imgui.cpp:2410
ImGuiCol_CheckMark
@ ImGuiCol_CheckMark
Definition: imgui.h:1104
ImDrawList::PathStroke
void PathStroke(ImU32 col, bool closed, float thickness=1.0f)
Definition: imgui.h:2028
h
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:4147
ImGuiWindowFlags_NoInputs
@ ImGuiWindowFlags_NoInputs
Definition: imgui.h:791
ImVec2::y
float y
Definition: imgui.h:210
width
GLint GLsizei width
Definition: glcorearb.h:2768
benchmarks.python.py_benchmark.args
args
Definition: py_benchmark.py:24
ImGuiStorage::GetFloatRef
IMGUI_API float * GetFloatRef(ImGuiID key, float default_val=0.0f)
Definition: imgui.cpp:1968
ImGuiLogType_TTY
@ ImGuiLogType_TTY
Definition: imgui_internal.h:575
ImGuiIO::SetClipboardTextFn
void(* SetClipboardTextFn)(void *user_data, const char *text)
Definition: imgui.h:1464
ImGuiStyle::ButtonTextAlign
ImVec2 ButtonTextAlign
Definition: imgui.h:1393
ImGui::SetNavID
IMGUI_API void SetNavID(ImGuiID id, int nav_layer, ImGuiID focus_scope_id)
Definition: imgui.cpp:7909
NavScoreItemDistInterval
static float NavScoreItemDistInterval(float a0, float a1, float b0, float b1)
Definition: imgui.cpp:7960
ImGui::UpdateMouseInputs
static void UpdateMouseInputs()
Definition: imgui.cpp:3442
ImGuiWindow::BeginOrderWithinContext
short BeginOrderWithinContext
Definition: imgui_internal.h:1491
ImFontGlyph::X0
float X0
Definition: imgui.h:2125
ImGui::GetFont
IMGUI_API ImFont * GetFont()
Definition: imgui.cpp:6535
ImDrawCmd::ElemCount
unsigned int ElemCount
Definition: imgui.h:1873
ImGui::BeginChildFrame
IMGUI_API bool BeginChildFrame(ImGuiID id, const ImVec2 &size, ImGuiWindowFlags flags=0)
Definition: imgui.cpp:4799
ImGuiWindowFlags_NavFlattened
@ ImGuiWindowFlags_NavFlattened
Definition: imgui.h:794
ImGuiWindowTempData::LastItemRect
ImRect LastItemRect
Definition: imgui_internal.h:1382
ImGuiFocusedFlags_ChildWindows
@ ImGuiFocusedFlags_ChildWindows
Definition: imgui.h:911
ImGui::NavUpdateMoveResult
static void NavUpdateMoveResult()
Definition: imgui.cpp:8653


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:54