From 27924e49968866f1982baa804595ace2bf05d271 Mon Sep 17 00:00:00 2001 From: attila Date: Wed, 29 Jun 2022 14:05:44 +0200 Subject: [PATCH] Viewport: Stop ongoing physical drag upon user interaction An animated drag operation will now stop if the user interacts with the content area again before the animation is finished. It is also stopped if the user interacts with the scrollbars. --- .../juce_gui_basics/layout/juce_Viewport.cpp | 27 +++++++++++++++---- .../juce_gui_basics/layout/juce_Viewport.h | 2 ++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/modules/juce_gui_basics/layout/juce_Viewport.cpp b/modules/juce_gui_basics/layout/juce_Viewport.cpp index c302763264..e227a2ea4b 100644 --- a/modules/juce_gui_basics/layout/juce_Viewport.cpp +++ b/modules/juce_gui_basics/layout/juce_Viewport.cpp @@ -61,6 +61,12 @@ struct Viewport::DragToScrollListener : private MouseListener, Desktop::getInstance().removeGlobalMouseListener (this); } + void stopOngoingAnimation() + { + offsetX.setPosition (offsetX.getPosition()); + offsetY.setPosition (offsetY.getPosition()); + } + void positionChanged (ViewportDragPosition&, double) override { viewport.setViewPosition (originalViewPos - Point ((int) offsetX.getPosition(), @@ -119,9 +125,11 @@ struct Viewport::DragToScrollListener : private MouseListener, void endDragAndClearGlobalMouseListener() { - offsetX.endDrag(); - offsetY.endDrag(); - isDragging = false; + if (std::exchange (isDragging, false) == true) + { + offsetX.endDrag(); + offsetY.endDrag(); + } viewport.contentHolder.addMouseListener (this, true); Desktop::getInstance().removeGlobalMouseListener (this); @@ -229,6 +237,8 @@ void Viewport::recreateScrollbars() getVerticalScrollBar().addListener (this); getHorizontalScrollBar().addListener (this); + getVerticalScrollBar().addMouseListener (this, true); + getHorizontalScrollBar().addMouseListener (this, true); resized(); } @@ -531,8 +541,15 @@ void Viewport::scrollBarMoved (ScrollBar* scrollBarThatHasMoved, double newRange void Viewport::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel) { - if (! useMouseWheelMoveIfNeeded (e, wheel)) - Component::mouseWheelMove (e, wheel); + if (e.eventComponent == this) + if (! useMouseWheelMoveIfNeeded (e, wheel)) + Component::mouseWheelMove (e, wheel); +} + +void Viewport::mouseDown (const MouseEvent& e) +{ + if (e.eventComponent == horizontalScrollBar.get() || e.eventComponent == verticalScrollBar.get()) + dragToScrollListener->stopOngoingAnimation(); } static int rescaleMouseWheelDistance (float distance, int singleStepSize) noexcept diff --git a/modules/juce_gui_basics/layout/juce_Viewport.h b/modules/juce_gui_basics/layout/juce_Viewport.h index c7a75a1165..17762b1cd8 100644 --- a/modules/juce_gui_basics/layout/juce_Viewport.h +++ b/modules/juce_gui_basics/layout/juce_Viewport.h @@ -318,6 +318,8 @@ public: /** @internal */ void mouseWheelMove (const MouseEvent&, const MouseWheelDetails&) override; /** @internal */ + void mouseDown (const MouseEvent& e) override; + /** @internal */ bool keyPressed (const KeyPress&) override; /** @internal */ void componentMovedOrResized (Component&, bool wasMoved, bool wasResized) override;