diff --git a/modules/juce_gui_basics/layout/juce_Viewport.cpp b/modules/juce_gui_basics/layout/juce_Viewport.cpp index d4d0e7297c..04064ed907 100644 --- a/modules/juce_gui_basics/layout/juce_Viewport.cpp +++ b/modules/juce_gui_basics/layout/juce_Viewport.cpp @@ -30,6 +30,8 @@ Viewport::Viewport (const String& name) showHScrollbar (true), showVScrollbar (true), deleteContent (true), + allowScrollingWithoutScrollbarV (false), + allowScrollingWithoutScrollbarH (false), verticalScrollBar (true), horizontalScrollBar (false) { @@ -234,31 +236,23 @@ void Viewport::updateVisibleArea() Point visibleOrigin (-contentBounds.getPosition()); - if (hBarVisible) - { - horizontalScrollBar.setBounds (0, contentArea.getHeight(), contentArea.getWidth(), scrollbarWidth); - horizontalScrollBar.setRangeLimits (0.0, contentBounds.getWidth()); - horizontalScrollBar.setCurrentRange (visibleOrigin.x, contentArea.getWidth()); - horizontalScrollBar.setSingleStepSize (singleStepX); - horizontalScrollBar.cancelPendingUpdate(); - } - else if (canShowHBar) - { - visibleOrigin.setX (0); - } + horizontalScrollBar.setBounds (0, contentArea.getHeight(), contentArea.getWidth(), scrollbarWidth); + horizontalScrollBar.setRangeLimits (0.0, contentBounds.getWidth()); + horizontalScrollBar.setCurrentRange (visibleOrigin.x, contentArea.getWidth()); + horizontalScrollBar.setSingleStepSize (singleStepX); + horizontalScrollBar.cancelPendingUpdate(); - if (vBarVisible) - { - verticalScrollBar.setBounds (contentArea.getWidth(), 0, scrollbarWidth, contentArea.getHeight()); - verticalScrollBar.setRangeLimits (0.0, contentBounds.getHeight()); - verticalScrollBar.setCurrentRange (visibleOrigin.y, contentArea.getHeight()); - verticalScrollBar.setSingleStepSize (singleStepY); - verticalScrollBar.cancelPendingUpdate(); - } - else if (canShowVBar) - { + if (canShowHBar && ! hBarVisible) + visibleOrigin.setX (0); + + verticalScrollBar.setBounds (contentArea.getWidth(), 0, scrollbarWidth, contentArea.getHeight()); + verticalScrollBar.setRangeLimits (0.0, contentBounds.getHeight()); + verticalScrollBar.setCurrentRange (visibleOrigin.y, contentArea.getHeight()); + verticalScrollBar.setSingleStepSize (singleStepY); + verticalScrollBar.cancelPendingUpdate(); + + if (canShowVBar && ! vBarVisible) visibleOrigin.setY (0); - } // Force the visibility *after* setting the ranges to avoid flicker caused by edge conditions in the numbers. horizontalScrollBar.setVisible (hBarVisible); @@ -301,8 +295,13 @@ void Viewport::setSingleStepSizes (const int stepX, const int stepY) } void Viewport::setScrollBarsShown (const bool showVerticalScrollbarIfNeeded, - const bool showHorizontalScrollbarIfNeeded) + const bool showHorizontalScrollbarIfNeeded, + const bool allowVerticalScrollingWithoutScrollbar, + const bool allowHorizontalScrollingWithoutScrollbar) { + allowScrollingWithoutScrollbarV = allowVerticalScrollingWithoutScrollbar; + allowScrollingWithoutScrollbarH = allowHorizontalScrollingWithoutScrollbar; + if (showVScrollbar != showVerticalScrollbarIfNeeded || showHScrollbar != showHorizontalScrollbarIfNeeded) { @@ -347,47 +346,44 @@ void Viewport::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& whe Component::mouseWheelMove (e, wheel); } +static float rescaleMouseWheelDistance (float distance, int singleStepSize) noexcept +{ + if (distance == 0) + return 0; + + distance *= 14.0f * singleStepSize; + + return distance < 0 ? jmin (distance, -1.0f) + : jmax (distance, 1.0f); +} + bool Viewport::useMouseWheelMoveIfNeeded (const MouseEvent& e, const MouseWheelDetails& wheel) { if (! (e.mods.isAltDown() || e.mods.isCtrlDown() || e.mods.isCommandDown())) { - const bool hasVertBar = verticalScrollBar.isVisible(); - const bool hasHorzBar = horizontalScrollBar.isVisible(); + const bool canScrollVert = (allowScrollingWithoutScrollbarV || verticalScrollBar.isVisible()); + const bool canScrollHorz = (allowScrollingWithoutScrollbarH || horizontalScrollBar.isVisible()); - if (hasHorzBar || hasVertBar) + if (canScrollHorz || canScrollVert) { - float wheelIncrementX = wheel.deltaX; - float wheelIncrementY = wheel.deltaY; - - if (wheelIncrementX != 0) - { - wheelIncrementX *= 14.0f * singleStepX; - wheelIncrementX = (wheelIncrementX < 0) ? jmin (wheelIncrementX, -1.0f) - : jmax (wheelIncrementX, 1.0f); - } - - if (wheelIncrementY != 0) - { - wheelIncrementY *= 14.0f * singleStepY; - wheelIncrementY = (wheelIncrementY < 0) ? jmin (wheelIncrementY, -1.0f) - : jmax (wheelIncrementY, 1.0f); - } + float wheelIncrementX = rescaleMouseWheelDistance (wheel.deltaX, singleStepX); + float wheelIncrementY = rescaleMouseWheelDistance (wheel.deltaY, singleStepY); Point pos (getViewPosition()); - if (wheelIncrementX != 0 && wheelIncrementY != 0 && hasHorzBar && hasVertBar) + if (wheelIncrementX != 0 && wheelIncrementY != 0 && canScrollHorz && canScrollVert) { pos.setX (pos.x - roundToInt (wheelIncrementX)); pos.setY (pos.y - roundToInt (wheelIncrementY)); } - else if (hasHorzBar && (wheelIncrementX != 0 || e.mods.isShiftDown() || ! hasVertBar)) + else if (canScrollHorz && (wheelIncrementX != 0 || e.mods.isShiftDown() || ! canScrollVert)) { - if (wheelIncrementX == 0 && ! hasVertBar) + if (wheelIncrementX == 0 && ! canScrollVert) wheelIncrementX = wheelIncrementY; pos.setX (pos.x - roundToInt (wheelIncrementX)); } - else if (hasVertBar && wheelIncrementY != 0) + else if (canScrollVert && wheelIncrementY != 0) { pos.setY (pos.y - roundToInt (wheelIncrementY)); } diff --git a/modules/juce_gui_basics/layout/juce_Viewport.h b/modules/juce_gui_basics/layout/juce_Viewport.h index f67b6b06b1..baeb42a729 100644 --- a/modules/juce_gui_basics/layout/juce_Viewport.h +++ b/modules/juce_gui_basics/layout/juce_Viewport.h @@ -191,9 +191,15 @@ public: If set to false, the scrollbars won't ever appear. When true (the default) they will appear only when needed. + + The allowVerticalScrollingWithoutScrollbar parameters allow you to enable + mouse-wheel scrolling even when there the scrollbars are hidden. When the + scrollbars are visible, these parameters are ignored. */ void setScrollBarsShown (bool showVerticalScrollbarIfNeeded, - bool showHorizontalScrollbarIfNeeded); + bool showHorizontalScrollbarIfNeeded, + bool allowVerticalScrollingWithoutScrollbar = false, + bool allowHorizontalScrollingWithoutScrollbar = false); /** True if the vertical scrollbar is enabled. @see setScrollBarsShown @@ -258,9 +264,9 @@ private: int scrollBarThickness; int singleStepX, singleStepY; bool showHScrollbar, showVScrollbar, deleteContent; + bool allowScrollingWithoutScrollbarV, allowScrollingWithoutScrollbarH; Component contentHolder; - ScrollBar verticalScrollBar; - ScrollBar horizontalScrollBar; + ScrollBar verticalScrollBar, horizontalScrollBar; Point viewportPosToCompPos (Point) const; void updateVisibleArea();