mirror of
https://github.com/Drezil/imgui.git
synced 2025-10-28 11:41:05 +01:00
BeginChild(): added ImGuiChildFlags_AutoResizeX, ImGuiChildFlags_AutoResizeY, ImGuiChildFlags_AlwaysAutoResize + support for SetNextWindowSizeConstraints(). (#1666, #1395, #1496, #1710) + Demo
Note that child don't report ideal content size to parent so nesting may be difficult. Note4e4042bsimplified SkipItems logic. Notee2035a5standardizing WindowMinSize application on child
This commit is contained in:
@@ -94,6 +94,21 @@ Other changes:
|
||||
child windows from the bottom/right border (toward layout direction). Resized child windows
|
||||
settings are saved and persistent in .ini file. (#1710)
|
||||
- BeginChild(): Added ImGuiChildFlags_Border as a replacement for 'bool border = true' parameter.
|
||||
- BeginChild(): Added ImGuiChildFlags_AutoResizeX and ImGuiChildFlags_AutoResizeY to auto-resize
|
||||
on one axis, while generally providing a size on the other axis. (#1666, #1395, #1496, #1710)
|
||||
e.g. BeginChild("name", {-FLT_MIN, 0.0f}, ImGuiChildFlags_AutoResizeY);
|
||||
- Size is only reevaluated if the child window is within visible boundaries or just appearing.
|
||||
This allows coarse clipping to be performed and auto-resizing childs to return false when
|
||||
hidden because of being scrolled out.
|
||||
- Combining this with also specifying ImGuiChildFlags_AlwaysAutoResize disables
|
||||
this optimization, meaning child contents will never be clipped (not recommended).
|
||||
- Please be considerate that child are full windows and carry significiant overhead:
|
||||
combining auto-resizing for both axises to create a non-scrolling child to merely draw
|
||||
a border would be better more optimally using BeginGroup().
|
||||
(until we come up with new helpers for framed groups and work-rect adjustments).
|
||||
- BeginChild(): made it possible to use SetNextWindowSizeConstraints() rectangle, often
|
||||
useful when ImGuiChildFlags_AutoResizeX or ImGuiChildFlags_AutoResizeY. (#1666, #1395, #1496)
|
||||
Custom constraint callback are not supported with child window.
|
||||
- BeginChild(): Added ImGuiChildFlags_FrameStyle as a replacement for BeginChildFrame(),
|
||||
use it to make child window use FrameBg, FrameRounding, FrameBorderSize, FramePadding
|
||||
instead of ChildBg, ChildRounding, ChildBorderSize, WindowPadding.
|
||||
@@ -192,6 +207,7 @@ Other changes:
|
||||
- ImVector: Added find_index() helper.
|
||||
- Demo: Added "Drag and Drop -> Tooltip at target location" demo.
|
||||
- Demo: Added "Layout -> Child Windows -> Manual-resize" demo. (#1710)
|
||||
- Demo: Added "Layout -> Child Windows -> Auto-resize with constraints" demo. (#1666, #1395, #1496, #1710)
|
||||
- Backends: GLFW: Clear emscripten's MouseWheel callback before shutdown. (#6790, #6096, #4019) [@halx99]
|
||||
- Backends: GLFW: Added support for F13 to F24 function keys. (#6891)
|
||||
- Backends: SDL2, SDL3: Added support for F13 to F24 function keys, AppBack, AppForward. (#6891)
|
||||
|
||||
42
imgui.cpp
42
imgui.cpp
@@ -5444,19 +5444,29 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, I
|
||||
IM_ASSERT(id != 0);
|
||||
|
||||
// Sanity check as it is likely that some user will accidentally pass ImGuiWindowFlags into the ImGuiChildFlags argument.
|
||||
const ImGuiChildFlags ImGuiChildFlags_SupportedMask_ = ImGuiChildFlags_Border | ImGuiChildFlags_AlwaysUseWindowPadding | ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY | ImGuiChildFlags_FrameStyle;
|
||||
const ImGuiChildFlags ImGuiChildFlags_SupportedMask_ = ImGuiChildFlags_Border | ImGuiChildFlags_AlwaysUseWindowPadding | ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_FrameStyle;
|
||||
IM_UNUSED(ImGuiChildFlags_SupportedMask_);
|
||||
IM_ASSERT((child_flags & ~ImGuiChildFlags_SupportedMask_) == 0 && "Illegal ImGuiChildFlags value. Did you pass ImGuiWindowFlags values instead of ImGuiChildFlags?");
|
||||
if (window_flags & ImGuiWindowFlags_AlwaysAutoResize)
|
||||
IM_ASSERT((child_flags & (ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY)) == 0 && "Cannot combine ImGuiChildFlags_ResizeX/ImGuiChildFlags_ResizeY with ImGuiWindowFlags_AlwaysAutoResize.");
|
||||
IM_ASSERT((window_flags & ImGuiWindowFlags_AlwaysAutoResize) == 0 && "Cannot specify ImGuiWindowFlags_AlwaysAutoResize for BeginChild(). Use ImGuiChildFlags_AlwaysAutoResize!");
|
||||
if (child_flags & ImGuiChildFlags_AlwaysAutoResize)
|
||||
{
|
||||
IM_ASSERT((child_flags & (ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY)) == 0 && "Cannot use ImGuiChildFlags_ResizeX or ImGuiChildFlags_ResizeY with ImGuiChildFlags_AlwaysAutoResize!");
|
||||
IM_ASSERT((child_flags & (ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY)) != 0 && "Must use ImGuiChildFlags_AutoResizeX or ImGuiChildFlags_AutoResizeY with ImGuiChildFlags_AlwaysAutoResize!");
|
||||
}
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
if (window_flags & ImGuiWindowFlags_AlwaysUseWindowPadding)
|
||||
child_flags |= ImGuiChildFlags_AlwaysUseWindowPadding;
|
||||
#endif
|
||||
if (child_flags & ImGuiChildFlags_AutoResizeX)
|
||||
child_flags &= ~ImGuiChildFlags_ResizeX;
|
||||
if (child_flags & ImGuiChildFlags_AutoResizeY)
|
||||
child_flags &= ~ImGuiChildFlags_ResizeY;
|
||||
|
||||
// Set window flags
|
||||
window_flags |= ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoTitleBar;
|
||||
window_flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove); // Inherit the NoMove flag
|
||||
|
||||
if (child_flags & (ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_AlwaysAutoResize))
|
||||
window_flags |= ImGuiWindowFlags_AlwaysAutoResize;
|
||||
if ((child_flags & (ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY)) == 0)
|
||||
window_flags |= ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings;
|
||||
|
||||
@@ -5478,12 +5488,9 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, I
|
||||
// Forward size
|
||||
// Important: Begin() has special processing to switch condition to ImGuiCond_FirstUseEver for a given axis when ImGuiChildFlags_ResizeXXX is set.
|
||||
// (the alternative would to store conditional flags per axis, which is possible but more code)
|
||||
const ImVec2 content_avail = GetContentRegionAvail();
|
||||
ImVec2 size = ImTrunc(size_arg);
|
||||
if (size.x <= 0.0f)
|
||||
size.x = ImMax(content_avail.x + size.x, 4.0f); // Arbitrary minimum child size (0.0f causing too many issues)
|
||||
if (size.y <= 0.0f)
|
||||
size.y = ImMax(content_avail.y + size.y, 4.0f);
|
||||
const ImVec2 size_avail = GetContentRegionAvail();
|
||||
const ImVec2 size_default((child_flags & ImGuiChildFlags_AutoResizeX) ? 0.0f : size_avail.x, (child_flags & ImGuiChildFlags_AutoResizeY) ? 0.0f : size_avail.y);
|
||||
const ImVec2 size = CalcItemSize(size_arg, size_default.x, size_default.y);
|
||||
SetNextWindowSize(size);
|
||||
|
||||
// Build up name. If you need to append to a same child from multiple location in the ID stack, use BeginChild(ImGuiID id) with a stable value.
|
||||
@@ -7010,7 +7017,12 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||
const bool nav_request = (flags & ImGuiWindowFlags_NavFlattened) && (g.NavAnyRequest && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav);
|
||||
if (!g.LogEnabled && !nav_request)
|
||||
if (window->OuterRectClipped.Min.x >= window->OuterRectClipped.Max.x || window->OuterRectClipped.Min.y >= window->OuterRectClipped.Max.y)
|
||||
window->HiddenFramesCanSkipItems = 1;
|
||||
{
|
||||
if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0)
|
||||
window->HiddenFramesCannotSkipItems = 1;
|
||||
else
|
||||
window->HiddenFramesCanSkipItems = 1;
|
||||
}
|
||||
|
||||
// Hide along with parent or if parent is collapsed
|
||||
if (parent_window && (parent_window->Collapsed || parent_window->HiddenFramesCanSkipItems > 0))
|
||||
@@ -7591,10 +7603,14 @@ void ImGui::SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond con
|
||||
IM_ASSERT(cond == 0 || ImIsPowerOfTwo(cond)); // Make sure the user doesn't attempt to combine multiple condition flags.
|
||||
window->SetWindowSizeAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing);
|
||||
|
||||
// Enable auto-fit (not done in BeginChild() path unless appearing or combined with ImGuiChildFlags_AlwaysAutoResize)
|
||||
if ((window->Flags & ImGuiWindowFlags_ChildWindow) == 0 || window->Appearing || (window->ChildFlags & ImGuiChildFlags_AlwaysAutoResize) != 0)
|
||||
window->AutoFitFramesX = (size.x <= 0.0f) ? 2 : 0;
|
||||
if ((window->Flags & ImGuiWindowFlags_ChildWindow) == 0 || window->Appearing || (window->ChildFlags & ImGuiChildFlags_AlwaysAutoResize) != 0)
|
||||
window->AutoFitFramesY = (size.y <= 0.0f) ? 2 : 0;
|
||||
|
||||
// Set
|
||||
ImVec2 old_size = window->SizeFull;
|
||||
window->AutoFitFramesX = (size.x <= 0.0f) ? 2 : 0;
|
||||
window->AutoFitFramesY = (size.y <= 0.0f) ? 2 : 0;
|
||||
if (size.x <= 0.0f)
|
||||
window->AutoFitOnlyGrows = false;
|
||||
else
|
||||
|
||||
17
imgui.h
17
imgui.h
@@ -338,7 +338,12 @@ namespace ImGui
|
||||
|
||||
// Child Windows
|
||||
// - Use child windows to begin into a self-contained independent scrolling/clipping regions within a host window. Child windows can embed their own child.
|
||||
// - For each independent axis of 'size': ==0.0f: use remaining host window size / >0.0f: fixed size / <0.0f: use remaining window size minus abs(size) / Each axis can use a different mode, e.g. ImVec2(0,400).
|
||||
// - Manual sizing (each axis can use a different setting e.g. ImVec2(0.0f, 400.0f)):
|
||||
// == 0.0f: use remaining parent window size for this axis.
|
||||
// > 0.0f: use specified size for this axis.
|
||||
// < 0.0f: right/bottom-align to specified distance from available content boundaries.
|
||||
// - Specifying ImGuiChildFlags_AutoResizeX or ImGuiChildFlags_AutoResizeY makes the sizing automatic based on child contents.
|
||||
// Combining both ImGuiChildFlags_AutoResizeX _and_ ImGuiChildFlags_AutoResizeY defeats purpose of a scrolling region and is NOT recommended.
|
||||
// - BeginChild() returns false to indicate the window is collapsed or fully clipped, so you may early out and omit submitting
|
||||
// anything to the window. Always call a matching EndChild() for each BeginChild() call, regardless of its return value.
|
||||
// [Important: due to legacy reason, Begin/End and BeginChild/EndChild are inconsistent with all other functions
|
||||
@@ -1015,6 +1020,13 @@ enum ImGuiWindowFlags_
|
||||
|
||||
// Flags for ImGui::BeginChild()
|
||||
// (Legacy: bit 0 must always correspond to ImGuiChildFlags_Border to be backward compatible with old API using 'bool border'.
|
||||
// About using AutoResizeX/AutoResizeY flags:
|
||||
// - May be combined with SetNextWindowSizeConstraints() to set a min/max size for each axis (see "Demo->Child->Auto-resize with Constraints").
|
||||
// - Size measurement for a given axis is only performed when the child window is within visible boundaries, or is just appearing.
|
||||
// - This allows BeginChild() to return false when not within boundaries (e.g. when scrolling), which is more optimal. BUT it won't update its auto-size while clipped.
|
||||
// While not perfect, it is a better default behavior as the always-on performance gain is more valuable than the occasional "resizing after becoming visible again" glitch.
|
||||
// - You may also use ImGuiChildFlags_AlwaysAutoResize to force an update even when child window is not in view.
|
||||
// HOWEVER PLEASE UNDERSTAND THAT DOING SO WILL PREVENT BeginChild() FROM EVER RETURNING FALSE, disabling benefits of coarse clipping.
|
||||
enum ImGuiChildFlags_
|
||||
{
|
||||
ImGuiChildFlags_None = 0,
|
||||
@@ -1022,6 +1034,9 @@ enum ImGuiChildFlags_
|
||||
ImGuiChildFlags_AlwaysUseWindowPadding = 1 << 1, // Pad with style.WindowPadding even if no border are drawn (no padding by default for non-bordered child windows because it makes more sense)
|
||||
ImGuiChildFlags_ResizeX = 1 << 2, // Allow resize from right border (layout direction). Enable .ini saving (unless ImGuiWindowFlags_NoSavedSettings passed to window flags)
|
||||
ImGuiChildFlags_ResizeY = 1 << 3, // Allow resize from bottom border (layout direction). "
|
||||
ImGuiChildFlags_AutoResizeX = 1 << 4, // Enable auto-resizing width. Read "IMPORTANT: Size measurement" details above.
|
||||
ImGuiChildFlags_AutoResizeY = 1 << 5, // Enable auto-resizing height. Read "IMPORTANT: Size measurement" details above.
|
||||
ImGuiChildFlags_AlwaysAutoResize = 1 << 6, // Combined with AutoResizeX/AutoResizeY. Always measure size even when child is hidden, always return true, always disable clipping optimization! NOT RECOMMENDED.
|
||||
ImGuiChildFlags_FrameStyle = 1 << 7, // Style the child window like a framed item: use FrameBg, FrameRounding, FrameBorderSize, FramePadding instead of ChildBg, ChildRounding, ChildBorderSize, WindowPadding.
|
||||
};
|
||||
|
||||
|
||||
@@ -2779,6 +2779,23 @@ static void ShowDemoWindowLayout()
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
// Child 4: auto-resizing height with a limit
|
||||
ImGui::SeparatorText("Auto-resize with constraints");
|
||||
{
|
||||
static int draw_lines = 3;
|
||||
static int max_height_in_lines = 10;
|
||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
||||
ImGui::DragInt("Lines Count", &draw_lines, 0.2f);
|
||||
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
|
||||
ImGui::DragInt("Max Height (in Lines)", &max_height_in_lines, 0.2f);
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(0.0f, ImGui::GetTextLineHeightWithSpacing() * 1), ImVec2(FLT_MAX, ImGui::GetTextLineHeightWithSpacing() * max_height_in_lines));
|
||||
if (ImGui::BeginChild("ConstrainedChild", ImVec2(-FLT_MIN, 0.0f), ImGuiChildFlags_Border | ImGuiChildFlags_AutoResizeY))
|
||||
for (int n = 0; n < draw_lines; n++)
|
||||
ImGui::Text("Line %04d", n);
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
ImGui::SeparatorText("Misc/Advanced");
|
||||
|
||||
// Demonstrate a few extra things
|
||||
@@ -6605,6 +6622,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
"Left-click on color square to open color picker,\n"
|
||||
"Right-click to open edit options menu.");
|
||||
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(0.0f, ImGui::GetTextLineHeightWithSpacing() * 10), ImVec2(FLT_MAX, FLT_MAX));
|
||||
ImGui::BeginChild("##colors", ImVec2(0, 0), ImGuiChildFlags_Border, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NavFlattened);
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * -12);
|
||||
for (int i = 0; i < ImGuiCol_COUNT; i++)
|
||||
|
||||
Reference in New Issue
Block a user