Revision a8009d0e
Added by david.sorber 8 months ago
| external/imgui/imgui.cpp | ||
|---|---|---|
|
// dear imgui, v1.91.5
|
||
|
// dear imgui, v1.92.5
|
||
|
// (main code and documentation)
|
||
|
|
||
|
// Help:
|
||
|
// - See links below.
|
||
|
// - Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp. All applications in examples/ are doing that.
|
||
|
// - Read top of imgui.cpp for more details, links and comments.
|
||
|
// - Add '#define IMGUI_DEFINE_MATH_OPERATORS' before including imgui.h (or in imconfig.h) to access courtesy maths operators for ImVec2 and ImVec4.
|
||
|
|
||
|
// Resources:
|
||
|
// - FAQ ........................ https://dearimgui.com/faq (in repository as docs/FAQ.md)
|
||
|
// - Homepage ................... https://github.com/ocornut/imgui
|
||
|
// - Releases & changelog ....... https://github.com/ocornut/imgui/releases
|
||
|
// - Releases & Changelog ....... https://github.com/ocornut/imgui/releases
|
||
|
// - Gallery .................... https://github.com/ocornut/imgui/issues?q=label%3Agallery (please post your screenshots/video there!)
|
||
|
// - Wiki ....................... https://github.com/ocornut/imgui/wiki (lots of good stuff there)
|
||
|
// - Getting Started https://github.com/ocornut/imgui/wiki/Getting-Started (how to integrate in an existing app by adding ~25 lines of code)
|
||
|
// - Third-party Extensions https://github.com/ocornut/imgui/wiki/Useful-Extensions (ImPlot & many more)
|
||
|
// - Bindings/Backends https://github.com/ocornut/imgui/wiki/Bindings (language bindings, backends for various tech/engines)
|
||
|
// - Glossary https://github.com/ocornut/imgui/wiki/Glossary
|
||
|
// - Bindings/Backends https://github.com/ocornut/imgui/wiki/Bindings (language bindings + backends for various tech/engines)
|
||
|
// - Debug Tools https://github.com/ocornut/imgui/wiki/Debug-Tools
|
||
|
// - Glossary https://github.com/ocornut/imgui/wiki/Glossary
|
||
|
// - Software using Dear ImGui https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui
|
||
|
// - Issues & support ........... https://github.com/ocornut/imgui/issues
|
||
|
// - Test Engine & Automation ... https://github.com/ocornut/imgui_test_engine (test suite, test engine to automate your apps)
|
||
|
// - Web version of the Demo .... https://pthom.github.io/imgui_manual_online/manual/imgui_manual.html (w/ source code browser)
|
||
|
|
||
|
// For first-time users having issues compiling/linking/running/loading fonts:
|
||
|
// For FIRST-TIME users having issues compiling/linking/running:
|
||
|
// please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above.
|
||
|
// Everything else should be asked in 'Issues'! We are building a database of cross-linked knowledge there.
|
||
|
// Since 1.92, we encourage font loading questions to also be posted in 'Issues'.
|
||
|
|
||
|
// Copyright (c) 2014-2024 Omar Cornut
|
||
|
// Copyright (c) 2014-2025 Omar Cornut
|
||
|
// Developed by Omar Cornut and every direct or indirect contributors to the GitHub.
|
||
|
// See LICENSE.txt for copyright and licensing details (standard MIT License).
|
||
|
// This library is free but needs your support to sustain development and maintenance.
|
||
| ... | ... | |
|
- HOW TO UPDATE TO A NEWER VERSION OF DEAR IMGUI
|
||
|
- GETTING STARTED WITH INTEGRATING DEAR IMGUI IN YOUR CODE/ENGINE
|
||
|
- HOW A SIMPLE APPLICATION MAY LOOK LIKE
|
||
|
- HOW A SIMPLE RENDERING FUNCTION MAY LOOK LIKE
|
||
|
- USING CUSTOM BACKEND / CUSTOM ENGINE
|
||
|
- API BREAKING CHANGES (read me when you update!)
|
||
|
- FREQUENTLY ASKED QUESTIONS (FAQ)
|
||
|
- Read all answers online: https://www.dearimgui.com/faq, or in docs/FAQ.md (with a Markdown viewer)
|
||
| ... | ... | |
|
// [SECTION] RENDER HELPERS
|
||
|
// [SECTION] INITIALIZATION, SHUTDOWN
|
||
|
// [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!)
|
||
|
// [SECTION] FONTS, TEXTURES
|
||
|
// [SECTION] ID STACK
|
||
|
// [SECTION] INPUTS
|
||
|
// [SECTION] ERROR CHECKING, STATE RECOVERY
|
||
| ... | ... | |
|
// [SECTION] SCROLLING
|
||
|
// [SECTION] TOOLTIPS
|
||
|
// [SECTION] POPUPS
|
||
|
// [SECTION] WINDOW FOCUS
|
||
|
// [SECTION] KEYBOARD/GAMEPAD NAVIGATION
|
||
|
// [SECTION] DRAG AND DROP
|
||
|
// [SECTION] LOGGING/CAPTURING
|
||
| ... | ... | |
|
Designed primarily for developers and content-creators, not the typical end-user!
|
||
|
Some of the current weaknesses (which we aim to address in the future) includes:
|
||
|
|
||
|
- Doesn't look fancy.
|
||
|
- Doesn't look fancy by default.
|
||
|
- Limited layout features, intricate layouts are typically crafted in code.
|
||
|
|
||
|
|
||
| ... | ... | |
|
|
||
|
- MOUSE CONTROLS
|
||
|
- Mouse wheel: Scroll vertically.
|
||
|
- SHIFT+Mouse wheel: Scroll horizontally.
|
||
|
- Shift+Mouse wheel: Scroll horizontally.
|
||
|
- Click [X]: Close a window, available when 'bool* p_open' is passed to ImGui::Begin().
|
||
|
- Click ^, Double-Click title: Collapse window.
|
||
|
- Drag on corner/border: Resize window (double-click to auto fit window to its contents).
|
||
| ... | ... | |
|
- Left-click outside popup: Close popup stack (right-click over underlying popup: Partially close popup stack).
|
||
|
|
||
|
- TEXT EDITOR
|
||
|
- Hold SHIFT or Drag Mouse: Select text.
|
||
|
- CTRL+Left/Right: Word jump.
|
||
|
- CTRL+Shift+Left/Right: Select words.
|
||
|
- CTRL+A or Double-Click: Select All.
|
||
|
- CTRL+X, CTRL+C, CTRL+V: Use OS clipboard.
|
||
|
- CTRL+Z, CTRL+Y: Undo, Redo.
|
||
|
- Hold Shift or Drag Mouse: Select text.
|
||
|
- Ctrl+Left/Right: Word jump.
|
||
|
- Ctrl+Shift+Left/Right: Select words.
|
||
|
- Ctrl+A or Double-Click: Select All.
|
||
|
- Ctrl+X, Ctrl+C, Ctrl+V: Use OS clipboard.
|
||
|
- Ctrl+Z Undo.
|
||
|
- Ctrl+Y or Ctrl+Shift+Z: Redo.
|
||
|
- ESCAPE: Revert text to its original value.
|
||
|
- On OSX, controls are automatically adjusted to match standard OSX text editing 2ts and behaviors.
|
||
|
- On macOS, controls are automatically adjusted to match standard macOS text editing and behaviors.
|
||
|
(for 99% of shortcuts, Ctrl is replaced by Cmd on macOS).
|
||
|
|
||
|
- KEYBOARD CONTROLS
|
||
|
- Basic:
|
||
|
- Tab, SHIFT+Tab Cycle through text editable fields.
|
||
|
- CTRL+Tab, CTRL+Shift+Tab Cycle through windows.
|
||
|
- CTRL+Click Input text into a Slider or Drag widget.
|
||
|
- Tab, Shift+Tab Cycle through text editable fields.
|
||
|
- Ctrl+Tab, Ctrl+Shift+Tab Cycle through windows.
|
||
|
- Ctrl+Click Input text into a Slider or Drag widget.
|
||
|
- Extended features with `io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard`:
|
||
|
- Tab, SHIFT+Tab: Cycle through every items.
|
||
|
- Tab, Shift+Tab: Cycle through every items.
|
||
|
- Arrow keys Move through items using directional navigation. Tweak value.
|
||
|
- Arrow keys + Alt, Shift Tweak slower, tweak faster (when using arrow keys).
|
||
|
- Enter Activate item (prefer text input when possible).
|
||
| ... | ... | |
|
- Page Up, Page Down Previous page, next page.
|
||
|
- Home, End Scroll to top, scroll to bottom.
|
||
|
- Alt Toggle between scrolling layer and menu layer.
|
||
|
- CTRL+Tab then Ctrl+Arrows Move window. Hold SHIFT to resize instead of moving.
|
||
|
- Ctrl+Tab then Ctrl+Arrows Move window. Hold Shift to resize instead of moving.
|
||
|
- Output when ImGuiConfigFlags_NavEnableKeyboard set,
|
||
|
- io.WantCaptureKeyboard flag is set when keyboard is claimed.
|
||
|
- io.NavActive: true when a window is focused and it doesn't have the ImGuiWindowFlags_NoNavInputs flag set.
|
||
| ... | ... | |
|
|
||
|
READ FIRST
|
||
|
----------
|
||
|
- Remember to check the wonderful Wiki (https://github.com/ocornut/imgui/wiki)
|
||
|
- Remember to check the wonderful Wiki: https://github.com/ocornut/imgui/wiki
|
||
|
- Your code creates the UI every frame of your application loop, if your code doesn't run the UI is gone!
|
||
|
The UI can be highly dynamic, there are no construction or destruction steps, less superfluous
|
||
|
data retention on your side, less state duplication, less state synchronization, fewer bugs.
|
||
| ... | ... | |
|
|
||
|
HOW A SIMPLE APPLICATION MAY LOOK LIKE
|
||
|
--------------------------------------
|
||
|
EXHIBIT 1: USING THE EXAMPLE BACKENDS (= imgui_impl_XXX.cpp files from the backends/ folder).
|
||
|
|
||
|
USING THE EXAMPLE BACKENDS (= imgui_impl_XXX.cpp files from the backends/ folder).
|
||
|
The sub-folders in examples/ contain examples applications following this structure.
|
||
|
|
||
|
// Application init: create a dear imgui context, setup some options, load fonts
|
||
| ... | ... | |
|
// Any application code here
|
||
|
ImGui::Text("Hello, world!");
|
||
|
|
||
|
// Render dear imgui into screen
|
||
|
// Render dear imgui into framebuffer
|
||
|
ImGui::Render();
|
||
|
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||
|
g_pSwapChain->Present(1, 0);
|
||
| ... | ... | |
|
ImGui_ImplWin32_Shutdown();
|
||
|
ImGui::DestroyContext();
|
||
|
|
||
|
EXHIBIT 2: IMPLEMENTING CUSTOM BACKEND / CUSTOM ENGINE
|
||
|
To decide whether to dispatch mouse/keyboard inputs to Dear ImGui to the rest of your application,
|
||
|
you should read the 'io.WantCaptureMouse', 'io.WantCaptureKeyboard' and 'io.WantTextInput' flags!
|
||
|
Please read the FAQ entry "How can I tell whether to dispatch mouse/keyboard to Dear ImGui or my application?" about this.
|
||
|
|
||
|
|
||
|
// Application init: create a dear imgui context, setup some options, load fonts
|
||
|
USING CUSTOM BACKEND / CUSTOM ENGINE
|
||
|
------------------------------------
|
||
|
|
||
|
IMPLEMENTING YOUR PLATFORM BACKEND:
|
||
|
-> see https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md for basic instructions.
|
||
|
-> the Platform backends in impl_impl_XXX.cpp files contain many implementations.
|
||
|
|
||
|
IMPLEMENTING YOUR RenderDrawData() function:
|
||
|
-> see https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md
|
||
|
-> the Renderer Backends in impl_impl_XXX.cpp files contain many implementations of a ImGui_ImplXXXX_RenderDrawData() function.
|
||
|
|
||
|
IMPLEMENTING SUPPORT for ImGuiBackendFlags_RendererHasTextures:
|
||
|
-> see https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md
|
||
|
-> the Renderer Backends in impl_impl_XXX.cpp files contain many implementations of a ImGui_ImplXXXX_UpdateTexture() function.
|
||
|
|
||
|
Basic application/backend skeleton:
|
||
|
|
||
|
// Application init: create a Dear ImGui context, setup some options, load fonts
|
||
|
ImGui::CreateContext();
|
||
|
ImGuiIO& io = ImGui::GetIO();
|
||
|
// TODO: Set optional io.ConfigFlags values, e.g. 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard' to enable keyboard controls.
|
||
|
// TODO: Fill optional fields of the io structure later.
|
||
|
// TODO: Load TTF/OTF fonts if you don't want to use the default font.
|
||
|
// TODO: set io.ConfigXXX values, e.g.
|
||
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable keyboard controls
|
||
|
|
||
|
// Build and load the texture atlas into a texture
|
||
|
// (In the examples/ app this is usually done within the ImGui_ImplXXX_Init() function from one of the demo Renderer)
|
||
|
int width, height;
|
||
|
unsigned char* pixels = nullptr;
|
||
|
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||
|
|
||
|
// At this point you've got the texture data and you need to upload that to your graphic system:
|
||
|
// After we have created the texture, store its pointer/identifier (_in whichever format your engine uses_) in 'io.Fonts->TexID'.
|
||
|
// This will be passed back to your via the renderer. Basically ImTextureID == void*. Read FAQ for details about ImTextureID.
|
||
|
MyTexture* texture = MyEngine::CreateTextureFromMemoryPixels(pixels, width, height, TEXTURE_TYPE_RGBA32)
|
||
|
io.Fonts->SetTexID((void*)texture);
|
||
|
// TODO: Load TTF/OTF fonts if you don't want to use the default font.
|
||
|
io.Fonts->AddFontFromFileTTF("NotoSans.ttf");
|
||
|
|
||
|
// Application main loop
|
||
|
while (true)
|
||
| ... | ... | |
|
MyGameUpdate(); // may use any Dear ImGui functions, e.g. ImGui::Begin("My window"); ImGui::Text("Hello, world!"); ImGui::End();
|
||
|
MyGameRender(); // may use any Dear ImGui functions as well!
|
||
|
|
||
|
// Render dear imgui, swap buffers
|
||
|
// End the dear imgui frame
|
||
|
// (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)
|
||
|
ImGui::EndFrame();
|
||
|
ImGui::EndFrame(); // this is automatically called by Render(), but available
|
||
|
ImGui::Render();
|
||
|
|
||
|
// Update textures
|
||
|
ImDrawData* draw_data = ImGui::GetDrawData();
|
||
|
MyImGuiRenderFunction(draw_data);
|
||
|
for (ImTextureData* tex : *draw_data->Textures)
|
||
|
if (tex->Status != ImTextureStatus_OK)
|
||
|
MyImGuiBackend_UpdateTexture(tex);
|
||
|
|
||
|
// Render dear imgui contents, swap buffers
|
||
|
MyImGuiBackend_RenderDrawData(draw_data);
|
||
|
SwapBuffers();
|
||
|
}
|
||
|
|
||
|
// Shutdown
|
||
|
ImGui::DestroyContext();
|
||
|
|
||
|
To decide whether to dispatch mouse/keyboard inputs to Dear ImGui to the rest of your application,
|
||
|
you should read the 'io.WantCaptureMouse', 'io.WantCaptureKeyboard' and 'io.WantTextInput' flags!
|
||
|
Please read the FAQ entry "How can I tell whether to dispatch mouse/keyboard to Dear ImGui or my application?" about this.
|
||
|
|
||
|
|
||
|
HOW A SIMPLE RENDERING FUNCTION MAY LOOK LIKE
|
||
|
---------------------------------------------
|
||
|
The backends in impl_impl_XXX.cpp files contain many working implementations of a rendering function.
|
||
|
|
||
|
void MyImGuiRenderFunction(ImDrawData* draw_data)
|
||
|
{
|
||
|
// TODO: Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled
|
||
|
// TODO: Setup texture sampling state: sample with bilinear filtering (NOT point/nearest filtering). Use 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines;' to allow point/nearest filtering.
|
||
|
// TODO: Setup viewport covering draw_data->DisplayPos to draw_data->DisplayPos + draw_data->DisplaySize
|
||
|
// TODO: Setup orthographic projection matrix cover draw_data->DisplayPos to draw_data->DisplayPos + draw_data->DisplaySize
|
||
|
// TODO: Setup shader: vertex { float2 pos, float2 uv, u32 color }, fragment shader sample color from 1 texture, multiply by vertex color.
|
||
|
ImVec2 clip_off = draw_data->DisplayPos;
|
||
|
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||
|
{
|
||
|
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||
|
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; // vertex buffer generated by Dear ImGui
|
||
|
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; // index buffer generated by Dear ImGui
|
||
|
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||
|
{
|
||
|
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||
|
if (pcmd->UserCallback)
|
||
|
{
|
||
|
pcmd->UserCallback(cmd_list, pcmd);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Project scissor/clipping rectangles into framebuffer space
|
||
|
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
||
|
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
||
|
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||
|
continue;
|
||
|
|
||
|
// We are using scissoring to clip some objects. All low-level graphics API should support it.
|
||
|
// - If your engine doesn't support scissoring yet, you may ignore this at first. You will get some small glitches
|
||
|
// (some elements visible outside their bounds) but you can fix that once everything else works!
|
||
|
// - Clipping coordinates are provided in imgui coordinates space:
|
||
|
// - For a given viewport, draw_data->DisplayPos == viewport->Pos and draw_data->DisplaySize == viewport->Size
|
||
|
// - In a single viewport application, draw_data->DisplayPos == (0,0) and draw_data->DisplaySize == io.DisplaySize, but always use GetMainViewport()->Pos/Size instead of hardcoding those values.
|
||
|
// - In the interest of supporting multi-viewport applications (see 'docking' branch on github),
|
||
|
// always subtract draw_data->DisplayPos from clipping bounds to convert them to your viewport space.
|
||
|
// - Note that pcmd->ClipRect contains Min+Max bounds. Some graphics API may use Min+Max, other may use Min+Size (size being Max-Min)
|
||
|
MyEngineSetScissor(clip_min.x, clip_min.y, clip_max.x, clip_max.y);
|
||
|
|
||
|
// The texture for the draw call is specified by pcmd->GetTexID().
|
||
|
// The vast majority of draw calls will use the Dear ImGui texture atlas, which value you have set yourself during initialization.
|
||
|
MyEngineBindTexture((MyTexture*)pcmd->GetTexID());
|
||
|
|
||
|
// Render 'pcmd->ElemCount/3' indexed triangles.
|
||
|
// 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.
|
||
|
MyEngineDrawIndexedTriangles(pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer + pcmd->IdxOffset, vtx_buffer, pcmd->VtxOffset);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
API BREAKING CHANGES
|
||
| ... | ... | |
|
When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files.
|
||
|
You can read releases logs https://github.com/ocornut/imgui/releases for more details.
|
||
|
|
||
|
- 2025/11/06 (1.92.5) - BeginChild: commented out some legacy names which were obsoleted in 1.90.0 (Nov 2023), 1.90.9 (July 2024), 1.91.1 (August 2024):
|
||
|
- ImGuiChildFlags_Border --> ImGuiChildFlags_Borders
|
||
|
- ImGuiWindowFlags_NavFlattened --> ImGuiChildFlags_NavFlattened (moved to ImGuiChildFlags). BeginChild(name, size, 0, ImGuiWindowFlags_NavFlattened) --> BeginChild(name, size, ImGuiChildFlags_NavFlattened, 0)
|
||
|
- ImGuiWindowFlags_AlwaysUseWindowPadding --> ImGuiChildFlags_AlwaysUseWindowPadding (moved to ImGuiChildFlags). BeginChild(name, size, 0, ImGuiWindowFlags_AlwaysUseWindowPadding) --> BeginChild(name, size, ImGuiChildFlags_AlwaysUseWindowPadding, 0)
|
||
|
- 2025/11/06 (1.92.5) - Keys: commented out legacy names which were obsoleted in 1.89.0 (August 2022):
|
||
|
- ImGuiKey_ModCtrl --> ImGuiMod_Ctrl
|
||
|
- ImGuiKey_ModShift --> ImGuiMod_Shift
|
||
|
- ImGuiKey_ModAlt --> ImGuiMod_Alt
|
||
|
- ImGuiKey_ModSuper --> ImGuiMod_Super
|
||
|
- 2025/11/06 (1.92.5) - IO: commented out legacy io.ClearInputCharacters() obsoleted in 1.89.8 (Aug 2023). Calling io.ClearInputKeys() is enough.
|
||
|
- 2025/11/06 (1.92.5) - Commented out legacy SetItemAllowOverlap() obsoleted in 1.89.7: this never worked right. Use SetNextItemAllowOverlap() _before_ item instead.
|
||
|
- 2025/10/14 (1.92.4) - TreeNode, Selectable, Clipper: commented out legacy names which were obsoleted in 1.89.7 (July 2023) and 1.89.9 (Sept 2023);
|
||
|
- ImGuiTreeNodeFlags_AllowItemOverlap --> ImGuiTreeNodeFlags_AllowOverlap
|
||
|
- ImGuiSelectableFlags_AllowItemOverlap --> ImGuiSelectableFlags_AllowOverlap
|
||
|
- ImGuiListClipper::IncludeRangeByIndices() --> ImGuiListClipper::IncludeItemsByIndex()
|
||
|
- 2025/08/08 (1.92.2) - Backends: SDL_GPU3: Changed ImTextureID type from SDL_GPUTextureSamplerBinding* to SDL_GPUTexture*, which is more natural and easier for user to manage. If you need to change the current sampler, you can access the ImGui_ImplSDLGPU3_RenderState struct. (#8866, #8163, #7998, #7988)
|
||
|
- 2025/07/31 (1.92.2) - Tabs: Renamed ImGuiTabBarFlags_FittingPolicyResizeDown to ImGuiTabBarFlags_FittingPolicyShrink. Kept inline redirection enum (will obsolete).
|
||
|
- 2025/06/25 (1.92.0) - Layout: commented out legacy ErrorCheckUsingSetCursorPosToExtendParentBoundaries() fallback obsoleted in 1.89 (August 2022) which allowed a SetCursorPos()/SetCursorScreenPos() call WITHOUT AN ITEM
|
||
|
to extend parent window/cell boundaries. Replaced with assert/tooltip that would already happens if previously using IMGUI_DISABLE_OBSOLETE_FUNCTIONS. (#5548, #4510, #3355, #1760, #1490, #4152, #150)
|
||
|
- Incorrect way to make a window content size 200x200:
|
||
|
Begin(...) + SetCursorScreenPos(GetCursorScreenPos() + ImVec2(200,200)) + End();
|
||
|
- Correct ways to make a window content size 200x200:
|
||
|
Begin(...) + SetCursorScreenPos(GetCursorScreenPos() + ImVec2(200,200)) + Dummy(ImVec2(0,0)) + End();
|
||
|
Begin(...) + Dummy(ImVec2(200,200)) + End();
|
||
|
- TL;DR; if the assert triggers, you can add a Dummy({0,0}) call to validate extending parent boundaries.
|
||
|
- 2025/06/11 (1.92.0) - THIS VERSION CONTAINS THE LARGEST AMOUNT OF BREAKING CHANGES SINCE 2015! I TRIED REALLY HARD TO KEEP THEM TO A MINIMUM, REDUCE THE AMOUNT OF INTERFERENCES, BUT INEVITABLY SOME USERS WILL BE AFFECTED.
|
||
|
IN ORDER TO HELP US IMPROVE THE TRANSITION PROCESS, INCL. DOCUMENTATION AND COMMENTS, PLEASE REPORT **ANY** DOUBT, CONFUSION, QUESTIONS, FEEDBACK TO: https://github.com/ocornut/imgui/issues/
|
||
|
As part of the plan to reduce impact of API breaking changes, several unfinished changes/features/refactors related to font and text systems and scaling will be part of subsequent releases (1.92.1+).
|
||
|
If you are updating from an old version, and expecting a massive or difficult update, consider first updating to 1.91.9 to reduce the amount of changes.
|
||
|
- Hard to read? Refer to 'docs/Changelog.txt' for a less compact and more complete version of this!
|
||
|
- Fonts: **IMPORTANT**: if your app was solving the OSX/iOS Retina screen specific logical vs display scale problem by setting io.DisplayFramebufferScale (e.g. to 2.0f) + setting io.FontGlobalScale (e.g. to 1.0f/2.0f) + loading fonts at scaled sizes (e.g. size X * 2.0f):
|
||
|
This WILL NOT map correctly to the new system! Because font will rasterize as requested size.
|
||
|
- With a legacy backend (< 1.92): Instead of setting io.FontGlobalScale = 1.0f/N -> set ImFontCfg::RasterizerDensity = N. This already worked before, but is now pretty much required.
|
||
|
- With a new backend (1.92+): This should be all automatic. FramebufferScale is automatically used to set current font RasterizerDensity. FramebufferScale is a per-viewport property provided by backend through the Platform_GetWindowFramebufferScale() handler in 'docking' branch.
|
||
|
- Fonts: **IMPORTANT** on Font Sizing: Before 1.92, fonts were of a single size. They can now be dynamically sized.
|
||
|
- PushFont() API now has a REQUIRED size parameter.
|
||
|
- Before 1.92: PushFont() always used font "default" size specified in AddFont() call. It is equivalent to calling PushFont(font, font->LegacySize).
|
||
|
- Since 1.92: PushFont(font, 0.0f) preserve the current font size which is a shared value.
|
||
|
- To use old behavior: use 'ImGui::PushFont(font, font->LegacySize)' at call site.
|
||
|
- Kept inline single parameter function. Will obsolete.
|
||
|
- Fonts: **IMPORTANT** on Font Merging:
|
||
|
- When searching for a glyph in multiple merged fonts: we search for the FIRST font source which contains the desired glyph.
|
||
|
Because the user doesn't need to provide glyph ranges any more, it is possible that a glyph that you expected to fetch from a secondary/merged icon font may be erroneously fetched from the primary font.
|
||
|
- When searching for a glyph in multiple merged fonts: we now search for the FIRST font source which contains the desired glyph. This is technically a different behavior than before!
|
||
|
- e.g. If you are merging fonts you may have glyphs that you expected to load from Font Source 2 which exists in Font Source 1.
|
||
|
After the update and when using a new backend, those glyphs may now loaded from Font Source 1!
|
||
|
- We added `ImFontConfig::GlyphExcludeRanges[]` to specify ranges to exclude from a given font source:
|
||
|
// Add Font Source 1 but ignore ICON_MIN_FA..ICON_MAX_FA range
|
||
|
static ImWchar exclude_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
|
||
|
ImFontConfig cfg1;
|
||
|
cfg1.GlyphExcludeRanges = exclude_ranges;
|
||
|
io.Fonts->AddFontFromFileTTF("segoeui.ttf", 0.0f, &cfg1);
|
||
|
// Add Font Source 2, which expects to use the range above
|
||
|
ImFontConfig cfg2;
|
||
|
cfg2.MergeMode = true;
|
||
|
io.Fonts->AddFontFromFileTTF("FontAwesome4.ttf", 0.0f, &cfg2);
|
||
|
- You can use `Metrics/Debugger->Fonts->Font->Input Glyphs Overlap Detection Tool` to see list of glyphs available in multiple font sources. This can facilitate understanding which font input is providing which glyph.
|
||
|
- Fonts: **IMPORTANT** on Thread Safety:
|
||
|
- A few functions such as font->CalcTextSizeA() were, by sheer luck (== accidentally) thread-safe even thou we had never provided that guarantee. They are definitively not thread-safe anymore as new glyphs may be loaded.
|
||
|
- Fonts: ImFont::FontSize was removed and does not make sense anymore. ImFont::LegacySize is the size passed to AddFont().
|
||
|
- Fonts: Removed support for PushFont(NULL) which was a shortcut for "default font".
|
||
|
- Fonts: Renamed/moved 'io.FontGlobalScale' to 'style.FontScaleMain'.
|
||
|
- Textures: all API functions taking a 'ImTextureID' parameter are now taking a 'ImTextureRef'. Affected functions are: ImGui::Image(), ImGui::ImageWithBg(), ImGui::ImageButton(), ImDrawList::AddImage(), ImDrawList::AddImageQuad(), ImDrawList::AddImageRounded().
|
||
|
- Fonts: obsoleted ImFontAtlas::GetTexDataAsRGBA32(), GetTexDataAsAlpha8(), Build(), SetTexID(), IsBuilt() functions. The new protocol for backends to handle textures doesn't need them. Kept redirection functions (will obsolete).
|
||
|
- Fonts: ImFontConfig::OversampleH/OversampleV default to automatic (== 0) since v1.91.8. It is quite important you keep it automatic until we decide if we want to provide a way to express finer policy, otherwise you will likely waste texture space when using large glyphs. Note that the imgui_freetype backend doesn't use and does not need oversampling.
|
||
|
- Fonts: specifying glyph ranges is now unnecessary. The value of ImFontConfig::GlyphRanges[] is only useful for legacy backends. All GetGlyphRangesXXXX() functions are now marked obsolete: GetGlyphRangesDefault(), GetGlyphRangesGreek(), GetGlyphRangesKorean(), GetGlyphRangesJapanese(), GetGlyphRangesChineseSimplifiedCommon(), GetGlyphRangesChineseFull(), GetGlyphRangesCyrillic(), GetGlyphRangesThai(), GetGlyphRangesVietnamese().
|
||
|
- Fonts: removed ImFontAtlas::TexDesiredWidth to enforce a texture width. (#327)
|
||
|
- Fonts: if you create and manage ImFontAtlas instances yourself (instead of relying on ImGuiContext to create one), you'll need to call ImFontAtlasUpdateNewFrame() yourself. An assert will trigger if you don't.
|
||
|
- Fonts: obsolete ImGui::SetWindowFontScale() which is not useful anymore. Prefer using 'PushFont(NULL, style.FontSizeBase * factor)' or to manipulate other scaling factors.
|
||
|
- Fonts: obsoleted ImFont::Scale which is not useful anymore.
|
||
|
- Fonts: generally reworked Internals of ImFontAtlas and ImFont. While in theory a vast majority of users shouldn't be affected, some use cases or extensions might be. Among other things:
|
||
|
- ImDrawCmd::TextureId has been changed to ImDrawCmd::TexRef.
|
||
|
- ImFontAtlas::TexID has been changed to ImFontAtlas::TexRef.
|
||
|
- ImFontAtlas::ConfigData[] has been renamed to ImFontAtlas::Sources[]
|
||
|
- ImFont::ConfigData[], ConfigDataCount has been renamed to Sources[], SourceCount.
|
||
|
- Each ImFont has a number of ImFontBaked instances corresponding to actively used sizes. ImFont::GetFontBaked(size) retrieves the one for a given size.
|
||
|
- Fields moved from ImFont to ImFontBaked: IndexAdvanceX[], Glyphs[], Ascent, Descent, FindGlyph(), FindGlyphNoFallback(), GetCharAdvance().
|
||
|
- Fields moved from ImFontAtlas to ImFontAtlas->Tex: ImFontAtlas::TexWidth => TexData->Width, ImFontAtlas::TexHeight => TexData->Height, ImFontAtlas::TexPixelsAlpha8/TexPixelsRGBA32 => TexData->GetPixels().
|
||
|
- Widget code may use ImGui::GetFontBaked() instead of ImGui::GetFont() to access font data for current font at current font size (and you may use font->GetFontBaked(size) to access it for any other size.)
|
||
|
- Fonts: (users of imgui_freetype): renamed ImFontAtlas::FontBuilderFlags to ImFontAtlas::FontLoaderFlags. Renamed ImFontConfig::FontBuilderFlags to ImFontConfig::FontLoaderFlags. Renamed ImGuiFreeTypeBuilderFlags to ImGuiFreeTypeLoaderFlags.
|
||
|
If you used runtime imgui_freetype selection rather than the default IMGUI_ENABLE_FREETYPE compile-time option: Renamed/reworked ImFontBuilderIO into ImFontLoader. Renamed ImGuiFreeType::GetBuilderForFreeType() to ImGuiFreeType::GetFontLoader().
|
||
|
- old: io.Fonts->FontBuilderIO = ImGuiFreeType::GetBuilderForFreeType()
|
||
|
- new: io.Fonts->FontLoader = ImGuiFreeType::GetFontLoader()
|
||
|
- new: io.Fonts->SetFontLoader(ImGuiFreeType::GetFontLoader()) to change dynamically at runtime [from 1.92.1]
|
||
|
- Fonts: (users of custom rectangles, see #8466): Renamed AddCustomRectRegular() to AddCustomRect(). Added GetCustomRect() as a replacement for GetCustomRectByIndex() + CalcCustomRectUV().
|
||
|
- The output type of GetCustomRect() is now ImFontAtlasRect, which include UV coordinates. X->x, Y->y, Width->w, Height->h.
|
||
|
- old:
|
||
|
const ImFontAtlasCustomRect* r = atlas->GetCustomRectByIndex(custom_rect_id);
|
||
|
ImVec2 uv0, uv1;
|
||
|
atlas->GetCustomRectUV(r, &uv0, &uv1);
|
||
|
ImGui::Image(atlas->TexRef, ImVec2(r->w, r->h), uv0, uv1);
|
||
|
- new;
|
||
|
ImFontAtlasRect r;
|
||
|
atlas->GetCustomRect(custom_rect_id, &r);
|
||
|
ImGui::Image(atlas->TexRef, ImVec2(r.w, r.h), r.uv0, r.uv1);
|
||
|
- We added a redirecting typedef but haven't attempted to magically redirect the field names, as this API is rarely used and the fix is simple.
|
||
|
- Obsoleted AddCustomRectFontGlyph() as the API does not make sense for scalable fonts. Kept existing function which uses the font "default size" (Sources[0]->LegacySize). Added a helper AddCustomRectFontGlyphForSize() which is immediately marked obsolete, but can facilitate transitioning old code.
|
||
|
- Prefer adding a font source (ImFontConfig) using a custom/procedural loader.
|
||
|
- DrawList: Renamed ImDrawList::PushTextureID()/PopTextureID() to PushTexture()/PopTexture().
|
||
|
- Backends: removed ImGui_ImplXXXX_CreateFontsTexture()/ImGui_ImplXXXX_DestroyFontsTexture() for all backends that had them. They should not be necessary any more.
|
||
|
- 2025/05/23 (1.92.0) - Fonts: changed ImFont::CalcWordWrapPositionA() to ImFont::CalcWordWrapPosition()
|
||
|
- old: const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, ....);
|
||
|
- new: const char* ImFont::CalcWordWrapPosition (float size, const char* text, ....);
|
||
|
The leading 'float scale' parameters was changed to 'float size'. This was necessary as 'scale' is assuming standard font size which is a concept we aim to eliminate in an upcoming update. Kept inline redirection function.
|
||
|
- 2025/05/15 (1.92.0) - TreeNode: renamed ImGuiTreeNodeFlags_NavLeftJumpsBackHere to ImGuiTreeNodeFlags_NavLeftJumpsToParent for clarity. Kept inline redirection enum (will obsolete).
|
||
|
- 2025/05/15 (1.92.0) - Commented out PushAllowKeyboardFocus()/PopAllowKeyboardFocus() which was obsoleted in 1.89.4. Use PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop)/PopItemFlag() instead. (#3092)
|
||
|
- 2025/05/15 (1.92.0) - Commented out ImGuiListClipper::ForceDisplayRangeByIndices() which was obsoleted in 1.89.6. Use ImGuiListClipper::IncludeItemsByIndex() instead.
|
||
|
- 2025/03/05 (1.91.9) - BeginMenu(): Internals: reworked mangling of menu windows to use "###Menu_00" etc. instead of "##Menu_00", allowing them to also store the menu name before it. This shouldn't affect code unless directly accessing menu window from their mangled name.
|
||
|
- 2025/04/16 (1.91.9) - Internals: RenderTextEllipsis() function removed the 'float clip_max_x' parameter directly preceding 'float ellipsis_max_x'. Values were identical for a vast majority of users. (#8387)
|
||
|
- 2025/02/27 (1.91.9) - Image(): removed 'tint_col' and 'border_col' parameter from Image() function. Added ImageWithBg() replacement. (#8131, #8238)
|
||
|
- old: void Image (ImTextureID tex_id, ImVec2 image_size, ImVec2 uv0 = (0,0), ImVec2 uv1 = (1,1), ImVec4 tint_col = (1,1,1,1), ImVec4 border_col = (0,0,0,0));
|
||
|
- new: void Image (ImTextureID tex_id, ImVec2 image_size, ImVec2 uv0 = (0,0), ImVec2 uv1 = (1,1));
|
||
|
- new: void ImageWithBg(ImTextureID tex_id, ImVec2 image_size, ImVec2 uv0 = (0,0), ImVec2 uv1 = (1,1), ImVec4 bg_col = (0,0,0,0), ImVec4 tint_col = (1,1,1,1));
|
||
|
- TL;DR: 'border_col' had misleading side-effect on layout, 'bg_col' was missing, parameter order couldn't be consistent with ImageButton().
|
||
|
- new behavior always use ImGuiCol_Border color + style.ImageBorderSize / ImGuiStyleVar_ImageBorderSize.
|
||
|
- old behavior altered border size (and therefore layout) based on border color's alpha, which caused variety of problems + old behavior a fixed 1.0f for border size which was not tweakable.
|
||
|
- kept legacy signature (will obsolete), which mimics the old behavior, but uses Max(1.0f, style.ImageBorderSize) when border_col is specified.
|
||
|
- added ImageWithBg() function which has both 'bg_col' (which was missing) and 'tint_col'. It was impossible to add 'bg_col' to Image() with a parameter order consistent with other functions, so we decided to remove 'tint_col' and introduce ImageWithBg().
|
||
|
- 2025/02/25 (1.91.9) - internals: fonts: ImFontAtlas::ConfigData[] has been renamed to ImFontAtlas::Sources[]. ImFont::ConfigData[], ConfigDataCount has been renamed to Sources[], SourcesCount.
|
||
|
- 2025/02/06 (1.91.9) - renamed ImFontConfig::GlyphExtraSpacing.x to ImFontConfig::GlyphExtraAdvanceX.
|
||
|
- 2025/01/22 (1.91.8) - removed ImGuiColorEditFlags_AlphaPreview (made value 0): it is now the default behavior.
|
||
|
prior to 1.91.8: alpha was made opaque in the preview by default _unless_ using ImGuiColorEditFlags_AlphaPreview. We now display the preview as transparent by default. You can use ImGuiColorEditFlags_AlphaOpaque to use old behavior.
|
||
|
the new flags (ImGuiColorEditFlags_AlphaOpaque, ImGuiColorEditFlags_AlphaNoBg + existing ImGuiColorEditFlags_AlphaPreviewHalf) may be combined better and allow finer controls:
|
||
|
- 2025/01/14 (1.91.7) - renamed ImGuiTreeNodeFlags_SpanTextWidth to ImGuiTreeNodeFlags_SpanLabelWidth for consistency with other names. Kept redirection enum (will obsolete). (#6937)
|
||
|
- 2024/11/27 (1.91.6) - changed CRC32 table from CRC32-adler to CRC32c polynomial in order to be compatible with the result of SSE 4.2 instructions.
|
||
|
As a result, old .ini data may be partially lost (docking and tables information particularly).
|
||
|
Because some users have crafted and storing .ini data as a way to workaround limitations of the docking API, we are providing a '#define IMGUI_USE_LEGACY_CRC32_ADLER' compile-time option to keep using old CRC32 tables if you cannot afford invalidating old .ini data.
|
||
|
- 2024/11/06 (1.91.5) - commented/obsoleted out pre-1.87 IO system (equivalent to using IMGUI_DISABLE_OBSOLETE_KEYIO or IMGUI_DISABLE_OBSOLETE_FUNCTIONS before)
|
||
|
- io.KeyMap[] and io.KeysDown[] are removed (obsoleted February 2022).
|
||
|
- io.NavInputs[] and ImGuiNavInput are removed (obsoleted July 2022).
|
||
| ... | ... | |
|
in doubt it is almost always better to do an intermediate intptr_t cast, since it allows casting any pointer/integer type without warning:
|
||
|
- May warn: ImGui::Image((void*)MyTextureData, ...);
|
||
|
- May warn: ImGui::Image((void*)(intptr_t)MyTextureData, ...);
|
||
|
- Won't warn: ImGui::Image((ImTextureID)(intptr_t)MyTextureData), ...);
|
||
|
- Won't warn: ImGui::Image((ImTextureID)(intptr_t)MyTextureData, ...);
|
||
|
- note that you can always define ImTextureID to be your own high-level structures (with dedicated constructors) if you like.
|
||
|
- 2024/10/03 (1.91.3) - drags: treat v_min==v_max as a valid clamping range when != 0.0f. Zero is a still special value due to legacy reasons, unless using ImGuiSliderFlags_ClampZeroRange. (#7968, #3361, #76)
|
||
|
- drags: extended behavior of ImGuiSliderFlags_AlwaysClamp to include _ClampZeroRange. It considers v_min==v_max==0.0f as a valid clamping range (aka edits not allowed).
|
||
|
although unlikely, it you wish to only clamp on text input but want v_min==v_max==0.0f to mean unclamped drags, you can use _ClampOnInput instead of _AlwaysClamp. (#7968, #3361, #76)
|
||
|
- 2024/09/10 (1.91.2) - internals: using multiple overlayed ButtonBehavior() with same ID will now have io.ConfigDebugHighlightIdConflicts=true feature emit a warning. (#8030)
|
||
|
- 2024/09/10 (1.91.2) - internals: using multiple overlaid ButtonBehavior() with same ID will now have io.ConfigDebugHighlightIdConflicts=true feature emit a warning. (#8030)
|
||
|
it was one of the rare case where using same ID is legal. workarounds: (1) use single ButtonBehavior() call with multiple _MouseButton flags, or (2) surround the calls with PushItemFlag(ImGuiItemFlags_AllowDuplicateId, true); ... PopItemFlag()
|
||
|
- 2024/08/23 (1.91.1) - renamed ImGuiChildFlags_Border to ImGuiChildFlags_Borders for consistency. kept inline redirection flag.
|
||
|
- 2024/08/22 (1.91.1) - moved some functions from ImGuiIO to ImGuiPlatformIO structure:
|
||
| ... | ... | |
|
- 2022/04/05 (1.88) - inputs: renamed ImGuiKeyModFlags to ImGuiModFlags. Kept inline redirection enums (will obsolete). This was never used in public API functions but technically present in imgui.h and ImGuiIO.
|
||
|
- 2022/01/20 (1.87) - inputs: reworded gamepad IO.
|
||
|
- Backend writing to io.NavInputs[] -> backend should call io.AddKeyEvent()/io.AddKeyAnalogEvent() with ImGuiKey_GamepadXXX values.
|
||
|
- 2022/01/19 (1.87) - sliders, drags: removed support for legacy arithmetic operators (+,+-,*,/) when inputing text. This doesn't break any api/code but a feature that used to be accessible by end-users (which seemingly no one used).
|
||
|
- 2022/01/19 (1.87) - sliders, drags: removed support for legacy arithmetic operators (+,+-,*,/) when inputting text. This doesn't break any api/code but a feature that used to be accessible by end-users (which seemingly no one used).
|
||
|
- 2022/01/17 (1.87) - inputs: reworked mouse IO.
|
||
|
- Backend writing to io.MousePos -> backend should call io.AddMousePosEvent()
|
||
|
- Backend writing to io.MouseDown[] -> backend should call io.AddMouseButtonEvent()
|
||
| ... | ... | |
|
- Backend writing to io.MouseHoveredViewport -> backend should call io.AddMouseViewportEvent() [Docking branch w/ multi-viewports only]
|
||
|
note: for all calls to IO new functions, the Dear ImGui context should be bound/current.
|
||
|
read https://github.com/ocornut/imgui/issues/4921 for details.
|
||
|
- 2022/01/10 (1.87) - inputs: reworked keyboard IO. Removed io.KeyMap[], io.KeysDown[] in favor of calling io.AddKeyEvent(). Removed GetKeyIndex(), now unnecessary. All IsKeyXXX() functions now take ImGuiKey values. All features are still functional until IMGUI_DISABLE_OBSOLETE_KEYIO is defined. Read Changelog and Release Notes for details.
|
||
|
- 2022/01/10 (1.87) - inputs: reworked keyboard IO. Removed io.KeyMap[], io.KeysDown[] in favor of calling io.AddKeyEvent(), ImGui::IsKeyDown(). Removed GetKeyIndex(), now unnecessary. All IsKeyXXX() functions now take ImGuiKey values. All features are still functional until IMGUI_DISABLE_OBSOLETE_KEYIO is defined. Read Changelog and Release Notes for details.
|
||
|
- IsKeyPressed(MY_NATIVE_KEY_XXX) -> use IsKeyPressed(ImGuiKey_XXX)
|
||
|
- IsKeyPressed(GetKeyIndex(ImGuiKey_XXX)) -> use IsKeyPressed(ImGuiKey_XXX)
|
||
|
- Backend writing to io.KeyMap[],io.KeysDown[] -> backend should call io.AddKeyEvent() (+ call io.SetKeyEventNativeData() if you want legacy user code to stil function with legacy key codes).
|
||
|
- Backend writing to io.KeyMap[],io.KeysDown[] -> backend should call io.AddKeyEvent() (+ call io.SetKeyEventNativeData() if you want legacy user code to still function with legacy key codes).
|
||
|
- Backend writing to io.KeyCtrl, io.KeyShift.. -> backend should call io.AddKeyEvent() with ImGuiMod_XXX values. *IF YOU PULLED CODE BETWEEN 2021/01/10 and 2021/01/27: We used to have a io.AddKeyModsEvent() function which was now replaced by io.AddKeyEvent() with ImGuiMod_XXX values.*
|
||
|
- one case won't work with backward compatibility: if your custom backend used ImGuiKey as mock native indices (e.g. "io.KeyMap[ImGuiKey_A] = ImGuiKey_A") because those values are now larger than the legacy KeyDown[] array. Will assert.
|
||
|
- inputs: added ImGuiKey_ModCtrl/ImGuiKey_ModShift/ImGuiKey_ModAlt/ImGuiKey_ModSuper values to submit keyboard modifiers using io.AddKeyEvent(), instead of writing directly to io.KeyCtrl, io.KeyShift, io.KeyAlt, io.KeySuper.
|
||
| ... | ... | |
|
- ShowTestWindow() -> use ShowDemoWindow()
|
||
|
- IsRootWindowFocused() -> use IsWindowFocused(ImGuiFocusedFlags_RootWindow)
|
||
|
- IsRootWindowOrAnyChildFocused() -> use IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows)
|
||
|
- SetNextWindowContentWidth(w) -> use SetNextWindowContentSize(ImVec2(w, 0.0f)
|
||
|
- SetNextWindowContentWidth(w) -> use SetNextWindowContentSize(ImVec2(w, 0.0f))
|
||
|
- GetItemsLineHeightWithSpacing() -> use GetFrameHeightWithSpacing()
|
||
|
- ImGuiCol_ChildWindowBg -> use ImGuiCol_ChildBg
|
||
|
- ImGuiStyleVar_ChildWindowRounding -> use ImGuiStyleVar_ChildRounding
|
||
| ... | ... | |
|
- renamed IsMouseHoveringAnyWindow() to IsAnyWindowHovered() for consistency. Kept inline redirection function (will obsolete).
|
||
|
- renamed IsMouseHoveringWindow() to IsWindowRectHovered() for consistency. Kept inline redirection function (will obsolete).
|
||
|
- 2017/08/20 (1.51) - renamed GetStyleColName() to GetStyleColorName() for consistency.
|
||
|
- 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.
|
||
|
- 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 explicitly to fix.
|
||
|
- 2017/08/15 (1.51) - marked the weird IMGUI_ONCE_UPON_A_FRAME helper macro as obsolete. prefer using the more explicit ImGuiOnceUponAFrame type.
|
||
|
- 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.
|
||
|
- 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).
|
||
| ... | ... | |
|
associated with it.
|
||
|
|
||
|
Q: What is this library called?
|
||
|
Q: What is the difference between Dear ImGui and traditional UI toolkits?
|
||
|
Q: Which version should I get?
|
||
|
>> This library is called "Dear ImGui", please don't call it "ImGui" :)
|
||
|
>> See https://www.dearimgui.com/faq for details.
|
||
| ... | ... | |
|
#else
|
||
|
#include <windows.h>
|
||
|
#endif
|
||
|
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP || WINAPI_FAMILY == WINAPI_FAMILY_GAMES)
|
||
|
#if defined(WINAPI_FAMILY) && ((defined(WINAPI_FAMILY_APP) && WINAPI_FAMILY == WINAPI_FAMILY_APP) || (defined(WINAPI_FAMILY_GAMES) && WINAPI_FAMILY == WINAPI_FAMILY_GAMES))
|
||
|
// The UWP and GDK Win32 API subsets don't support clipboard nor IME functions
|
||
|
#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS
|
||
|
#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS
|
||
| ... | ... | |
|
#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning: unknown warning group 'xxx'
|
||
|
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
||
|
#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.
|
||
|
#pragma clang diagnostic ignored "-Wformat" // warning: format specifies type 'int' but the argument has type 'unsigned int'
|
||
|
#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.
|
||
|
#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.
|
||
|
#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.
|
||
|
#pragma clang diagnostic ignored "-Wglobal-constructors" // warning: declaration requires a global destructor // similar to above, not sure what the exact difference is.
|
||
|
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||
|
#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.
|
||
|
#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning: cast to 'void *' from smaller integer type 'int'
|
||
|
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" // warning: zero as null pointer constant // some standard header variations use #define NULL 0
|
||
|
#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.
|
||
|
#pragma clang diagnostic ignored "-Wimplicit-int-float-conversion" // warning: implicit conversion from 'xxx' to 'float' may lose precision
|
||
|
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage" // warning: 'xxx' is an unsafe pointer used for buffer access
|
||
|
#pragma clang diagnostic ignored "-Wnontrivial-memaccess" // warning: first argument in call to 'memset' is a pointer to non-trivially copyable type
|
||
|
#pragma clang diagnostic ignored "-Wswitch-default" // warning: 'switch' missing 'default' label
|
||
|
#elif defined(__GNUC__)
|
||
|
// We disable -Wpragmas because GCC doesn't provide a has_warning equivalent and some forks/patches may not follow the warning/version association.
|
||
|
#pragma GCC diagnostic ignored "-Wpragmas" // warning: unknown option after '#pragma GCC diagnostic' kind
|
||
|
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
|
||
|
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size
|
||
|
#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'void*', but argument 6 has type 'ImGuiWindow*'
|
||
|
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
||
|
#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'int'/'void*', but argument X has type 'unsigned int'/'ImGuiWindow*'
|
||
|
#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function
|
||
|
#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value
|
||
|
#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked
|
||
|
#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when assuming that (X - c) > X is always false
|
||
|
#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
|
||
|
#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'const xxxx *' to type 'xxxx *' casts away qualifiers
|
||
|
#endif
|
||
|
|
||
|
// Debug options
|
||
|
#define IMGUI_DEBUG_NAV_SCORING 0 // Display navigation scoring preview when hovering items. Hold CTRL to display for all candidates. CTRL+Arrow to change last direction.
|
||
|
#define IMGUI_DEBUG_NAV_SCORING 0 // Display navigation scoring preview when hovering items. Hold Ctrl to display for all candidates. Ctrl+Arrow to change last direction.
|
||
|
#define IMGUI_DEBUG_NAV_RECTS 0 // Display the reference navigation rectangle for each window
|
||
|
|
||
|
// 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.
|
||
|
// Default font size if unspecified in both style.FontSizeBase and AddFontXXX() calls.
|
||
|
static const float FONT_DEFAULT_SIZE = 20.0f;
|
||
|
|
||
|
// 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.
|
||
|
static const float NAV_WINDOWING_HIGHLIGHT_DELAY = 0.20f; // Time before the highlight and screen dimming starts fading in
|
||
|
static const float NAV_WINDOWING_LIST_APPEAR_DELAY = 0.15f; // Time before the window list starts to appear
|
||
|
|
||
|
static const float NAV_ACTIVATE_HIGHLIGHT_TIMER = 0.10f; // Time to highlight an item activated by a shortcut.
|
||
|
|
||
|
// Window resizing from edges (when io.ConfigWindowsResizeFromEdges = true and ImGuiBackendFlags_HasMouseCursors is set in io.BackendFlags by backend)
|
||
|
static const float WINDOWS_HOVER_PADDING = 4.0f; // Extend outside window for hovering/resizing (maxxed with TouchPadding) and inside windows for borders. Affect FindHoveredWindow().
|
||
|
static const float WINDOWS_RESIZE_FROM_EDGES_FEEDBACK_TIMER = 0.04f; // Reduce visual noise by only highlighting the border after a certain time.
|
||
|
static const float WINDOWS_MOUSE_WHEEL_SCROLL_LOCK_TIMER = 0.70f; // Lock scrolled window (so it doesn't pick child windows that are scrolling through) for a certain time, unless mouse moved.
|
||
|
|
||
| ... | ... | |
|
// Item
|
||
|
static void ItemHandleShortcut(ImGuiID id);
|
||
|
|
||
|
// Window Focus
|
||
|
static int FindWindowFocusIndex(ImGuiWindow* window);
|
||
|
static void UpdateWindowInFocusOrderList(ImGuiWindow* window, bool just_created, ImGuiWindowFlags new_flags);
|
||
|
|
||
|
// Navigation
|
||
|
static void NavUpdate();
|
||
|
static void NavUpdateWindowing();
|
||
|
static void NavUpdateWindowingApplyFocus(ImGuiWindow* window);
|
||
|
static void NavUpdateWindowingOverlay();
|
||
|
static void NavUpdateCancelRequest();
|
||
|
static void NavUpdateCreateMoveRequest();
|
||
| ... | ... | |
|
static inline void NavUpdateAnyRequestFlag();
|
||
|
static void NavUpdateCreateWrappingRequest();
|
||
|
static void NavEndFrame();
|
||
|
static bool NavScoreItem(ImGuiNavItemData* result);
|
||
|
static bool NavScoreItem(ImGuiNavItemData* result, const ImRect& nav_bb);
|
||
|
static void NavApplyItemToResult(ImGuiNavItemData* result);
|
||
|
static void NavProcessItem();
|
||
|
static void NavProcessItemForTabbingRequest(ImGuiID id, ImGuiItemFlags item_flags, ImGuiNavMoveFlags move_flags);
|
||
| ... | ... | |
|
static void NavSaveLastChildNavWindowIntoParent(ImGuiWindow* nav_window);
|
||
|
static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window);
|
||
|
static void NavRestoreLayer(ImGuiNavLayer layer);
|
||
|
static int FindWindowFocusIndex(ImGuiWindow* window);
|
||
|
|
||
|
// Error Checking and Debug Tools
|
||
|
static void ErrorCheckNewFrameSanityChecks();
|
||
|
static void ErrorCheckEndFrameSanityChecks();
|
||
|
#ifndef IMGUI_DISABLE_DEBUG_TOOLS
|
||
|
static void UpdateDebugToolItemPicker();
|
||
|
static void UpdateDebugToolStackQueries();
|
||
|
static void UpdateDebugToolItemPathQuery();
|
||
|
static void UpdateDebugToolFlashStyleColor();
|
||
|
#endif
|
||
|
|
||
| ... | ... | |
|
static void UpdateKeyRoutingTable(ImGuiKeyRoutingTable* rt);
|
||
|
|
||
|
// Misc
|
||
|
static void UpdateFontsNewFrame();
|
||
|
static void UpdateFontsEndFrame();
|
||
|
static void UpdateTexturesNewFrame();
|
||
|
static void UpdateTexturesEndFrame();
|
||
|
static void UpdateSettings();
|
||
|
static int UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_hovered, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect);
|
||
|
static int UpdateWindowManualResize(ImGuiWindow* window, int* border_hovered, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4], const ImRect& visibility_rect);
|
||
|
static void RenderWindowOuterBorders(ImGuiWindow* window);
|
||
|
static void RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, bool handle_borders_and_resize_grips, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size);
|
||
|
static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open);
|
||
|
static void RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col);
|
||
|
static void RenderDimmedBackgrounds();
|
||
|
static void SetLastItemDataForWindow(ImGuiWindow* window, const ImRect& rect);
|
||
|
static void SetLastItemDataForChildWindowItem(ImGuiWindow* window, const ImRect& rect);
|
||
|
|
||
|
// Viewports
|
||
|
const ImGuiID IMGUI_VIEWPORT_DEFAULT_ID = 0x11111111; // Using an arbitrary constant instead of e.g. ImHashStr("ViewportDefault", 0); so it's easier to spot in the debugger. The exact value doesn't matter.
|
||
| ... | ... | |
|
|
||
|
ImGuiStyle::ImGuiStyle()
|
||
|
{
|
||
|
FontSizeBase = 0.0f; // Will default to io.Fonts->Fonts[0] on first frame.
|
||
|
FontScaleMain = 1.0f; // Main scale factor. May be set by application once, or exposed to end-user.
|
||
|
FontScaleDpi = 1.0f; // Additional scale factor from viewport/monitor contents scale. When io.ConfigDpiScaleFonts is enabled, this is automatically overwritten when changing monitor DPI.
|
||
|
|
||
|
Alpha = 1.0f; // Global alpha applies to everything in Dear ImGui.
|
||
|
DisabledAlpha = 0.60f; // Additional alpha multiplier applied by BeginDisabled(). Multiply over current value of Alpha.
|
||
|
WindowPadding = ImVec2(8,8); // Padding within a window
|
||
|
WindowRounding = 0.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows. Large values tend to lead to variety of artifacts and are not recommended.
|
||
|
WindowBorderSize = 1.0f; // Thickness of border around windows. Generally set to 0.0f or 1.0f. Other values not well tested.
|
||
|
WindowBorderHoverPadding = 4.0f; // Hit-testing extent outside/inside resizing border. Also extend determination of hovered window. Generally meaningfully larger than WindowBorderSize to make it easy to reach borders.
|
||
|
WindowMinSize = ImVec2(32,32); // Minimum window size
|
||
|
WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text
|
||
|
WindowMenuButtonPosition = ImGuiDir_Left; // Position of the collapsing/docking button in the title bar (left/right). Defaults to ImGuiDir_Left.
|
||
| ... | ... | |
|
ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns. Preferably > (FramePadding.x + 1).
|
||
|
ScrollbarSize = 14.0f; // Width of the vertical scrollbar, Height of the horizontal scrollbar
|
||
|
ScrollbarRounding = 9.0f; // Radius of grab corners rounding for scrollbar
|
||
|
ScrollbarPadding = 2.0f; // Padding of scrollbar grab within its frame (same for both axises)
|
||
|
GrabMinSize = 12.0f; // Minimum width/height of a grab box for slider/scrollbar
|
||
|
GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs.
|
||
|
LogSliderDeadzone = 4.0f; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero.
|
||
|
TabRounding = 4.0f; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs.
|
||
|
ImageBorderSize = 0.0f; // Thickness of border around tabs.
|
||
|
TabRounding = 5.0f; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs.
|
||
|
TabBorderSize = 0.0f; // Thickness of border around tabs.
|
||
|
TabMinWidthForCloseButton = 0.0f; // Minimum width for close button to appear on an unselected tab when hovered. Set to 0.0f to always show when hovering, set to FLT_MAX to never show close button unless selected.
|
||
|
TabMinWidthBase = 1.0f; // Minimum tab width, to make tabs larger than their contents. TabBar buttons are not affected.
|
||
|
TabMinWidthShrink = 80.0f; // Minimum tab width after shrinking, when using ImGuiTabBarFlags_FittingPolicyMixed policy.
|
||
|
TabCloseButtonMinWidthSelected = -1.0f; // -1: always visible. 0.0f: visible when hovered. >0.0f: visible when hovered if minimum width.
|
||
|
TabCloseButtonMinWidthUnselected = 0.0f; // -1: always visible. 0.0f: visible when hovered. >0.0f: visible when hovered if minimum width. FLT_MAX: never show close button when unselected.
|
||
|
TabBarBorderSize = 1.0f; // Thickness of tab-bar separator, which takes on the tab active color to denote focus.
|
||
|
TabBarOverlineSize = 2.0f; // Thickness of tab-bar overline, which highlights the selected tab-bar.
|
||
|
TabBarOverlineSize = 1.0f; // Thickness of tab-bar overline, which highlights the selected tab-bar.
|
||
|
TableAngledHeadersAngle = 35.0f * (IM_PI / 180.0f); // Angle of angled headers (supported values range from -50 degrees to +50 degrees).
|
||
|
TableAngledHeadersTextAlign = ImVec2(0.5f,0.0f);// Alignment of angled headers within the cell
|
||
|
TreeLinesFlags = ImGuiTreeNodeFlags_DrawLinesNone;
|
||
|
TreeLinesSize = 1.0f; // Thickness of outlines when using ImGuiTreeNodeFlags_DrawLines.
|
||
|
TreeLinesRounding = 0.0f; // Radius of lines connecting child nodes to the vertical line.
|
||
|
DragDropTargetRounding = 0.0f; // Radius of the drag and drop target frame.
|
||
|
DragDropTargetBorderSize = 2.0f; // Thickness of the drag and drop target border.
|
||
|
DragDropTargetPadding = 3.0f; // Size to expand the drag and drop target from actual target item size.
|
||
|
ColorButtonPosition = ImGuiDir_Right; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
|
||
|
ButtonTextAlign = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text.
|
||
|
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.
|
||
| ... | ... | |
|
HoverFlagsForTooltipMouse = ImGuiHoveredFlags_Stationary | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_AllowWhenDisabled; // Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using mouse.
|
||
|
HoverFlagsForTooltipNav = ImGuiHoveredFlags_NoSharedDelay | ImGuiHoveredFlags_DelayNormal | ImGuiHoveredFlags_AllowWhenDisabled; // Default flags when using IsItemHovered(ImGuiHoveredFlags_ForTooltip) or BeginItemTooltip()/SetItemTooltip() while using keyboard/gamepad.
|
||
|
|
||
|
// [Internal]
|
||
|
_MainScale = 1.0f;
|
||
|
_NextFrameFontSizeBase = 0.0f;
|
||
|
|
||
|
// Default theme
|
||
|
ImGui::StyleColorsDark(this);
|
||
|
}
|
||
|
|
||
|
// 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.
|
||
|
|
||
|
// Scale all spacing/padding/thickness values. Do not scale fonts.
|
||
|
// 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.
|
||
|
void ImGuiStyle::ScaleAllSizes(float scale_factor)
|
||
|
{
|
||
|
_MainScale *= scale_factor;
|
||
|
WindowPadding = ImTrunc(WindowPadding * scale_factor);
|
||
|
WindowRounding = ImTrunc(WindowRounding * scale_factor);
|
||
|
WindowMinSize = ImTrunc(WindowMinSize * scale_factor);
|
||
|
WindowBorderHoverPadding = ImTrunc(WindowBorderHoverPadding * scale_factor);
|
||
|
ChildRounding = ImTrunc(ChildRounding * scale_factor);
|
||
|
PopupRounding = ImTrunc(PopupRounding * scale_factor);
|
||
|
FramePadding = ImTrunc(FramePadding * scale_factor);
|
||
| ... | ... | |
|
ColumnsMinSpacing = ImTrunc(ColumnsMinSpacing * scale_factor);
|
||
|
ScrollbarSize = ImTrunc(ScrollbarSize * scale_factor);
|
||
|
ScrollbarRounding = ImTrunc(ScrollbarRounding * scale_factor);
|
||
|
ScrollbarPadding = ImTrunc(ScrollbarPadding * scale_factor);
|
||
|
GrabMinSize = ImTrunc(GrabMinSize * scale_factor);
|
||
|
GrabRounding = ImTrunc(GrabRounding * scale_factor);
|
||
|
LogSliderDeadzone = ImTrunc(LogSliderDeadzone * scale_factor);
|
||
|
ImageBorderSize = ImTrunc(ImageBorderSize * scale_factor);
|
||
|
TabRounding = ImTrunc(TabRounding * scale_factor);
|
||
|
TabMinWidthForCloseButton = (TabMinWidthForCloseButton != FLT_MAX) ? ImTrunc(TabMinWidthForCloseButton * scale_factor) : FLT_MAX;
|
||
|
TabMinWidthBase = ImTrunc(TabMinWidthBase * scale_factor);
|
||
|
TabMinWidthShrink = ImTrunc(TabMinWidthShrink * scale_factor);
|
||
|
TabCloseButtonMinWidthSelected = (TabCloseButtonMinWidthSelected > 0.0f && TabCloseButtonMinWidthSelected != FLT_MAX) ? ImTrunc(TabCloseButtonMinWidthSelected * scale_factor) : TabCloseButtonMinWidthSelected;
|
||
|
TabCloseButtonMinWidthUnselected = (TabCloseButtonMinWidthUnselected > 0.0f && TabCloseButtonMinWidthUnselected != FLT_MAX) ? ImTrunc(TabCloseButtonMinWidthUnselected * scale_factor) : TabCloseButtonMinWidthUnselected;
|
||
|
TabBarOverlineSize = ImTrunc(TabBarOverlineSize * scale_factor);
|
||
|
TreeLinesRounding = ImTrunc(TreeLinesRounding * scale_factor);
|
||
|
DragDropTargetRounding = ImTrunc(DragDropTargetRounding * scale_factor);
|
||
|
DragDropTargetBorderSize = ImTrunc(DragDropTargetBorderSize * scale_factor);
|
||
|
DragDropTargetPadding = ImTrunc(DragDropTargetPadding * scale_factor);
|
||
|
SeparatorTextPadding = ImTrunc(SeparatorTextPadding * scale_factor);
|
||
|
DisplayWindowPadding = ImTrunc(DisplayWindowPadding * scale_factor);
|
||
|
DisplaySafeAreaPadding = ImTrunc(DisplaySafeAreaPadding * scale_factor);
|
||
| ... | ... | |
|
UserData = NULL;
|
||
|
|
||
|
Fonts = NULL;
|
||
|
FontGlobalScale = 1.0f;
|
||
|
FontDefault = NULL;
|
||
|
FontAllowUserScaling = false;
|
||
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||
|
FontGlobalScale = 1.0f; // Use style.FontScaleMain instead!
|
||
|
#endif
|
||
|
DisplayFramebufferScale = ImVec2(1.0f, 1.0f);
|
||
|
|
||
|
// Keyboard/Gamepad Navigation options
|
||
| ... | ... | |
|
ConfigMemoryCompactTimer = 60.0f;
|
||
|
ConfigDebugIsDebuggerPresent = false;
|
||
|
ConfigDebugHighlightIdConflicts = true;
|
||
|
ConfigDebugHighlightIdConflictsShowItemPicker = true;
|
||
|
ConfigDebugBeginReturnValueOnce = false;
|
||
|
ConfigDebugBeginReturnValueLoop = false;
|
||
|
|
||
| ... | ... | |
|
AddInputCharacter((unsigned)cp);
|
||
|
}
|
||
|
|
||
|
void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars)
|
||
|
void ImGuiIO::AddInputCharactersUTF8(const char* str)
|
||
|
{
|
||
|
if (!AppAcceptingEvents)
|
||
|
return;
|
||
|
while (*utf8_chars != 0)
|
||
|
const char* str_end = str + strlen(str);
|
||
|
while (*str != 0)
|
||
|
{
|
||
|
unsigned int c = 0;
|
||
|
utf8_chars += ImTextCharFromUtf8(&c, utf8_chars, NULL);
|
||
|
str += ImTextCharFromUtf8(&c, str, str_end);
|
||
|
AddInputCharacter(c);
|
||
|
}
|
||
|
}
|
||
| ... | ... | |
|
MouseWheel = MouseWheelH = 0.0f;
|
||
|
}
|
||
|
|
||
|
// Removed this as it is ambiguous/misleading and generally incorrect to use with the existence of a higher-level input queue.
|
||
|
// Current frame character buffer is now also cleared by ClearInputKeys().
|
||
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||
|
void ImGuiIO::ClearInputCharacters()
|
||
|
{
|
||
|
InputQueueCharacters.resize(0);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
static ImGuiInputEvent* FindLatestInputEvent(ImGuiContext* ctx, ImGuiInputEventType type, int arg = -1)
|
||
|
{
|
||
|
ImGuiContext& g = *ctx;
|
||
| ... | ... | |
|
// On MacOS X: Convert Ctrl(Super)+Left click into Right-click: handle held button.
|
||
|
if (ConfigMacOSXBehaviors && mouse_button == 0 && MouseCtrlLeftAsRightClick)
|
||
|
{
|
||
|
// Order of both statements matterns: this event will still release mouse button 1
|
||
|
// Order of both statements matters: this event will still release mouse button 1
|
||
|
mouse_button = 1;
|
||
|
if (!down)
|
||
|
MouseCtrlLeftAsRightClick = false;
|
||
| ... | ... | |
|
if (count < 1)
|
||
|
return;
|
||
|
if (count > 1)
|
||
|
strncpy(dst, src, count - 1);
|
||
|
strncpy(dst, src, count - 1); // FIXME-OPT: strncpy not only doesn't guarantee 0-termination, it also always writes the whole array
|
||
|
dst[count - 1] = 0;
|
||
|
}
|
||
|
|
||
|
char* ImStrdup(const char* str)
|
||
|
{
|
||
|
size_t len = strlen(str);
|
||
|
size_t len = ImStrlen(str);
|
||
|
void* buf = IM_ALLOC(len + 1);
|
||
|
return (char*)memcpy(buf, (const void*)str, len + 1);
|
||
|
}
|
||
|
|
||
|
void* ImMemdup(const void* src, size_t size)
|
||
|
{
|
||
|
void* dst = IM_ALLOC(size);
|
||
|
return memcpy(dst, src, size);
|
||
|
}
|
||
|
|
||
|
char* ImStrdupcpy(char* dst, size_t* p_dst_size, const char* src)
|
||
|
{
|
||
|
size_t dst_buf_size = p_dst_size ? *p_dst_size : strlen(dst) + 1;
|
||
|
size_t src_size = strlen(src) + 1;
|
||
|
size_t dst_buf_size = p_dst_size ? *p_dst_size : ImStrlen(dst) + 1;
|
||
|
size_t src_size = ImStrlen(src) + 1;
|
||
|
if (dst_buf_size < src_size)
|
||
|
{
|
||
|
IM_FREE(dst);
|
||
| ... | ... | |
|
|
||
|
const char* ImStrchrRange(const char* str, const char* str_end, char c)
|
||
|
{
|
||
|
const char* p = (const char*)memchr(str, (int)c, str_end - str);
|
||
|
const char* p = (const char*)ImMemchr(str, (int)c, str_end - str);
|
||
|
return p;
|
||
|
}
|
||
|
|
||
| ... | ... | |
|
// Find end-of-line. Return pointer will point to either first \n, either str_end.
|
||
|
const char* ImStreolRange(const char* str, const char* str_end)
|
||
|
{
|
||
|
const char* p = (const char*)memchr(str, '\n', str_end - str);
|
||
|
const char* p = (const char*)ImMemchr(str, '\n', str_end - str);
|
||
|
return p ? p : str_end;
|
||
|
}
|
||
|
|
||
|
const char* ImStrbol(const char* buf_mid_line, const char* buf_begin) // find beginning-of-line
|
||
|
{
|
||
|
IM_ASSERT_PARANOID(buf_mid_line >= buf_begin && buf_mid_line <= buf_begin + ImStrlen(buf_begin));
|
||
|
while (buf_mid_line > buf_begin && buf_mid_line[-1] != '\n')
|
||
|
buf_mid_line--;
|
||
|
return buf_mid_line;
|
||
| ... | ... | |
|
const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end)
|
||
|
{
|
||
|
if (!needle_end)
|
||
|
needle_end = needle + strlen(needle);
|
||
|
needle_end = needle + ImStrlen(needle);
|
||
|
|
||
|
const char un0 = (char)ImToUpper(*needle);
|
||
|
while ((!haystack_end && *haystack) || (haystack_end && haystack < haystack_end))
|
||
| ... | ... | |
|
if (buf == NULL)
|
||
|
buf = "(null)";
|
||
|
*out_buf = buf;
|
||
|
if (out_buf_end) { *out_buf_end = buf + strlen(buf); }
|
||
|
if (out_buf_end) { *out_buf_end = buf + ImStrlen(buf); }
|
||
|
}
|
||
|
else if (fmt[0] == '%' && fmt[1] == '.' && fmt[2] == '*' && fmt[3] == 's' && fmt[4] == 0)
|
||
|
{
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
|
||
|
#ifndef IMGUI_ENABLE_SSE4_2_CRC
|
||
|
// CRC32 needs a 1KB lookup table (not cache friendly)
|
||
|
// Although the code to generate the table is simple and shorter than the table itself, using a const table allows us to easily:
|
||
|
// - avoid an unnecessary branch/memory tap, - keep the ImHashXXX functions usable by static constructors, - make it thread-safe.
|
||
|
static const ImU32 GCrc32LookupTable[256] =
|
||
|
{
|
||
|
#ifdef IMGUI_USE_LEGACY_CRC32_ADLER
|
||
|
// Legacy CRC32-adler table used pre 1.91.6 (before 2024/11/27). Only use if you cannot afford invalidating old .ini data.
|
||
|
0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535,0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD,0xE7B82D07,0x90BF1D91,
|
||
|
0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,0x6DDDE4EB,0xF4D4B551,0x83D385C7,0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5,
|
||
|
0x3B6E20C8,0x4C69105E,0xD56041E4,0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,0x35B5A8FA,0x42B2986C,0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59,
|
||
| ... | ... | |
|
0x86D3D2D4,0xF1D4E242,0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777,0x88085AE6,0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45,
|
||
|
0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D,0x3E6E77DB,0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,0x47B2CF7F,0x30B5FFE9,
|
||
|
0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,0xCDD70693,0x54DE5729,0x23D967BF,0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D,
|
||
|
#else
|
||
|
// CRC32c table compatible with SSE 4.2 instructions
|
||
|
0x00000000,0xF26B8303,0xE13B70F7,0x1350F3F4,0xC79A971F,0x35F1141C,0x26A1E7E8,0xD4CA64EB,0x8AD958CF,0x78B2DBCC,0x6BE22838,0x9989AB3B,0x4D43CFD0,0xBF284CD3,0xAC78BF27,0x5E133C24,
|
||
|
0x105EC76F,0xE235446C,0xF165B798,0x030E349B,0xD7C45070,0x25AFD373,0x36FF2087,0xC494A384,0x9A879FA0,0x68EC1CA3,0x7BBCEF57,0x89D76C54,0x5D1D08BF,0xAF768BBC,0xBC267848,0x4E4DFB4B,
|
||
|
0x20BD8EDE,0xD2D60DDD,0xC186FE29,0x33ED7D2A,0xE72719C1,0x154C9AC2,0x061C6936,0xF477EA35,0xAA64D611,0x580F5512,0x4B5FA6E6,0xB93425E5,0x6DFE410E,0x9F95C20D,0x8CC531F9,0x7EAEB2FA,
|
||
|
0x30E349B1,0xC288CAB2,0xD1D83946,0x23B3BA45,0xF779DEAE,0x05125DAD,0x1642AE59,0xE4292D5A,0xBA3A117E,0x4851927D,0x5B016189,0xA96AE28A,0x7DA08661,0x8FCB0562,0x9C9BF696,0x6EF07595,
|
||
|
0x417B1DBC,0xB3109EBF,0xA0406D4B,0x522BEE48,0x86E18AA3,0x748A09A0,0x67DAFA54,0x95B17957,0xCBA24573,0x39C9C670,0x2A993584,0xD8F2B687,0x0C38D26C,0xFE53516F,0xED03A29B,0x1F682198,
|
||
|
0x5125DAD3,0xA34E59D0,0xB01EAA24,0x42752927,0x96BF4DCC,0x64D4CECF,0x77843D3B,0x85EFBE38,0xDBFC821C,0x2997011F,0x3AC7F2EB,0xC8AC71E8,0x1C661503,0xEE0D9600,0xFD5D65F4,0x0F36E6F7,
|
||
|
0x61C69362,0x93AD1061,0x80FDE395,0x72966096,0xA65C047D,0x5437877E,0x4767748A,0xB50CF789,0xEB1FCBAD,0x197448AE,0x0A24BB5A,0xF84F3859,0x2C855CB2,0xDEEEDFB1,0xCDBE2C45,0x3FD5AF46,
|
||
|
0x7198540D,0x83F3D70E,0x90A324FA,0x62C8A7F9,0xB602C312,0x44694011,0x5739B3E5,0xA55230E6,0xFB410CC2,0x092A8FC1,0x1A7A7C35,0xE811FF36,0x3CDB9BDD,0xCEB018DE,0xDDE0EB2A,0x2F8B6829,
|
||
|
0x82F63B78,0x709DB87B,0x63CD4B8F,0x91A6C88C,0x456CAC67,0xB7072F64,0xA457DC90,0x563C5F93,0x082F63B7,0xFA44E0B4,0xE9141340,0x1B7F9043,0xCFB5F4A8,0x3DDE77AB,0x2E8E845F,0xDCE5075C,
|
||
|
0x92A8FC17,0x60C37F14,0x73938CE0,0x81F80FE3,0x55326B08,0xA759E80B,0xB4091BFF,0x466298FC,0x1871A4D8,0xEA1A27DB,0xF94AD42F,0x0B21572C,0xDFEB33C7,0x2D80B0C4,0x3ED04330,0xCCBBC033,
|
||
|
0xA24BB5A6,0x502036A5,0x4370C551,0xB11B4652,0x65D122B9,0x97BAA1BA,0x84EA524E,0x7681D14D,0x2892ED69,0xDAF96E6A,0xC9A99D9E,0x3BC21E9D,0xEF087A76,0x1D63F975,0x0E330A81,0xFC588982,
|
||
|
0xB21572C9,0x407EF1CA,0x532E023E,0xA145813D,0x758FE5D6,0x87E466D5,0x94B49521,0x66DF1622,0x38CC2A06,0xCAA7A905,0xD9F75AF1,0x2B9CD9F2,0xFF56BD19,0x0D3D3E1A,0x1E6DCDEE,0xEC064EED,
|
||
|
0xC38D26C4,0x31E6A5C7,0x22B65633,0xD0DDD530,0x0417B1DB,0xF67C32D8,0xE52CC12C,0x1747422F,0x49547E0B,0xBB3FFD08,0xA86F0EFC,0x5A048DFF,0x8ECEE914,0x7CA56A17,0x6FF599E3,0x9D9E1AE0,
|
||
|
0xD3D3E1AB,0x21B862A8,0x32E8915C,0xC083125F,0x144976B4,0xE622F5B7,0xF5720643,0x07198540,0x590AB964,0xAB613A67,0xB831C993,0x4A5A4A90,0x9E902E7B,0x6CFBAD78,0x7FAB5E8C,0x8DC0DD8F,
|
||
|
0xE330A81A,0x115B2B19,0x020BD8ED,0xF0605BEE,0x24AA3F05,0xD6C1BC06,0xC5914FF2,0x37FACCF1,0x69E9F0D5,0x9B8273D6,0x88D28022,0x7AB90321,0xAE7367CA,0x5C18E4C9,0x4F48173D,0xBD23943E,
|
||
|
0xF36E6F75,0x0105EC76,0x12551F82,0xE03E9C81,0x34F4F86A,0xC69F7B69,0xD5CF889D,0x27A40B9E,0x79B737BA,0x8BDCB4B9,0x988C474D,0x6AE7C44E,0xBE2DA0A5,0x4C4623A6,0x5F16D052,0xAD7D5351
|
||
|
#endif
|
||
|
};
|
||
|
#endif
|
||
|
|
||
|
// Known size hash
|
||
|
// It is ok to call ImHashData on a string with known length but the ### operator won't be supported.
|
||
| ... | ... | |
|
{
|
||
|
ImU32 crc = ~seed;
|
||
|
const unsigned char* data = (const unsigned char*)data_p;
|
||
|
const unsigned char *data_end = (const unsigned char*)data_p + data_size;
|
||
|
#ifndef IMGUI_ENABLE_SSE4_2_CRC
|
||
|
const ImU32* crc32_lut = GCrc32LookupTable;
|
||
|
while (data_size-- != 0)
|
||
|
while (data < data_end)
|
||
|
crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ *data++];
|
||
|
return ~crc;
|
||
|
#else
|
||
|
while (data + 4 <= data_end)
|
||
|
{
|
||
|
crc = _mm_crc32_u32(crc, *(ImU32*)data);
|
||
|
data += 4;
|
||
|
}
|
||
|
while (data < data_end)
|
||
|
crc = _mm_crc32_u8(crc, *data++);
|
||
|
return ~crc;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
// Zero-terminated string hash, with support for ### to reset back to seed value
|
||
| ... | ... | |
|
seed = ~seed;
|
||
|
ImU32 crc = seed;
|
||
|
const unsigned char* data = (const unsigned char*)data_p;
|
||
|
#ifndef IMGUI_ENABLE_SSE4_2_CRC
|
||
|
const ImU32* crc32_lut = GCrc32LookupTable;
|
||
|
#endif
|
||
|
if (data_size != 0)
|
||
|
{
|
||
|
while (data_size-- != 0)
|
||
| ... | ... | |
|
unsigned char c = *data++;
|
||
|
if (c == '#' && data_size >= 2 && data[0] == '#' && data[1] == '#')
|
||
|
crc = seed;
|
||
|
#ifndef IMGUI_ENABLE_SSE4_2_CRC
|
||
|
crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c];
|
||
|
#else
|
||
|
crc = _mm_crc32_u8(crc, c);
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
else
|
||
| ... | ... | |
|
{
|
||
|
if (c == '#' && data[0] == '#' && data[1] == '#')
|
||
|
crc = seed;
|
||
|
#ifndef IMGUI_ENABLE_SSE4_2_CRC
|
||
|
crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c];
|
||
|
#else
|
||
|
crc = _mm_crc32_u8(crc, c);
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
return ~crc;
|
||
|
}
|
||
|
|
||
|
// Skip to the "###" marker if any. We don't skip past to match the behavior of GetID()
|
||
|
// FIXME-OPT: This is not designed to be optimal. Use with care.
|
||
|
const char* ImHashSkipUncontributingPrefix(const char* label)
|
||
|
{
|
||
|
const char* result = label;
|
||
|
while (unsigned char c = *label++)
|
||
|
if (c == '#' && label[0] == '#' && label[1] == '#')
|
||
|
result = label - 1;
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// [SECTION] MISC HELPERS/UTILITIES (File functions)
|
||
|
//-----------------------------------------------------------------------------
|
||
| ... | ... | |
|
|
||
|
ImFileHandle ImFileOpen(const char* filename, const char* mode)
|
||
|
{
|
||
|
#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && !defined(__CYGWIN__) && !defined(__GNUC__)
|
||
|
#if defined(_WIN32) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) && (defined(__MINGW32__) || (!defined(__CYGWIN__) && !defined(__GNUC__)))
|
||
|
// We need a fopen() wrapper because MSVC/Windows fopen doesn't handle UTF-8 filenames.
|
||
|
// Previously we used ImTextCountCharsFromUtf8/ImTextStrFromUtf8 here but we now need to support ImWchar16 and ImWchar32!
|
||
|
const int filename_wsize = ::MultiByteToWideChar(CP_UTF8, 0, filename, -1, NULL, 0);
|
||
| ... | ... | |
|
int len = lengths[*(const unsigned char*)in_text >> 3];
|
||
|
int wanted = len + (len ? 0 : 1);
|
||
|
|
||
|
// IMPORTANT: if in_text_end == NULL it assume we have enough space!
|
||
|
if (in_text_end == NULL)
|
||
|
in_text_end = in_text + wanted; // Max length, nulls will be taken into account.
|
||
|
|
||
| ... | ... | |
|
int e = 0;
|
||
|
e = (*out_char < mins[len]) << 6; // non-canonical encoding
|
||
|
e |= ((*out_char >> 11) == 0x1b) << 7; // surrogate half?
|
||
|
e |= (*out_char > IM_UNICODE_CODEPOINT_MAX) << 8; // out of range?
|
||
|
e |= (*out_char > IM_UNICODE_CODEPOINT_MAX) << 8; // out of range we can store in ImWchar (FIXME: May evolve)
|
||
|
e |= (s[1] & 0xc0) >> 2;
|
||
|
e |= (s[2] & 0xc0) >> 4;
|
||
|
e |= (s[3] ) >> 6;
|
||
| ... | ... | |
|
return 0;
|
||
|
}
|
||
|
|
||
|
const char* ImTextCharToUtf8(char out_buf[5], unsigned int c)
|
||
|
int ImTextCharToUtf8(char out_buf[5], unsigned int c)
|
||
|
{
|
||
|
int count = ImTextCharToUtf8_inline(out_buf, 5, c);
|
||
|
out_buf[count] = 0;
|
||
|
return out_buf;
|
||
|
return count;
|
||
|
}
|
||
|
|
||
|
// Not optimal but we very rarely use this function.
|
||
| ... | ... | |
|
return bytes_count;
|
||
|
}
|
||
|
|
||
|
const char* ImTextFindPreviousUtf8Codepoint(const char* in_text_start, const char* in_text_curr)
|
||
|
const char* ImTextFindPreviousUtf8Codepoint(const char* in_text_start, const char* in_p)
|
||
|
{
|
||
|
while (in_text_curr > in_text_start)
|
||
|
while (in_p > in_text_start)
|
||
|
{
|
||
|
in_text_curr--;
|
||
|
if ((*in_text_curr & 0xC0) != 0x80)
|
||
|
return in_text_curr;
|
||
|
in_p--;
|
||
|
if ((*in_p & 0xC0) != 0x80)
|
||
|
return in_p;
|
||
|
}
|
||
|
return in_text_start;
|
||
|
}
|
||
|
|
||
|
const char* ImTextFindValidUtf8CodepointEnd(const char* in_text_start, const char* in_text_end, const char* in_p)
|
||
|
{
|
||
|
if (in_text_start == in_p)
|
||
|
return in_text_start;
|
||
|
const char* prev = ImTextFindPreviousUtf8Codepoint(in_text_start, in_p);
|
||
|
unsigned int prev_c;
|
||
|
int prev_c_len = ImTextCharFromUtf8(&prev_c, prev, in_text_end);
|
||
|
if (prev_c != IM_UNICODE_CODEPOINT_INVALID && prev_c_len <= (int)(in_p - prev))
|
||
|
return in_p;
|
||
|
return prev;
|
||
|
}
|
||
|
|
||
|
int ImTextCountLines(const char* in_text, const char* in_text_end)
|
||
|
{
|
||
|
if (in_text_end == NULL)
|
||
|
in_text_end = in_text + strlen(in_text); // FIXME-OPT: Not optimal approach, discourage use for now.
|
||
|
in_text_end = in_text + ImStrlen(in_text); // FIXME-OPT: Not optimal approach, discourage use for now.
|
||
|
int count = 0;
|
||
|
while (in_text < in_text_end)
|
||
|
{
|
||
|
const char* line_end = (const char*)memchr(in_text, '\n', in_text_end - in_text);
|
||
|
const char* line_end = (const char*)ImMemchr(in_text, '\n', in_text_end - in_text);
|
||
|
in_text = line_end ? line_end + 1 : in_text_end;
|
||
|
count++;
|
||
|
}
|
||
| ... | ... | |
|
void ImGuiTextFilter::Build()
|
||
|
{
|
||
|
Filters.resize(0);
|
||
|
ImGuiTextRange input_range(InputBuf, InputBuf + strlen(InputBuf));
|
||
|
ImGuiTextRange input_range(InputBuf, InputBuf + ImStrlen(InputBuf));
|
||
|
input_range.split(',', &Filters);
|
||
|
|
||
|
CountGrep = 0;
|
||
| ... | ... | |
|
|
||
|
void ImGuiTextBuffer::append(const char* str, const char* str_end)
|
||
|
{
|
||
|
int len = str_end ? (int)(str_end - str) : (int)strlen(str);
|
||
|
int len = str_end ? (int)(str_end - str) : (int)ImStrlen(str);
|
||
|
|
||
|
// Add zero-terminator the first time
|
||
|
const int write_off = (Buf.Size != 0) ? Buf.Size : 1;
|
||
| ... | ... | |
|
va_end(args_copy);
|
||
|
}
|
||
|
|
||
|
IM_MSVC_RUNTIME_CHECKS_OFF
|
||
|
void ImGuiTextIndex::append(const char* base, int old_size, int new_size)
|
||
|
{
|
||
|
IM_ASSERT(old_size >= 0 && new_size >= old_size && new_size >= EndOffset);
|
||
|
if (old_size == new_size)
|
||
|
return;
|
||
|
if (EndOffset == 0 || base[EndOffset - 1] == '\n')
|
||
|
LineOffsets.push_back(EndOffset);
|
||
|
Offsets.push_back(EndOffset);
|
||
|
const char* base_end = base + new_size;
|
||
|
for (const char* p = base + old_size; (p = (const char*)memchr(p, '\n', base_end - p)) != 0; )
|
||
|
for (const char* p = base + old_size; (p = (const char*)ImMemchr(p, '\n', base_end - p)) != 0; )
|
||
|
if (++p < base_end) // Don't push a trailing offset on last \n
|
||
|
LineOffsets.push_back((int)(intptr_t)(p - base));
|
||
|
Offsets.push_back((int)(intptr_t)(p - base));
|
||
|
EndOffset = ImMax(EndOffset, new_size);
|
||
|
}
|
||
|
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// [SECTION] ImGuiListClipper
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
|
||
|
static void ImGuiListClipper_SeekCursorAndSetupPrevLine(float pos_y, float line_height)
|
||
|
static void ImGuiListClipper_SeekCursorAndSetupPrevLine(ImGuiListClipper* clipper, float pos_y, float line_height)
|
||
|
{
|
||
|
// Set cursor position and a few other things so that SetScrollHereY() and Columns() can work when seeking cursor.
|
||
|
// FIXME: It is problematic that we have to do that here, because custom/equivalent end-user code would stumble on the same issue.
|
||
| ... | ... | |
|
{
|
||
|
if (table->IsInsideRow)
|
||
|
ImGui::TableEndRow(table);
|
||
|
table->RowPosY2 = window->DC.CursorPos.y;
|
||
|
const int row_increase = (int)((off_y / line_height) + 0.5f);
|
||
|
//table->CurrentRow += row_increase; // Can't do without fixing TableEndRow()
|
||
|
table->RowBgColorCounter += row_increase;
|
||
|
if (row_increase > 0 && (clipper->Flags & ImGuiListClipperFlags_NoSetTableRowCounters) == 0) // If your clipper item height is != from actual table row height, consider using ImGuiListClipperFlags_NoSetTableRowCounters. See #8886.
|
||
|
{
|
||
|
table->CurrentRow += row_increase;
|
||
|
table->RowBgColorCounter += row_increase;
|
||
|
}
|
||
|
table->RowPosY2 = window->DC.CursorPos.y;
|
||
|
}
|
||
|
}
|
||
|
|
||
| ... | ... | |
|
// - StartPosY starts from ItemsFrozen, by adding SeekOffsetY we generally cancel that out (SeekOffsetY == LossynessOffset - ItemsFrozen * ItemsHeight).
|
||
|
// - The reason we store SeekOffsetY instead of inferring it, is because we want to allow user to perform Seek after the last step, where ImGuiListClipperData is already done.
|
||
|
float pos_y = (float)((double)StartPosY + StartSeekOffsetY + (double)item_n * ItemsHeight);
|
||
|
ImGuiListClipper_SeekCursorAndSetupPrevLine(pos_y, ItemsHeight);
|
||
|
ImGuiListClipper_SeekCursorAndSetupPrevLine(this, pos_y, ItemsHeight);
|
||
|
}
|
||
|
|
||
|
static bool ImGuiListClipper_StepInternal(ImGuiListClipper* clipper)
|
||
| ... | ... | |
|
if (table)
|
||
|
IM_ASSERT(table->RowPosY1 == clipper->StartPosY && table->RowPosY2 == window->DC.CursorPos.y);
|
||
|
|
||
|
clipper->ItemsHeight = (window->DC.CursorPos.y - clipper->StartPosY) / (float)(clipper->DisplayEnd - clipper->DisplayStart);
|
||
|
bool affected_by_floating_point_precision = ImIsFloatAboveGuaranteedIntegerPrecision(clipper->StartPosY) || ImIsFloatAboveGuaranteedIntegerPrecision(window->DC.CursorPos.y);
|
||
|
bool affected_by_floating_point_precision = ImIsFloatAboveGuaranteedIntegerPrecision((float)clipper->StartPosY) || ImIsFloatAboveGuaranteedIntegerPrecision(window->DC.CursorPos.y);
|
||
|
if (affected_by_floating_point_precision)
|
||
|
{
|
||
|
// Mitigation/hack for very large range: assume last time height constitute line height.
|
||
|
clipper->ItemsHeight = window->DC.PrevLineSize.y + g.Style.ItemSpacing.y; // FIXME: Technically wouldn't allow multi-line entries.
|
||
|
window->DC.CursorPos.y = (float)(clipper->StartPosY + clipper->ItemsHeight);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
clipper->ItemsHeight = (float)(window->DC.CursorPos.y - clipper->StartPosY) / (float)(clipper->DisplayEnd - clipper->DisplayStart);
|
||
|
}
|
||
|
if (clipper->ItemsHeight == 0.0f && clipper->ItemsCount == INT_MAX) // Accept that no item have been submitted if in indeterminate mode.
|
||
|
return false;
|
||
|
IM_ASSERT(clipper->ItemsHeight > 0.0f && "Unable to calculate item height! First item hasn't moved the cursor vertically!");
|
||
| ... | ... | |
|
{
|
||
|
// Add range selected to be included for navigation
|
||
|
const bool is_nav_request = (g.NavMoveScoringItems && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav);
|
||
|
const int nav_off_min = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Up) ? -1 : 0;
|
||
|
const int nav_off_max = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Down) ? 1 : 0;
|
||
|
if (is_nav_request)
|
||
|
data->Ranges.push_back(ImGuiListClipperRange::FromPositions(g.NavScoringNoClipRect.Min.y, g.NavScoringNoClipRect.Max.y, 0, 0));
|
||
|
{
|
||
|
data->Ranges.push_back(ImGuiListClipperRange::FromPositions(g.NavScoringRect.Min.y, g.NavScoringRect.Max.y, nav_off_min, nav_off_max));
|
||
|
data->Ranges.push_back(ImGuiListClipperRange::FromPositions(g.NavScoringNoClipRect.Min.y, g.NavScoringNoClipRect.Max.y, nav_off_min, nav_off_max));
|
||
|
}
|
||
|
if (is_nav_request && (g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) && g.NavTabbingDir == -1)
|
||
|
data->Ranges.push_back(ImGuiListClipperRange::FromIndices(clipper->ItemsCount - 1, clipper->ItemsCount));
|
||
|
|
||
| ... | ... | |
|
if (g.NavId != 0 && window->NavLastIds[0] == g.NavId)
|
||
|
data->Ranges.push_back(ImGuiListClipperRange::FromPositions(nav_rect_abs.Min.y, nav_rect_abs.Max.y, 0, 0));
|
||
|
|
||
|
// Add visible range
|
||
|
float min_y = window->ClipRect.Min.y;
|
||
|
float max_y = window->ClipRect.Max.y;
|
||
|
|
||
| ... | ... | |
|
data->Ranges.push_back(ImGuiListClipperRange::FromPositions(bs->UnclipRect.Min.y, bs->UnclipRect.Max.y, 0, 0));
|
||
|
}
|
||
|
|
||
|
const int off_min = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Up) ? -1 : 0;
|
||
|
const int off_max = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Down) ? 1 : 0;
|
||
|
data->Ranges.push_back(ImGuiListClipperRange::FromPositions(min_y, max_y, off_min, off_max));
|
||
|
// Add main visible range
|
||
|
data->Ranges.push_back(ImGuiListClipperRange::FromPositions(min_y, max_y, nav_off_min, nav_off_max));
|
||
|
}
|
||
|
|
||
|
// Convert position ranges to item index ranges
|
||
| ... | ... | |
|
{
|
||
|
clipper->DisplayStart = ImMax(data->Ranges[data->StepNo].Min, already_submitted);
|
||
|
clipper->DisplayEnd = ImMin(data->Ranges[data->StepNo].Max, clipper->ItemsCount);
|
||
|
if (clipper->DisplayStart > already_submitted) //-V1051
|
||
|
clipper->SeekCursorForItem(clipper->DisplayStart);
|
||
|
data->StepNo++;
|
||
|
if (clipper->DisplayStart == clipper->DisplayEnd && data->StepNo < data->Ranges.Size)
|
||
|
if (clipper->DisplayStart >= clipper->DisplayEnd)
|
||
|
continue;
|
||
|
if (clipper->DisplayStart > already_submitted)
|
||
|
clipper->SeekCursorForItem(clipper->DisplayStart);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
| ... | ... | |
|
ImGuiContext& g = *Ctx;
|
||
|
bool need_items_height = (ItemsHeight <= 0.0f);
|
||
|
bool ret = ImGuiListClipper_StepInternal(this);
|
||
|
if (ret && (DisplayStart == DisplayEnd))
|
||
|
if (ret && (DisplayStart >= DisplayEnd))
|
||
|
ret = false;
|
||
|
if (g.CurrentTable && g.CurrentTable->IsUnfrozenRows == false)
|
||
|
IMGUI_DEBUG_LOG_CLIPPER("Clipper: Step(): inside frozen table row.\n");
|
||
| ... | ... | |
|
return ret;
|
||
|
}
|
||
|
|
||
|
// Generic helper, equivalent to old ImGui::CalcListClipping() but statelesss
|
||
|
void ImGui::CalcClipRectVisibleItemsY(const ImRect& clip_rect, const ImVec2& pos, float items_height, int* out_visible_start, int* out_visible_end)
|
||
|
{
|
||
|
*out_visible_start = ImMax((int)((clip_rect.Min.y - pos.y) / items_height), 0);
|
||
|
*out_visible_end = ImMax((int)ImCeil((clip_rect.Max.y - pos.y) / items_height), *out_visible_start);
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// [SECTION] STYLING
|
||
|
//-----------------------------------------------------------------------------
|
||
| ... | ... | |
|
}
|
||
|
}
|
||
|
|
||
|
static const ImGuiDataVarInfo GStyleVarInfo[] =
|
||
|
{
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, DisabledAlpha) }, // ImGuiStyleVar_DisabledAlpha
|
||
|
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize
|
||
|
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize
|
||
|
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, WindowTitleAlign) }, // ImGuiStyleVar_WindowTitleAlign
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize
|
||
|
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize
|
||
|
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing
|
||
|
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing
|
||
|
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, CellPadding) }, // ImGuiStyleVar_CellPadding
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ScrollbarSize) }, // ImGuiStyleVar_ScrollbarSize
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, ScrollbarRounding) }, // ImGuiStyleVar_ScrollbarRounding
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabRounding) }, // ImGuiStyleVar_TabRounding
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBorderSize) }, // ImGuiStyleVar_TabBorderSize
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBarBorderSize) }, // ImGuiStyleVar_TabBarBorderSize
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TabBarOverlineSize) }, // ImGuiStyleVar_TabBarOverlineSize
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersAngle)}, // ImGuiStyleVar_TableAngledHeadersAngle
|
||
|
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersTextAlign)},// ImGuiStyleVar_TableAngledHeadersTextAlign
|
||
|
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign
|
||
|
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign
|
||
|
{ ImGuiDataType_Float, 1, (ImU32)offsetof(ImGuiStyle, SeparatorTextBorderSize)}, // ImGuiStyleVar_SeparatorTextBorderSize
|
||
|
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SeparatorTextAlign) }, // ImGuiStyleVar_SeparatorTextAlign
|
||
|
{ ImGuiDataType_Float, 2, (ImU32)offsetof(ImGuiStyle, SeparatorTextPadding) }, // ImGuiStyleVar_SeparatorTextPadding
|
||
|
static const ImGuiStyleVarInfo GStyleVarsInfo[] =
|
||
|
{
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, DisabledAlpha) }, // ImGuiStyleVar_DisabledAlpha
|
||
|
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize
|
||
|
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize
|
||
|
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, WindowTitleAlign) }, // ImGuiStyleVar_WindowTitleAlign
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize
|
||
|
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize
|
||
|
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing
|
||
|
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing
|
||
|
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, CellPadding) }, // ImGuiStyleVar_CellPadding
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ScrollbarSize) }, // ImGuiStyleVar_ScrollbarSize
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ScrollbarRounding) }, // ImGuiStyleVar_ScrollbarRounding
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ScrollbarPadding) }, // ImGuiStyleVar_ScrollbarPadding
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ImageBorderSize) }, // ImGuiStyleVar_ImageBorderSize
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TabRounding) }, // ImGuiStyleVar_TabRounding
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TabBorderSize) }, // ImGuiStyleVar_TabBorderSize
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TabMinWidthBase) }, // ImGuiStyleVar_TabMinWidthBase
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TabMinWidthShrink) }, // ImGuiStyleVar_TabMinWidthShrink
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TabBarBorderSize) }, // ImGuiStyleVar_TabBarBorderSize
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TabBarOverlineSize) }, // ImGuiStyleVar_TabBarOverlineSize
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersAngle)}, // ImGuiStyleVar_TableAngledHeadersAngle
|
||
|
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersTextAlign)},// ImGuiStyleVar_TableAngledHeadersTextAlign
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TreeLinesSize)}, // ImGuiStyleVar_TreeLinesSize
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TreeLinesRounding)}, // ImGuiStyleVar_TreeLinesRounding
|
||
|
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign
|
||
|
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign
|
||
|
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorTextBorderSize)}, // ImGuiStyleVar_SeparatorTextBorderSize
|
||
|
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorTextAlign) }, // ImGuiStyleVar_SeparatorTextAlign
|
||
|
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorTextPadding) }, // ImGuiStyleVar_SeparatorTextPadding
|
||
|
};
|
||
|
|
||
|
const ImGuiDataVarInfo* ImGui::GetStyleVarInfo(ImGuiStyleVar idx)
|
||
|
const ImGuiStyleVarInfo* ImGui::GetStyleVarInfo(ImGuiStyleVar idx)
|
||
|
{
|
||
|
IM_ASSERT(idx >= 0 && idx < ImGuiStyleVar_COUNT);
|
||
|
IM_STATIC_ASSERT(IM_ARRAYSIZE(GStyleVarInfo) == ImGuiStyleVar_COUNT);
|
||
|
return &GStyleVarInfo[idx];
|
||
|
IM_STATIC_ASSERT(IM_ARRAYSIZE(GStyleVarsInfo) == ImGuiStyleVar_COUNT);
|
||
|
return &GStyleVarsInfo[idx];
|
||
|
}
|
||
|
|
||
|
void ImGui::PushStyleVar(ImGuiStyleVar idx, float val)
|
||
|
{
|
||
|
ImGuiContext& g = *GImGui;
|
||
|
const ImGuiDataVarInfo* var_info = GetStyleVarInfo(idx);
|
||
|
if (var_info->Type != ImGuiDataType_Float || var_info->Count != 1)
|
||
|
const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx);
|
||
|
if (var_info->DataType != ImGuiDataType_Float || var_info->Count != 1)
|
||
|
{
|
||
|
IM_ASSERT_USER_ERROR(0, "Calling PushStyleVar() variant with wrong type!");
|
||
|
return;
|
||
| ... | ... | |
|
void ImGui::PushStyleVarX(ImGuiStyleVar idx, float val_x)
|
||
|
{
|
||
|
ImGuiContext& g = *GImGui;
|
||
|
const ImGuiDataVarInfo* var_info = GetStyleVarInfo(idx);
|
||
|
if (var_info->Type != ImGuiDataType_Float || var_info->Count != 2)
|
||
|
const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx);
|
||
|
if (var_info->DataType != ImGuiDataType_Float || var_info->Count != 2)
|
||
|
{
|
||
|
IM_ASSERT_USER_ERROR(0, "Calling PushStyleVar() variant with wrong type!");
|
||
|
return;
|
||
| ... | ... | |
|
void ImGui::PushStyleVarY(ImGuiStyleVar idx, float val_y)
|
||
|
{
|
||
|
ImGuiContext& g = *GImGui;
|
||
|
const ImGuiDataVarInfo* var_info = GetStyleVarInfo(idx);
|
||
|
if (var_info->Type != ImGuiDataType_Float || var_info->Count != 2)
|
||
|
const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx);
|
||
|
if (var_info->DataType != ImGuiDataType_Float || var_info->Count != 2)
|
||
|
{
|
||
|
IM_ASSERT_USER_ERROR(0, "Calling PushStyleVar() variant with wrong type!");
|
||
|
return;
|
||
| ... | ... | |
|
void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val)
|
||
|
{
|
||
|
ImGuiContext& g = *GImGui;
|
||
|
const ImGuiDataVarInfo* var_info = GetStyleVarInfo(idx);
|
||
|
if (var_info->Type != ImGuiDataType_Float || var_info->Count != 2)
|
||
|
const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx);
|
||
|
if (var_info->DataType != ImGuiDataType_Float || var_info->Count != 2)
|
||
|
{
|
||
|
IM_ASSERT_USER_ERROR(0, "Calling PushStyleVar() variant with wrong type!");
|
||
|
return;
|
||
| ... | ... | |
|
{
|
||
|
// We avoid a generic memcpy(data, &backup.Backup.., GDataTypeSize[info->Type] * info->Count), the overhead in Debug is not worth it.
|
||
|
ImGuiStyleMod& backup = g.StyleVarStack.back();
|
||
|
const ImGuiDataVarInfo* info = GetStyleVarInfo(backup.VarIdx);
|
||
|
void* data = info->GetVarPtr(&g.Style);
|
||
|
if (info->Type == ImGuiDataType_Float && info->Count == 1) { ((float*)data)[0] = backup.BackupFloat[0]; }
|
||
|
else if (info->Type == ImGuiDataType_Float && info->Count == 2) { ((float*)data)[0] = backup.BackupFloat[0]; ((float*)data)[1] = backup.BackupFloat[1]; }
|
||
|
const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(backup.VarIdx);
|
||
|
void* data = var_info->GetVarPtr(&g.Style);
|
||
|
if (var_info->DataType == ImGuiDataType_Float && var_info->Count == 1) { ((float*)data)[0] = backup.BackupFloat[0]; }
|
||
|
else if (var_info->DataType == ImGuiDataType_Float && var_info->Count == 2) { ((float*)data)[0] = backup.BackupFloat[0]; ((float*)data)[1] = backup.BackupFloat[1]; }
|
||
|
g.StyleVarStack.pop_back();
|
||
|
count--;
|
||
|
}
|
||
| ... | ... | |
|
case ImGuiCol_ResizeGrip: return "ResizeGrip";
|
||
|
case ImGuiCol_ResizeGripHovered: return "ResizeGripHovered";
|
||
|
case ImGuiCol_ResizeGripActive: return "ResizeGripActive";
|
||
|
case ImGuiCol_InputTextCursor: return "InputTextCursor";
|
||
|
case ImGuiCol_TabHovered: return "TabHovered";
|
||
|
case ImGuiCol_Tab: return "Tab";
|
||
|
case ImGuiCol_TabSelected: return "TabSelected";
|
||
| ... | ... | |
|
case ImGuiCol_TableRowBgAlt: return "TableRowBgAlt";
|
||
|
case ImGuiCol_TextLink: return "TextLink";
|
||
|
case ImGuiCol_TextSelectedBg: return "TextSelectedBg";
|
||
|
case ImGuiCol_TreeLines: return "TreeLines";
|
||
|
case ImGuiCol_DragDropTarget: return "DragDropTarget";
|
||
|
case ImGuiCol_DragDropTargetBg: return "DragDropTargetBg";
|
||
|
case ImGuiCol_UnsavedMarker: return "UnsavedMarker";
|
||
|
case ImGuiCol_NavCursor: return "NavCursor";
|
||
|
case ImGuiCol_NavWindowingHighlight: return "NavWindowingHighlight";
|
||
|
case ImGuiCol_NavWindowingDimBg: return "NavWindowingDimBg";
|
||
| ... | ... | |
|
return "Unknown";
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// [SECTION] RENDER HELPERS
|
||
|
// Some of those (internal) functions are currently quite a legacy mess - their signature and behavior will change,
|
||
| ... | ... | |
|
else
|
||
|
{
|
||
|
if (!text_end)
|
||
|
text_end = text + strlen(text); // FIXME-OPT
|
||
|
text_end = text + ImStrlen(text); // FIXME-OPT
|
||
|
text_display_end = text_end;
|
||
|
}
|
||
|
|
||
| ... | ... | |
|
ImGuiWindow* window = g.CurrentWindow;
|
||
|
|
||
|
if (!text_end)
|
||
|
text_end = text + strlen(text); // FIXME-OPT
|
||
|
text_end = text + ImStrlen(text); // FIXME-OPT
|
||
|
|
||
|
if (text != text_end)
|
||
|
{
|
||
| ... | ... | |
|
|
||
|
// Default clip_rect uses (pos_min,pos_max)
|
||
|
// Handle clipping on CPU immediately (vs typically let the GPU clip the triangles that are overlapping the clipping rectangle edges)
|
||
|
// FIXME-OPT: Since we have or calculate text_size we could coarse clip whole block immediately, especally for text above draw_list->DrawList.
|
||
|
// FIXME-OPT: Since we have or calculate text_size we could coarse clip whole block immediately, especially for text above draw_list->DrawList.
|
||
|
// Effectively as this is called from widget doing their own coarse clipping it's not very valuable presently. Next time function will take
|
||
|
// better advantage of the render function taking size into account for coarse clipping.
|
||
|
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)
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
// Another overly complex function until we reorganize everything into a nice all-in-one helper.
|
||
|
// 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.
|
||
|
// This is made more complex because we have dissociated the layout rectangle (pos_min..pos_max) from 'ellipsis_max_x' which may be beyond it.
|
||
|
// 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.
|
||
|
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)
|
||
|
// (BREAKING) On 2025/04/16 we removed the 'float clip_max_x' parameters which was preceding 'float ellipsis_max' and was the same value for 99% of users.
|
||
|
void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, float ellipsis_max_x, const char* text, const char* text_end_full, const ImVec2* text_size_if_known)
|
||
|
{
|
||
|
ImGuiContext& g = *GImGui;
|
||
|
if (text_end_full == NULL)
|
||
|
text_end_full = FindRenderedTextEnd(text);
|
||
|
const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_end_full, false, 0.0f);
|
||
|
|
||
|
//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));
|
||
|
//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));
|
||
|
//draw_list->AddLine(ImVec2(clip_max_x, pos_min.y), ImVec2(clip_max_x, pos_max.y), IM_COL32(255, 0, 0, 255));
|
||
|
//draw_list->AddLine(ImVec2(pos_max.x, pos_min.y - 4), ImVec2(pos_max.x, pos_max.y + 6), IM_COL32(0, 0, 255, 255));
|
||
|
//draw_list->AddLine(ImVec2(ellipsis_max_x, pos_min.y - 2), ImVec2(ellipsis_max_x, pos_max.y + 3), IM_COL32(0, 255, 0, 255));
|
||
|
|
||
|
// FIXME: We could technically remove (last_glyph->AdvanceX - last_glyph->X1) from text_size.x here and save a few pixels.
|
||
|
if (text_size.x > pos_max.x - pos_min.x)
|
||
|
{
|
||
| ... | ... | |
|
const float font_size = draw_list->_Data->FontSize;
|
||
|
const float font_scale = draw_list->_Data->FontScale;
|
||
|
const char* text_end_ellipsis = NULL;
|
||
|
const float ellipsis_width = font->EllipsisWidth * font_scale;
|
||
|
ImFontBaked* baked = font->GetFontBaked(font_size);
|
||
|
const float ellipsis_width = baked->GetCharAdvance(font->EllipsisChar) * font_scale;
|
||
|
|
||
|
// We can now claim the space between pos_max.x and ellipsis_max.x
|
||
|
const float text_avail_width = ImMax((ImMax(pos_max.x, ellipsis_max_x) - ellipsis_width) - pos_min.x, 1.0f);
|
||
|
float text_size_clipped_x = font->CalcTextSizeA(font_size, text_avail_width, 0.0f, text, text_end_full, &text_end_ellipsis).x;
|
||
|
if (text == text_end_ellipsis && text_end_ellipsis < text_end_full)
|
||
|
{
|
||
|
// Always display at least 1 character if there's no room for character + ellipsis
|
||
|
text_end_ellipsis = text + ImTextCountUtf8BytesFromChar(text, text_end_full);
|
||
|
text_size_clipped_x = font->CalcTextSizeA(font_size, FLT_MAX, 0.0f, text, text_end_ellipsis).x;
|
||
|
}
|
||
|
while (text_end_ellipsis > text && ImCharIsBlankA(text_end_ellipsis[-1]))
|
||
|
{
|
||
|
// 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)
|
||
| ... | ... | |
|
}
|
||
|
|
||
|
// Render text, render ellipsis
|
||
|
RenderTextClippedEx(draw_list, pos_min, ImVec2(clip_max_x, pos_max.y), text, text_end_ellipsis, &text_size, ImVec2(0.0f, 0.0f));
|
||
|
RenderTextClippedEx(draw_list, pos_min, pos_max, text, text_end_ellipsis, &text_size, ImVec2(0.0f, 0.0f));
|
||
|
ImVec4 cpu_fine_clip_rect(pos_min.x, pos_min.y, pos_max.x, pos_max.y);
|
||
|
ImVec2 ellipsis_pos = ImTrunc(ImVec2(pos_min.x + text_size_clipped_x, pos_min.y));
|
||
|
if (ellipsis_pos.x + ellipsis_width <= ellipsis_max_x)
|
||
|
for (int i = 0; i < font->EllipsisCharCount; i++, ellipsis_pos.x += font->EllipsisCharStep * font_scale)
|
||
|
font->RenderChar(draw_list, font_size, ellipsis_pos, GetColorU32(ImGuiCol_Text), font->EllipsisChar);
|
||
|
font->RenderChar(draw_list, font_size, ellipsis_pos, GetColorU32(ImGuiCol_Text), font->EllipsisChar, &cpu_fine_clip_rect);
|
||
|
}
|
||
|
else
|
||
Update Dear ImGui to version 1.92.5.