mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-25 21:17: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
|
// Error Checking
|
||||||
static void ErrorCheckNewFrameSanityChecks();
|
static void ErrorCheckNewFrameSanityChecks();
|
||||||
static void ErrorCheckEndFrameSanityChecks();
|
static void ErrorCheckEndFrameSanityChecks();
|
||||||
static void ErrorCheckBeginEndCompareStacksSize(ImGuiWindow* window, bool begin);
|
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
static void UpdateSettings();
|
static void UpdateSettings();
|
||||||
@ -2352,7 +2351,7 @@ void ImGui::PushStyleColor(ImGuiCol idx, ImU32 col)
|
|||||||
ImGuiColorMod backup;
|
ImGuiColorMod backup;
|
||||||
backup.Col = idx;
|
backup.Col = idx;
|
||||||
backup.BackupValue = g.Style.Colors[idx];
|
backup.BackupValue = g.Style.Colors[idx];
|
||||||
g.ColorModifiers.push_back(backup);
|
g.ColorStack.push_back(backup);
|
||||||
g.Style.Colors[idx] = ColorConvertU32ToFloat4(col);
|
g.Style.Colors[idx] = ColorConvertU32ToFloat4(col);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2362,7 +2361,7 @@ void ImGui::PushStyleColor(ImGuiCol idx, const ImVec4& col)
|
|||||||
ImGuiColorMod backup;
|
ImGuiColorMod backup;
|
||||||
backup.Col = idx;
|
backup.Col = idx;
|
||||||
backup.BackupValue = g.Style.Colors[idx];
|
backup.BackupValue = g.Style.Colors[idx];
|
||||||
g.ColorModifiers.push_back(backup);
|
g.ColorStack.push_back(backup);
|
||||||
g.Style.Colors[idx] = col;
|
g.Style.Colors[idx] = col;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2371,9 +2370,9 @@ void ImGui::PopStyleColor(int count)
|
|||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
while (count > 0)
|
while (count > 0)
|
||||||
{
|
{
|
||||||
ImGuiColorMod& backup = g.ColorModifiers.back();
|
ImGuiColorMod& backup = g.ColorStack.back();
|
||||||
g.Style.Colors[backup.Col] = backup.BackupValue;
|
g.Style.Colors[backup.Col] = backup.BackupValue;
|
||||||
g.ColorModifiers.pop_back();
|
g.ColorStack.pop_back();
|
||||||
count--;
|
count--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2427,7 +2426,7 @@ void ImGui::PushStyleVar(ImGuiStyleVar idx, float val)
|
|||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
float* pvar = (float*)var_info->GetVarPtr(&g.Style);
|
float* pvar = (float*)var_info->GetVarPtr(&g.Style);
|
||||||
g.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar));
|
g.StyleVarStack.push_back(ImGuiStyleMod(idx, *pvar));
|
||||||
*pvar = val;
|
*pvar = val;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2441,7 +2440,7 @@ void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val)
|
|||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&g.Style);
|
ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&g.Style);
|
||||||
g.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar));
|
g.StyleVarStack.push_back(ImGuiStyleMod(idx, *pvar));
|
||||||
*pvar = val;
|
*pvar = val;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2454,12 +2453,12 @@ void ImGui::PopStyleVar(int count)
|
|||||||
while (count > 0)
|
while (count > 0)
|
||||||
{
|
{
|
||||||
// We avoid a generic memcpy(data, &backup.Backup.., GDataTypeSize[info->Type] * info->Count), the overhead in Debug is not worth it.
|
// 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);
|
const ImGuiStyleVarInfo* info = GetStyleVarInfo(backup.VarIdx);
|
||||||
void* data = info->GetVarPtr(&g.Style);
|
void* data = info->GetVarPtr(&g.Style);
|
||||||
if (info->Type == ImGuiDataType_Float && info->Count == 1) { ((float*)data)[0] = backup.BackupFloat[0]; }
|
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]; }
|
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--;
|
count--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3996,8 +3995,8 @@ void ImGui::Shutdown(ImGuiContext* context)
|
|||||||
g.HoveredWindow = g.HoveredRootWindow = g.HoveredWindowUnderMovingWindow = NULL;
|
g.HoveredWindow = g.HoveredRootWindow = g.HoveredWindowUnderMovingWindow = NULL;
|
||||||
g.ActiveIdWindow = g.ActiveIdPreviousFrameWindow = NULL;
|
g.ActiveIdWindow = g.ActiveIdPreviousFrameWindow = NULL;
|
||||||
g.MovingWindow = NULL;
|
g.MovingWindow = NULL;
|
||||||
g.ColorModifiers.clear();
|
g.ColorStack.clear();
|
||||||
g.StyleModifiers.clear();
|
g.StyleVarStack.clear();
|
||||||
g.FontStack.clear();
|
g.FontStack.clear();
|
||||||
g.OpenPopupStack.clear();
|
g.OpenPopupStack.clear();
|
||||||
g.BeginPopupStack.clear();
|
g.BeginPopupStack.clear();
|
||||||
@ -5515,8 +5514,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
|||||||
// Add to stack
|
// Add to stack
|
||||||
// We intentionally set g.CurrentWindow to NULL to prevent usage until when the viewport is set, then will call SetCurrentWindow()
|
// 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.CurrentWindowStack.push_back(window);
|
||||||
|
g.CurrentWindow = window;
|
||||||
|
window->DC.StackSizesOnBegin.SetToCurrentState();
|
||||||
g.CurrentWindow = NULL;
|
g.CurrentWindow = NULL;
|
||||||
ErrorCheckBeginEndCompareStacksSize(window, true);
|
|
||||||
if (flags & ImGuiWindowFlags_Popup)
|
if (flags & ImGuiWindowFlags_Popup)
|
||||||
{
|
{
|
||||||
ImGuiPopupData& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size];
|
ImGuiPopupData& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size];
|
||||||
@ -6112,7 +6113,7 @@ void ImGui::End()
|
|||||||
g.CurrentWindowStack.pop_back();
|
g.CurrentWindowStack.pop_back();
|
||||||
if (window->Flags & ImGuiWindowFlags_Popup)
|
if (window->Flags & ImGuiWindowFlags_Popup)
|
||||||
g.BeginPopupStack.pop_back();
|
g.BeginPopupStack.pop_back();
|
||||||
ErrorCheckBeginEndCompareStacksSize(window, false);
|
window->DC.StackSizesOnBegin.CompareWithCurrentState();
|
||||||
SetCurrentWindow(g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back());
|
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!");
|
IM_ASSERT_USER_ERROR(g.GroupStack.Size == 0, "Missing EndGroup call!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save and compare stack sizes on Begin()/End() to detect usage errors
|
// Save current stack sizes for later compare
|
||||||
// Begin() calls this with write=true
|
void ImGuiStackSizes::SetToCurrentState()
|
||||||
// End() calls this with write=false
|
|
||||||
static void ImGui::ErrorCheckBeginEndCompareStacksSize(ImGuiWindow* window, bool begin)
|
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
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
|
// 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)
|
// 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
|
// 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.
|
// 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()
|
IM_ASSERT(SizeOfGroupStack == g.GroupStack.Size && "BeginGroup/EndGroup Mismatch!");
|
||||||
{ 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()
|
IM_ASSERT(SizeOfBeginPopupStack == g.BeginPopupStack.Size && "BeginPopup/EndPopup or BeginMenu/EndMenu Mismatch!");
|
||||||
{ 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()
|
IM_ASSERT(SizeOfColorStack >= g.ColorStack.Size && "PushStyleColor/PopStyleColor Mismatch!");
|
||||||
{ 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()
|
IM_ASSERT(SizeOfStyleVarStack >= g.StyleVarStack.Size && "PushStyleVar/PopStyleVar Mismatch!");
|
||||||
{ 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(SizeOfFontStack >= g.FontStack.Size && "PushFont/PopFont Mismatch!");
|
||||||
IM_ASSERT(p == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup));
|
IM_ASSERT(SizeOfFocusScopeStack == g.FocusScopeStack.Size && "PushFocusScope/PopFocusScope Mismatch!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@ Index of this file:
|
|||||||
// [SECTION] Docking support
|
// [SECTION] Docking support
|
||||||
// [SECTION] Viewport support
|
// [SECTION] Viewport support
|
||||||
// [SECTION] Settings support
|
// [SECTION] Settings support
|
||||||
|
// [SECTION] Metrics, Debug
|
||||||
// [SECTION] Generic context hooks
|
// [SECTION] Generic context hooks
|
||||||
// [SECTION] ImGuiContext (main imgui context)
|
// [SECTION] ImGuiContext (main imgui context)
|
||||||
// [SECTION] ImGuiWindowTempData, ImGuiWindow
|
// [SECTION] ImGuiWindowTempData, ImGuiWindow
|
||||||
@ -106,6 +107,7 @@ struct ImGuiNextWindowData; // Storage for SetNextWindow** functions
|
|||||||
struct ImGuiNextItemData; // Storage for SetNextItem** functions
|
struct ImGuiNextItemData; // Storage for SetNextItem** functions
|
||||||
struct ImGuiPopupData; // Storage for current popup stack
|
struct ImGuiPopupData; // Storage for current popup stack
|
||||||
struct ImGuiSettingsHandler; // Storage for one type registered in the .ini file
|
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 ImGuiStyleMod; // Stacked style modifier, backup of modified data so we can restore it
|
||||||
struct ImGuiTabBar; // Storage for a tab bar
|
struct ImGuiTabBar; // Storage for a tab bar
|
||||||
struct ImGuiTabItem; // Storage for a tab item (within 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)); }
|
ImGuiSettingsHandler() { memset(this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// [SECTION] Metrics, Debug
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
struct ImGuiMetricsConfig
|
struct ImGuiMetricsConfig
|
||||||
{
|
{
|
||||||
bool ShowWindowsRects;
|
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
|
// [SECTION] Generic context hooks
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -1205,12 +1226,12 @@ struct ImGuiContext
|
|||||||
ImGuiNextItemData NextItemData; // Storage for SetNextItem** functions
|
ImGuiNextItemData NextItemData; // Storage for SetNextItem** functions
|
||||||
|
|
||||||
// Shared stacks
|
// Shared stacks
|
||||||
ImVector<ImGuiColorMod> ColorModifiers; // Stack for PushStyleColor()/PopStyleColor()
|
ImVector<ImGuiColorMod> ColorStack; // Stack for PushStyleColor()/PopStyleColor() - inherited by Begin()
|
||||||
ImVector<ImGuiStyleMod> StyleModifiers; // Stack for PushStyleVar()/PopStyleVar()
|
ImVector<ImGuiStyleMod> StyleVarStack; // Stack for PushStyleVar()/PopStyleVar() - inherited by Begin()
|
||||||
ImVector<ImFont*> FontStack; // Stack for PushFont()/PopFont()
|
ImVector<ImFont*> FontStack; // Stack for PushFont()/PopFont() - inherited by Begin()
|
||||||
ImVector<ImGuiID> FocusScopeStack; // Stack for PushFocusScope()/PopFocusScope()
|
ImVector<ImGuiID> FocusScopeStack; // Stack for PushFocusScope()/PopFocusScope() - not inherited by Begin(), unless child window
|
||||||
ImVector<ImGuiItemFlags>ItemFlagsStack; // Stack for PushItemFlag()/PopItemFlag()
|
ImVector<ImGuiItemFlags>ItemFlagsStack; // Stack for PushItemFlag()/PopItemFlag() - inherited by Begin()
|
||||||
ImVector<ImGuiGroupData>GroupStack; // Stack for BeginGroup()/EndGroup()
|
ImVector<ImGuiGroupData>GroupStack; // Stack for BeginGroup()/EndGroup() - not inherited by Begin()
|
||||||
ImVector<ImGuiPopupData>OpenPopupStack; // Which popups are open (persistent)
|
ImVector<ImGuiPopupData>OpenPopupStack; // Which popups are open (persistent)
|
||||||
ImVector<ImGuiPopupData>BeginPopupStack; // Which level of BeginPopup() we are in (reset every frame)
|
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]
|
float TextWrapPos; // == TextWrapPosStack.back() [empty == -1.0f]
|
||||||
ImVector<float> ItemWidthStack;
|
ImVector<float> ItemWidthStack;
|
||||||
ImVector<float> TextWrapPosStack;
|
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
|
// Storage for one window
|
||||||
|
Loading…
Reference in New Issue
Block a user