Window: Fixed clicking over an item which hovering has been disabled (e.g inhibited by a popup) from marking the window as moved.

+ comments
This commit is contained in:
omar 2020-08-03 18:04:58 +02:00
parent 5d87941451
commit a876ad877d
4 changed files with 21 additions and 5 deletions

View File

@ -40,6 +40,8 @@ Other Changes:
- Nav: Fixed clicking on void (behind any windows) from not clearing the focused window. - Nav: Fixed clicking on void (behind any windows) from not clearing the focused window.
This would be problematic e.g. in situation where the application relies on io.WantCaptureKeyboard This would be problematic e.g. in situation where the application relies on io.WantCaptureKeyboard
flag being cleared accordingly. (bug introduced in 1.77 WIP on 2020/06/16) (#3344, #2880) flag being cleared accordingly. (bug introduced in 1.77 WIP on 2020/06/16) (#3344, #2880)
- Window: Fixed clicking over an item which hovering has been disabled (e.g inhibited by a popup)
from marking the window as moved.
- DragFloatRange2, DragIntRange2: Fixed an issue allowing to drag out of bounds when both - DragFloatRange2, DragIntRange2: Fixed an issue allowing to drag out of bounds when both
min and max value are on the same value. (#1441) min and max value are on the same value. (#1441)
- InputText, ImDrawList: Fixed assert triggering when drawing single line of text with more - InputText, ImDrawList: Fixed assert triggering when drawing single line of text with more

View File

@ -3061,10 +3061,13 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id)
return false; return false;
if (!IsMouseHoveringRect(bb.Min, bb.Max)) if (!IsMouseHoveringRect(bb.Min, bb.Max))
return false; return false;
if (g.NavDisableMouseHover || !IsWindowContentHoverable(window, ImGuiHoveredFlags_None)) if (g.NavDisableMouseHover)
return false; return false;
if (window->DC.ItemFlags & ImGuiItemFlags_Disabled) if (!IsWindowContentHoverable(window, ImGuiHoveredFlags_None) || (window->DC.ItemFlags & ImGuiItemFlags_Disabled))
{
g.HoveredIdDisabled = true;
return false; return false;
}
// We exceptionally allow this function to be called with id==0 to allow using it for easy high-level // 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. // hover test in widgets code. We could also decide to split this function is two.
@ -3364,9 +3367,15 @@ void ImGui::UpdateMouseMovingWindowEndFrame()
if (root_window != NULL && !is_closed_popup) if (root_window != NULL && !is_closed_popup)
{ {
StartMouseMovingWindow(g.HoveredWindow); StartMouseMovingWindow(g.HoveredWindow);
// Cancel moving if clicked outside of title bar
if (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(root_window->Flags & ImGuiWindowFlags_NoTitleBar)) if (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(root_window->Flags & ImGuiWindowFlags_NoTitleBar))
if (!root_window->TitleBarRect().Contains(g.IO.MouseClickedPos[0])) if (!root_window->TitleBarRect().Contains(g.IO.MouseClickedPos[0]))
g.MovingWindow = NULL; g.MovingWindow = NULL;
// Cancel moving if clicked over an item which was disabled or inhibited by popups
if (g.HoveredId == 0 && g.HoveredIdDisabled)
g.MovingWindow = NULL;
} }
else if (root_window == NULL && g.NavWindow != NULL && GetTopMostPopupModal() == NULL) else if (root_window == NULL && g.NavWindow != NULL && GetTopMostPopupModal() == NULL)
{ {
@ -3723,6 +3732,7 @@ void ImGui::NewFrame()
g.HoveredIdPreviousFrame = g.HoveredId; g.HoveredIdPreviousFrame = g.HoveredId;
g.HoveredId = 0; g.HoveredId = 0;
g.HoveredIdAllowOverlap = false; g.HoveredIdAllowOverlap = false;
g.HoveredIdDisabled = false;
// Update ActiveId data (clear reference to active widget if the widget isn't alive anymore) // Update ActiveId data (clear reference to active widget if the widget isn't alive anymore)
if (g.ActiveIdIsAlive != g.ActiveId && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0) if (g.ActiveIdIsAlive != g.ActiveId && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0)

View File

@ -1144,8 +1144,9 @@ struct ImGuiContext
// Item/widgets state and tracking information // Item/widgets state and tracking information
ImGuiID HoveredId; // Hovered widget ImGuiID HoveredId; // Hovered widget
bool HoveredIdAllowOverlap;
ImGuiID HoveredIdPreviousFrame; ImGuiID HoveredIdPreviousFrame;
bool HoveredIdAllowOverlap;
bool HoveredIdDisabled; // At least one widget passed the rect test, but has been discarded by disabled flag or popup inhibit. May be true even if HoveredId == 0.
float HoveredIdTimer; // Measure contiguous hovering time float HoveredIdTimer; // Measure contiguous hovering time
float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active float HoveredIdNotActiveTimer; // Measure contiguous hovering time where the item has not been active
ImGuiID ActiveId; // Active widget ImGuiID ActiveId; // Active widget
@ -1348,9 +1349,9 @@ struct ImGuiContext
WheelingWindow = NULL; WheelingWindow = NULL;
WheelingWindowTimer = 0.0f; WheelingWindowTimer = 0.0f;
HoveredId = 0; HoveredId = HoveredIdPreviousFrame = 0;
HoveredIdAllowOverlap = false; HoveredIdAllowOverlap = false;
HoveredIdPreviousFrame = 0; HoveredIdDisabled = false;
HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f; HoveredIdTimer = HoveredIdNotActiveTimer = 0.0f;
ActiveId = 0; ActiveId = 0;
ActiveIdIsAlive = 0; ActiveIdIsAlive = 0;

View File

@ -595,6 +595,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
} }
} }
// Process while held
bool held = false; bool held = false;
if (g.ActiveId == id) if (g.ActiveId == id)
{ {
@ -615,6 +616,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
bool release_anywhere = (flags & ImGuiButtonFlags_PressedOnClickReleaseAnywhere) != 0; bool release_anywhere = (flags & ImGuiButtonFlags_PressedOnClickReleaseAnywhere) != 0;
if ((release_in || release_anywhere) && !g.DragDropActive) if ((release_in || release_anywhere) && !g.DragDropActive)
{ {
// Report as pressed when releasing the mouse (this is the most common path)
bool is_double_click_release = (flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseDownWasDoubleClick[mouse_button]; bool is_double_click_release = (flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseDownWasDoubleClick[mouse_button];
bool is_repeating_already = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button] >= g.IO.KeyRepeatDelay; // Repeat mode trumps <on release> bool is_repeating_already = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button] >= g.IO.KeyRepeatDelay; // Repeat mode trumps <on release>
if (!is_double_click_release && !is_repeating_already) if (!is_double_click_release && !is_repeating_already)
@ -627,6 +629,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
} }
else if (g.ActiveIdSource == ImGuiInputSource_Nav) else if (g.ActiveIdSource == ImGuiInputSource_Nav)
{ {
// When activated using Nav, we hold on the ActiveID until activation button is released
if (g.NavActivateDownId != id) if (g.NavActivateDownId != id)
ClearActiveID(); ClearActiveID();
} }