From e1a7fe671ab2cf3421f12a252ffd7b464bd2bedc Mon Sep 17 00:00:00 2001 From: reuk Date: Mon, 14 Feb 2022 16:38:24 +0000 Subject: [PATCH] Component: Make wheel/magnify behaviour more intuitive for disabled components The previous implementation would pass the mouse wheel event up to the component's parent, as long as the parent was enabled. This meant that a wheel event on the innermost component of a hierarchy such as "[[disabled] enabled]" would send the event to the parent, but a wheel event on the innermost component of a hierarchy such as "[[[disabled] disabled] enabled]" would 'eat' the event and prevent it from propagating. After this change, unhandled mouse wheel events will always be passed to the nearest enabled parent. This behaviour is more consistent and intuitive. --- BREAKING-CHANGES.txt | 24 +++++++++++++++++++ .../components/juce_Component.cpp | 23 +++++++++++++----- 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/BREAKING-CHANGES.txt b/BREAKING-CHANGES.txt index cdf1333639..227a93843b 100644 --- a/BREAKING-CHANGES.txt +++ b/BREAKING-CHANGES.txt @@ -4,6 +4,30 @@ JUCE breaking changes develop ======= +Change +------ +Unhandled mouse wheel and magnify events will now be passed to the closest +enclosing enabled ancestor component. + +Possible Issues +--------------- +Components that previously blocked mouse wheel events when in a disabled state +may no longer block the events as expected. + +Workaround +---------- +If a component should explicitly prevent events from propagating when disabled, +it should override mouseWheelMove() and mouseMagnify() to do nothing when the +component is disabled. + +Rationale +--------- +Previously, unhandled wheel events would be passed to the parent component, +but only if the parent was enabled. This meant that scrolling on a component +nested inside a disabled component would have no effect by default. This +behaviour was not intuitive. + + Change ------ The invalidPressure, invalidOrientation, invalidRotation, invalidTiltX and diff --git a/modules/juce_gui_basics/components/juce_Component.cpp b/modules/juce_gui_basics/components/juce_Component.cpp index 3c85054ca1..ecb0599f7a 100644 --- a/modules/juce_gui_basics/components/juce_Component.cpp +++ b/modules/juce_gui_basics/components/juce_Component.cpp @@ -26,6 +26,17 @@ namespace juce { +static Component* findFirstEnabledAncestor (Component* in) +{ + if (in == nullptr) + return nullptr; + + if (in->isEnabled()) + return in; + + return findFirstEnabledAncestor (in->getParentComponent()); +} + Component* Component::currentlyFocusedComponent = nullptr; @@ -2269,16 +2280,16 @@ void Component::mouseDoubleClick (const MouseEvent&) {} void Component::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel) { - // the base class just passes this event up to its parent.. - if (parentComponent != nullptr && parentComponent->isEnabled()) - parentComponent->mouseWheelMove (e.getEventRelativeTo (parentComponent), wheel); + // the base class just passes this event up to the nearest enabled ancestor + if (auto* enabledComponent = findFirstEnabledAncestor (getParentComponent())) + enabledComponent->mouseWheelMove (e.getEventRelativeTo (enabledComponent), wheel); } void Component::mouseMagnify (const MouseEvent& e, float magnifyAmount) { - // the base class just passes this event up to its parent.. - if (parentComponent != nullptr && parentComponent->isEnabled()) - parentComponent->mouseMagnify (e.getEventRelativeTo (parentComponent), magnifyAmount); + // the base class just passes this event up to the nearest enabled ancestor + if (auto* enabledComponent = findFirstEnabledAncestor (getParentComponent())) + enabledComponent->mouseMagnify (e.getEventRelativeTo (enabledComponent), magnifyAmount); } //==============================================================================