Internals: added SetNextWindowFlags(), SetNextWindowChildFlags() helpers + made BeginChildEx() itself read from them. (#9503, #8280, #9412, #9499, #9393, #8488)

As a result BeginTable() doesn't need to read itself and pass that to BeginChildEx().
This commit is contained in:
ocornut
2026-08-05 20:38:18 +02:00
parent a5a3e1bd04
commit 6a6d7bc3ca
4 changed files with 38 additions and 23 deletions

View File

@@ -6537,6 +6537,9 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, I
ImGuiWindow* parent_window = g.CurrentWindow;
IM_ASSERT(id != 0);
if (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasChildFlags)
child_flags = (child_flags | g.NextWindowData.ChildFlagsSet) & ~g.NextWindowData.ChildFlagsClear;
// Sanity check as it is likely that some user will accidentally pass ImGuiWindowFlags into the ImGuiChildFlags argument.
const ImGuiChildFlags ImGuiChildFlags_SupportedMask_ = ImGuiChildFlags_Borders | ImGuiChildFlags_AlwaysUseWindowPadding | ImGuiChildFlags_ResizeX | ImGuiChildFlags_ResizeY | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_FrameStyle | ImGuiChildFlags_NavFlattened;
IM_UNUSED(ImGuiChildFlags_SupportedMask_);
@@ -6599,13 +6602,7 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, I
}
}
SetNextWindowSize(size);
// Forward child flags (we allow prior settings to merge but it'll only work for adding flags)
if (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasChildFlags)
g.NextWindowData.ChildFlags |= child_flags;
else
g.NextWindowData.ChildFlags = child_flags;
g.NextWindowData.HasFlags |= ImGuiNextWindowDataFlags_HasChildFlags;
SetNextWindowChildFlags(child_flags, true);
// 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.
// FIXME: 2023/11/14: commented out shorted version. We had an issue with multiple ### in child window path names, which the trailing hash helped workaround.
@@ -7550,6 +7547,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
if (g.DebugBreakInWindow == window->ID)
IM_DEBUG_BREAK();
if (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasWindowFlags)
flags = (flags | g.NextWindowData.WindowFlagsSet) & ~g.NextWindowData.WindowFlagsClear;
// Automatically disable manual moving/resizing when NoInputs is set
if ((flags & ImGuiWindowFlags_NoInputs) == ImGuiWindowFlags_NoInputs)
flags |= ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize;
@@ -7575,7 +7575,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
{
UpdateWindowInFocusOrderList(window, window_just_created, flags);
window->Flags = (ImGuiWindowFlags)flags;
window->ChildFlags = (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasChildFlags) ? g.NextWindowData.ChildFlags : 0;
window->ChildFlags = (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasChildFlags) ? g.NextWindowData.ChildFlagsSet : 0;
window->LastFrameActive = current_frame;
window->LastTimeActive = (float)g.Time;
window->BeginOrderWithinParent = 0;
@@ -8834,6 +8834,26 @@ void ImGui::SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags)
g.NextWindowData.RefreshFlagsVal = flags;
}
void ImGui::SetNextWindowFlags(ImGuiWindowFlags flags, bool enabled)
{
ImGuiContext& g = *GImGui;
if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasWindowFlags) == 0)
g.NextWindowData.WindowFlagsSet = g.NextWindowData.WindowFlagsClear = ImGuiChildFlags_None;
g.NextWindowData.WindowFlagsSet = enabled ? (g.NextWindowData.WindowFlagsSet | flags) : (g.NextWindowData.WindowFlagsSet & ~flags);
g.NextWindowData.WindowFlagsClear = !enabled ? (g.NextWindowData.WindowFlagsClear | flags) : (g.NextWindowData.WindowFlagsClear & ~flags);
g.NextWindowData.HasFlags |= ImGuiNextWindowDataFlags_HasWindowFlags;
}
void ImGui::SetNextWindowChildFlags(ImGuiChildFlags flags, bool enabled)
{
ImGuiContext& g = *GImGui;
if ((g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasChildFlags) == 0)
g.NextWindowData.ChildFlagsSet = g.NextWindowData.ChildFlagsClear = ImGuiChildFlags_None;
g.NextWindowData.ChildFlagsSet = enabled ? (g.NextWindowData.ChildFlagsSet | flags) : (g.NextWindowData.ChildFlagsSet & ~flags);
g.NextWindowData.ChildFlagsClear = !enabled ? (g.NextWindowData.ChildFlagsClear | flags) : (g.NextWindowData.ChildFlagsClear & ~flags);
g.NextWindowData.HasFlags |= ImGuiNextWindowDataFlags_HasChildFlags;
}
ImDrawList* ImGui::GetWindowDrawList()
{
ImGuiWindow* window = GetCurrentWindow();
@@ -12674,13 +12694,7 @@ bool ImGui::BeginPopupMenuEx(ImGuiID id, const char* label, ImGuiWindowFlags ext
// As we bypass BeginChild(), set ImGuiChildFlags_AlwaysAutoResize as it is checked independently from ImGuiWindowFlags_AlwaysAutoResize for now (see #9355)
// Ideally we should remove setting ImGuiWindowFlags_AlwaysAutoResize in BeginChild().
if ((extra_window_flags & ImGuiWindowFlags_ChildWindow) && (extra_window_flags & ImGuiWindowFlags_AlwaysAutoResize))
{
if (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasChildFlags)
g.NextWindowData.ChildFlags |= ImGuiChildFlags_AlwaysAutoResize;
else
g.NextWindowData.ChildFlags = ImGuiChildFlags_AlwaysAutoResize;
g.NextWindowData.HasFlags |= ImGuiNextWindowDataFlags_HasChildFlags;
}
SetNextWindowChildFlags(ImGuiChildFlags_AlwaysAutoResize, true);
char name[128];
IM_ASSERT(extra_window_flags & ImGuiWindowFlags_ChildMenu);

View File

@@ -30,7 +30,7 @@
// Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.93.0 WIP"
#define IMGUI_VERSION_NUM 19292
#define IMGUI_VERSION_NUM 19293
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198

View File

@@ -1360,8 +1360,10 @@ struct ImGuiNextWindowData
ImVec2 SizeVal;
ImVec2 ContentSizeVal;
ImVec2 ScrollVal;
ImGuiWindowFlags WindowFlags; // Only honored by BeginTable()
ImGuiChildFlags ChildFlags;
ImGuiWindowFlags WindowFlagsSet; // Flags to set. Use SetNextWindowFlags()!
ImGuiWindowFlags WindowFlagsClear;
ImGuiChildFlags ChildFlagsSet; // Flags to set. Use SetNextWindowChildFlags().
ImGuiChildFlags ChildFlagsClear;
bool CollapsedVal;
ImRect SizeConstraintRect;
ImGuiSizeCallback SizeCallback;
@@ -3368,6 +3370,8 @@ namespace ImGui
inline ImRect WindowRectRelToAbs(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x + off.x, r.Min.y + off.y, r.Max.x + off.x, r.Max.y + off.y); }
inline ImVec2 WindowPosAbsToRel(ImGuiWindow* window, const ImVec2& p) { ImVec2 off = window->DC.CursorStartPos; return ImVec2(p.x - off.x, p.y - off.y); }
inline ImVec2 WindowPosRelToAbs(ImGuiWindow* window, const ImVec2& p) { ImVec2 off = window->DC.CursorStartPos; return ImVec2(p.x + off.x, p.y + off.y); }
IMGUI_API void SetNextWindowFlags(ImGuiWindowFlags flags, bool enabled);
IMGUI_API void SetNextWindowChildFlags(ImGuiChildFlags flags, bool enabled);
// Windows: Display Order and Focus Order
IMGUI_API void FocusWindow(ImGuiWindow* window, ImGuiFocusRequestFlags flags = 0);

View File

@@ -428,11 +428,8 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
SetNextWindowScroll(ImVec2(0.0f, 0.0f));
// Create scrolling region (without border and zero window padding)
ImGuiChildFlags child_child_flags = (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasChildFlags) ? g.NextWindowData.ChildFlags : ImGuiChildFlags_None;
ImGuiWindowFlags child_window_flags = (g.NextWindowData.HasFlags & ImGuiNextWindowDataFlags_HasWindowFlags) ? g.NextWindowData.WindowFlags : ImGuiWindowFlags_None;
if (flags & ImGuiTableFlags_ScrollX)
child_window_flags |= ImGuiWindowFlags_HorizontalScrollbar;
BeginChildEx(name, instance_id, outer_rect.GetSize(), child_child_flags, child_window_flags);
ImGuiWindowFlags child_window_flags = (flags & ImGuiTableFlags_ScrollX) ? ImGuiWindowFlags_HorizontalScrollbar : ImGuiWindowFlags_None;
BeginChildEx(name, instance_id, outer_rect.GetSize(), ImGuiChildFlags_None, child_window_flags);
table->InnerWindow = g.CurrentWindow;
table->WorkRect = table->InnerWindow->WorkRect;
table->OuterRect = table->InnerWindow->Rect();