Merge branch 'master' into docking

# Conflicts:
#	backends/imgui_impl_opengl2.cpp
#	backends/imgui_impl_opengl3.cpp
#	imgui.cpp
docking
ocornut 4 years ago
commit b11518d7d7

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2014-2020 Omar Cornut
Copyright (c) 2014-2021 Omar Cornut
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

@ -1,8 +1,8 @@
// dear imgui: Platform Backend for GLUT/FreeGLUT
// This needs to be used along with a Renderer (e.g. OpenGL2)
// !!! GLUT/FreeGLUT IS OBSOLETE SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!!
// !!! If someone or something is teaching you GLUT in 2020, you are being abused. Please show some resistance. !!!
// !!! GLUT/FreeGLUT IS OBSOLETE PREHISTORIC SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!!
// !!! If someone or something is teaching you GLUT today, you are being abused. Please show some resistance. !!!
// !!! Nowadays, prefer using GLFW or SDL instead!
// Issues:

@ -1,8 +1,8 @@
// dear imgui: Platform Backend for GLUT/FreeGLUT
// This needs to be used along with a Renderer (e.g. OpenGL2)
// !!! GLUT/FreeGLUT IS OBSOLETE SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!!
// !!! If someone or something is teaching you GLUT in 2020, you are being abused. Please show some resistance. !!!
// !!! GLUT/FreeGLUT IS OBSOLETE PREHISTORIC SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!!
// !!! If someone or something is teaching you GLUT today, you are being abused. Please show some resistance. !!!
// !!! Nowadays, prefer using GLFW or SDL instead!
// Issues:

@ -20,7 +20,8 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2020-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2020-01-23: OpenGL: Explicitly backup, setup and restore GL_TEXTURE_ENV to increase compatibility with legacy OpenGL applications.
// 2021-01-03: OpenGL: Backup, setup and restore GL_SHADE_MODEL state, disable GL_STENCIL_TEST and disable GL_NORMAL_ARRAY client state to increase compatibility with legacy OpenGL applications.
// 2020-01-23: OpenGL: Backup, setup and restore GL_TEXTURE_ENV to increase compatibility with legacy OpenGL applications.
// 2019-04-30: OpenGL: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
// 2019-02-11: OpenGL: Projecting clipping rectangles correctly using draw_data->FramebufferScale to allow multi-viewports for retina display.
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
@ -93,23 +94,29 @@ static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_wid
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
glDisable(GL_LIGHTING);
glDisable(GL_COLOR_MATERIAL);
glEnable(GL_SCISSOR_TEST);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glEnable(GL_TEXTURE_2D);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glShadeModel(GL_SMOOTH);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
// you may need to backup/reset/restore current shader using the lines below. DO NOT MODIFY THIS FILE! Add the code in your calling function:
// GLint last_program;
// glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
// glUseProgram(0);
// ImGui_ImplOpenGL2_RenderDrawData(...);
// glUseProgram(last_program)
// you may need to backup/reset/restore other state, e.g. for current shader using the commented lines below.
// (DO NOT MODIFY THIS FILE! Add the code in your calling function)
// GLint last_program;
// glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
// glUseProgram(0);
// ImGui_ImplOpenGL2_RenderDrawData(...);
// glUseProgram(last_program)
// There are potentially many more states you could need to clear/setup that we can't access from default headers.
// e.g. glBindBuffer(GL_ARRAY_BUFFER, 0), glDisable(GL_TEXTURE_CUBE_MAP).
// Setup viewport, orthographic projection matrix
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
@ -139,6 +146,7 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
GLint last_polygon_mode[2]; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode);
GLint last_viewport[4]; glGetIntegerv(GL_VIEWPORT, last_viewport);
GLint last_scissor_box[4]; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box);
GLint last_shade_model; glGetIntegerv(GL_SHADE_MODEL, &last_shade_model);
GLint last_tex_env_mode; glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &last_tex_env_mode);
glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT);
@ -207,6 +215,7 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]);
glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]);
glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]);
glShadeModel(last_shade_model);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, last_tex_env_mode);
}

@ -15,7 +15,8 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2020-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2020-10-23: OpenGL: Save and restore current GL_PRIMITIVE_RESTART state.
// 2021-01-03: OpenGL: Backup, setup and restore GL_STENCIL_TEST state.
// 2020-10-23: OpenGL: Backup, setup and restore GL_PRIMITIVE_RESTART state.
// 2020-10-15: OpenGL: Use glGetString(GL_VERSION) instead of glGetIntegerv(GL_MAJOR_VERSION, ...) when the later returns zero (e.g. Desktop GL 2.x)
// 2020-09-17: OpenGL: Fix to avoid compiling/calling glBindSampler() on ES or pre 3.3 context which have the defines set by a loader.
// 2020-07-10: OpenGL: Added support for glad2 OpenGL loader.
@ -260,6 +261,7 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_STENCIL_TEST);
glEnable(GL_SCISSOR_TEST);
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
if (g_GlVersion >= 310)
@ -270,8 +272,8 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
#endif
// Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
bool clip_origin_lower_left = true;
#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__)
bool clip_origin_lower_left = true;
GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&current_clip_origin);
if (current_clip_origin == GL_UPPER_LEFT)
clip_origin_lower_left = false;
@ -284,7 +286,9 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
float T = draw_data->DisplayPos.y;
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
#if defined(GL_CLIP_ORIGIN) && !defined(__APPLE__)
if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left
#endif
const float ortho_projection[4][4] =
{
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
@ -354,6 +358,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
GLboolean last_enable_blend = glIsEnabled(GL_BLEND);
GLboolean last_enable_cull_face = glIsEnabled(GL_CULL_FACE);
GLboolean last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST);
GLboolean last_enable_stencil_test = glIsEnabled(GL_STENCIL_TEST);
GLboolean last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST);
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
GLboolean last_enable_primitive_restart = (g_GlVersion >= 310) ? glIsEnabled(GL_PRIMITIVE_RESTART) : GL_FALSE;
@ -442,6 +447,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
if (last_enable_blend) glEnable(GL_BLEND); else glDisable(GL_BLEND);
if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);
if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
if (last_enable_stencil_test) glEnable(GL_STENCIL_TEST); else glDisable(GL_STENCIL_TEST);
if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST);
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_PRIMITIVE_RESTART
if (g_GlVersion >= 310) { if (last_enable_primitive_restart) glEnable(GL_PRIMITIVE_RESTART); else glDisable(GL_PRIMITIVE_RESTART); }

@ -56,7 +56,7 @@ List of Platforms Backends:
imgui_impl_osx.mm ; macOS native API (not as feature complete as glfw/sdl backends)
imgui_impl_sdl.cpp ; SDL2 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org
imgui_impl_win32.cpp ; Win32 native API (Windows)
imgui_impl_glut.cpp ; GLUT/FreeGLUT (absolutely not recommended in 2020!)
imgui_impl_glut.cpp ; GLUT/FreeGLUT (this is prehistoric software and absolutely not recommended today!)
List of Renderer Backends:

@ -159,6 +159,7 @@ Other Changes:
- InputText: Fixed updating cursor/selection position when a callback altered the buffer in a way
where the byte count is unchanged but the decoded character count changes. (#3587) [@gqw]
- InputText: Fixed swiching from single to multi-line while preserving same ID.
- Fixed using IsItemEdited() after Combo() not matching the return value from Combo(). (#2034)
- Nav: Fixed IsItemFocused() from returning false when Nav highlight is hidden because mouse has moved.
It's essentially been always the case but it doesn't make much sense. Instead we will aim at exposing
feedback and control of keyboard/gamepad navigation highlight and mouse hover disable flag. (#787, #2048)
@ -180,10 +181,16 @@ Other Changes:
- Misc: Made EndFrame() assertion for key modifiers being unchanged during the frame (added in 1.76) more
lenient, allowing full mid-frame releases. This is to accommodate the use of mid-frame modal native
windows calls, which leads backends such as GLFW to send key clearing events on focus loss. (#3575)
- Style: Changed default style.WindowRounding value to 0.0f (matches default for multi-viewports).
- Style: Reduced the size of the resizing grip, made alpha less prominent.
- Style: Classic: Increase the default alpha value of WindowBg to be closer to other styles.
- Demo: Clarify usage of right-aligned items in Demo>Layout>Widgets Width.
- Backends: OpenGL3: Use glGetString(GL_VERSION) query instead of glGetIntegerv(GL_MAJOR_VERSION, ...)
when the later returns zero (e.g. Desktop GL 2.x). (#3530) [@xndcn]
- Backends: OpenGL2: Backup and restore GL_SHADE_MODEL and disable GL_NORMAL_ARRAY state to increase
compatibility with legacy code. (#3671)
- Backends: OpenGL3: Backup and restore GL_PRIMITIVE_RESTART state. (#3544) [@Xipiryon]
- Backends: OpenGL2, OpenGL3: Backup and restore GL_STENCIL_TEST enable state. (#3668)
- Backends: Vulkan: Added support for specifying which subpass to reference during VkPipeline creation. (@3579) [@bdero]
- Backends: Win32: Fix setting of io.DisplaySize to invalid/uninitialized data after hwnd has been closed.
- Backends: OSX: Fix keypad-enter key not working on MacOS. (#3554) [@rokups, @lfnoise]

@ -198,9 +198,9 @@ This is quite long and tedious, because: DirectX12.
**Building**
Unfortunately in 2020 it is still tedious to create and maintain portable build files using external
Unfortunately nowadays it is still tedious to create and maintain portable build files using external
libraries (the kind we're using here to create a window and render 3D triangles) without relying on
third party software. For most examples here we choose to provide:
third party software and build systems. For most examples here we choose to provide:
- Makefiles for Linux/OSX
- Batch files for Visual Studio 2008+
- A .sln project file for Visual Studio 2012+

@ -23,7 +23,7 @@ or view this file with any Markdown viewer.
| [I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around..](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-clipping-or-disappearing-when-i-move-windows-around) |
| [I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries..](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-displaying-outside-their-expected-windows-boundaries) |
| **Q&A: Usage** |
| **[Why is my widget not reacting when I click on it?<br>How can I have multiple widgets with the same label?<br>Why are multiple widgets reacting when I interact with one?](#q-why-is-my-widget-not-reacting-when-i-click-on-it)** |
| **[Why is my widget not reacting when I click on it?<br>How can I have widgets with an empty label?<br>How can I have multiple widgets with the same label?](#q-why-is-my-widget-not-reacting-when-i-click-on-it)** |
| [How can I display an image? What is ImTextureID, how does it work?](#q-how-can-i-display-an-image-what-is-imtextureid-how-does-it-work)|
| [How can I use my own math types instead of ImVec2/ImVec4?](#q-how-can-i-use-my-own-math-types-instead-of-imvec2imvec4) |
| [How can I interact with standard C++ types (such as std::string and std::vector)?](#q-how-can-i-interact-with-standard-c-types-such-as-stdstring-and-stdvector) |

@ -120,7 +120,7 @@ Officially maintained backends/bindings (in repository):
- Frameworks: Emscripten, Allegro5, Marmalade.
[Third-party backends/bindings](https://github.com/ocornut/imgui/wiki/Bindings) wiki page:
- Languages: C, C# and: Beef, ChaiScript, Crystal, D, Go, Haskell, Haxe/hxcpp, Java, JavaScript, Julia, Kotlin, Lua, Odin, Pascal, PureBasic, Python, Ruby, Rust, Swift...
- Languages: C, C# and: Beef, ChaiScript, Crystal, D, Go, Haskell, Haxe/hxcpp, Java, JavaScript, Julia, Kotlin, Lobster, Lua, Odin, Pascal, PureBasic, Python, Ruby, Rust, Swift...
- Frameworks: AGS/Adventure Game Studio, Amethyst, bsf, Cinder, Cocos2d-x, Diligent Engine, Flexium, GML/Game Maker Studio2, Godot, GTK3+OpenGL3, Irrlicht Engine, LÖVE+LUA, Magnum, NanoRT, nCine, Nim Game Lib, Ogre, openFrameworks, OSG/OpenSceneGraph, Orx, Photoshop, px_render, Qt/QtDirect3D, SFML, Sokol, Unity, Unreal Engine 4, vtk, Win32 GDI, WxWidgets.
- Note that C bindings ([cimgui](https://github.com/cimgui/cimgui)) are auto-generated, you can use its json/lua output to generate bindings for other languages.

@ -148,7 +148,7 @@ int main(int, char**)
glClear(GL_COLOR_BUFFER_BIT);
// If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
// you may need to backup/reset/restore current shader using the commented lines below.
// you may need to backup/reset/restore other state, e.g. for current shader using the commented lines below.
//GLint last_program;
//glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
//glUseProgram(0);

@ -2,8 +2,8 @@
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
// Read online: https://github.com/ocornut/imgui/tree/master/docs
// !!! GLUT/FreeGLUT IS OBSOLETE SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!!
// !!! If someone or something is teaching you GLUT in 2020, you are being abused. Please show some resistance. !!!
// !!! GLUT/FreeGLUT IS OBSOLETE PREHISTORIC SOFTWARE. Using GLUT is not recommended unless you really miss the 90's. !!!
// !!! If someone or something is teaching you GLUT today, you are being abused. Please show some resistance. !!!
// !!! Nowadays, prefer using GLFW or SDL instead!
#include "imgui.h"

@ -968,7 +968,7 @@ ImGuiStyle::ImGuiStyle()
{
Alpha = 1.0f; // Global alpha applies to everything in ImGui
WindowPadding = ImVec2(8,8); // Padding within a window
WindowRounding = 7.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.
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.
WindowMinSize = ImVec2(32,32); // Minimum window size
WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text
@ -2323,7 +2323,7 @@ bool ImGuiListClipper::Step()
{
// While we are in frozen row state, keep displaying items one by one, unclipped
// FIXME: Could be stored as a table-agnostic state.
if (table != NULL && !table->IsUnfrozen)
if (table != NULL && !table->IsUnfrozenRows)
{
DisplayStart = ItemsFrozen;
DisplayEnd = ItemsFrozen + 1;
@ -3069,6 +3069,7 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
// Clear declaration of inputs claimed by the widget
// (Please note that this is WIP and not all keys/inputs are thoroughly declared by all widgets yet)
g.ActiveIdUsingMouseWheel = false;
g.ActiveIdUsingNavDirMask = 0x00;
g.ActiveIdUsingNavInputMask = 0x00;
g.ActiveIdUsingKeyInputMask = 0x00;
@ -3084,6 +3085,7 @@ void ImGui::SetHoveredID(ImGuiID id)
ImGuiContext& g = *GImGui;
g.HoveredId = id;
g.HoveredIdAllowOverlap = false;
g.HoveredIdUsingMouseWheel = false;
if (id != 0 && g.HoveredIdPreviousFrame != id)
g.HoveredIdTimer = g.HoveredIdNotActiveTimer = 0.0f;
}
@ -3764,6 +3766,9 @@ void ImGui::UpdateMouseWheel()
if (g.IO.MouseWheel == 0.0f && g.IO.MouseWheelH == 0.0f)
return;
if ((g.ActiveId != 0 && g.ActiveIdUsingMouseWheel) || (g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrameUsingMouseWheel))
return;
ImGuiWindow* window = g.WheelingWindow ? g.WheelingWindow : g.HoveredWindow;
if (!window || window->Collapsed)
return;
@ -4003,8 +4008,10 @@ void ImGui::NewFrame()
if (g.HoveredId && g.ActiveId != g.HoveredId)
g.HoveredIdNotActiveTimer += g.IO.DeltaTime;
g.HoveredIdPreviousFrame = g.HoveredId;
g.HoveredIdPreviousFrameUsingMouseWheel = g.HoveredIdUsingMouseWheel;
g.HoveredId = 0;
g.HoveredIdAllowOverlap = false;
g.HoveredIdUsingMouseWheel = false;
g.HoveredIdDisabled = false;
// Update ActiveId data (clear reference to active widget if the widget isn't alive anymore)
@ -5081,12 +5088,23 @@ bool ImGui::IsItemEdited()
void ImGui::SetItemAllowOverlap()
{
ImGuiContext& g = *GImGui;
if (g.HoveredId == g.CurrentWindow->DC.LastItemId)
ImGuiID id = g.CurrentWindow->DC.LastItemId;
if (g.HoveredId == id)
g.HoveredIdAllowOverlap = true;
if (g.ActiveId == g.CurrentWindow->DC.LastItemId)
if (g.ActiveId == id)
g.ActiveIdAllowOverlap = true;
}
void ImGui::SetItemUsingMouseWheel()
{
ImGuiContext& g = *GImGui;
ImGuiID id = g.CurrentWindow->DC.LastItemId;
if (g.HoveredId == id)
g.HoveredIdUsingMouseWheel = true;
if (g.ActiveId == id)
g.ActiveIdUsingMouseWheel = true;
}
ImVec2 ImGui::GetItemRectMin()
{
ImGuiWindow* window = GetCurrentWindowRead();
@ -6402,7 +6420,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
int border_held = -1;
ImU32 resize_grip_col[4] = {};
const int resize_grip_count = g.IO.ConfigWindowsResizeFromEdges ? 2 : 1; // Allow resize from lower-left if we have the mouse cursor feedback for it.
const float resize_grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
const float resize_grip_draw_size = IM_FLOOR(ImMax(g.FontSize * 1.10f, window->WindowRounding + 1.0f + g.FontSize * 0.2f));
if (handle_borders_and_resize_grips && !window->Collapsed)
if (UpdateWindowManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0], visibility_rect))
use_current_size_for_scrollbar_x = use_current_size_for_scrollbar_y = true;

@ -60,7 +60,7 @@ Index of this file:
// Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
#define IMGUI_VERSION "1.80 WIP"
#define IMGUI_VERSION_NUM 17907
#define IMGUI_VERSION_NUM 17909
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_TABLE
#define IMGUI_HAS_VIEWPORT // Viewport WIP branch
@ -676,7 +676,7 @@ namespace ImGui
// - 1. Call BeginTable()
// - 2. Optionally call TableSetupColumn() to submit column name/flags/defaults
// - 3. Optionally call TableSetupScrollFreeze() to request scroll freezing of columns/rows
// - 4. Optionally call TableHeadersRow() to submit a header row (names will be pulled from data submitted to TableSetupColumns)
// - 4. Optionally call TableHeadersRow() to submit a header row. Names will be pulled from data provided TableSetupColumn() calls)
// - 5. Populate contents
// - In most situations you can use TableNextRow() + TableSetColumnIndex(N) to start appending into a column.
// - If you are using tables as a sort of grid, where every columns is holding the same type of contents,
@ -1079,30 +1079,34 @@ enum ImGuiTabItemFlags_
};
// Flags for ImGui::BeginTable()
// - Important! Sizing policies have particularly complex and subtle side effects, more so than you would expect.
// - Important! Sizing policies have complex and subtle side effects, more so than you would expect.
// Read comments/demos carefully + experiment with live demos to get acquainted with them.
// - The default sizing policy for columns depends on whether the ScrollX flag is set on the table:
// When ScrollX is off:
// - Table defaults to ImGuiTableFlags_ColumnsWidthStretch -> all Columns defaults to ImGuiTableColumnFlags_WidthStretch.
// - Columns sizing policy allowed: Stretch (default) or Fixed/Auto.
// - Fixed Columns will generally obtain their requested width (unless the Table cannot fit them all).
// - The DEFAULT policy depends on whether the _ScrollX flag is set on the table, and whether _AlwaysAutoResize flag is set on window.
// - ImGuiTableFlags_SizingPolicyStretch is the default if ScrollX if off.
// - ImGuiTableFlags_SizingPolicyFixed is the default if ScrollX is on, or if host window has ImGuiWindowFlags_AlwaysAutoResize.
// - When ScrollX is off:
// - Table defaults to ImGuiTableFlags_SizingPolicyStretch -> all Columns defaults to ImGuiTableColumnFlags_WidthStretch.
// - Columns sizing policy allowed: Stretch (default), Fixed/Auto.
// - Fixed Columns will generally obtain their requested width (unless the table cannot fit them all).
// - Stretch Columns will share the remaining width.
// When ScrollX is on:
// - Table defaults to ImGuiTableFlags_ColumnsWidthFixed -> all Columns defaults to ImGuiTableColumnFlags_WidthFixed.
// - Columns sizing policy allowed: Fixed/Auto mostly!
// - Mixed Fixed/Stretch columns is possible but has various side-effects on resizing behaviors.
// The typical use of mixing sizing policies is: any number of LEADING Fixed columns, followed by one or two TRAILING Stretch columns.
// (this is because the visible order of columns have subtle but necessary effects on how they react to manual resizing).
// - When ScrollX is on:
// - Table defaults to ImGuiTableFlags_SizingPolicyFixed -> all Columns defaults to ImGuiTableColumnFlags_WidthFixed or ImGuiTableColumnFlags_WidthAuto.
// - Columns sizing policy allowed: Fixed/Auto mostly.
// - Fixed Columns can be enlarged as needed. Table will show an horizontal scrollbar if needed.
// - Using Stretch columns OFTEN DOES NOT MAKE SENSE if ScrollX is on, UNLESS you have specified a value for 'inner_width' in BeginTable().
// - Mixing up columns with different sizing policy is possible BUT can be tricky and has some side-effects and restrictions.
// (their visible order and the scrolling state have subtle but necessary effects on how they can be manually resized).
// The typical use of mixing sizing policies is to have ScrollX disabled, first Fixed columns and then one or two TRAILING Stretch columns.
// If you specify a value for 'inner_width' then effectively the scrolling space is known and Stretch or mixed Fixed/Stretch columns become meaningful again.
// - Read on documentation at the top of imgui_tables.cpp for details.
enum ImGuiTableFlags_
{
// Features
ImGuiTableFlags_None = 0,
ImGuiTableFlags_Resizable = 1 << 0, // Allow resizing columns.
ImGuiTableFlags_Reorderable = 1 << 1, // Allow reordering columns in header row (need calling TableSetupColumn() + TableHeadersRow() to display headers)
ImGuiTableFlags_Hideable = 1 << 2, // Allow hiding/disabling columns in context menu.
ImGuiTableFlags_Sortable = 1 << 3, // Allow sorting on one column (sort_specs_count will always be == 1). Call TableGetSortSpecs() to obtain sort specs.
ImGuiTableFlags_Resizable = 1 << 0, // Enable resizing columns.
ImGuiTableFlags_Reorderable = 1 << 1, // Enable reordering columns in header row (need calling TableSetupColumn() + TableHeadersRow() to display headers)
ImGuiTableFlags_Hideable = 1 << 2, // Enable hiding/disabling columns in context menu.
ImGuiTableFlags_Sortable = 1 << 3, // Enable sorting. Call TableGetSortSpecs() to obtain sort specs. Also see ImGuiTableFlags_SortMulti and ImGuiTableFlags_SortTristate.
ImGuiTableFlags_NoSavedSettings = 1 << 4, // Disable persisting columns order, width and sort settings in the .ini file.
ImGuiTableFlags_ContextMenuInBody = 1 << 5, // Right-click on columns body/contents will display table context menu. By default it is available in TableHeadersRow().
// Decorations
@ -1116,11 +1120,12 @@ enum ImGuiTableFlags_
ImGuiTableFlags_BordersInner = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersInnerH, // Draw inner borders.
ImGuiTableFlags_BordersOuter = ImGuiTableFlags_BordersOuterV | ImGuiTableFlags_BordersOuterH, // Draw outer borders.
ImGuiTableFlags_Borders = ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter, // Draw all borders.
ImGuiTableFlags_NoBordersInBody = 1 << 11, // Disable vertical borders in columns Body (borders will always appears in Headers).
ImGuiTableFlags_NoBordersInBodyUntilResize = 1 << 12, // Disable vertical borders in columns Body until hovered for resize (borders will always appears in Headers).
// Sizing
ImGuiTableFlags_ColumnsWidthStretch = 1 << 13, // Default if ScrollX is off. Columns will default to use _WidthStretch. Read description above for more details.
ImGuiTableFlags_ColumnsWidthFixed = 1 << 14, // Default if ScrollX is on. Columns will default to use _WidthFixed or _WidthAutoResize policy (if Resizable is off). Read description above for more details.
ImGuiTableFlags_NoBordersInBody = 1 << 11, // [ALPHA] Disable vertical borders in columns Body (borders will always appears in Headers). -> May move to style
ImGuiTableFlags_NoBordersInBodyUntilResize = 1 << 12, // [ALPHA] Disable vertical borders in columns Body until hovered for resize (borders will always appears in Headers). -> May move to style
// Sizing Policy
ImGuiTableFlags_SizingPolicyFixed = 1 << 13, // [Default if ScrollX is on] Columns default to _WidthFixed (if resizable) or _WidthAuto (if not resizable), matching contents width.
ImGuiTableFlags_SizingPolicyStretch = 1 << 14, // [Default if ScrollX is off] Columns default to _WidthStretch with same weights.
// Sizing Extra Options
ImGuiTableFlags_SameWidths = 1 << 15, // Make all columns the same widths which is useful with Fixed columns policy (but granted by default with Stretch policy + no resize). Implicitly enable ImGuiTableFlags_NoKeepColumnsVisible and disable ImGuiTableFlags_Resizable.
ImGuiTableFlags_NoHostExtendY = 1 << 16, // Disable extending table past the limit set by outer_size.y. Only meaningful when neither ScrollX nor ScrollY are set (data below the limit will be clipped and not visible)
ImGuiTableFlags_NoKeepColumnsVisible = 1 << 17, // Disable keeping column always minimally visible when ScrollX is off and table gets too small. Not recommended if columns are resizable.
@ -1137,6 +1142,11 @@ enum ImGuiTableFlags_
// Sorting
ImGuiTableFlags_SortMulti = 1 << 25, // Hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1).
ImGuiTableFlags_SortTristate = 1 << 26 // Allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0).
// Obsolete names (will be removed soon)
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
, ImGuiTableFlags_ColumnsWidthFixed = ImGuiTableFlags_SizingPolicyFixed, ImGuiTableFlags_ColumnsWidthStretch = ImGuiTableFlags_SizingPolicyStretch
#endif
};
// Flags for ImGui::TableSetupColumn()
@ -1146,9 +1156,9 @@ enum ImGuiTableColumnFlags_
ImGuiTableColumnFlags_None = 0,
ImGuiTableColumnFlags_DefaultHide = 1 << 0, // Default as a hidden/disabled column.
ImGuiTableColumnFlags_DefaultSort = 1 << 1, // Default as a sorting column.
ImGuiTableColumnFlags_WidthStretch = 1 << 2, // Column will stretch. Preferable with horizontal scrolling disabled (default if table sizing policy is _ColumnsWidthStretch).
ImGuiTableColumnFlags_WidthFixed = 1 << 3, // Column will not stretch. Preferable with horizontal scrolling enabled (default if table sizing policy is _ColumnsWidthFixed and table is resizable).
ImGuiTableColumnFlags_WidthAutoResize = 1 << 4, // Column will not stretch and keep resizing based on submitted contents (default if table sizing policy is _ColumnsWidthFixed and table is not resizable).
ImGuiTableColumnFlags_WidthStretch = 1 << 2, // Column will stretch. Preferable with horizontal scrolling disabled (default if table sizing policy is _SizingPolicyStretch).
ImGuiTableColumnFlags_WidthFixed = 1 << 3, // Column will not stretch. Preferable with horizontal scrolling enabled (default if table sizing policy is _SizingPolicyFixed and table is resizable).
ImGuiTableColumnFlags_WidthAuto = 1 << 4, // Column will not stretch and keep resizing based on submitted contents (default if table sizing policy is _SizingPolicyFixed and table is not resizable). Generally compatible with using right-most fitting widgets (e.g. SetNextItemWidth(-FLT_MIN))
ImGuiTableColumnFlags_NoResize = 1 << 5, // Disable manual resizing.
ImGuiTableColumnFlags_NoReorder = 1 << 6, // Disable manual reordering this column, this will also prevent other columns from crossing over this column.
ImGuiTableColumnFlags_NoHide = 1 << 7, // Disable ability to hide/disable this column.
@ -1169,7 +1179,7 @@ enum ImGuiTableColumnFlags_
ImGuiTableColumnFlags_IsHovered = 1 << 23, // Status: is hovered by mouse
// [Internal] Combinations and masks
ImGuiTableColumnFlags_WidthMask_ = ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAutoResize,
ImGuiTableColumnFlags_WidthMask_ = ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAuto,
ImGuiTableColumnFlags_IndentMask_ = ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_IndentDisable,
ImGuiTableColumnFlags_StatusMask_ = ImGuiTableColumnFlags_IsEnabled | ImGuiTableColumnFlags_IsVisible | ImGuiTableColumnFlags_IsSorted | ImGuiTableColumnFlags_IsHovered,
ImGuiTableColumnFlags_NoDirectResize_ = 1 << 30 // [Internal] Disable user resizing this column directly (it may however we resized indirectly from its left edge)
@ -2427,6 +2437,7 @@ struct ImDrawList
ImVector<ImVec2> _Path; // [Internal] current path building
ImDrawCmdHeader _CmdHeader; // [Internal] template of active commands. Fields should match those of CmdBuffer.back().
ImDrawListSplitter _Splitter; // [Internal] for channels api (note: prefer using your own persistent instance of ImDrawListSplitter!)
float _FringeScale; // [Internal] anti-alias fringe is scaled by this value, this helps to keep things sharp while zooming at vertex buffer content
// If you want to create ImDrawList instances, pass them ImGui::GetDrawListSharedData() or create and use your own ImDrawListSharedData (so you can use ImDrawList without ImGui)
ImDrawList(const ImDrawListSharedData* shared_data) { memset(this, 0, sizeof(*this)); _Data = shared_data; }

@ -2032,18 +2032,18 @@ static void ShowDemoWindowWidgets()
ImGui::TreePop();
}
if (ImGui::TreeNode("Querying Status (Active/Focused/Hovered etc.)"))
if (ImGui::TreeNode("Querying Status (Edited/Active/Focused/Hovered etc.)"))
{
// Select an item type
const char* item_names[] =
{
"Text", "Button", "Button (w/ repeat)", "Checkbox", "SliderFloat", "InputText", "InputFloat",
"InputFloat3", "ColorEdit4", "MenuItem", "TreeNode", "TreeNode (w/ double-click)", "ListBox"
"InputFloat3", "ColorEdit4", "MenuItem", "TreeNode", "TreeNode (w/ double-click)", "Combo", "ListBox"
};
static int item_type = 1;
ImGui::Combo("Item Type", &item_type, item_names, IM_ARRAYSIZE(item_names), IM_ARRAYSIZE(item_names));
ImGui::SameLine();
HelpMarker("Testing how various types of items are interacting with the IsItemXXX functions.");
HelpMarker("Testing how various types of items are interacting with the IsItemXXX functions. Note that the bool return value of most ImGui function is generally equivalent to calling ImGui::IsItemHovered().");
// Submit selected item item so we can query their status in the code following it.
bool ret = false;
@ -2062,7 +2062,8 @@ static void ShowDemoWindowWidgets()
if (item_type == 9) { ret = ImGui::MenuItem("ITEM: MenuItem"); } // Testing menu item (they use ImGuiButtonFlags_PressedOnRelease button policy)
if (item_type == 10){ ret = ImGui::TreeNode("ITEM: TreeNode"); if (ret) ImGui::TreePop(); } // Testing tree node
if (item_type == 11){ ret = ImGui::TreeNodeEx("ITEM: TreeNode w/ ImGuiTreeNodeFlags_OpenOnDoubleClick", ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_NoTreePushOnOpen); } // Testing tree node with ImGuiButtonFlags_PressedOnDoubleClick button policy.
if (item_type == 12){ const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::ListBox("ITEM: ListBox", &current, items, IM_ARRAYSIZE(items), IM_ARRAYSIZE(items)); }
if (item_type == 12){ const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::Combo("ITEM: Combo", &current, items, IM_ARRAYSIZE(items)); }
if (item_type == 13){ const char* items[] = { "Apple", "Banana", "Cherry", "Kiwi" }; static int current = 1; ret = ImGui::ListBox("ITEM: ListBox", &current, items, IM_ARRAYSIZE(items), IM_ARRAYSIZE(items)); }
// Display the values of IsItemHovered() and other common item state functions.
// Note that the ImGuiHoveredFlags_XXX flags can be combined.
@ -3419,8 +3420,8 @@ static void EditTableColumnsFlags(ImGuiTableColumnFlags* p_flags)
*p_flags &= ~(ImGuiTableColumnFlags_WidthMask_ ^ ImGuiTableColumnFlags_WidthStretch);
if (ImGui::CheckboxFlags("_WidthFixed", p_flags, ImGuiTableColumnFlags_WidthFixed))
*p_flags &= ~(ImGuiTableColumnFlags_WidthMask_ ^ ImGuiTableColumnFlags_WidthFixed);
if (ImGui::CheckboxFlags("_WidthAutoResize", p_flags, ImGuiTableColumnFlags_WidthAutoResize))
*p_flags &= ~(ImGuiTableColumnFlags_WidthMask_ ^ ImGuiTableColumnFlags_WidthAutoResize);
if (ImGui::CheckboxFlags("_WidthAuto", p_flags, ImGuiTableColumnFlags_WidthAuto))
*p_flags &= ~(ImGuiTableColumnFlags_WidthMask_ ^ ImGuiTableColumnFlags_WidthAuto);
ImGui::CheckboxFlags("_NoResize", p_flags, ImGuiTableColumnFlags_NoResize);
ImGui::CheckboxFlags("_NoReorder", p_flags, ImGuiTableColumnFlags_NoReorder);
ImGui::CheckboxFlags("_NoHide", p_flags, ImGuiTableColumnFlags_NoHide);
@ -3647,17 +3648,19 @@ static void ShowDemoWindowTables()
ImGui::SetNextItemOpen(open_action != 0);
if (ImGui::TreeNode("Resizable, fixed"))
{
// Here we use ImGuiTableFlags_ColumnsWidthFixed (even though _ScrollX is not set)
// Here we use ImGuiTableFlags_SizingPolicyFixed (even though _ScrollX is not set)
// So columns will adopt the "Fixed" policy and will maintain a fixed width regardless of the whole available width (unless table is small)
// If there is not enough available width to fit all columns, they will however be resized down.
// FIXME-TABLE: Providing a stretch-on-init would make sense especially for tables which don't have saved settings
HelpMarker(
"Using _Resizable + _ColumnsWidthFixed flags.\n"
"Using _Resizable + _SizingPolicyFixed flags.\n"
"Fixed-width columns generally makes more sense if you want to use horizontal scrolling.\n\n"
"Double-click a column border to auto-fit the column to its contents.");
static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_ColumnsWidthFixed | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ContextMenuInBody;
static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingPolicyFixed | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ContextMenuInBody;
static bool use_all_width = true;
ImGui::Checkbox("Use all width", &use_all_width);
if (ImGui::RadioButton("fit", use_all_width == false)) { use_all_width = false; }
ImGui::SameLine();
if (ImGui::RadioButton("right-most edge", use_all_width == true)) { use_all_width = true; }
if (ImGui::BeginTable("##table1", 3, flags, ImVec2(use_all_width ? -FLT_MIN : 0.0f, 0.0f)))
{
@ -3680,7 +3683,7 @@ static void ShowDemoWindowTables()
if (ImGui::TreeNode("Resizable, mixed"))
{
HelpMarker("Using columns flag to alter resizing policy on a per-column basis.");
static ImGuiTableFlags flags = ImGuiTableFlags_ColumnsWidthFixed | ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable;
static ImGuiTableFlags flags = ImGuiTableFlags_SizingPolicyFixed | ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable;
if (ImGui::BeginTable("##table1", 3, flags))
{
@ -3757,7 +3760,7 @@ static void ShowDemoWindowTables()
}
// Use outer_size.x == 0.0f instead of default to make the table as tight as possible (only valid when no scrolling and no stretch column)
if (ImGui::BeginTable("##table2", 3, flags | ImGuiTableFlags_ColumnsWidthFixed, ImVec2(0.0f, 0.0f)))
if (ImGui::BeginTable("##table2", 3, flags | ImGuiTableFlags_SizingPolicyFixed, ImVec2(0.0f, 0.0f)))
{
ImGui::TableSetupColumn("One");
ImGui::TableSetupColumn("Two");
@ -3897,7 +3900,7 @@ static void ShowDemoWindowTables()
if (ImGui::BeginTable("##table1", 4, flags))
{
// We could also set ImGuiTableFlags_ColumnsWidthFixed on the table and all columns will default to ImGuiTableColumnFlags_WidthFixed.
// We could also set ImGuiTableFlags_SizingPolicyFixed on the table and all columns will default to ImGuiTableColumnFlags_WidthFixed.
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, 100.0f);
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 15.0f);
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 30.0f);
@ -3965,7 +3968,7 @@ static void ShowDemoWindowTables()
if (ImGui::TreeNode("Horizontal scrolling"))
{
HelpMarker(
"When ScrollX is enabled, the default sizing policy becomes ImGuiTableFlags_ColumnsWidthFixed,"
"When ScrollX is enabled, the default sizing policy becomes ImGuiTableFlags_SizingPolicyFixed,"
"as automatically stretching columns doesn't make much sense with horizontal scrolling.\n\n"
"Also note that as of the current version, you will almost always want to enable ScrollY along with ScrollX,"
"because the container window won't automatically extend vertically to fix contents (this may be improved in future versions).");
@ -3974,6 +3977,7 @@ static void ShowDemoWindowTables()
static int freeze_rows = 1;
PushStyleCompact();
ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable);
ImGui::CheckboxFlags("ImGuiTableFlags_ScrollX", &flags, ImGuiTableFlags_ScrollX);
ImGui::CheckboxFlags("ImGuiTableFlags_ScrollY", &flags, ImGuiTableFlags_ScrollY);
ImGui::SetNextItemWidth(ImGui::GetFrameHeight());
@ -4055,7 +4059,7 @@ static void ShowDemoWindowTables()
// We use a scrolling table to be able to showcase the difference between the _IsEnabled and _IsVisible flags above, otherwise in
// a non-scrolling table columns are always visible (unless using ImGuiTableFlags_NoKeepColumnsVisible + resizing the parent window down)
const ImGuiTableFlags flags
= ImGuiTableFlags_ColumnsWidthFixed | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY
= ImGuiTableFlags_SizingPolicyFixed | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY
| ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV
| ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Sortable;
ImVec2 size = ImVec2(-FLT_MIN, TEXT_BASE_HEIGHT * 9);
@ -4086,11 +4090,11 @@ static void ShowDemoWindowTables()
if (open_action != -1)
ImGui::SetNextItemOpen(open_action != 0);
if (ImGui::TreeNode("Recursive"))
if (ImGui::TreeNode("Nested"))
{
HelpMarker("This demonstrate embedding a table into another table cell.");
if (ImGui::BeginTable("recurse1", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
if (ImGui::BeginTable("nested1", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
{
ImGui::TableSetupColumn("A0");
ImGui::TableSetupColumn("A1");
@ -4100,7 +4104,7 @@ static void ShowDemoWindowTables()
ImGui::Text("A0 Cell 0");
{
float rows_height = TEXT_BASE_HEIGHT * 2;
if (ImGui::BeginTable("recurse2", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
if (ImGui::BeginTable("nested2", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
{
ImGui::TableSetupColumn("B0");
ImGui::TableSetupColumn("B1");
@ -4139,26 +4143,26 @@ static void ShowDemoWindowTables()
static int column_count = 3;
PushStyleCompact();
ImGui::SetNextItemWidth(TEXT_BASE_WIDTH * 22);
ImGui::PushItemWidth(TEXT_BASE_WIDTH * 30);
ImGui::Combo("Contents", &contents_type, "Short Text\0Long Text\0Button\0Fill Button\0InputText\0");
if (contents_type == CT_FillButton)
{
ImGui::SameLine();
HelpMarker("Be mindful that using right-alignment (e.g. size.x = -FLT_MIN) creates a feedback loop where contents width can feed into auto-column width can feed into contents width.");
}
ImGui::SetNextItemWidth(TEXT_BASE_WIDTH * 22);
ImGui::DragInt("Columns", &column_count, 0.1f, 1, 64, "%d", ImGuiSliderFlags_AlwaysClamp);
ImGui::PopItemWidth();
ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerH", &flags, ImGuiTableFlags_BordersInnerH);
ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterH", &flags, ImGuiTableFlags_BordersOuterH);
ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerV", &flags, ImGuiTableFlags_BordersInnerV);
ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterV", &flags, ImGuiTableFlags_BordersOuterV);
ImGui::CheckboxFlags("ImGuiTableFlags_ScrollX", &flags, ImGuiTableFlags_ScrollX);
ImGui::CheckboxFlags("ImGuiTableFlags_ScrollY", &flags, ImGuiTableFlags_ScrollY);
if (ImGui::CheckboxFlags("ImGuiTableFlags_ColumnsWidthStretch", &flags, ImGuiTableFlags_ColumnsWidthStretch))
flags &= ~ImGuiTableFlags_ColumnsWidthFixed; // Can't specify both sizing polices so we clear the other
if (ImGui::CheckboxFlags("ImGuiTableFlags_SizingPolicyStretch", &flags, ImGuiTableFlags_SizingPolicyStretch))
flags &= ~ImGuiTableFlags_SizingPolicyFixed; // Can't specify both sizing polices so we clear the other
ImGui::SameLine(); HelpMarker("Default if _ScrollX if disabled. Makes columns use _WidthStretch policy by default.");
if (ImGui::CheckboxFlags("ImGuiTableFlags_ColumnsWidthFixed", &flags, ImGuiTableFlags_ColumnsWidthFixed))
flags &= ~ImGuiTableFlags_ColumnsWidthStretch; // Can't specify both sizing polices so we clear the other
if (ImGui::CheckboxFlags("ImGuiTableFlags_SizingPolicyFixed", &flags, ImGuiTableFlags_SizingPolicyFixed))
flags &= ~ImGuiTableFlags_SizingPolicyStretch; // Can't specify both sizing polices so we clear the other
ImGui::SameLine(); HelpMarker("Default if _ScrollX if enabled. Makes columns use _WidthFixed by default, or _WidthFixedResize if _Resizable is not set.");
ImGui::CheckboxFlags("ImGuiTableFlags_PreciseWidths", &flags, ImGuiTableFlags_PreciseWidths);
ImGui::SameLine(); HelpMarker("Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth.");
@ -4236,20 +4240,21 @@ static void ShowDemoWindowTables()
"Showcase using Stretch columns + ScrollX together: "
"this is rather unusual and only makes sense when specifying an 'inner_width' for the table!\n"
"Without an explicit value, inner_width is == outer_size.x and therefore using Stretch columns + ScrollX together doesn't make sense.");
static ImGuiTableFlags flags3 = ImGuiTableFlags_ColumnsWidthStretch | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_RowBg;
static ImGuiTableFlags flags3 = ImGuiTableFlags_SizingPolicyStretch | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_RowBg;
static float inner_width = 1000.0f;
PushStyleCompact();
ImGui::PushID("flags3");
ImGui::PushItemWidth(TEXT_BASE_WIDTH * 30);
ImGui::CheckboxFlags("ImGuiTableFlags_ScrollX", &flags3, ImGuiTableFlags_ScrollX);
if (ImGui::CheckboxFlags("ImGuiTableFlags_ColumnsWidthStretch", &flags3, ImGuiTableFlags_ColumnsWidthStretch))
flags3 &= ~ImGuiTableFlags_ColumnsWidthFixed; // Can't specify both sizing polices so we clear the other
if (ImGui::CheckboxFlags("ImGuiTableFlags_ColumnsWidthFixed", &flags3, ImGuiTableFlags_ColumnsWidthFixed))
flags3 &= ~ImGuiTableFlags_ColumnsWidthStretch; // Can't specify both sizing polices so we clear the other
ImGui::SetNextItemWidth(TEXT_BASE_WIDTH * 10.0f);
if (ImGui::CheckboxFlags("ImGuiTableFlags_SizingPolicyStretch", &flags3, ImGuiTableFlags_SizingPolicyStretch))
flags3 &= ~ImGuiTableFlags_SizingPolicyFixed; // Can't specify both sizing polices so we clear the other
if (ImGui::CheckboxFlags("ImGuiTableFlags_SizingPolicyFixed", &flags3, ImGuiTableFlags_SizingPolicyFixed))
flags3 &= ~ImGuiTableFlags_SizingPolicyStretch; // Can't specify both sizing polices so we clear the other
ImGui::DragFloat("inner_width", &inner_width, 1.0f, 0.0f, FLT_MAX, "%.1f");
ImGui::PopItemWidth();
ImGui::PopID();
PopStyleCompact();
if (ImGui::BeginTable("##table3", 7, flags3 | ImGuiTableFlags_ColumnsWidthStretch | ImGuiTableFlags_ContextMenuInBody, outer_size, inner_width))
if (ImGui::BeginTable("##table3", 7, flags3 | ImGuiTableFlags_SizingPolicyStretch | ImGuiTableFlags_ContextMenuInBody, outer_size, inner_width))
{
for (int cell = 0; cell < 20 * 7; cell++)
{
@ -4289,7 +4294,7 @@ static void ShowDemoWindowTables()
// The default value of outer_size.x is -FLT_MIN which right-align tables.
// Using outer_size.x == 0.0f on a table with no scrolling and no stretch column we can make them tighter.
ImGui::Text("Using auto/all width, using NoHostExtendY:");
static ImGuiTableFlags flags = ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_ContextMenuInBody | ImGuiTableFlags_RowBg | ImGuiTableFlags_ColumnsWidthFixed;
static ImGuiTableFlags flags = ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_ContextMenuInBody | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingPolicyFixed;
static bool use_all_width = false;
ImGui::Checkbox("Use all width", &use_all_width);
ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendY", &flags, ImGuiTableFlags_NoHostExtendY);
@ -4561,7 +4566,7 @@ static void ShowDemoWindowTables()
// [2.2] Right-click on the ".." to open a custom popup
// [2.3] Right-click in columns to open another custom popup
HelpMarker("Demonstrate mixing table context menu (over header), item context button (over button) and custom per-colum context menu (over column body).");
ImGuiTableFlags flags2 = ImGuiTableFlags_Resizable | ImGuiTableFlags_ColumnsWidthFixed | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders;
ImGuiTableFlags flags2 = ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingPolicyFixed | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders;
if (ImGui::BeginTable("##table2", COLUMNS_COUNT, flags2))
{
ImGui::TableSetupColumn("One");
@ -4635,7 +4640,7 @@ static void ShowDemoWindowTables()
char buf[32];
sprintf(buf, "Synced Table %d", n);
bool open = ImGui::CollapsingHeader(buf, ImGuiTreeNodeFlags_DefaultOpen);
if (open && ImGui::BeginTable("Table", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_ColumnsWidthFixed | ImGuiTableFlags_NoSavedSettings))
if (open && ImGui::BeginTable("Table", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_SizingPolicyFixed | ImGuiTableFlags_NoSavedSettings))
{
ImGui::TableSetupColumn("One");
ImGui::TableSetupColumn("Two");
@ -4751,7 +4756,7 @@ static void ShowDemoWindowTables()
| ImGuiTableFlags_Sortable | ImGuiTableFlags_SortMulti
| ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders | ImGuiTableFlags_NoBordersInBody
| ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY
| ImGuiTableFlags_ColumnsWidthFixed;
| ImGuiTableFlags_SizingPolicyFixed;
enum ContentsType { CT_Text, CT_Button, CT_SmallButton, CT_FillButton, CT_Selectable, CT_SelectableSpanRow };
static int contents_type = CT_SelectableSpanRow;
@ -4800,11 +4805,11 @@ static void ShowDemoWindowTables()
if (ImGui::TreeNodeEx("Sizing:", ImGuiTreeNodeFlags_DefaultOpen))
{
if (ImGui::CheckboxFlags("ImGuiTableFlags_ColumnsWidthStretch", &flags, ImGuiTableFlags_ColumnsWidthStretch))
flags &= ~ImGuiTableFlags_ColumnsWidthFixed; // Can't specify both sizing polices so we clear the other
if (ImGui::CheckboxFlags("ImGuiTableFlags_SizingPolicyStretch", &flags, ImGuiTableFlags_SizingPolicyStretch))
flags &= ~ImGuiTableFlags_SizingPolicyFixed; // Can't specify both sizing polices so we clear the other
ImGui::SameLine(); HelpMarker("[Default if ScrollX is off]\nFit all columns within available width (or specified inner_width). Fixed and Stretch columns allowed.");
if (ImGui::CheckboxFlags("ImGuiTableFlags_ColumnsWidthFixed", &flags, ImGuiTableFlags_ColumnsWidthFixed))
flags &= ~ImGuiTableFlags_ColumnsWidthStretch; // Can't specify both sizing polices so we clear the other
if (ImGui::CheckboxFlags("ImGuiTableFlags_SizingPolicyFixed", &flags, ImGuiTableFlags_SizingPolicyFixed))
flags &= ~ImGuiTableFlags_SizingPolicyStretch; // Can't specify both sizing polices so we clear the other
ImGui::SameLine(); HelpMarker("[Default if ScrollX is on]\nEnlarge as needed: enable scrollbar if ScrollX is enabled, otherwise extend parent window's contents rectangle. Only Fixed columns allowed. Stretched columns will calculate their width assuming no scrolling.");
ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendY", &flags, ImGuiTableFlags_NoHostExtendY);
ImGui::CheckboxFlags("ImGuiTableFlags_NoKeepColumnsVisible", &flags, ImGuiTableFlags_NoKeepColumnsVisible);
@ -4851,6 +4856,7 @@ static void ShowDemoWindowTables()
{
ImGui::Checkbox("show_headers", &show_headers);
ImGui::Checkbox("show_wrapped_text", &show_wrapped_text);
ImGui::DragFloat2("##OuterSize", &outer_size_value.x);
ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x);
ImGui::Checkbox("outer_size", &outer_size_enabled);
@ -4862,12 +4868,14 @@ static void ShowDemoWindowTables()
"- OuterSize.y then becomes the minimum size for the table, which will extend vertically if there are more rows (unless NoHostExtendY is set).");
// From a user point of view we will tend to use 'inner_width' differently depending on whether our table is embedding scrolling.
// To facilitate experimentation we expose two values and will select the right one depending on active flags.
// To facilitate toying with this demo we will actually pass 0.0f to the BeginTable() when ScrollX is disabled.
ImGui::DragFloat("inner_width (when ScrollX active)", &inner_width_with_scroll, 1.0f, 0.0f, FLT_MAX);
ImGui::DragFloat("row_min_height", &row_min_height, 1.0f, 0.0f, FLT_MAX);
ImGui::SameLine(); HelpMarker("Specify height of the Selectable item.");
ImGui::DragInt("items_count", &items_count, 0.1f, 0, 9999);
ImGui::Combo("contents_type (first column)", &contents_type, contents_type_names, IM_ARRAYSIZE(contents_type_names));
ImGui::Combo("items_type (first column)", &contents_type, contents_type_names, IM_ARRAYSIZE(contents_type_names));
//filter.Draw("filter");
ImGui::TreePop();
}
@ -4909,8 +4917,8 @@ static void ShowDemoWindowTables()
ImGui::TableSetupColumn("ID", ImGuiTableColumnFlags_DefaultSort | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoHide, -1.0f, MyItemColumnID_ID);
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, -1.0f, MyItemColumnID_Name);
ImGui::TableSetupColumn("Action", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, -1.0f, MyItemColumnID_Action);
ImGui::TableSetupColumn("Quantity", ImGuiTableColumnFlags_PreferSortDescending, 1.0f, MyItemColumnID_Quantity);
ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthStretch, 1.0f, MyItemColumnID_Description);
ImGui::TableSetupColumn("Quantity", ImGuiTableColumnFlags_PreferSortDescending, -1.0f, MyItemColumnID_Quantity);
ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthStretch, -1.0f, MyItemColumnID_Description);
ImGui::TableSetupColumn("Hidden", ImGuiTableColumnFlags_DefaultHide | ImGuiTableColumnFlags_NoSort);
ImGui::TableSetupScrollFreeze(freeze_cols, freeze_rows);
@ -6119,7 +6127,7 @@ struct ExampleAppConsole
// Portable helpers
static int Stricmp(const char* s1, const char* s2) { int d; while ((d = toupper(*s2) - toupper(*s1)) == 0 && *s1) { s1++; s2++; } return d; }
static int Strnicmp(const char* s1, const char* s2, int n) { int d = 0; while (n > 0 && (d = toupper(*s2) - toupper(*s1)) == 0 && *s1) { s1++; s2++; n--; } return d; }
static char* Strdup(const char* s) { size_t len = strlen(s) + 1; void* buf = malloc(len); IM_ASSERT(buf); return (char*)memcpy(buf, (const void*)s, len); }
static char* Strdup(const char* s) { IM_ASSERT(s); size_t len = strlen(s) + 1; void* buf = malloc(len); IM_ASSERT(buf); return (char*)memcpy(buf, (const void*)s, len); }
static void Strtrim(char* s) { char* str_end = s + strlen(s); while (str_end > s && str_end[-1] == ' ') str_end--; *str_end = 0; }
void ClearLog()

@ -210,7 +210,7 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst)
colors[ImGuiCol_Separator] = colors[ImGuiCol_Border];
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f);
colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.25f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.20f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f);
@ -244,7 +244,7 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f);
colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f);
colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.85f);
colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.11f, 0.14f, 0.92f);
colors[ImGuiCol_Border] = ImVec4(0.50f, 0.50f, 0.50f, 0.50f);
@ -272,7 +272,7 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 0.60f);
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f);
colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.16f);
colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.10f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.78f, 0.82f, 1.00f, 0.60f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.78f, 0.82f, 1.00f, 0.90f);
colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f);
@ -335,7 +335,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
colors[ImGuiCol_Separator] = ImVec4(0.39f, 0.39f, 0.39f, 0.62f);
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.14f, 0.44f, 0.80f, 0.78f);
colors[ImGuiCol_SeparatorActive] = ImVec4(0.14f, 0.44f, 0.80f, 1.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.80f, 0.80f, 0.80f, 0.56f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.35f, 0.35f, 0.35f, 0.17f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.90f);
@ -411,6 +411,7 @@ void ImDrawList::_ResetForNewFrame()
_Path.resize(0);
_Splitter.Clear();
CmdBuffer.push_back(ImDrawCmd());
_FringeScale = 1.0f;
}
void ImDrawList::_ClearFreeMemory()
@ -686,12 +687,12 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
const ImVec2 opaque_uv = _Data->TexUvWhitePixel;
const int count = closed ? points_count : points_count - 1; // The number of line segments we need to draw
const bool thick_line = (thickness > 1.0f);
const bool thick_line = (thickness > _FringeScale);
if (Flags & ImDrawListFlags_AntiAliasedLines)
{
// Anti-aliased stroke
const float AA_SIZE = 1.0f;
const float AA_SIZE = _FringeScale;
const ImU32 col_trans = col & ~IM_COL32_A_MASK;
// Thicknesses <1.0 should behave like thickness 1.0
@ -702,7 +703,7 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32
// Do we want to draw this line using a texture?
// - For now, only draw integer-width lines using textures to avoid issues with the way scaling occurs, could be improved.
// - If AA_SIZE is not 1.0f we cannot use the texture path.
const bool use_texture = (Flags & ImDrawListFlags_AntiAliasedLinesUseTex) && (integer_thickness < IM_DRAWLIST_TEX_LINES_WIDTH_MAX) && (fractional_thickness <= 0.00001f);
const bool use_texture = (Flags & ImDrawListFlags_AntiAliasedLinesUseTex) && (integer_thickness < IM_DRAWLIST_TEX_LINES_WIDTH_MAX) && (fractional_thickness <= 0.00001f) && (AA_SIZE == 1.0f);
// We should never hit this, because NewFrame() doesn't set ImDrawListFlags_AntiAliasedLinesUseTex unless ImFontAtlasFlags_NoBakedLines is off
IM_ASSERT_PARANOID(!use_texture || !(_Data->Font->ContainerAtlas->Flags & ImFontAtlasFlags_NoBakedLines));
@ -944,7 +945,7 @@ void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_coun
if (Flags & ImDrawListFlags_AntiAliasedFill)
{
// Anti-aliased Fill
const float AA_SIZE = 1.0f;
const float AA_SIZE = _FringeScale;
const ImU32 col_trans = col & ~IM_COL32_A_MASK;
const int idx_count = (points_count - 2)*3 + points_count * 6;
const int vtx_count = (points_count * 2);
@ -2176,10 +2177,11 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas)
for (int output_i = 0; output_i < atlas->Fonts.Size && src_tmp.DstIndex == -1; output_i++)
if (cfg.DstFont == atlas->Fonts[output_i])
src_tmp.DstIndex = output_i;
IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array?
if (src_tmp.DstIndex == -1)
{
IM_ASSERT(src_tmp.DstIndex != -1); // cfg.DstFont not pointing within atlas->Fonts[] array?
return false;
}
// Initialize helper structure for font loading and verify that the TTF/OTF data is correct
const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo);
IM_ASSERT(font_offset >= 0 && "FontData is incorrect, or FontNo cannot be found.");

@ -1444,9 +1444,11 @@ struct ImGuiContext
float WheelingWindowTimer;
// Item/widgets state and tracking information
ImGuiID HoveredId; // Hovered widget
ImGuiID HoveredId; // Hovered widget, filled during the frame
ImGuiID HoveredIdPreviousFrame;
bool HoveredIdAllowOverlap;
bool HoveredIdUsingMouseWheel; // Hovered widget will use mouse wheel. Blocks scrolling the underlying window.
bool HoveredIdPreviousFrameUsingMouseWheel;
bool HoveredIdDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0.
float HoveredIdTimer; // Measure contiguous hovering time
float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active
@ -1459,6 +1461,7 @@ struct ImGuiContext
bool ActiveIdHasBeenPressedBefore; // Track whether the active id led to a press (this is to allow changing between PressOnClick and PressOnRelease without pressing twice). Used by range_select branch.
bool ActiveIdHasBeenEditedBefore; // Was the value associated to the widget Edited over the course of the Active state.
bool ActiveIdHasBeenEditedThisFrame;
bool ActiveIdUsingMouseWheel; // Active widget will want to read mouse wheel. Blocks scrolling the underlying window.
ImU32 ActiveIdUsingNavDirMask; // Active widget will want to read those nav move requests (e.g. can activate a button and move away from it)
ImU32 ActiveIdUsingNavInputMask; // Active widget will want to read those nav inputs.
ImU64 ActiveIdUsingKeyInputMask; // Active widget will want to read those key inputs. When we grow the ImGuiKey enum we'll need to either to order the enum to make useful keys come first, either redesign this into e.g. a small array.
@ -1681,6 +1684,7 @@ struct ImGuiContext
HoveredId = HoveredIdPreviousFrame = 0;
HoveredIdAllowOverlap = false;
HoveredIdUsingMouseWheel = HoveredIdPreviousFrameUsingMouseWheel = false;
HoveredIdDisabled = false;
HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f;
ActiveId = 0;
@ -1692,6 +1696,7 @@ struct ImGuiContext
ActiveIdHasBeenPressedBefore = false;
ActiveIdHasBeenEditedBefore = false;
ActiveIdHasBeenEditedThisFrame = false;
ActiveIdUsingMouseWheel = false;
ActiveIdUsingNavDirMask = 0x00;
ActiveIdUsingNavInputMask = 0x00;
ActiveIdUsingKeyInputMask = 0x00;
@ -2212,6 +2217,7 @@ struct ImGuiTable
float BorderX1;
float BorderX2;
float HostIndentX;
float MinColumnWidth;
float OuterPaddingX;
float CellPaddingX; // Padding from each borders
float CellPaddingY;
@ -2220,7 +2226,7 @@ struct ImGuiTable
float LastOuterHeight; // Outer height from last frame
float LastFirstRowHeight; // Height of first row from last frame
float InnerWidth; // User value passed to BeginTable(), see comments at the top of BeginTable() for details.
float ColumnsTotalWidth; // Sum of current column width
float ColumnsGivenWidth; // Sum of current column width
float ColumnsAutoFitWidth; // Sum of ideal column width in order nothing to be clipped, used for auto-fitting and content width submission in outer window
float ResizedColumnNextWidth;
float ResizeLockMinContentsX2; // Lock minimum contents width while resizing down in order to not create feedback loops. But we allow growing the table.
@ -2284,7 +2290,7 @@ struct ImGuiTable
bool IsDefaultDisplayOrder; // Set when display order is unchanged from default (DisplayOrder contains 0...Count-1)
bool IsResetAllRequest;
bool IsResetDisplayOrderRequest;
bool IsUnfrozen; // Set when we got past the frozen row.
bool IsUnfrozenRows; // Set when we got past the frozen row.
bool IsOuterRectAutoFitX; // Set when outer_size.x == 0.0f in BeginTable(), scrolling is disabled, and there are stretch columns.
bool MemoryCompacted;
bool HostSkipItems; // Backup of InnerWindow->SkipItem at the end of BeginTable(), because we will overwrite InnerWindow->SkipItem on a per-column basis
@ -2482,6 +2488,7 @@ namespace ImGui
// Inputs
// FIXME: Eventually we should aim to move e.g. IsActiveIdUsingKey() into IsKeyXXX functions.
IMGUI_API void SetItemUsingMouseWheel();
inline bool IsActiveIdUsingNavDir(ImGuiDir dir) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavDirMask & (1 << dir)) != 0; }
inline bool IsActiveIdUsingNavInput(ImGuiNavInput input) { ImGuiContext& g = *GImGui; return (g.ActiveIdUsingNavInputMask & (1 << input)) != 0; }
inline bool IsActiveIdUsingKey(ImGuiKey key) { ImGuiContext& g = *GImGui; IM_ASSERT(key < 64); return (g.ActiveIdUsingKeyInputMask & ((ImU64)1 << key)) != 0; }
@ -2581,6 +2588,7 @@ namespace ImGui
IMGUI_API void TableSortSpecsBuild(ImGuiTable* table);
IMGUI_API ImGuiSortDirection TableGetColumnNextSortDirection(ImGuiTableColumn* column);
IMGUI_API void TableFixColumnSortDirection(ImGuiTable* table, ImGuiTableColumn* column);
IMGUI_API float TableGetColumnWidthAuto(ImGuiTable* table, ImGuiTableColumn* column);
IMGUI_API void TableBeginRow(ImGuiTable* table);
IMGUI_API void TableEndRow(ImGuiTable* table);
IMGUI_API void TableBeginCell(ImGuiTable* table, int column_n);
@ -2588,7 +2596,6 @@ namespace ImGui
IMGUI_API ImRect TableGetCellBgRect(const ImGuiTable* table, int column_n);
IMGUI_API const char* TableGetColumnName(const ImGuiTable* table, int column_n);
IMGUI_API ImGuiID TableGetColumnResizeID(const ImGuiTable* table, int column_n, int instance_no = 0);
IMGUI_API float TableGetMinColumnWidth();
IMGUI_API float TableGetMaxColumnWidth(const ImGuiTable* table, int column_n);
IMGUI_API void TableSetColumnWidthAutoSingle(ImGuiTable* table, int column_n);
IMGUI_API void TableSetColumnWidthAutoAll(ImGuiTable* table);
@ -2663,6 +2670,8 @@ namespace ImGui
IMGUI_API ImGuiID GetWindowScrollbarID(ImGuiWindow* window, ImGuiAxis axis);
IMGUI_API ImGuiID GetWindowResizeID(ImGuiWindow* window, int n); // 0..3: corners, 4..7: borders
IMGUI_API void SeparatorEx(ImGuiSeparatorFlags flags);
IMGUI_API bool CheckboxFlags(const char* label, ImS64* flags, ImS64 flags_value);
IMGUI_API bool CheckboxFlags(const char* label, ImU64* flags, ImU64 flags_value);
// Widgets low-level behaviors
IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0);

@ -98,12 +98,34 @@ Index of this file:
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// TABLES CULLING
// COLUMNS SIZING POLICIES
//-----------------------------------------------------------------------------
// About overriding column width/weight with TableSetupColumn():
// We use a default parameter of 'init_width_or_weight == -1'.
// - With ImGuiTableColumnFlags_WidthAuto, init_width (ignored) --> width is automatic
// - With ImGuiTableColumnFlags_WidthFixed, init_width <= 0 (default) --> width is automatic
// - With ImGuiTableColumnFlags_WidthFixed, init_width > 0 (explicit) --> width is custom
// - With ImGuiTableColumnFlags_WidthStretch, init_weight <= 0 (default) --> weight is 1.0f
// - With ImGuiTableColumnFlags_WidthStretch, init_weight > 0 (explicit) --> weight is custom
// Widths are specified _without_ CellPadding. If you specify a width of 100.0f, the column will be cover (100.0f + Padding * 2.0f)
// and you can fit a 100.0f wide item in it without clipping and with full padding.
//-----------------------------------------------------------------------------
// About default width policy (if you don't specify a ImGuiTableColumnFlags_WidthXXXX flag)
// - When Table policy ImGuiTableFlags_SizingPolicyStretch --> default Column policy is ImGuiTableColumnFlags_WidthStretch
// - When Table policy ImGuiTableFlags_SizingPolicyFixed and (Table is Resizable or init_width > 0) --> default Column policy is ImGuiTableColumnFlags_WidthFixed
// - When Table policy ImGuiTableFlags_SizingPolicyFixed and (Table is not Resizable and init_width <= 0) --> default Column policy is ImGuiTableColumnFlags_WidthAuto
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// TABLES CLIPPING/CULLING
//-----------------------------------------------------------------------------
// About clipping/culling of Rows in Tables:
// - For large numbers of rows, it is recommended you use ImGuiListClipper to only submit visible rows.
// ImGuiListClipper is reliant on the fact that rows are of equal height.
// See 'Demo->Tables->Vertical Scrolling' or 'Demo->Tables->Advanced' for a demo of using the clipper.
// - Note that columns with the ImGuiTableColumnFlags_WidthAuto policy generally don't play well with using the clipper,
// and by default a table with _ScrollX but without _Resizable will have columns default to _WidthAuto.
// So, if you want to use the clipper, make sure to either enable _Resizable, either setup columns explicitly with _WidthFixed.
//-----------------------------------------------------------------------------
// About clipping/culling of Columns in Tables:
// - Case A: column is not hidden by user, and at least partially in sight (most common case).
@ -192,8 +214,8 @@ static const float TABLE_RESIZE_SEPARATOR_FEEDBACK_TIMER = 0.06f; // Delay/tim
inline ImGuiTableFlags TableFixFlags(ImGuiTableFlags flags, ImGuiWindow* outer_window)
{
// Adjust flags: set default sizing policy
if ((flags & (ImGuiTableFlags_ColumnsWidthStretch | ImGuiTableFlags_ColumnsWidthFixed)) == 0)
flags |= (flags & ImGuiTableFlags_ScrollX) ? ImGuiTableFlags_ColumnsWidthFixed : ImGuiTableFlags_ColumnsWidthStretch;
if ((flags & (ImGuiTableFlags_SizingPolicyStretch | ImGuiTableFlags_SizingPolicyFixed)) == 0)
flags |= ((flags & ImGuiTableFlags_ScrollX) || (outer_window->Flags & ImGuiWindowFlags_AlwaysAutoResize)) ? ImGuiTableFlags_SizingPolicyFixed : ImGuiTableFlags_SizingPolicyStretch;
// Adjust flags: disable Resizable when using SameWidths (done above enforcing BordersInnerV)
if (flags & ImGuiTableFlags_SameWidths)
@ -370,7 +392,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->RowTextBaseline = 0.0f; // This will be cleared again by TableBeginRow()
table->FreezeRowsRequest = table->FreezeRowsCount = 0; // This will be setup by TableSetupScrollFreeze(), if any
table->FreezeColumnsRequest = table->FreezeColumnsCount = 0;
table->IsUnfrozen = true;
table->IsUnfrozenRows = true;
table->DeclColumnsCount = 0;
// Using opaque colors facilitate overlapping elements of the grid
@ -564,14 +586,14 @@ static void TableSetupColumnFlags(ImGuiTable* table, ImGuiTableColumn* column, I
// Sizing Policy
if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0)
{
// FIXME-TABLE: Inconsistent to promote columns to WidthAutoResize
if (table->Flags & ImGuiTableFlags_ColumnsWidthFixed)
flags |= ((table->Flags & ImGuiTableFlags_Resizable) && !(flags & ImGuiTableColumnFlags_NoResize)) ? ImGuiTableColumnFlags_WidthFixed : ImGuiTableColumnFlags_WidthAutoResize;
// FIXME-TABLE: Inconsistent to promote columns to WidthAuto
if (table->Flags & ImGuiTableFlags_SizingPolicyFixed)
flags |= ((table->Flags & ImGuiTableFlags_Resizable) && !(flags & ImGuiTableColumnFlags_NoResize)) ? ImGuiTableColumnFlags_WidthFixed : ImGuiTableColumnFlags_WidthAuto;
else
flags |= ImGuiTableColumnFlags_WidthStretch;
}
IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiTableColumnFlags_WidthMask_)); // Check that only 1 of each set is used.
if (flags & ImGuiTableColumnFlags_WidthAutoResize)
if (flags & ImGuiTableColumnFlags_WidthAuto)
flags |= ImGuiTableColumnFlags_NoResize;
// Sorting
@ -609,22 +631,23 @@ static void TableSetupColumnFlags(ImGuiTable* table, ImGuiTableColumn* column, I
// Layout columns for the frame. This is in essence the followup to BeginTable().
// Runs on the first call to TableNextRow(), to give a chance for TableSetupColumn() to be called first.
// FIXME-TABLE: Our width (and therefore our WorkRect) will be minimal in the first frame for WidthAutoResize
// columns, increase feedback side-effect with widgets relying on WorkRect.Max.x. Maybe provide a default distribution
// for WidthAutoResize columns?
// FIXME-TABLE: Our width (and therefore our WorkRect) will be minimal in the first frame for _WidthAuto columns.
// Increase feedback side-effect with widgets relying on WorkRect.Max.x... Maybe provide a default distribution for _WidthAuto columns?
void ImGui::TableUpdateLayout(ImGuiTable* table)
{
ImGuiContext& g = *GImGui;
IM_ASSERT(table->IsLayoutLocked == false);
// [Part 1] Apply/lock Enabled and Order states.
// Process columns in their visible orders as we are building the Prev/Next indices.
int last_visible_column_idx = -1;
bool want_column_auto_fit = false;
table->IsDefaultDisplayOrder = true;
table->ColumnsEnabledCount = 0;
table->EnabledMaskByIndex = 0x00;
table->EnabledMaskByDisplayOrder = 0x00;
table->MinColumnWidth = ImMax(1.0f, g.Style.FramePadding.x * 1.0f); // g.Style.ColumnsMinSpacing; // FIXME-TABLE
// [Part 1] Apply/lock Enabled and Order states. Calculate auto/ideal width for columns.
// Process columns in their visible orders as we are building the Prev/Next indices.
int last_visible_column_idx = -1;
bool want_auto_fit = false;
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
{
const int column_n = table->DisplayOrderToIndex[order_n];
@ -657,36 +680,40 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
table->IsSortSpecsDirty = true;
bool start_auto_fit = false;
if (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAutoResize))
if (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAuto))
start_auto_fit = column->WidthRequest < 0.0f;
else
start_auto_fit = column->StretchWeight < 0.0f;
if (start_auto_fit)
column->AutoFitQueue = column->CannotSkipItemsQueue = (1 << 3) - 1; // Fit for three frames
if (column->AutoFitQueue != 0x00)
want_column_auto_fit = true;
ImU64 index_mask = (ImU64)1 << column_n;
ImU64 display_order_mask = (ImU64)1 << column->DisplayOrder;
if (column->IsEnabled)
{
// Mark as enabled and link to previous/next enabled column
column->PrevEnabledColumn = (ImGuiTableColumnIdx)last_visible_column_idx;
column->NextEnabledColumn = -1;
if (last_visible_column_idx != -1)
table->Columns[last_visible_column_idx].NextEnabledColumn = (ImGuiTableColumnIdx)column_n;
column->IndexWithinEnabledSet = table->ColumnsEnabledCount;
table->ColumnsEnabledCount++;
table->EnabledMaskByIndex |= index_mask;
table->EnabledMaskByDisplayOrder |= display_order_mask;
last_visible_column_idx = column_n;
}
else
if (!column->IsEnabled)
{
column->IndexWithinEnabledSet = -1;
continue;
}
// Mark as enabled and link to previous/next enabled column
column->PrevEnabledColumn = (ImGuiTableColumnIdx)last_visible_column_idx;
column->NextEnabledColumn = -1;
if (last_visible_column_idx != -1)
table->Columns[last_visible_column_idx].NextEnabledColumn = (ImGuiTableColumnIdx)column_n;
column->IndexWithinEnabledSet = table->ColumnsEnabledCount;
table->ColumnsEnabledCount++;
table->EnabledMaskByIndex |= index_mask;
table->EnabledMaskByDisplayOrder |= display_order_mask;
last_visible_column_idx = column_n;
IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder);
// Calculate ideal/auto column width (that's the width required for all contents to be visible without clipping)
// Combine width from regular rows + width from headers unless requested not to.
if (!column->IsPreserveWidthAuto)
column->WidthAuto = TableGetColumnWidthAuto(table, column);
if (column->AutoFitQueue != 0x00)
want_auto_fit = true;
}
if ((table->Flags & ImGuiTableFlags_Sortable) && table->SortSpecsCount == 0 && !(table->Flags & ImGuiTableFlags_SortTristate))
table->IsSortSpecsDirty = true;
@ -696,13 +723,12 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// [Part 2] Disable child window clipping while fitting columns. This is not strictly necessary but makes it possible
// to avoid the column fitting to wait until the first visible frame of the child container (may or not be a good thing).
// FIXME-TABLE: for always auto-resizing columns may not want to do that all the time.
if (want_column_auto_fit && table->OuterWindow != table->InnerWindow)
if (want_auto_fit && table->OuterWindow != table->InnerWindow)
table->InnerWindow->SkipItems = false;
if (want_column_auto_fit)
if (want_auto_fit)
table->IsSettingsDirty = true;
// [Part 3] Fix column flags. Calculate ideal width for columns. Count how many fixed/stretch columns we have and sum of weights.
const float min_column_width = TableGetMinColumnWidth();
// [Part 3] Fix column flags. Count how many fixed/stretch columns we have and sum of weights.
int count_fixed = 0; // Number of columns that have fixed sizing policy (not stretched sizing policy) (this is NOT the opposite of count_resizable!)
int count_resizable = 0; // Number of columns the user can resize (this is NOT the opposite of count_fixed!)
float sum_weights_stretched = 0.0f; // Sum of all weights for weighted columns.
@ -719,31 +745,16 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
if ((column->Flags & ImGuiTableColumnFlags_NoResize) == 0)
count_resizable++;
// Calculate ideal/auto column width (that's the width required for all contents to be visible without clipping)
// Combine width from regular rows + width from headers unless requested not to.
if (!column->IsPreserveWidthAuto)
if (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAuto))
{
const float content_width_body = ImMax(column->ContentMaxXFrozen, column->ContentMaxXUnfrozen) - column->WorkMinX;
const float content_width_headers = column->ContentMaxXHeadersIdeal - column->WorkMinX;
float width_auto = content_width_body;
if (!(column->Flags & ImGuiTableColumnFlags_NoHeaderWidth))
width_auto = ImMax(width_auto, content_width_headers);
width_auto = ImMax(width_auto, min_column_width);
// Non-resizable columns also submit their requested width
// Non-resizable columns keep their requested width
if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && column->InitStretchWeightOrWidth > 0.0f)
if (!(table->Flags & ImGuiTableFlags_Resizable) || (column->Flags & ImGuiTableColumnFlags_NoResize))
width_auto = ImMax(width_auto, column->InitStretchWeightOrWidth);
column->WidthRequest = column->WidthAuto = ImMax(column->WidthAuto, column->InitStretchWeightOrWidth); // Use user value regardless of IsPreserveWidthAuto
column->WidthAuto = width_auto;
}
column->IsPreserveWidthAuto = false;
if (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAutoResize))
{
// Process auto-fit for non-stretched columns
// Latch initial size for fixed columns and update it constantly for auto-resizing column (unless clipped!)
if ((column->AutoFitQueue != 0x00) || ((column->Flags & ImGuiTableColumnFlags_WidthAutoResize) && column->IsVisibleX))
if ((column->AutoFitQueue != 0x00) || ((column->Flags & ImGuiTableColumnFlags_WidthAuto) && column->IsVisibleX))
column->WidthRequest = column->WidthAuto;
// FIXME-TABLE: Increase minimum size during init frame to avoid biasing auto-fitting widgets
@ -751,8 +762,9 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// large height (= first frame scrollbar display very off + clipper would skip lots of items).
// This is merely making the side-effect less extreme, but doesn't properly fixes it.
// FIXME: Move this to ->WidthGiven to avoid temporary lossyless?
if (column->AutoFitQueue > 0x01 && table->IsInitializing)
column->WidthRequest = ImMax(column->WidthRequest, min_column_width * 4.0f); // FIXME-TABLE: Another constant/scale?
// FIXME: This break IsPreserveWidthAuto from not flickering if the stored WidthAuto was smaller.
if (column->AutoFitQueue > 0x01 && table->IsInitializing && !column->IsPreserveWidthAuto)
column->WidthRequest = ImMax(column->WidthRequest, table->MinColumnWidth * 4.0f); // FIXME-TABLE: Another constant/scale?
count_fixed += 1;
sum_width_fixed_requests += column->WidthRequest;
}
@ -770,6 +782,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
if (table->RightMostStretchedColumn == -1 || table->Columns[table->RightMostStretchedColumn].DisplayOrder < column->DisplayOrder)
table->RightMostStretchedColumn = (ImGuiTableColumnIdx)column_n;
}
column->IsPreserveWidthAuto = false;
max_width_auto = ImMax(max_width_auto, column->WidthAuto);
sum_width_fixed_requests += table->CellPaddingX * 2.0f;
}
@ -786,7 +799,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
if (!(table->EnabledMaskByIndex & ((ImU64)1 << column_n)))
continue;
ImGuiTableColumn* column = &table->Columns[column_n];
if (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAutoResize))
if (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAuto))
{
sum_width_fixed_requests += max_width_auto - column->WidthRequest; // Update old sum
column->WidthRequest = max_width_auto;
@ -807,8 +820,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
const float width_avail = ((table->Flags & ImGuiTableFlags_ScrollX) && table->InnerWidth == 0.0f) ? table->InnerClipRect.GetWidth() : work_rect.GetWidth();
const float width_avail_for_stretched_columns = mixed_same_widths ? 0.0f : width_avail - width_spacings - sum_width_fixed_requests;
float width_remaining_for_stretched_columns = width_avail_for_stretched_columns;
table->ColumnsTotalWidth = width_spacings;
table->ColumnsAutoFitWidth = width_spacings;
table->ColumnsGivenWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount;
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
{
if (!(table->EnabledMaskByIndex & ((ImU64)1 << column_n)))
@ -819,7 +831,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
if ((column->Flags & ImGuiTableColumnFlags_WidthStretch) && !mixed_same_widths)
{
float weight_ratio = column->StretchWeight / sum_weights_stretched;
column->WidthRequest = IM_FLOOR(ImMax(width_avail_for_stretched_columns * weight_ratio, min_column_width) + 0.01f);
column->WidthRequest = IM_FLOOR(ImMax(width_avail_for_stretched_columns * weight_ratio, table->MinColumnWidth) + 0.01f);
width_remaining_for_stretched_columns -= column->WidthRequest;
}
@ -829,9 +841,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
column->Flags |= ImGuiTableColumnFlags_NoDirectResize_;
// Assign final width, record width in case we will need to shrink
column->WidthGiven = ImFloor(ImMax(column->WidthRequest, min_column_width));
table->ColumnsTotalWidth += column->WidthGiven + table->CellPaddingX * 2.0f;
table->ColumnsAutoFitWidth += column->WidthAuto + table->CellPaddingX * 2.0f;
column->WidthGiven = ImFloor(ImMax(column->WidthRequest, table->MinColumnWidth));
table->ColumnsGivenWidth += column->WidthGiven;
}
// [Part 6] Redistribute stretch remainder width due to rounding (remainder width is < 1.0f * number of Stretch column).
@ -857,6 +868,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// [Part 7] Setup final position, offset, skip/clip states and clipping rectangles, detect hovered column
// Process columns in their visible orders as we are comparing the visible order and adjusting host_clip_rect while looping.
int visible_n = 0;
bool offset_x_frozen = (table->FreezeColumnsCount > 0);
float offset_x = ((table->FreezeColumnsCount > 0) ? table->OuterRect.Min.x : work_rect.Min.x) + table->OuterPaddingX - table->CellSpacingX1;
ImRect host_clip_rect = table->InnerClipRect;
//host_clip_rect.Max.x += table->CellPaddingX + table->CellSpacingX2;
@ -869,8 +881,11 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
column->NavLayerCurrent = (ImS8)((table->FreezeRowsCount > 0 || column_n < table->FreezeColumnsCount) ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main);
if (table->FreezeColumnsCount > 0 && table->FreezeColumnsCount == visible_n)
if (offset_x_frozen && table->FreezeColumnsCount == visible_n)
{
offset_x += work_rect.Min.x - table->OuterRect.Min.x;
offset_x_frozen = false;
}
// Clear status flags
column->Flags &= ~ImGuiTableColumnFlags_StatusMask_;
@ -900,7 +915,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// Lock width based on start position and minimum/maximum width for this position
float max_width = TableGetMaxColumnWidth(table, column_n);
column->WidthGiven = ImMin(column->WidthGiven, max_width);
column->WidthGiven = ImMax(column->WidthGiven, ImMin(column->WidthRequest, min_column_width));
column->WidthGiven = ImMax(column->WidthGiven, ImMin(column->WidthRequest, table->MinColumnWidth));
column->MaxX = offset_x + column->WidthGiven + table->CellSpacingX1 + table->CellSpacingX2 + table->CellPaddingX * 2.0f;
// Lock other positions
@ -978,7 +993,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// [Part 8] Detect/store when we are hovering the unused space after the right-most column (so e.g. context menus can react on it)
// Clear Resizable flag if none of our column are actually resizable (either via an explicit _NoResize flag, either
// because of using _WidthAutoResize/_WidthStretch). This will hide the resizing option from the context menu.
// because of using _WidthAuto/_WidthStretch). This will hide the resizing option from the context menu.
const float unused_x1 = ImMax(table->WorkRect.Min.x, table->Columns[table->RightMostEnabledColumn].ClipRect.Max.x);
if (is_hovering_table && table->HoveredColumnBody == -1)
{
@ -1073,6 +1088,10 @@ void ImGui::TableUpdateBorders(ImGuiTable* table)
if ((table->Flags & ImGuiTableFlags_NoBordersInBody) && table->IsUsingHeaders == false)
continue;
if (table->FreezeColumnsCount > 0)
if (column->MaxX < table->Columns[table->DisplayOrderToIndex[table->FreezeColumnsCount - 1]].MaxX)
continue;
ImGuiID column_id = TableGetColumnResizeID(table, column_n, table->InstanceCurrent);
ImRect hit_rect(column->MaxX - hit_half_width, hit_y1, column->MaxX + hit_half_width, border_y2_hit);
//GetForegroundDrawList()->AddRect(hit_rect.Min, hit_rect.Max, IM_COL32(255, 0, 0, 100));
@ -1156,16 +1175,6 @@ void ImGui::EndTable()
if ((flags & ImGuiTableFlags_Borders) != 0)
TableDrawBorders(table);
// Store content width reference for each column (before attempting to merge draw calls)
const float backup_outer_cursor_pos_x = outer_window->DC.CursorPos.x;
const float backup_outer_max_pos_x = outer_window->DC.CursorMaxPos.x;
const float backup_inner_max_pos_x = inner_window->DC.CursorMaxPos.x;
float max_pos_x = backup_inner_max_pos_x;
if (table->RightMostEnabledColumn != -1)
max_pos_x = ImMax(max_pos_x, table->Columns[table->RightMostEnabledColumn].MaxX);
if (table->ResizedColumn != -1)
max_pos_x = ImMax(max_pos_x, table->ResizeLockMinContentsX2);
#if 0
// Strip out dummy channel draw calls
// We have no way to prevent user submitting direct ImDrawList calls into a hidden column (but ImGui:: calls will be clipped out)
@ -1185,14 +1194,22 @@ void ImGui::EndTable()
TableMergeDrawChannels(table);
table->DrawSplitter.Merge(inner_window->DrawList);
if (!(table->Flags & ImGuiTableFlags_ScrollX) && inner_window != outer_window)
// Update ColumnsAutoFitWidth to get us ahead for host using our size to auto-resize without waiting for next BeginTable()
const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1);
table->ColumnsAutoFitWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount;
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
if (table->EnabledMaskByIndex & ((ImU64)1 << column_n))
table->ColumnsAutoFitWidth += TableGetColumnWidthAuto(table, &table->Columns[column_n]);
// Update scroll
if ((table->Flags & ImGuiTableFlags_ScrollX) == 0 && inner_window != outer_window)
{
inner_window->Scroll.x = 0.0f;
}
else if (table->LastResizedColumn != -1 && table->ResizedColumn == -1 && inner_window->ScrollbarX && table->InstanceInteracted == table->InstanceCurrent)
{
// When releasing a column being resized, scroll to keep the resulting column in sight
const float neighbor_width_to_keep_visible = TableGetMinColumnWidth() + table->CellPaddingX * 2.0f;
const float neighbor_width_to_keep_visible = table->MinColumnWidth + table->CellPaddingX * 2.0f;
ImGuiTableColumn* column = &table->Columns[table->LastResizedColumn];
if (column->MaxX < table->InnerClipRect.Min.x)
SetScrollFromPosX(inner_window, column->MaxX - inner_window->Pos.x - neighbor_width_to_keep_visible, 1.0f);
@ -1209,10 +1226,20 @@ void ImGui::EndTable()
table->ResizedColumnNextWidth = new_width;
}
// Layout in outer window
// Pop from id stack
IM_ASSERT_USER_ERROR(inner_window->IDStack.back() == table->ID + table->InstanceCurrent, "Mismatching PushID/PopID!");
IM_ASSERT_USER_ERROR(outer_window->DC.ItemWidthStack.Size >= table->HostBackupItemWidthStackSize, "Too many PopItemWidth!");
PopID();
// Layout in outer window
const float backup_outer_cursor_pos_x = outer_window->DC.CursorPos.x;
const float backup_outer_max_pos_x = outer_window->DC.CursorMaxPos.x;
const float backup_inner_max_pos_x = inner_window->DC.CursorMaxPos.x;
float max_pos_x = backup_inner_max_pos_x;
if (table->RightMostEnabledColumn != -1)
max_pos_x = ImMax(max_pos_x, table->Columns[table->RightMostEnabledColumn].MaxX);
if (table->ResizedColumn != -1)
max_pos_x = ImMax(max_pos_x, table->ResizeLockMinContentsX2);
inner_window->WorkRect = table->HostBackupWorkRect;
inner_window->ParentWorkRect = table->HostBackupParentWorkRect;
inner_window->SkipItems = table->HostSkipItems;
@ -1236,7 +1263,7 @@ void ImGui::EndTable()
if (table->Flags & ImGuiTableFlags_ScrollX)
{
inner_window->DC.CursorMaxPos.x = max_pos_x; // Set contents width for scrolling
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos_x, backup_outer_cursor_pos_x + table->ColumnsTotalWidth + inner_window->ScrollbarSizes.x); // For auto-fit
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos_x, backup_outer_cursor_pos_x + table->ColumnsGivenWidth + inner_window->ScrollbarSizes.x); // For scrolling
}
else
{
@ -1256,12 +1283,7 @@ void ImGui::EndTable()
outer_window->DC.CurrentTableIdx = g.CurrentTable ? g.Tables.GetIndex(g.CurrentTable) : -1;
}
// We use a default parameter of 'init_width_or_weight == -1',
// - with ImGuiTableColumnFlags_WidthFixed, width <= 0 --> init width == auto
// - with ImGuiTableColumnFlags_WidthFixed, width > 0 --> init width == manual
// - with ImGuiTableColumnFlags_WidthStretch, weight < 0 --> init weight == 1.0f
// - with ImGuiTableColumnFlags_WidthStretch, weight >= 0 --> init weight == custom
// Widths are specified _without_ CellPadding. So if you specify a width of 100.0f the column will be 100.0f+Padding*2.0f and you can fit a 100.0-wide item in it.
// See "COLUMN SIZING POLICIES" comments at the top of this file
void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id)
{
ImGuiContext& g = *GImGui;
@ -1279,9 +1301,9 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
table->DeclColumnsCount++;
// When passing a width automatically enforce WidthFixed policy
// (whereas TableSetupColumnFlags would default to WidthAutoResize)
// (whereas TableSetupColumnFlags would default to WidthAuto if table is not Resizable)
if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0)
if ((table->Flags & ImGuiTableFlags_ColumnsWidthFixed) && (init_width_or_weight > 0.0f))
if ((table->Flags & ImGuiTableFlags_SizingPolicyFixed) && (init_width_or_weight > 0.0f))
flags |= ImGuiTableColumnFlags_WidthFixed;
TableSetupColumnFlags(table, column, flags);
@ -1298,7 +1320,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
if ((flags & ImGuiTableColumnFlags_WidthFixed) && init_width_or_weight > 0.0f)
column->WidthRequest = init_width_or_weight;
if (flags & ImGuiTableColumnFlags_WidthStretch)
column->StretchWeight = (init_width_or_weight > 0.0f) ? init_width_or_weight : 1.0f;
column->StretchWeight = (init_width_or_weight > 0.0f) ? init_width_or_weight : -1.0f;
// Disable auto-fit if an explicit width/weight has been specified
if (init_width_or_weight > 0.0f)
@ -1339,7 +1361,7 @@ void ImGui::TableSetupScrollFreeze(int columns, int rows)
table->FreezeColumnsCount = (table->InnerWindow->Scroll.x != 0.0f) ? table->FreezeColumnsRequest : 0;
table->FreezeRowsRequest = (table->Flags & ImGuiTableFlags_ScrollY) ? (ImGuiTableColumnIdx)rows : 0;
table->FreezeRowsCount = (table->InnerWindow->Scroll.y != 0.0f) ? table->FreezeRowsRequest : 0;
table->IsUnfrozen = (table->FreezeRowsCount == 0); // Make sure this is set before TableUpdateLayout() so ImGuiListClipper can benefit from it.b
table->IsUnfrozenRows = (table->FreezeRowsCount == 0); // Make sure this is set before TableUpdateLayout() so ImGuiListClipper can benefit from it.b
}
int ImGui::TableGetColumnCount()
@ -1639,8 +1661,8 @@ void ImGui::TableEndRow(ImGuiTable* table)
}
if (unfreeze_rows_actual)
{
IM_ASSERT(table->IsUnfrozen == false);
table->IsUnfrozen = true;
IM_ASSERT(table->IsUnfrozenRows == false);
table->IsUnfrozenRows = true;
// BgClipRect starts as table->InnerClipRect, reduce it now and make BgClipRectForDrawCmd == BgClipRect
float y0 = ImMax(table->RowPosY2 + 1, window->InnerClipRect.Min.y);
@ -1798,7 +1820,7 @@ void ImGui::TableEndCell(ImGuiTable* table)
if (table->RowFlags & ImGuiTableRowFlags_Headers)
p_max_pos_x = &column->ContentMaxXHeadersUsed; // Useful in case user submit contents in header row that is not a TableHeader() call
else
p_max_pos_x = table->IsUnfrozen ? &column->ContentMaxXUnfrozen : &column->ContentMaxXFrozen;
p_max_pos_x = table->IsUnfrozenRows ? &column->ContentMaxXUnfrozen : &column->ContentMaxXFrozen;
*p_max_pos_x = ImMax(*p_max_pos_x, window->DC.CursorMaxPos.x);
table->RowPosY2 = ImMax(table->RowPosY2, window->DC.CursorMaxPos.y + table->CellPaddingY);
column->ItemWidth = window->DC.ItemWidth;
@ -1811,28 +1833,20 @@ void ImGui::TableEndCell(ImGuiTable* table)
//-------------------------------------------------------------------------
// [SECTION] Tables: Columns width management
//-------------------------------------------------------------------------
// - TableGetMinColumnWidth() [Internal]
// - TableGetMaxColumnWidth() [Internal]
// - TableGetColumnWidthAuto() [Internal]
// - TableSetColumnWidth()
// - TableSetColumnWidthAutoSingle() [Internal]
// - TableSetColumnWidthAutoAll() [Internal]
// - TableUpdateColumnsWeightFromWidth() [Internal]
//-------------------------------------------------------------------------
// Minimum column content width (without padding)
float ImGui::TableGetMinColumnWidth()
{
ImGuiContext& g = *GImGui;
//return g.Style.ColumnsMinSpacing; // FIXME-TABLE
return g.Style.FramePadding.x * 1.0f;
}
// Maximum column content width given current layout. Use column->MinX so this value on a per-column basis.
float ImGui::TableGetMaxColumnWidth(const ImGuiTable* table, int column_n)
{
const ImGuiTableColumn* column = &table->Columns[column_n];
float max_width = FLT_MAX;
const float min_column_distance = TableGetMinColumnWidth() + table->CellPaddingX * 2.0f + table->CellSpacingX1 + table->CellSpacingX2;
const float min_column_distance = table->MinColumnWidth + table->CellPaddingX * 2.0f + table->CellSpacingX1 + table->CellSpacingX2;
if (table->Flags & ImGuiTableFlags_ScrollX)
{
// Frozen columns can't reach beyond visible width else scrolling will naturally break.
@ -1858,6 +1872,23 @@ float ImGui::TableGetMaxColumnWidth(const ImGuiTable* table, int column_n)
return max_width;
}
// Note this is meant to be stored in column->WidthAuto, please generally use the WidthAuto field
float ImGui::TableGetColumnWidthAuto(ImGuiTable* table, ImGuiTableColumn* column)
{
const float content_width_body = ImMax(column->ContentMaxXFrozen, column->ContentMaxXUnfrozen) - column->WorkMinX;
const float content_width_headers = column->ContentMaxXHeadersIdeal - column->WorkMinX;
float width_auto = content_width_body;
if (!(column->Flags & ImGuiTableColumnFlags_NoHeaderWidth))
width_auto = ImMax(width_auto, content_width_headers);
// Non-resizable fixed columns preserve their requested width
if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && column->InitStretchWeightOrWidth > 0.0f)
if (!(table->Flags & ImGuiTableFlags_Resizable) || (column->Flags & ImGuiTableColumnFlags_NoResize))
width_auto = ImMax(width_auto, column->InitStretchWeightOrWidth);
return ImMax(width_auto, table->MinColumnWidth);
}
// 'width' = inner column width, without padding
void ImGui::TableSetColumnWidth(int column_n, float width)
{
@ -1870,8 +1901,9 @@ void ImGui::TableSetColumnWidth(int column_n, float width)
// Apply constraints early
// Compare both requested and actual given width to avoid overwriting requested width when column is stuck (minimum size, bounded)
const float min_width = TableGetMinColumnWidth();
const float max_width = TableGetMaxColumnWidth(table, column_n);
IM_ASSERT(table->MinColumnWidth > 0.0f);
const float min_width = table->MinColumnWidth;
const float max_width = ImMax(min_width, TableGetMaxColumnWidth(table, column_n));
column_0_width = ImClamp(column_0_width, min_width, max_width);
if (column_0->WidthGiven == column_0_width || column_0->WidthRequest == column_0_width)
return;
@ -1931,6 +1963,7 @@ void ImGui::TableSetColumnWidth(int column_n, float width)
// (old_a + old_b == new_a + new_b) --> (new_a == old_a + old_b - new_b)
float column_1_width = ImMax(column_1->WidthRequest - (column_0_width - column_0->WidthRequest), min_width);
column_0_width = column_0->WidthRequest + column_1->WidthRequest - column_1_width;
IM_ASSERT(column_0_width > 0.0f && column_1_width > 0.0f);
column_0->WidthRequest = column_0_width;
column_1->WidthRequest = column_1_width;
if ((column_0->Flags | column_1->Flags) & ImGuiTableColumnFlags_WidthStretch)
@ -3293,7 +3326,7 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
return;
bool clear_settings = SmallButton("Clear settings");
BulletText("OuterRect: Pos: (%.1f,%.1f) Size: (%.1f,%.1f)", table->OuterRect.Min.x, table->OuterRect.Min.y, table->OuterRect.GetWidth(), table->OuterRect.GetHeight());
BulletText("ColumnsWidth: %.1f, AutoFitWidth: %.1f, InnerWidth: %.1f%s", table->ColumnsTotalWidth, table->ColumnsAutoFitWidth, table->InnerWidth, table->InnerWidth == 0.0f ? " (auto)" : "");
BulletText("ColumnsGivenWidth: %.1f, ColumnsAutoFitWidth: %.1f, InnerWidth: %.1f%s", table->ColumnsGivenWidth, table->ColumnsAutoFitWidth, table->InnerWidth, table->InnerWidth == 0.0f ? " (auto)" : "");
BulletText("CellPaddingX: %.1f, CellSpacingX: %.1f/%.1f, OuterPaddingX: %.1f", table->CellPaddingX, table->CellSpacingX1, table->CellSpacingX2, table->OuterPaddingX);
BulletText("HoveredColumnBody: %d, HoveredColumnBorder: %d", table->HoveredColumnBody, table->HoveredColumnBorder);
BulletText("ResizedColumn: %d, ReorderColumn: %d, HeldHeaderColumn: %d", table->ResizedColumn, table->ReorderColumn, table->HeldHeaderColumn);
@ -3307,21 +3340,21 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
ImGuiTableColumn* column = &table->Columns[n];
const char* name = TableGetColumnName(table, n);
ImFormatString(buf, IM_ARRAYSIZE(buf),
"Column %d order %d name '%s': offset %+.2f to %+.2f\n"
"Column %d order %d '%s': offset %+.2f to %+.2f%s\n"
"Enabled: %d, VisibleX/Y: %d/%d, RequestOutput: %d, SkipItems: %d, DrawChannels: %d,%d\n"
"WidthGiven: %.1f, Request/Auto: %.1f/%.1f, StretchWeight: %.3f (%.1f%%)\n"
"MinX: %.1f, MaxX: %.1f (%+.1f), ClipRect: %.1f to %.1f (+%.1f)\n"
"ContentWidth: %.1f,%.1f, HeadersUsed/Ideal %.1f/%.1f\n"
"Sort: %d%s, UserID: 0x%08X, Flags: 0x%04X: %s%s%s%s..",
n, column->DisplayOrder, name, column->MinX - table->WorkRect.Min.x, column->MaxX - table->WorkRect.Min.x,
n, column->DisplayOrder, name, column->MinX - table->WorkRect.Min.x, column->MaxX - table->WorkRect.Min.x, (n < table->FreezeColumnsRequest) ? " (Frozen)" : "",
column->IsEnabled, column->IsVisibleX, column->IsVisibleY, column->IsRequestOutput, column->IsSkipItems, column->DrawChannelFrozen, column->DrawChannelUnfrozen,
column->WidthGiven, column->WidthRequest, column->WidthAuto, column->StretchWeight, (column->StretchWeight / sum_weights) * 100.0f,
column->WidthGiven, column->WidthRequest, column->WidthAuto, column->StretchWeight, column->StretchWeight > 0.0f ? (column->StretchWeight / sum_weights) * 100.0f : 0.0f,
column->MinX, column->MaxX, column->MaxX - column->MinX, column->ClipRect.Min.x, column->ClipRect.Max.x, column->ClipRect.Max.x - column->ClipRect.Min.x,
column->ContentMaxXFrozen - column->WorkMinX, column->ContentMaxXUnfrozen - column->WorkMinX, column->ContentMaxXHeadersUsed - column->WorkMinX, column->ContentMaxXHeadersIdeal - column->WorkMinX,
column->SortOrder, (column->SortDirection == ImGuiSortDirection_Ascending) ? " (Asc)" : (column->SortDirection == ImGuiSortDirection_Descending) ? " (Des)" : "", column->UserID, column->Flags,
(column->Flags & ImGuiTableColumnFlags_WidthStretch) ? "WidthStretch " : "",
(column->Flags & ImGuiTableColumnFlags_WidthFixed) ? "WidthFixed " : "",
(column->Flags & ImGuiTableColumnFlags_WidthAutoResize) ? "WidthAutoResize " : "",
(column->Flags & ImGuiTableColumnFlags_WidthAuto) ? "WidthAuto " : "",
(column->Flags & ImGuiTableColumnFlags_NoResize) ? "NoResize " : "");
Bullet();
Selectable(buf);

@ -1070,7 +1070,10 @@ bool ImGui::Checkbox(const char* label, bool* v)
const ImRect total_bb(pos, pos + ImVec2(square_sz + (label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f), label_size.y + style.FramePadding.y * 2.0f));
ItemSize(total_bb, style.FramePadding.y);
if (!ItemAdd(total_bb, id))
{
IMGUI_TEST_ENGINE_ITEM_INFO(id, label, window->DC.ItemFlags | ImGuiItemStatusFlags_Checkable | (*v ? ImGuiItemStatusFlags_Checked : 0));
return false;
}
bool hovered, held;
bool pressed = ButtonBehavior(total_bb, id, &hovered, &held);
@ -1146,6 +1149,16 @@ bool ImGui::CheckboxFlags(const char* label, unsigned int* flags, unsigned int f
return CheckboxFlagsT(label, flags, flags_value);
}
bool ImGui::CheckboxFlags(const char* label, ImS64* flags, ImS64 flags_value)
{
return CheckboxFlagsT(label, flags, flags_value);
}
bool ImGui::CheckboxFlags(const char* label, ImU64* flags, ImU64 flags_value)
{
return CheckboxFlagsT(label, flags, flags_value);
}
bool ImGui::RadioButton(const char* label, bool active)
{
ImGuiWindow* window = GetCurrentWindow();
@ -1707,6 +1720,9 @@ bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(voi
}
EndCombo();
if (value_changed)
MarkItemEdited(g.CurrentWindow->DC.LastItemId);
return value_changed;
}
@ -6159,7 +6175,9 @@ bool ImGui::ListBoxHeader(const char* label, int items_count, int height_in_item
// FIXME: In principle this function should be called EndListBox(). We should rename it after re-evaluating if we want to keep the same signature.
void ImGui::ListBoxFooter()
{
ImGuiWindow* parent_window = GetCurrentWindow()->ParentWindow;
ImGuiWindow * window = GetCurrentWindow();
IM_ASSERT((window->Flags & ImGuiWindowFlags_ChildWindow) && "Mismatched ListBoxHeader/ListBoxFooter calls. Did you test the return value of ListBoxHeader()?");
ImGuiWindow* parent_window = window->ParentWindow;
const ImRect bb = parent_window->DC.LastItemRect;
const ImGuiStyle& style = GetStyle();

Loading…
Cancel
Save