Merge branch 'master' into docking

# Conflicts:
#	imgui.cpp
This commit is contained in:
ocornut
2020-11-13 22:04:28 +01:00
12 changed files with 242 additions and 235 deletions

236
imgui.cpp
View File

@ -884,7 +884,6 @@ static int FindWindowFocusIndex(ImGuiWindow* window);
// Error Checking
static void ErrorCheckNewFrameSanityChecks();
static void ErrorCheckEndFrameSanityChecks();
static void ErrorCheckBeginEndCompareStacksSize(ImGuiWindow* window, bool write);
// Misc
static void UpdateSettings();
@ -2389,7 +2388,7 @@ void ImGui::PushStyleColor(ImGuiCol idx, ImU32 col)
ImGuiColorMod backup;
backup.Col = idx;
backup.BackupValue = g.Style.Colors[idx];
g.ColorModifiers.push_back(backup);
g.ColorStack.push_back(backup);
g.Style.Colors[idx] = ColorConvertU32ToFloat4(col);
}
@ -2399,7 +2398,7 @@ void ImGui::PushStyleColor(ImGuiCol idx, const ImVec4& col)
ImGuiColorMod backup;
backup.Col = idx;
backup.BackupValue = g.Style.Colors[idx];
g.ColorModifiers.push_back(backup);
g.ColorStack.push_back(backup);
g.Style.Colors[idx] = col;
}
@ -2408,9 +2407,9 @@ void ImGui::PopStyleColor(int count)
ImGuiContext& g = *GImGui;
while (count > 0)
{
ImGuiColorMod& backup = g.ColorModifiers.back();
ImGuiColorMod& backup = g.ColorStack.back();
g.Style.Colors[backup.Col] = backup.BackupValue;
g.ColorModifiers.pop_back();
g.ColorStack.pop_back();
count--;
}
}
@ -2464,7 +2463,7 @@ void ImGui::PushStyleVar(ImGuiStyleVar idx, float val)
{
ImGuiContext& g = *GImGui;
float* pvar = (float*)var_info->GetVarPtr(&g.Style);
g.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar));
g.StyleVarStack.push_back(ImGuiStyleMod(idx, *pvar));
*pvar = val;
return;
}
@ -2478,7 +2477,7 @@ void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val)
{
ImGuiContext& g = *GImGui;
ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&g.Style);
g.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar));
g.StyleVarStack.push_back(ImGuiStyleMod(idx, *pvar));
*pvar = val;
return;
}
@ -2491,12 +2490,12 @@ void ImGui::PopStyleVar(int count)
while (count > 0)
{
// We avoid a generic memcpy(data, &backup.Backup.., GDataTypeSize[info->Type] * info->Count), the overhead in Debug is not worth it.
ImGuiStyleMod& backup = g.StyleModifiers.back();
ImGuiStyleMod& backup = g.StyleVarStack.back();
const ImGuiStyleVarInfo* info = GetStyleVarInfo(backup.VarIdx);
void* data = info->GetVarPtr(&g.Style);
if (info->Type == ImGuiDataType_Float && info->Count == 1) { ((float*)data)[0] = backup.BackupFloat[0]; }
else if (info->Type == ImGuiDataType_Float && info->Count == 2) { ((float*)data)[0] = backup.BackupFloat[0]; ((float*)data)[1] = backup.BackupFloat[1]; }
g.StyleModifiers.pop_back();
g.StyleVarStack.pop_back();
count--;
}
}
@ -2813,83 +2812,31 @@ void ImGui::RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFl
//-----------------------------------------------------------------------------
// ImGuiWindow is mostly a dumb struct. It merely has a constructor and a few helper methods
ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
: DrawListInst(&context->DrawListSharedData)
ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) : DrawListInst(NULL)
{
memset(this, 0, sizeof(*this));
Name = ImStrdup(name);
NameBufLen = (int)strlen(name) + 1;
ID = ImHashStr(name);
IDStack.push_back(ID);
Flags = FlagsPreviousFrame = ImGuiWindowFlags_None;
Viewport = NULL;
ViewportId = 0;
ViewportAllowPlatformMonitorExtend = -1;
ViewportPos = ImVec2(FLT_MAX, FLT_MAX);
Pos = ImVec2(0.0f, 0.0f);
Size = SizeFull = ImVec2(0.0f, 0.0f);
ContentSize = ContentSizeExplicit = ImVec2(0.0f, 0.0f);
WindowPadding = ImVec2(0.0f, 0.0f);
WindowRounding = 0.0f;
WindowBorderSize = 0.0f;
NameBufLen = (int)strlen(name) + 1;
MoveId = GetID("#MOVE");
ChildId = 0;
Scroll = ImVec2(0.0f, 0.0f);
ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f);
ScrollbarSizes = ImVec2(0.0f, 0.0f);
ScrollbarX = ScrollbarY = false;
ViewportOwned = false;
Active = WasActive = false;
WriteAccessed = false;
Collapsed = false;
WantCollapseToggle = false;
SkipItems = false;
Appearing = false;
Hidden = false;
IsFallbackWindow = false;
HasCloseButton = false;
ResizeBorderHeld = -1;
BeginCount = 0;
BeginOrderWithinParent = -1;
BeginOrderWithinContext = -1;
PopupId = 0;
AutoFitFramesX = AutoFitFramesY = -1;
AutoFitChildAxises = 0x00;
AutoFitOnlyGrows = false;
AutoPosLastDirection = ImGuiDir_None;
HiddenFramesCanSkipItems = HiddenFramesCannotSkipItems = 0;
SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = SetWindowDockAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing;
SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX);
InnerRect = ImRect(0.0f, 0.0f, 0.0f, 0.0f); // Clear so the InnerRect.GetSize() code in Begin() doesn't lead to overflow even if the result isn't used.
LastFrameActive = -1;
LastFrameJustFocused = -1;
LastTimeActive = -1.0f;
ItemWidthDefault = 0.0f;
FontWindowScale = FontDpiScale = 1.0f;
SettingsOffset = -1;
DrawList = &DrawListInst;
DrawList->_OwnerName = Name;
ParentWindow = NULL;
RootWindow = NULL;
RootWindowDockStop = NULL;
RootWindowForTitleBarHighlight = NULL;
RootWindowForNav = NULL;
NavLastIds[0] = NavLastIds[1] = 0;
NavRectRel[0] = NavRectRel[1] = ImRect();
NavLastChildNavWindow = NULL;
MemoryCompacted = false;
MemoryDrawListIdxCapacity = MemoryDrawListVtxCapacity = 0;
DockNode = DockNodeAsHost = NULL;
DockId = 0;
DockTabItemStatusFlags = ImGuiItemStatusFlags_None;
DockOrder = -1;
DockIsActive = DockTabIsVisible = DockTabWantClose = false;
DrawList = &DrawListInst;
DrawList->_Data = &context->DrawListSharedData;
DrawList->_OwnerName = Name;
}
ImGuiWindow::~ImGuiWindow()
@ -2987,11 +2934,16 @@ static void SetCurrentWindow(ImGuiWindow* window)
g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize();
}
void ImGui::GcCompactTransientMiscBuffers()
{
ImGuiContext& g = *GImGui;
g.ItemFlagsStack.clear();
g.GroupStack.clear();
}
// Free up/compact internal window buffers, we can use this when a window becomes unused.
// This is currently unused by the library, but you may call this yourself for easy GC.
// Not freed:
// - ImGuiWindow, ImGuiWindowSettings, Name
// - StateStorage, ColumnsStorage (may hold useful data)
// - ImGuiWindow, ImGuiWindowSettings, Name, StateStorage, ColumnsStorage (may hold useful data)
// This should have no noticeable visual effect. When the window reappear however, expect new allocation/buffer growth/copy cost.
void ImGui::GcCompactTransientWindowBuffers(ImGuiWindow* window)
{
@ -3001,10 +2953,8 @@ void ImGui::GcCompactTransientWindowBuffers(ImGuiWindow* window)
window->IDStack.clear();
window->DrawList->_ClearFreeMemory();
window->DC.ChildWindows.clear();
window->DC.ItemFlagsStack.clear();
window->DC.ItemWidthStack.clear();
window->DC.TextWrapPosStack.clear();
window->DC.GroupStack.clear();
}
void ImGui::GcAwakeTransientWindowBuffers(ImGuiWindow* window)
@ -4066,7 +4016,7 @@ void ImGui::NewFrame()
// Mark all windows as not visible and compact unused memory.
IM_ASSERT(g.WindowsFocusOrder.Size == g.Windows.Size);
const float memory_compact_start_time = (g.IO.ConfigMemoryCompactTimer >= 0.0f) ? (float)g.Time - g.IO.ConfigMemoryCompactTimer : FLT_MAX;
const float memory_compact_start_time = (g.GcCompactAll || g.IO.ConfigMemoryCompactTimer < 0.0f) ? FLT_MAX : (float)g.Time - g.IO.ConfigMemoryCompactTimer;
for (int i = 0; i != g.Windows.Size; i++)
{
ImGuiWindow* window = g.Windows[i];
@ -4079,6 +4029,9 @@ void ImGui::NewFrame()
if (!window->WasActive && !window->MemoryCompacted && window->LastTimeActive < memory_compact_start_time)
GcCompactTransientWindowBuffers(window);
}
if (g.GcCompactAll)
GcCompactTransientMiscBuffers();
g.GcCompactAll = false;
// Closing the focused window restore focus to the first active root window in descending z-order
if (g.NavWindow && !g.NavWindow->WasActive)
@ -4088,6 +4041,9 @@ void ImGui::NewFrame()
// But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear.
g.CurrentWindowStack.resize(0);
g.BeginPopupStack.resize(0);
g.ItemFlagsStack.resize(0);
g.ItemFlagsStack.push_back(ImGuiItemFlags_Default_);
g.GroupStack.resize(0);
ClosePopupsOverWindow(g.NavWindow, false);
// Docking
@ -4229,8 +4185,8 @@ void ImGui::Shutdown(ImGuiContext* context)
g.HoveredWindow = g.HoveredRootWindow = g.HoveredWindowUnderMovingWindow = NULL;
g.ActiveIdWindow = g.ActiveIdPreviousFrameWindow = NULL;
g.MovingWindow = NULL;
g.ColorModifiers.clear();
g.StyleModifiers.clear();
g.ColorStack.clear();
g.StyleVarStack.clear();
g.FontStack.clear();
g.OpenPopupStack.clear();
g.BeginPopupStack.clear();
@ -4296,7 +4252,7 @@ static void AddWindowToSortBuffer(ImVector<ImGuiWindow*>* out_sorted_windows, Im
static void AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* draw_list)
{
// Remove trailing command if unused.
// Technically we could return directly instead of popping, but this make things looks neat in Metrics window as well.
// Technically we could return directly instead of popping, but this make things looks neat in Metrics/Debugger window as well.
draw_list->_PopUnusedDrawCmd();
if (draw_list->CmdBuffer.Size == 0)
return;
@ -4311,7 +4267,7 @@ static void AddDrawListToDrawData(ImVector<ImDrawList*>* out_list, ImDrawList* d
// Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = unsigned short = 2 bytes = 64K vertices per ImDrawList = per window)
// If this assert triggers because you are drawing lots of stuff manually:
// - First, make sure you are coarse clipping yourself and not trying to draw many things outside visible bounds.
// Be mindful that the ImDrawList API doesn't filter vertices. Use the Metrics window to inspect draw list contents.
// Be mindful that the ImDrawList API doesn't filter vertices. Use the Metrics/Debugger window to inspect draw list contents.
// - If you want large meshes with more than 64K vertices, you can either:
// (A) Handle the ImDrawCmd::VtxOffset value in your renderer backend, and set 'io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset'.
// Most example backends already support this from 1.71. Pre-1.71 backends won't.
@ -4989,12 +4945,13 @@ bool ImGui::IsItemDeactivatedAfterEdit()
return IsItemDeactivated() && (g.ActiveIdPreviousFrameHasBeenEditedBefore || (g.ActiveId == 0 && g.ActiveIdHasBeenEditedBefore));
}
// == GetItemID() == GetFocusID()
bool ImGui::IsItemFocused()
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
if (g.NavId == 0 || g.NavDisableHighlight || g.NavId != window->DC.LastItemId)
if (g.NavId != window->DC.LastItemId || g.NavId == 0)
return false;
// Special handling for the dummy item after Begin() which represent the title bar or tab.
@ -5971,8 +5928,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Add to stack
// We intentionally set g.CurrentWindow to NULL to prevent usage until when the viewport is set, then will call SetCurrentWindow()
g.CurrentWindowStack.push_back(window);
g.CurrentWindow = window;
window->DC.StackSizesOnBegin.SetToCurrentState();
g.CurrentWindow = NULL;
ErrorCheckBeginEndCompareStacksSize(window, true);
if (flags & ImGuiWindowFlags_Popup)
{
ImGuiPopupData& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size];
@ -6569,7 +6528,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->DC.NavLayerCurrent = ImGuiNavLayer_Main;
window->DC.NavLayerActiveMask = window->DC.NavLayerActiveMaskNext;
window->DC.NavLayerActiveMaskNext = 0x00;
window->DC.NavFocusScopeIdCurrent = (flags & ImGuiWindowFlags_ChildWindow) ? parent_window->DC.NavFocusScopeIdCurrent : 0; // -V595
window->DC.NavHideHighlightOneFrame = false;
window->DC.NavHasScroll = (window->ScrollMax.y > 0.0f);
@ -6586,13 +6544,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->DC.ItemWidth = window->ItemWidthDefault;
window->DC.TextWrapPos = -1.0f; // disabled
window->DC.ItemFlagsStack.resize(0);
window->DC.ItemWidthStack.resize(0);
window->DC.TextWrapPosStack.resize(0);
window->DC.GroupStack.resize(0);
window->DC.ItemFlags = parent_window ? parent_window->DC.ItemFlags : ImGuiItemFlags_Default_;
if (parent_window)
window->DC.ItemFlagsStack.push_back(window->DC.ItemFlags);
if (window->AutoFitFramesX > 0)
window->AutoFitFramesX--;
@ -6668,13 +6621,15 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
SetCurrentWindow(window);
}
// Pull/inherit current state
window->DC.ItemFlags = g.ItemFlagsStack.back(); // Inherit from shared stack
window->DC.NavFocusScopeIdCurrent = (flags & ImGuiWindowFlags_ChildWindow) ? parent_window->DC.NavFocusScopeIdCurrent : 0; // Inherit from parent only // -V595
if (!(flags & ImGuiWindowFlags_DockNodeHost))
PushClipRect(window->InnerClipRect.Min, window->InnerClipRect.Max, true);
// Clear 'accessed' flag last thing (After PushClipRect which will set the flag. We want the flag to stay false when the default "Debug" window is unused)
if (first_begin_of_the_frame)
window->WriteAccessed = false;
window->WriteAccessed = false;
window->BeginCount++;
g.NextWindowData.ClearFlags();
@ -6763,7 +6718,7 @@ void ImGui::End()
g.CurrentWindowStack.pop_back();
if (window->Flags & ImGuiWindowFlags_Popup)
g.BeginPopupStack.pop_back();
ErrorCheckBeginEndCompareStacksSize(window, false);
window->DC.StackSizesOnBegin.CompareWithCurrentState();
SetCurrentWindow(g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back());
if (g.CurrentWindow)
SetCurrentViewport(g.CurrentWindow, g.CurrentWindow->Viewport);
@ -6929,19 +6884,25 @@ void ImGui::PopFont()
void ImGui::PushItemFlag(ImGuiItemFlags option, bool enabled)
{
ImGuiWindow* window = GetCurrentWindow();
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
ImGuiItemFlags item_flags = window->DC.ItemFlags;
IM_ASSERT(item_flags == g.ItemFlagsStack.back());
if (enabled)
window->DC.ItemFlags |= option;
item_flags |= option;
else
window->DC.ItemFlags &= ~option;
window->DC.ItemFlagsStack.push_back(window->DC.ItemFlags);
item_flags &= ~option;
window->DC.ItemFlags = item_flags;
g.ItemFlagsStack.push_back(item_flags);
}
void ImGui::PopItemFlag()
{
ImGuiWindow* window = GetCurrentWindow();
window->DC.ItemFlagsStack.pop_back();
window->DC.ItemFlags = window->DC.ItemFlagsStack.empty() ? ImGuiItemFlags_Default_ : window->DC.ItemFlagsStack.back();
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
IM_ASSERT(g.ItemFlagsStack.Size > 1); // Too many calls to PopItemFlag() - we always leave a 0 at the bottom of the stack.
g.ItemFlagsStack.pop_back();
window->DC.ItemFlags = g.ItemFlagsStack.back();
}
// FIXME: Look into renaming this once we have settled the new Focus/Activation/TabStop system.
@ -7371,12 +7332,11 @@ void ImGui::ActivateItem(ImGuiID id)
g.NavNextActivateId = id;
}
// Note: this is storing in same stack as IDStack, so Push/Pop mismatch will be reported there.
void ImGui::PushFocusScope(ImGuiID id)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
window->IDStack.push_back(window->DC.NavFocusScopeIdCurrent);
g.FocusScopeStack.push_back(window->DC.NavFocusScopeIdCurrent);
window->DC.NavFocusScopeIdCurrent = id;
}
@ -7384,8 +7344,9 @@ void ImGui::PopFocusScope()
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
window->DC.NavFocusScopeIdCurrent = window->IDStack.back();
window->IDStack.pop_back();
IM_ASSERT(g.FocusScopeStack.Size > 0); // Too many PopFocusScope() ?
window->DC.NavFocusScopeIdCurrent = g.FocusScopeStack.back();
g.FocusScopeStack.pop_back();
}
void ImGui::SetKeyboardFocusHere(int offset)
@ -7484,6 +7445,7 @@ ImGuiID ImGui::GetIDWithSeed(const char* str, const char* str_end, ImGuiID seed)
void ImGui::PopID()
{
ImGuiWindow* window = GImGui->CurrentWindow;
IM_ASSERT(window->IDStack.Size > 1); // Too many PopID(), or could be popping in a wrong/different window?
window->IDStack.pop_back();
}
@ -7622,9 +7584,13 @@ static void ImGui::ErrorCheckEndFrameSanityChecks()
// Verify that io.KeyXXX fields haven't been tampered with. Key mods should not be modified between NewFrame() and EndFrame()
// One possible reason leading to this assert is that your backends update inputs _AFTER_ NewFrame().
const ImGuiKeyModFlags expected_key_mod_flags = GetMergedKeyModFlags();
IM_ASSERT(g.IO.KeyMods == expected_key_mod_flags && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods");
IM_UNUSED(expected_key_mod_flags);
// It is known that when some modal native windows called mid-frame takes focus away, some backends such as GLFW will
// send key release events mid-frame. This would normally trigger this assertion and lead to sheared inputs.
// We silently accommodate for this case by ignoring/ the case where all io.KeyXXX modifiers were released (aka key_mod_flags == 0),
// while still correctly asserting on mid-frame key press events.
const ImGuiKeyModFlags key_mod_flags = GetMergedKeyModFlags();
IM_ASSERT((key_mod_flags == 0 || g.IO.KeyMods == key_mod_flags) && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods");
IM_UNUSED(key_mod_flags);
// Report when there is a mismatch of Begin/BeginChild vs End/EndChild calls. Important: Remember that the Begin/BeginChild API requires you
// to always call End/EndChild even if Begin/BeginChild returns false! (this is unfortunately inconsistent with most other Begin* API).
@ -7641,28 +7607,42 @@ static void ImGui::ErrorCheckEndFrameSanityChecks()
IM_ASSERT_USER_ERROR(g.CurrentWindowStack.Size == 1, "Mismatched Begin/BeginChild vs End/EndChild calls: did you call End/EndChild too much?");
}
}
IM_ASSERT_USER_ERROR(g.GroupStack.Size == 0, "Missing EndGroup call!");
}
// Save and compare stack sizes on Begin()/End() to detect usage errors
// Begin() calls this with write=true
// End() calls this with write=false
static void ImGui::ErrorCheckBeginEndCompareStacksSize(ImGuiWindow* window, bool write)
// Save current stack sizes for later compare
void ImGuiStackSizes::SetToCurrentState()
{
ImGuiContext& g = *GImGui;
short* p = &window->DC.StackSizesBackup[0];
ImGuiWindow* window = g.CurrentWindow;
SizeOfIDStack = (short)window->IDStack.Size;
SizeOfColorStack = (short)g.ColorStack.Size;
SizeOfStyleVarStack = (short)g.StyleVarStack.Size;
SizeOfFontStack = (short)g.FontStack.Size;
SizeOfFocusScopeStack = (short)g.FocusScopeStack.Size;
SizeOfGroupStack = (short)g.GroupStack.Size;
SizeOfBeginPopupStack = (short)g.BeginPopupStack.Size;
}
// Compare to detect usage errors
void ImGuiStackSizes::CompareWithCurrentState()
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
// Window stacks
// NOT checking: DC.ItemWidth, DC.AllowKeyboardFocus, DC.ButtonRepeat, DC.TextWrapPos (per window) to allow user to conveniently push once and not pop (they are cleared on Begin)
{ int n = window->IDStack.Size; if (write) *p = (short)n; else IM_ASSERT(*p == n && "PushID/PopID or TreeNode/TreePop Mismatch!"); p++; } // Too few or too many PopID()/TreePop()
{ int n = window->DC.GroupStack.Size; if (write) *p = (short)n; else IM_ASSERT(*p == n && "BeginGroup/EndGroup Mismatch!"); p++; } // Too few or too many EndGroup()
// NOT checking: DC.ItemWidth, DC.TextWrapPos (per window) to allow user to conveniently push once and not pop (they are cleared on Begin)
IM_ASSERT(SizeOfIDStack == window->IDStack.Size && "PushID/PopID or TreeNode/TreePop Mismatch!");
// Global stacks
// For color, style and font stacks there is an incentive to use Push/Begin/Pop/.../End patterns, so we relax our checks a little to allow them.
{ int n = g.BeginPopupStack.Size; if (write) *p = (short)n; else IM_ASSERT(*p == n && "BeginMenu/EndMenu or BeginPopup/EndPopup Mismatch!"); p++; }// Too few or too many EndMenu()/EndPopup()
{ int n = g.ColorModifiers.Size; if (write) *p = (short)n; else IM_ASSERT(*p >= n && "PushStyleColor/PopStyleColor Mismatch!"); p++; } // Too few or too many PopStyleColor()
{ int n = g.StyleModifiers.Size; if (write) *p = (short)n; else IM_ASSERT(*p >= n && "PushStyleVar/PopStyleVar Mismatch!"); p++; } // Too few or too many PopStyleVar()
{ int n = g.FontStack.Size; if (write) *p = (short)n; else IM_ASSERT(*p >= n && "PushFont/PopFont Mismatch!"); p++; } // Too few or too many PopFont()
IM_ASSERT(p == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup));
IM_ASSERT(SizeOfGroupStack == g.GroupStack.Size && "BeginGroup/EndGroup Mismatch!");
IM_ASSERT(SizeOfBeginPopupStack == g.BeginPopupStack.Size && "BeginPopup/EndPopup or BeginMenu/EndMenu Mismatch!");
IM_ASSERT(SizeOfColorStack >= g.ColorStack.Size && "PushStyleColor/PopStyleColor Mismatch!");
IM_ASSERT(SizeOfStyleVarStack >= g.StyleVarStack.Size && "PushStyleVar/PopStyleVar Mismatch!");
IM_ASSERT(SizeOfFontStack >= g.FontStack.Size && "PushFont/PopFont Mismatch!");
IM_ASSERT(SizeOfFocusScopeStack == g.FocusScopeStack.Size && "PushFocusScope/PopFocusScope Mismatch!");
}
@ -8065,8 +8045,9 @@ void ImGui::BeginGroup()
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
window->DC.GroupStack.resize(window->DC.GroupStack.Size + 1);
ImGuiGroupData& group_data = window->DC.GroupStack.back();
g.GroupStack.resize(g.GroupStack.Size + 1);
ImGuiGroupData& group_data = g.GroupStack.back();
group_data.WindowID = window->ID;
group_data.BackupCursorPos = window->DC.CursorPos;
group_data.BackupCursorMaxPos = window->DC.CursorMaxPos;
group_data.BackupIndent = window->DC.Indent;
@ -8089,9 +8070,10 @@ void ImGui::EndGroup()
{
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
IM_ASSERT(window->DC.GroupStack.Size > 0); // Mismatched BeginGroup()/EndGroup() calls
IM_ASSERT(g.GroupStack.Size > 0); // Mismatched BeginGroup()/EndGroup() calls
ImGuiGroupData& group_data = window->DC.GroupStack.back();
ImGuiGroupData& group_data = g.GroupStack.back();
IM_ASSERT(group_data.WindowID == window->ID); // EndGroup() in wrong window?
ImRect group_bb(group_data.BackupCursorPos, ImMax(window->DC.CursorMaxPos, group_data.BackupCursorPos));
@ -8106,7 +8088,7 @@ void ImGui::EndGroup()
if (!group_data.EmitItem)
{
window->DC.GroupStack.pop_back();
g.GroupStack.pop_back();
return;
}
@ -8135,7 +8117,7 @@ void ImGui::EndGroup()
if (group_contains_prev_active_id && g.ActiveId != g.ActiveIdPreviousFrame)
window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_Deactivated;
window->DC.GroupStack.pop_back();
g.GroupStack.pop_back();
//window->DrawList->AddRect(group_bb.Min, group_bb.Max, IM_COL32(255,0,255,255)); // [Debug]
}
@ -15543,7 +15525,7 @@ static void MetricsHelpMarker(const char* desc)
void ImGui::ShowMetricsWindow(bool* p_open)
{
if (!Begin("Dear ImGui Metrics", p_open))
if (!Begin("Dear ImGui Metrics/Debugger", p_open))
{
End();
return;
@ -15559,6 +15541,8 @@ void ImGui::ShowMetricsWindow(bool* p_open)
Text("%d vertices, %d indices (%d triangles)", io.MetricsRenderVertices, io.MetricsRenderIndices, io.MetricsRenderIndices / 3);
Text("%d active windows (%d visible)", io.MetricsActiveWindows, io.MetricsRenderWindows);
Text("%d active allocations", io.MetricsActiveAllocations);
//SameLine(); if (SmallButton("GC")) { g.GcCompactAll = true; }
Separator();
// Debugging enums
@ -15569,7 +15553,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
if (cfg->ShowWindowsRectsType < 0)
cfg->ShowWindowsRectsType = WRT_WorkRect;
if (cfg->ShowTablesRectsType < 0)
cfg->ShowWindowsRectsType = TRT_WorkRect;
cfg->ShowTablesRectsType = TRT_WorkRect;
struct Funcs
{
@ -15597,7 +15581,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
MetricsHelpMarker("Will call the IM_DEBUG_BREAK() macro to break in debugger.\nWarning: If you don't have a debugger attached, this will probably crash.");
Checkbox("Show windows begin order", &cfg->ShowWindowsBeginOrder);
ImGui::Checkbox("Show windows rectangles", &cfg->ShowWindowsRects);
Checkbox("Show windows rectangles", &cfg->ShowWindowsRects);
SameLine();
SetNextItemWidth(GetFontSize() * 12);
cfg->ShowWindowsRects |= Combo("##show_windows_rect_type", &cfg->ShowWindowsRectsType, wrt_rects_names, WRT_Count, WRT_Count);
@ -15861,7 +15845,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
}
#endif // #ifdef IMGUI_HAS_DOCK
ImGui::End();
End();
}
// [DEBUG] Display contents of Columns