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); } //==============================================================================