Disabled: disabled items set HoveredId, allowing e.g. HoveredIdTimer to function. (#211, #3419) + Menus: fix hovering a disabled menu or menu item not closing other menus.

Rework of https://github.com/rokups/imgui/commit/c24b470
Note that the declared intent of that commit "Prevents window from being dragged if mouse hovers a disabled item." was already fullfilled by a876ad87.
Changes in ButtonBehavior() not needed anymore since ImGuiButtonFlags_Disabled is gone
This commit is contained in:
Rokas Kupstys 2021-07-09 19:45:30 +02:00 committed by ocornut
parent cac869b333
commit 5dd1e38b7a
3 changed files with 24 additions and 9 deletions

View File

@ -39,6 +39,9 @@ Breaking Changes:
- Backends: SDL2: removed unnecessary SDL_Window* parameter from ImGui_ImplSDL2_NewFrame(). (#3244) [@funchal]
Kept inline redirection function (will obsolete).
- Internals: (for custom widgets): because disabled items now sets HoveredId, if you want custom widgets to
not react as hovered when disabled, in the majority of use cases it is preferable to check the "hovered"
return value of ButtonBehavior() rather than (HoveredId == id).
Other Changes:
- Windows: ImGuiWindowFlags_UnsavedDocument/ImGuiTabItmeFlags_UnsavedDocument display a dot instead of a '*' so it
@ -55,7 +58,9 @@ Other Changes:
- InputInt/InputFloat: When used with Steps values and _ReadOnly flag, the step button look disabled. (#211)
- Drag and Drop: drop target highlight doesn't try to bypass host clipping rectangle. (#4281, #3272)
- Menus: MenuItem() and BeginMenu() are not affected/overlapping when style.SelectableTextAlign is altered.
- Menus: fix hovering a disabled menu or menu item not closing other menus. (#211)
- Nav: Disabled items are not candidate for default focus. (#211, #787)
- Disabled: disabled items set HoveredId, allowing e.g. HoveredIdTimer to function. (#211, #3419) [@rokups]
- Disabled: disabled mode more consistently release active id if the active item got disabled. (#211)
- Disabled: disabled mode doesn't prevent Selectable() from looking selected. (#211)
- Fixed printf-style format checks on non-MinGW flavors. (#4183, #3592)

View File

@ -3216,7 +3216,7 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
return false;
if (g.NavDisableMouseHover)
return false;
if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None) || (g.CurrentItemFlags & ImGuiItemFlags_Disabled))
if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None))
{
g.HoveredIdDisabled = true;
return false;
@ -3225,9 +3225,17 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
// We exceptionally allow this function to be called with id==0 to allow using it for easy high-level
// hover test in widgets code. We could also decide to split this function is two.
if (id != 0)
{
SetHoveredID(id);
// When disabled we'll return false but still set HoveredId
if (g.CurrentItemFlags & ImGuiItemFlags_Disabled)
{
g.HoveredIdDisabled = true;
return false;
}
if (id != 0)
{
// [DEBUG] Item Picker tool!
// We perform the check here because SetHoveredID() is not frequently called (1~ time a frame), making
// the cost of this tool near-zero. We can get slightly better call-stack and support picking non-hovered

View File

@ -1445,7 +1445,7 @@ bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float
if (g.ActiveId != id)
SetItemAllowOverlap();
if (held || (g.HoveredId == id && g.HoveredIdPreviousFrame == id && g.HoveredIdTimer >= hover_visibility_delay))
if (held || (hovered && g.HoveredIdPreviousFrame == id && g.HoveredIdTimer >= hover_visibility_delay))
SetMouseCursor(axis == ImGuiAxis_Y ? ImGuiMouseCursor_ResizeNS : ImGuiMouseCursor_ResizeEW);
ImRect bb_render = bb;
@ -2431,7 +2431,7 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
}
// Draw frame
const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
RenderNavHighlight(frame_bb, id);
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding);
@ -3037,7 +3037,7 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
}
// Draw frame
const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
RenderNavHighlight(frame_bb, id);
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, g.Style.FrameRounding);
@ -3185,7 +3185,7 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d
}
// Draw frame
const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg);
RenderNavHighlight(frame_bb, id);
RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, g.Style.FrameRounding);
@ -7964,7 +7964,6 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
bool pressed = ButtonBehavior(bb, id, &hovered, &held, button_flags);
if (pressed && !is_tab_button)
tab_bar->NextSelectedTabId = id;
hovered |= (g.HoveredId == id);
// Allow the close button to overlap unless we are dragging (in which case we don't want any overlapping tabs to be hovered)
if (g.ActiveId != id)
@ -8028,8 +8027,11 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
PopClipRect();
window->DC.CursorPos = backup_main_cursor_pos;
// Tooltip (FIXME: Won't work over the close button because ItemOverlap systems messes up with HoveredIdTimer)
// We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar (which g.HoveredId ignores)
// Tooltip
// (Won't work over the close button because ItemOverlap systems messes up with HoveredIdTimer-> seems ok)
// (We test IsItemHovered() to discard e.g. when another item is active or drag and drop over the tab bar, which g.HoveredId ignores)
// FIXME: This is a mess.
// FIXME: We may want disabled tab to still display the tooltip?
if (text_clipped && g.HoveredId == id && !held && g.HoveredIdNotActiveTimer > g.TooltipSlowDelay && IsItemHovered())
if (!(tab_bar->Flags & ImGuiTabBarFlags_NoTooltip) && !(tab->Flags & ImGuiTabItemFlags_NoTooltip))
SetTooltip("%.*s", (int)(FindRenderedTextEnd(label) - label), label);