mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-14 17:07:01 +00:00
Internals: extracted stack checking code into a ImGuiStackSizes helper struct + added test for FocusScope
+ renamed g.ColorModifiers > g.ColorStack, g.StyleModifiers > g.StyleVarStack
This commit is contained in:
parent
6e94013a3d
commit
8119759329
63
imgui.cpp
63
imgui.cpp
@ -872,7 +872,6 @@ static int FindWindowFocusIndex(ImGuiWindow* window);
|
||||
// Error Checking
|
||||
static void ErrorCheckNewFrameSanityChecks();
|
||||
static void ErrorCheckEndFrameSanityChecks();
|
||||
static void ErrorCheckBeginEndCompareStacksSize(ImGuiWindow* window, bool begin);
|
||||
|
||||
// Misc
|
||||
static void UpdateSettings();
|
||||
@ -2352,7 +2351,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);
|
||||
}
|
||||
|
||||
@ -2362,7 +2361,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;
|
||||
}
|
||||
|
||||
@ -2371,9 +2370,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--;
|
||||
}
|
||||
}
|
||||
@ -2427,7 +2426,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;
|
||||
}
|
||||
@ -2441,7 +2440,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;
|
||||
}
|
||||
@ -2454,12 +2453,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--;
|
||||
}
|
||||
}
|
||||
@ -3996,8 +3995,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();
|
||||
@ -5515,8 +5514,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];
|
||||
@ -6112,7 +6113,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());
|
||||
}
|
||||
|
||||
@ -6903,26 +6904,38 @@ static void ImGui::ErrorCheckEndFrameSanityChecks()
|
||||
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 begin)
|
||||
// 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.TextWrapPos (per window) to allow user to conveniently push once and not pop (they are cleared on Begin)
|
||||
{ IM_ASSERT(window->IDStack.Size == 1 && "PushID/PopID or TreeNode/TreePop Mismatch!"); } // Too few or too many PopID()/TreePop();
|
||||
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.GroupStack.Size; if (begin) *p = (short)n; else IM_ASSERT(*p == n && "BeginGroup/EndGroup Mismatch!"); p++; } // Too few or too many EndGroup()
|
||||
{ int n = g.BeginPopupStack.Size; if (begin) *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 (begin) *p = (short)n; else IM_ASSERT(*p >= n && "PushStyleColor/PopStyleColor Mismatch!"); p++; } // Too few or too many PopStyleColor()
|
||||
{ int n = g.StyleModifiers.Size; if (begin) *p = (short)n; else IM_ASSERT(*p >= n && "PushStyleVar/PopStyleVar Mismatch!"); p++; } // Too few or too many PopStyleVar()
|
||||
{ int n = g.FontStack.Size; if (begin) *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!");
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,6 +23,7 @@ Index of this file:
|
||||
// [SECTION] Docking support
|
||||
// [SECTION] Viewport support
|
||||
// [SECTION] Settings support
|
||||
// [SECTION] Metrics, Debug
|
||||
// [SECTION] Generic context hooks
|
||||
// [SECTION] ImGuiContext (main imgui context)
|
||||
// [SECTION] ImGuiWindowTempData, ImGuiWindow
|
||||
@ -106,6 +107,7 @@ struct ImGuiNextWindowData; // Storage for SetNextWindow** functions
|
||||
struct ImGuiNextItemData; // Storage for SetNextItem** functions
|
||||
struct ImGuiPopupData; // Storage for current popup stack
|
||||
struct ImGuiSettingsHandler; // Storage for one type registered in the .ini file
|
||||
struct ImGuiStackSizes; // Storage of stack sizes for debugging/asserting
|
||||
struct ImGuiStyleMod; // Stacked style modifier, backup of modified data so we can restore it
|
||||
struct ImGuiTabBar; // Storage for a tab bar
|
||||
struct ImGuiTabItem; // Storage for a tab item (within a tab bar)
|
||||
@ -1089,6 +1091,10 @@ struct ImGuiSettingsHandler
|
||||
ImGuiSettingsHandler() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Metrics, Debug
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct ImGuiMetricsConfig
|
||||
{
|
||||
bool ShowWindowsRects;
|
||||
@ -1111,6 +1117,21 @@ struct ImGuiMetricsConfig
|
||||
}
|
||||
};
|
||||
|
||||
struct IMGUI_API ImGuiStackSizes
|
||||
{
|
||||
short SizeOfIDStack;
|
||||
short SizeOfColorStack;
|
||||
short SizeOfStyleVarStack;
|
||||
short SizeOfFontStack;
|
||||
short SizeOfFocusScopeStack;
|
||||
short SizeOfGroupStack;
|
||||
short SizeOfBeginPopupStack;
|
||||
|
||||
ImGuiStackSizes() { memset(this, 0, sizeof(*this)); }
|
||||
IMGUI_API void SetToCurrentState();
|
||||
IMGUI_API void CompareWithCurrentState();
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Generic context hooks
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1205,12 +1226,12 @@ struct ImGuiContext
|
||||
ImGuiNextItemData NextItemData; // Storage for SetNextItem** functions
|
||||
|
||||
// Shared stacks
|
||||
ImVector<ImGuiColorMod> ColorModifiers; // Stack for PushStyleColor()/PopStyleColor()
|
||||
ImVector<ImGuiStyleMod> StyleModifiers; // Stack for PushStyleVar()/PopStyleVar()
|
||||
ImVector<ImFont*> FontStack; // Stack for PushFont()/PopFont()
|
||||
ImVector<ImGuiID> FocusScopeStack; // Stack for PushFocusScope()/PopFocusScope()
|
||||
ImVector<ImGuiItemFlags>ItemFlagsStack; // Stack for PushItemFlag()/PopItemFlag()
|
||||
ImVector<ImGuiGroupData>GroupStack; // Stack for BeginGroup()/EndGroup()
|
||||
ImVector<ImGuiColorMod> ColorStack; // Stack for PushStyleColor()/PopStyleColor() - inherited by Begin()
|
||||
ImVector<ImGuiStyleMod> StyleVarStack; // Stack for PushStyleVar()/PopStyleVar() - inherited by Begin()
|
||||
ImVector<ImFont*> FontStack; // Stack for PushFont()/PopFont() - inherited by Begin()
|
||||
ImVector<ImGuiID> FocusScopeStack; // Stack for PushFocusScope()/PopFocusScope() - not inherited by Begin(), unless child window
|
||||
ImVector<ImGuiItemFlags>ItemFlagsStack; // Stack for PushItemFlag()/PopItemFlag() - inherited by Begin()
|
||||
ImVector<ImGuiGroupData>GroupStack; // Stack for BeginGroup()/EndGroup() - not inherited by Begin()
|
||||
ImVector<ImGuiPopupData>OpenPopupStack; // Which popups are open (persistent)
|
||||
ImVector<ImGuiPopupData>BeginPopupStack; // Which level of BeginPopup() we are in (reset every frame)
|
||||
|
||||
@ -1561,7 +1582,7 @@ struct IMGUI_API ImGuiWindowTempData
|
||||
float TextWrapPos; // == TextWrapPosStack.back() [empty == -1.0f]
|
||||
ImVector<float> ItemWidthStack;
|
||||
ImVector<float> TextWrapPosStack;
|
||||
short StackSizesBackup[5]; // Store size of various stacks for asserting
|
||||
ImGuiStackSizes StackSizesOnBegin; // Store size of various stacks for asserting
|
||||
};
|
||||
|
||||
// Storage for one window
|
||||
|
Loading…
Reference in New Issue
Block a user