diff --git a/modules/juce_gui_basics/layout/juce_Viewport.cpp b/modules/juce_gui_basics/layout/juce_Viewport.cpp index b01851ba27..21463288c6 100644 --- a/modules/juce_gui_basics/layout/juce_Viewport.cpp +++ b/modules/juce_gui_basics/layout/juce_Viewport.cpp @@ -247,14 +247,22 @@ Point Viewport::viewportPosToCompPos (Point pos) const { jassert (contentComp != nullptr); - auto contentBounds = contentHolder.getLocalArea (contentComp.get(), contentComp->getLocalBounds()); + const auto contentBounds = getContentBounds(); - Point p (jmax (jmin (0, contentHolder.getWidth() - contentBounds.getWidth()), jmin (0, -(pos.x))), - jmax (jmin (0, contentHolder.getHeight() - contentBounds.getHeight()), jmin (0, -(pos.y)))); + const Point p (jmax (jmin (0, contentHolder.getWidth() - contentBounds.getWidth()), jmin (0, -(pos.x))), + jmax (jmin (0, contentHolder.getHeight() - contentBounds.getHeight()), jmin (0, -(pos.y)))); return p.transformedBy (contentComp->getTransform().inverted()); } +Rectangle Viewport::getContentBounds() const +{ + if (auto* cc = contentComp.get()) + return contentHolder.getLocalArea (cc, cc->getLocalBounds()); + + return {}; +} + void Viewport::setViewPosition (const int xPixelsOffset, const int yPixelsOffset) { setViewPosition ({ xPixelsOffset, yPixelsOffset }); @@ -406,11 +414,7 @@ void Viewport::updateVisibleArea() break; } - Rectangle contentBounds; - - if (auto cc = contentComp.get()) - contentBounds = contentHolder.getLocalArea (cc, cc->getLocalBounds()); - + const auto contentBounds = getContentBounds(); auto visibleOrigin = -contentBounds.getPosition(); auto& hbar = getHorizontalScrollBar(); @@ -521,15 +525,22 @@ int Viewport::getScrollBarThickness() const void Viewport::scrollBarMoved (ScrollBar* scrollBarThatHasMoved, double newRangeStart) { - auto newRangeStartInt = roundToInt (newRangeStart); + const auto contentOrigin = -getContentBounds().getPosition(); + const auto newRangeStartInt = roundToInt (newRangeStart); - if (scrollBarThatHasMoved == horizontalScrollBar.get()) + for (const auto& [member, bar] : { std::tuple (&Point::x, horizontalScrollBar.get()), + std::tuple (&Point::y, verticalScrollBar.get()) }) { - setViewPosition (newRangeStartInt, getViewPositionY()); - } - else if (scrollBarThatHasMoved == verticalScrollBar.get()) - { - setViewPosition (getViewPositionX(), newRangeStartInt); + if (scrollBarThatHasMoved != bar) + continue; + + if (contentOrigin.*member == newRangeStartInt) + return; + + auto pt = getViewPosition(); + pt.*member = newRangeStartInt; + setViewPosition (pt); + return; } } diff --git a/modules/juce_gui_basics/layout/juce_Viewport.h b/modules/juce_gui_basics/layout/juce_Viewport.h index f87a19de60..2ab00f802c 100644 --- a/modules/juce_gui_basics/layout/juce_Viewport.h +++ b/modules/juce_gui_basics/layout/juce_Viewport.h @@ -373,6 +373,7 @@ private: std::unique_ptr dragToScrollListener; Point viewportPosToCompPos (Point) const; + Rectangle getContentBounds() const; void updateVisibleArea(); void deleteOrRemoveContentComp();