ImGui: Apply patch from upstream that fixes tooltips of disabled buttons

Upstream commit: "Disabled: nested tooltips or other non-child window
 within a BeginDisabled() block disable the disabled state. (#211, #7640)"

Should be in the next Dear ImGui release
This commit is contained in:
Daniel Gibson 2024-06-05 16:58:12 +02:00
parent ab5d590b6f
commit af34aba577
2 changed files with 41 additions and 2 deletions

View file

@ -6648,6 +6648,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// [EXPERIMENTAL] Skip Refresh mode // [EXPERIMENTAL] Skip Refresh mode
UpdateWindowSkipRefresh(window); UpdateWindowSkipRefresh(window);
// Nested root windows (typically tooltips) override disabled state
if (window->RootWindow == window)
if ((window->DC.BackupItemDisabled = (g.CurrentItemFlags & ImGuiItemFlags_Disabled) != 0))
BeginDisabledOverrideReenable();
// 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.CurrentWindow = NULL; g.CurrentWindow = NULL;
@ -7257,6 +7262,8 @@ void ImGui::End()
if (!window->SkipRefresh) if (!window->SkipRefresh)
PopClipRect(); // Inner window clip rectangle PopClipRect(); // Inner window clip rectangle
PopFocusScope(); PopFocusScope();
if (window->RootWindow == window && window->DC.BackupItemDisabled)
EndDisabledOverrideReenable();
if (window->SkipRefresh) if (window->SkipRefresh)
{ {
@ -7521,7 +7528,7 @@ void ImGui::BeginDisabled(bool disabled)
} }
if (was_disabled || disabled) if (was_disabled || disabled)
g.CurrentItemFlags |= ImGuiItemFlags_Disabled; g.CurrentItemFlags |= ImGuiItemFlags_Disabled;
g.ItemFlagsStack.push_back(g.CurrentItemFlags); g.ItemFlagsStack.push_back(g.CurrentItemFlags); // FIXME-OPT: can we simply skip this and use DisabledStackSize?
g.DisabledStackSize++; g.DisabledStackSize++;
} }
@ -7538,6 +7545,29 @@ void ImGui::EndDisabled()
g.Style.Alpha = g.DisabledAlphaBackup; //PopStyleVar(); g.Style.Alpha = g.DisabledAlphaBackup; //PopStyleVar();
} }
// Could have been called BeginDisabledDisable() but it didn't want to be award nominated for most awkward function name.
// Ideally we would use a shared e.g. BeginDisabled()->BeginDisabledEx() but earlier needs to be optimal.
// The whole code for this is awkward, will reevaluate if we find a way to implement SetNextItemDisabled().
void ImGui::BeginDisabledOverrideReenable()
{
ImGuiContext& g = *GImGui;
IM_ASSERT(g.CurrentItemFlags & ImGuiItemFlags_Disabled);
g.Style.Alpha = g.DisabledAlphaBackup;
g.CurrentItemFlags &= ~ImGuiItemFlags_Disabled;
g.ItemFlagsStack.push_back(g.CurrentItemFlags);
g.DisabledStackSize++;
}
void ImGui::EndDisabledOverrideReenable()
{
ImGuiContext& g = *GImGui;
g.DisabledStackSize--;
IM_ASSERT(g.DisabledStackSize > 0);
g.ItemFlagsStack.pop_back();
g.CurrentItemFlags = g.ItemFlagsStack.back();
g.Style.Alpha = g.DisabledAlphaBackup * g.Style.DisabledAlpha;
}
void ImGui::PushTabStop(bool tab_stop) void ImGui::PushTabStop(bool tab_stop)
{ {
PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop); PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop);
@ -9993,7 +10023,13 @@ void ImGui::ErrorCheckEndWindowRecover(ImGuiErrorLogCallback log_callback, vo
while (g.DisabledStackSize > stack_sizes->SizeOfDisabledStack) //-V1044 while (g.DisabledStackSize > stack_sizes->SizeOfDisabledStack) //-V1044
{ {
if (log_callback) log_callback(user_data, "Recovered from missing EndDisabled() in '%s'", window->Name); if (log_callback) log_callback(user_data, "Recovered from missing EndDisabled() in '%s'", window->Name);
if (g.CurrentItemFlags & ImGuiItemFlags_Disabled)
EndDisabled(); EndDisabled();
else
{
EndDisabledOverrideReenable();
window->DC.BackupItemDisabled = false;
}
} }
while (g.ColorStack.Size > stack_sizes->SizeOfColorStack) while (g.ColorStack.Size > stack_sizes->SizeOfColorStack)
{ {

View file

@ -2468,6 +2468,7 @@ struct IMGUI_API ImGuiWindowTempData
bool NavWindowHasScrollY; // Set per window when scrolling can be used (== ScrollMax.y > 0.0f) bool NavWindowHasScrollY; // Set per window when scrolling can be used (== ScrollMax.y > 0.0f)
// Miscellaneous // Miscellaneous
bool BackupItemDisabled; // Non-child window override disabled flag
bool MenuBarAppending; // FIXME: Remove this bool MenuBarAppending; // FIXME: Remove this
ImVec2 MenuBarOffset; // MenuBarOffset.x is sort of equivalent of a per-layer CursorPos.x, saved/restored as we switch to the menu bar. The only situation when MenuBarOffset.y is > 0 if when (SafeAreaPadding.y > FramePadding.y), often used on TVs. ImVec2 MenuBarOffset; // MenuBarOffset.x is sort of equivalent of a per-layer CursorPos.x, saved/restored as we switch to the menu bar. The only situation when MenuBarOffset.y is > 0 if when (SafeAreaPadding.y > FramePadding.y), often used on TVs.
ImGuiMenuColumns MenuColumns; // Simplified columns storage for menu items measurement ImGuiMenuColumns MenuColumns; // Simplified columns storage for menu items measurement
@ -3124,6 +3125,8 @@ namespace ImGui
IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled);
IMGUI_API void PopItemFlag(); IMGUI_API void PopItemFlag();
IMGUI_API const ImGuiDataVarInfo* GetStyleVarInfo(ImGuiStyleVar idx); IMGUI_API const ImGuiDataVarInfo* GetStyleVarInfo(ImGuiStyleVar idx);
IMGUI_API void BeginDisabledOverrideReenable();
IMGUI_API void EndDisabledOverrideReenable();
// Logging/Capture // Logging/Capture
IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name. IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name.