diff --git a/modules/juce_gui_basics/components/juce_Component.h b/modules/juce_gui_basics/components/juce_Component.h index c5cbf8ae4d..8f91a31451 100644 --- a/modules/juce_gui_basics/components/juce_Component.h +++ b/modules/juce_gui_basics/components/juce_Component.h @@ -2234,12 +2234,12 @@ public: Viewport with drag-to-scroll functionality enabled. This is useful for Components such as sliders that should not move their parent Viewport when dragged. */ - void setViewportIgnoreDragFlag (bool ignoreDrag) { flags.viewportIgnoreDragFlag = ignoreDrag; }; + void setViewportIgnoreDragFlag (bool ignoreDrag) noexcept { flags.viewportIgnoreDragFlag = ignoreDrag; }; /** Retrieves the current state of the Viewport drag-to-scroll functionality flag. @see setViewportIgnoreDragFlag */ - bool getViewportIgnoreDragFlag() { return flags.viewportIgnoreDragFlag; } + bool getViewportIgnoreDragFlag() const noexcept { return flags.viewportIgnoreDragFlag; } //============================================================================== // These methods are deprecated - use localPointToGlobal, getLocalPoint, getLocalPoint, etc instead. diff --git a/modules/juce_gui_basics/layout/juce_Viewport.cpp b/modules/juce_gui_basics/layout/juce_Viewport.cpp index 58ca6e420a..4fdca1af22 100644 --- a/modules/juce_gui_basics/layout/juce_Viewport.cpp +++ b/modules/juce_gui_basics/layout/juce_Viewport.cpp @@ -193,7 +193,7 @@ struct Viewport::DragToScrollListener : private MouseListener, private ViewportDragPosition::Listener { DragToScrollListener (Viewport& v) - : viewport (v), numTouches (0), isDragging (false) + : viewport (v), numTouches (0), isDragging (false), isViewportDragBlocked (false) { viewport.contentHolder.addMouseListener (this, true); offsetX.addListener (this); @@ -213,16 +213,15 @@ struct Viewport::DragToScrollListener : private MouseListener, void mouseDown (const MouseEvent& e) override { - for (auto c = e.eventComponent; c != nullptr && c != &viewport; c = c->getParentComponent()) - if (c->getViewportIgnoreDragFlag()) - return; + if (doesMouseEventComponentBlockViewportDrag (e.eventComponent)) + isViewportDragBlocked = true; ++numTouches; } void mouseDrag (const MouseEvent& e) override { - if (numTouches == 1) + if (numTouches == 1 && ! isViewportDragBlocked) { Point totalOffset = e.getOffsetFromDragStart().toFloat(); @@ -245,8 +244,11 @@ struct Viewport::DragToScrollListener : private MouseListener, } } - void mouseUp (const MouseEvent&) override + void mouseUp (const MouseEvent& e) override { + if (doesMouseEventComponentBlockViewportDrag (e.eventComponent)) + isViewportDragBlocked = false; + if (--numTouches <= 0) { offsetX.endDrag(); @@ -256,12 +258,23 @@ struct Viewport::DragToScrollListener : private MouseListener, } } + bool doesMouseEventComponentBlockViewportDrag (const Component* eventComp) + { + for (auto c = eventComp; c != nullptr && c != &viewport; c = c->getParentComponent()) + if (c->getViewportIgnoreDragFlag()) + return true; + + return false; + } + Viewport& viewport; ViewportDragPosition offsetX, offsetY; Point originalViewPos; int numTouches; bool isDragging; + bool isViewportDragBlocked; + JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DragToScrollListener) };