diff --git a/modules/juce_gui_basics/layout/juce_Viewport.cpp b/modules/juce_gui_basics/layout/juce_Viewport.cpp index 282423387e..80266cea6f 100644 --- a/modules/juce_gui_basics/layout/juce_Viewport.cpp +++ b/modules/juce_gui_basics/layout/juce_Viewport.cpp @@ -52,6 +52,7 @@ Viewport::Viewport (const String& name) Viewport::~Viewport() { deleteContentComp(); + mouseWheelTimer = nullptr; } //============================================================================== @@ -357,6 +358,30 @@ static int rescaleMouseWheelDistance (float distance, int singleStepSize) noexce : jmax (distance, 1.0f)); } +// This puts a temporary component overlay over the content component, to prevent +// wheel events from reaching components inside it, so that while spinning a wheel +// with momentum, it won't accidentally scroll any subcomponents of the viewport. +struct Viewport::MouseWheelTimer : public Timer +{ + MouseWheelTimer (Viewport& v) : viewport (v) + { + viewport.contentHolder.addAndMakeVisible (dummyOverlay); + dummyOverlay.setAlwaysOnTop (true); + dummyOverlay.setPaintingIsUnclipped (true); + dummyOverlay.setBounds (viewport.contentHolder.getLocalBounds()); + } + + void timerCallback() override + { + viewport.mouseWheelTimer = nullptr; + } + + Component dummyOverlay; + Viewport& viewport; + + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MouseWheelTimer) +}; + bool Viewport::useMouseWheelMoveIfNeeded (const MouseEvent& e, const MouseWheelDetails& wheel) { if (! (e.mods.isAltDown() || e.mods.isCtrlDown() || e.mods.isCommandDown())) @@ -387,6 +412,11 @@ bool Viewport::useMouseWheelMoveIfNeeded (const MouseEvent& e, const MouseWheelD if (pos != getViewPosition()) { + if (mouseWheelTimer == nullptr) + mouseWheelTimer = new MouseWheelTimer (*this); + + mouseWheelTimer->startTimer (300); + setViewPosition (pos); return true; } diff --git a/modules/juce_gui_basics/layout/juce_Viewport.h b/modules/juce_gui_basics/layout/juce_Viewport.h index baeb42a729..c427515298 100644 --- a/modules/juce_gui_basics/layout/juce_Viewport.h +++ b/modules/juce_gui_basics/layout/juce_Viewport.h @@ -267,6 +267,9 @@ private: bool allowScrollingWithoutScrollbarV, allowScrollingWithoutScrollbarH; Component contentHolder; ScrollBar verticalScrollBar, horizontalScrollBar; + struct MouseWheelTimer; + ScopedPointer mouseWheelTimer; + Point viewportPosToCompPos (Point) const; void updateVisibleArea();