From 3847842ae83a4fc6463a940feabb76bd84b7acb5 Mon Sep 17 00:00:00 2001 From: Julian Storer Date: Sat, 15 May 2010 18:28:29 +0100 Subject: [PATCH] Tweak to Viewport logic. Jucer development. --- .../jucer_ComponentEditorCodeView.h | 31 +++- .../Editor Base/jucer_EditorDragOperation.h | 2 +- .../Source/utility/jucer_CodeHelpers.cpp | 2 +- juce_amalgamated.cpp | 150 ++++++++++-------- juce_amalgamated.h | 20 +-- .../layout/juce_TabbedComponent.cpp | 9 +- src/gui/components/layout/juce_Viewport.cpp | 141 ++++++++-------- src/gui/components/layout/juce_Viewport.h | 20 +-- 8 files changed, 211 insertions(+), 164 deletions(-) diff --git a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCodeView.h b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCodeView.h index 1d980a3ce2..0f6010e488 100644 --- a/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCodeView.h +++ b/extras/Jucer (experimental)/Source/ui/Component Editor/jucer_ComponentEditorCodeView.h @@ -54,20 +54,39 @@ public: viewport.setBounds (getLocalBounds()); int visWidth = viewport.getMaximumVisibleWidth(); - dynamic_cast (viewport.getViewedComponent())->updateSize (visWidth); - if (viewport.getMaximumVisibleWidth() != visWidth) - dynamic_cast (viewport.getViewedComponent())->updateSize (viewport.getMaximumVisibleWidth()); + ContentHolder* ch = dynamic_cast (viewport.getViewedComponent()); + + if (ch != 0) + { + ch->updateSize (visWidth); + + if (viewport.getMaximumVisibleWidth() != visWidth) + ch->updateSize (viewport.getMaximumVisibleWidth()); + } switchFileButton.setBounds (getWidth() - 150, 4, 120, 20); } + void refreshContent() + { + viewport.setViewedComponent (new ContentHolder (editor.getDocument(), showingHeader)); + resized(); + switchFileButton.setButtonText (showingHeader ? "Show CPP file" : "Show header file"); + } + void buttonClicked (Button*) { showingHeader = ! showingHeader; - viewport.setViewedComponent (new ContentHolder (editor.getDocument(), showingHeader)); - resized(); - switchFileButton.setButtonText (showingHeader ? "Show CPP file" : "Show header file"); + refreshContent(); + } + + void parentHierarchyChanged() + { + if (getParentComponent() != 0) + refreshContent(); + else + viewport.setViewedComponent (0); } private: diff --git a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h index 8ae795d117..946469e6f3 100644 --- a/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h +++ b/extras/Jucer (experimental)/Source/ui/Editor Base/jucer_EditorDragOperation.h @@ -193,7 +193,7 @@ public: snapGuides.clear(); - if (canvas->getPanel()->isSnappingEnabled() != e.mods.isCommandDown()) + if (canvas->getPanel()->isSnappingEnabled() != (e.mods.isCommandDown() || e.mods.isCtrlDown())) { performSnap (verticalSnapTargets, getVerticalSnapPositions (distance), true, distance); performSnap (horizontalSnapTargets, getHorizontalSnapPositions (distance), false, distance); diff --git a/extras/Jucer (experimental)/Source/utility/jucer_CodeHelpers.cpp b/extras/Jucer (experimental)/Source/utility/jucer_CodeHelpers.cpp index 68e4c98a76..be0afcc5c3 100644 --- a/extras/Jucer (experimental)/Source/utility/jucer_CodeHelpers.cpp +++ b/extras/Jucer (experimental)/Source/utility/jucer_CodeHelpers.cpp @@ -344,7 +344,7 @@ namespace CodeHelpers if (canUseStringLiteral) { - int numEscaped = 0; + unsigned int numEscaped = 0; for (size_t i = 0; i < mb.getSize(); ++i) { diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index 2a3c0b84fe..d76b17b596 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -62883,14 +62883,12 @@ public: { } - void currentTabChanged (int newCurrentTabIndex, - const String& newTabName) + void currentTabChanged (int newCurrentTabIndex, const String& newTabName) { owner->changeCallback (newCurrentTabIndex, newTabName); } - void popupMenuClickOnTab (int tabIndex, - const String& tabName) + void popupMenuClickOnTab (int tabIndex, const String& tabName) { owner->popupMenuClickOnTab (tabIndex, tabName); } @@ -62993,8 +62991,7 @@ void TabbedComponent::addTab (const String& tabName, tabs->addTab (tabName, tabBackgroundColour, insertIndex); } -void TabbedComponent::setTabName (const int tabIndex, - const String& newName) +void TabbedComponent::setTabName (const int tabIndex, const String& newName) { tabs->setTabName (tabIndex, newName); } @@ -63250,16 +63247,16 @@ void Viewport::setViewedComponent (Component* const newViewedComponent) contentComp->addComponentListener (this); } - updateVisibleRegion(); + updateVisibleArea(); } } -int Viewport::getMaximumVisibleWidth() const throw() +int Viewport::getMaximumVisibleWidth() const { return jmax (0, getWidth() - (verticalScrollBar->isVisible() ? getScrollBarThickness() : 0)); } -int Viewport::getMaximumVisibleHeight() const throw() +int Viewport::getMaximumVisibleHeight() const { return jmax (0, getHeight() - (horizontalScrollBar->isVisible() ? getScrollBarThickness() : 0)); } @@ -63267,8 +63264,7 @@ int Viewport::getMaximumVisibleHeight() const throw() void Viewport::setViewPosition (const int xPixelsOffset, const int yPixelsOffset) { if (contentComp != 0) - contentComp->setTopLeftPosition (-xPixelsOffset, - -yPixelsOffset); + contentComp->setTopLeftPosition (-xPixelsOffset, -yPixelsOffset); } void Viewport::setViewPositionProportionately (const double x, const double y) @@ -63324,72 +63320,84 @@ bool Viewport::autoScroll (int mouseX, int mouseY, int activeBorderThickness, in void Viewport::componentMovedOrResized (Component&, bool, bool) { - updateVisibleRegion(); + updateVisibleArea(); } void Viewport::resized() { - updateVisibleRegion(); + updateVisibleArea(); } -void Viewport::updateVisibleRegion() +void Viewport::updateVisibleArea() { + const int scrollbarWidth = getScrollBarThickness(); + const bool canShowAnyBars = getWidth() > scrollbarWidth && getHeight() > scrollbarWidth; + const bool canShowHBar = showHScrollbar && canShowAnyBars; + const bool canShowVBar = showVScrollbar && canShowAnyBars; + + bool hBarVisible = canShowHBar && ! horizontalScrollBar->autoHides(); + bool vBarVisible = canShowVBar && ! horizontalScrollBar->autoHides(); + if (contentComp != 0) { - Rectangle newViewPos; - newViewPos.setPosition (-contentComp->getPosition()); + Rectangle contentArea (getLocalBounds()); - if (newViewPos.getX() == 0 && newViewPos.getY() == 0 - && contentComp->getWidth() <= getWidth() - && contentComp->getHeight() <= getHeight()) + if (! contentArea.contains (contentComp->getBounds())) { - horizontalScrollBar->setVisible (! horizontalScrollBar->autoHides()); - verticalScrollBar->setVisible (! verticalScrollBar->autoHides()); + hBarVisible = canShowHBar && (hBarVisible || contentComp->getX() < 0 || contentComp->getRight() > contentArea.getWidth()); + vBarVisible = canShowVBar && (vBarVisible || contentComp->getY() < 0 || contentComp->getBottom() > contentArea.getHeight()); + + if (vBarVisible) + contentArea.setWidth (getWidth() - scrollbarWidth); + + if (hBarVisible) + contentArea.setHeight (getHeight() - scrollbarWidth); + + if (! contentArea.contains (contentComp->getBounds())) + { + hBarVisible = canShowHBar && (hBarVisible || contentComp->getRight() > contentArea.getWidth()); + vBarVisible = canShowVBar && (vBarVisible || contentComp->getBottom() > contentArea.getHeight()); + } } - horizontalScrollBar->setRangeLimits (0.0, contentComp->getWidth()); - horizontalScrollBar->setCurrentRange (newViewPos.getX(), getMaximumVisibleWidth()); - horizontalScrollBar->setSingleStepSize (singleStepX); + if (vBarVisible) + contentArea.setWidth (getWidth() - scrollbarWidth); - if (! (contentComp->getWidth() > 0 && showHScrollbar && getHeight() > getScrollBarThickness())) - horizontalScrollBar->setVisible (! horizontalScrollBar->autoHides()); + if (hBarVisible) + contentArea.setHeight (getHeight() - scrollbarWidth); - verticalScrollBar->setRangeLimits (0.0, contentComp->getHeight()); - verticalScrollBar->setCurrentRange (newViewPos.getY(), getMaximumVisibleHeight()); - verticalScrollBar->setSingleStepSize (singleStepY); + const Point visibleOrigin (-contentComp->getPosition()); - if (! (contentComp->getHeight() > 0 && showVScrollbar && getWidth() > getScrollBarThickness())) - verticalScrollBar->setVisible (! verticalScrollBar->autoHides()); - - if (verticalScrollBar->isVisible()) + if (hBarVisible) { - horizontalScrollBar->setCurrentRange (newViewPos.getX(), getMaximumVisibleWidth()); - verticalScrollBar->setCurrentRange (newViewPos.getY(), getMaximumVisibleHeight()); - - verticalScrollBar - ->setBounds (getMaximumVisibleWidth(), 0, - getScrollBarThickness(), getMaximumVisibleHeight()); + horizontalScrollBar->setBounds (0, contentArea.getHeight(), contentArea.getWidth(), scrollbarWidth); + horizontalScrollBar->setRangeLimits (0.0, contentComp->getWidth()); + horizontalScrollBar->setCurrentRange (visibleOrigin.getX(), contentArea.getWidth()); + horizontalScrollBar->setSingleStepSize (singleStepX); } - if (horizontalScrollBar->isVisible()) + if (vBarVisible) { - horizontalScrollBar->setCurrentRange (newViewPos.getX(), getMaximumVisibleWidth()); - - horizontalScrollBar - ->setBounds (0, getMaximumVisibleHeight(), - getMaximumVisibleWidth(), getScrollBarThickness()); + verticalScrollBar->setBounds (contentArea.getWidth(), 0, scrollbarWidth, contentArea.getHeight()); + verticalScrollBar->setRangeLimits (0.0, contentComp->getHeight()); + verticalScrollBar->setCurrentRange (visibleOrigin.getY(), contentArea.getHeight()); + verticalScrollBar->setSingleStepSize (singleStepY); } - contentHolder->setSize (getMaximumVisibleWidth(), - getMaximumVisibleHeight()); + // Force the visibility *after* setting the ranges to avoid flicker caused by edge conditions in the numbers. + horizontalScrollBar->setVisible (hBarVisible); + verticalScrollBar->setVisible (vBarVisible); - newViewPos.setSize (jmin (contentComp->getRight(), getMaximumVisibleWidth()), - jmin (contentComp->getBottom(), getMaximumVisibleHeight())); + contentHolder->setBounds (contentArea); - if (lastViewPos != newViewPos) + const Rectangle visibleArea (visibleOrigin.getX(), visibleOrigin.getY(), + jmin (contentComp->getWidth() - visibleOrigin.getX(), contentArea.getWidth()), + jmin (contentComp->getHeight() - visibleOrigin.getY(), contentArea.getHeight())); + + if (lastVisibleArea != visibleArea) { - lastViewPos = newViewPos; - visibleAreaChanged (newViewPos.getX(), newViewPos.getY(), newViewPos.getWidth(), newViewPos.getHeight()); + lastVisibleArea = visibleArea; + visibleAreaChanged (visibleArea.getX(), visibleArea.getY(), visibleArea.getWidth(), visibleArea.getHeight()); } horizontalScrollBar->handleUpdateNowIfNeeded(); @@ -63397,16 +63405,19 @@ void Viewport::updateVisibleRegion() } else { - horizontalScrollBar->setVisible (! horizontalScrollBar->autoHides()); - verticalScrollBar->setVisible (! verticalScrollBar->autoHides()); + horizontalScrollBar->setVisible (hBarVisible); + verticalScrollBar->setVisible (vBarVisible); } } void Viewport::setSingleStepSizes (const int stepX, const int stepY) { - singleStepX = stepX; - singleStepY = stepY; - updateVisibleRegion(); + if (singleStepX != stepX || singleStepY != stepY) + { + singleStepX = stepX; + singleStepY = stepY; + updateVisibleArea(); + } } void Viewport::setScrollBarsShown (const bool showVerticalScrollbarIfNeeded, @@ -63417,22 +63428,23 @@ void Viewport::setScrollBarsShown (const bool showVerticalScrollbarIfNeeded, { showVScrollbar = showVerticalScrollbarIfNeeded; showHScrollbar = showHorizontalScrollbarIfNeeded; - horizontalScrollBar->setVisible (true); - verticalScrollBar->setVisible (true); - updateVisibleRegion(); + updateVisibleArea(); } } void Viewport::setScrollBarThickness (const int thickness) { - scrollBarThickness = thickness; - updateVisibleRegion(); + if (scrollBarThickness != thickness) + { + scrollBarThickness = thickness; + updateVisibleArea(); + } } -int Viewport::getScrollBarThickness() const throw() +int Viewport::getScrollBarThickness() const { - return (scrollBarThickness > 0) ? scrollBarThickness - : getLookAndFeel().getDefaultScrollbarWidth(); + return scrollBarThickness > 0 ? scrollBarThickness + : getLookAndFeel().getDefaultScrollbarWidth(); } void Viewport::setScrollBarButtonVisibility (const bool buttonsVisible) @@ -63443,17 +63455,19 @@ void Viewport::setScrollBarButtonVisibility (const bool buttonsVisible) void Viewport::scrollBarMoved (ScrollBar* scrollBarThatHasMoved, double newRangeStart) { + const int newRangeStartInt = roundToInt (newRangeStart); + if (scrollBarThatHasMoved == horizontalScrollBar) { - setViewPosition (roundToInt (newRangeStart), getViewPositionY()); + setViewPosition (newRangeStartInt, getViewPositionY()); } else if (scrollBarThatHasMoved == verticalScrollBar) { - setViewPosition (getViewPositionX(), roundToInt (newRangeStart)); + setViewPosition (getViewPositionX(), newRangeStartInt); } } -void Viewport::mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY) +void Viewport::mouseWheelMove (const MouseEvent& e, const float wheelIncrementX, const float wheelIncrementY) { if (! useMouseWheelMoveIfNeeded (e, wheelIncrementX, wheelIncrementY)) Component::mouseWheelMove (e, wheelIncrementX, wheelIncrementY); diff --git a/juce_amalgamated.h b/juce_amalgamated.h index a8c5c3f0ec..7f5942e6c4 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -33986,45 +33986,45 @@ public: /** Returns the position within the child component of the top-left of its visible area. */ - const Point getViewPosition() const throw() { return lastViewPos.getPosition(); } + const Point getViewPosition() const throw() { return lastVisibleArea.getPosition(); } /** Returns the position within the child component of the top-left of its visible area. @see getViewWidth, setViewPosition */ - int getViewPositionX() const throw() { return lastViewPos.getX(); } + int getViewPositionX() const throw() { return lastVisibleArea.getX(); } /** Returns the position within the child component of the top-left of its visible area. @see getViewHeight, setViewPosition */ - int getViewPositionY() const throw() { return lastViewPos.getY(); } + int getViewPositionY() const throw() { return lastVisibleArea.getY(); } /** Returns the width of the visible area of the child component. This may be less than the width of this Viewport if there's a vertical scrollbar or if the child component is itself smaller. */ - int getViewWidth() const throw() { return lastViewPos.getWidth(); } + int getViewWidth() const throw() { return lastVisibleArea.getWidth(); } /** Returns the height of the visible area of the child component. This may be less than the height of this Viewport if there's a horizontal scrollbar or if the child component is itself smaller. */ - int getViewHeight() const throw() { return lastViewPos.getHeight(); } + int getViewHeight() const throw() { return lastVisibleArea.getHeight(); } /** Returns the width available within this component for the contents. This will be the width of the viewport component minus the width of a vertical scrollbar (if visible). */ - int getMaximumVisibleWidth() const throw(); + int getMaximumVisibleWidth() const; /** Returns the height available within this component for the contents. This will be the height of the viewport component minus the space taken up by a horizontal scrollbar (if visible). */ - int getMaximumVisibleHeight() const throw(); + int getMaximumVisibleHeight() const; /** Callback method that is called when the visible area changes. @@ -34064,7 +34064,7 @@ public: @see setScrollBarThickness */ - int getScrollBarThickness() const throw(); + int getScrollBarThickness() const; /** Changes the distance that a single-step click on a scrollbar button will move the viewport. @@ -34106,7 +34106,7 @@ public: private: Component::SafePointer contentComp; - Rectangle lastViewPos; + Rectangle lastVisibleArea; int scrollBarThickness; int singleStepX, singleStepY; bool showHScrollbar, showVScrollbar; @@ -34114,7 +34114,7 @@ private: ScrollBar* verticalScrollBar; ScrollBar* horizontalScrollBar; - void updateVisibleRegion(); + void updateVisibleArea(); Viewport (const Viewport&); Viewport& operator= (const Viewport&); diff --git a/src/gui/components/layout/juce_TabbedComponent.cpp b/src/gui/components/layout/juce_TabbedComponent.cpp index a233bb2ecd..c4626fc973 100644 --- a/src/gui/components/layout/juce_TabbedComponent.cpp +++ b/src/gui/components/layout/juce_TabbedComponent.cpp @@ -46,14 +46,12 @@ public: { } - void currentTabChanged (int newCurrentTabIndex, - const String& newTabName) + void currentTabChanged (int newCurrentTabIndex, const String& newTabName) { owner->changeCallback (newCurrentTabIndex, newTabName); } - void popupMenuClickOnTab (int tabIndex, - const String& tabName) + void popupMenuClickOnTab (int tabIndex, const String& tabName) { owner->popupMenuClickOnTab (tabIndex, tabName); } @@ -159,8 +157,7 @@ void TabbedComponent::addTab (const String& tabName, tabs->addTab (tabName, tabBackgroundColour, insertIndex); } -void TabbedComponent::setTabName (const int tabIndex, - const String& newName) +void TabbedComponent::setTabName (const int tabIndex, const String& newName) { tabs->setTabName (tabIndex, newName); } diff --git a/src/gui/components/layout/juce_Viewport.cpp b/src/gui/components/layout/juce_Viewport.cpp index 41074eab31..8feba6e1ee 100644 --- a/src/gui/components/layout/juce_Viewport.cpp +++ b/src/gui/components/layout/juce_Viewport.cpp @@ -88,16 +88,16 @@ void Viewport::setViewedComponent (Component* const newViewedComponent) contentComp->addComponentListener (this); } - updateVisibleRegion(); + updateVisibleArea(); } } -int Viewport::getMaximumVisibleWidth() const throw() +int Viewport::getMaximumVisibleWidth() const { return jmax (0, getWidth() - (verticalScrollBar->isVisible() ? getScrollBarThickness() : 0)); } -int Viewport::getMaximumVisibleHeight() const throw() +int Viewport::getMaximumVisibleHeight() const { return jmax (0, getHeight() - (horizontalScrollBar->isVisible() ? getScrollBarThickness() : 0)); } @@ -105,8 +105,7 @@ int Viewport::getMaximumVisibleHeight() const throw() void Viewport::setViewPosition (const int xPixelsOffset, const int yPixelsOffset) { if (contentComp != 0) - contentComp->setTopLeftPosition (-xPixelsOffset, - -yPixelsOffset); + contentComp->setTopLeftPosition (-xPixelsOffset, -yPixelsOffset); } void Viewport::setViewPositionProportionately (const double x, const double y) @@ -162,74 +161,86 @@ bool Viewport::autoScroll (int mouseX, int mouseY, int activeBorderThickness, in void Viewport::componentMovedOrResized (Component&, bool, bool) { - updateVisibleRegion(); + updateVisibleArea(); } void Viewport::resized() { - updateVisibleRegion(); + updateVisibleArea(); } //============================================================================== -void Viewport::updateVisibleRegion() +void Viewport::updateVisibleArea() { + const int scrollbarWidth = getScrollBarThickness(); + const bool canShowAnyBars = getWidth() > scrollbarWidth && getHeight() > scrollbarWidth; + const bool canShowHBar = showHScrollbar && canShowAnyBars; + const bool canShowVBar = showVScrollbar && canShowAnyBars; + + bool hBarVisible = canShowHBar && ! horizontalScrollBar->autoHides(); + bool vBarVisible = canShowVBar && ! horizontalScrollBar->autoHides(); + if (contentComp != 0) { - Rectangle newViewPos; - newViewPos.setPosition (-contentComp->getPosition()); + Rectangle contentArea (getLocalBounds()); - if (newViewPos.getX() == 0 && newViewPos.getY() == 0 - && contentComp->getWidth() <= getWidth() - && contentComp->getHeight() <= getHeight()) + if (! contentArea.contains (contentComp->getBounds())) { - horizontalScrollBar->setVisible (! horizontalScrollBar->autoHides()); - verticalScrollBar->setVisible (! verticalScrollBar->autoHides()); + hBarVisible = canShowHBar && (hBarVisible || contentComp->getX() < 0 || contentComp->getRight() > contentArea.getWidth()); + vBarVisible = canShowVBar && (vBarVisible || contentComp->getY() < 0 || contentComp->getBottom() > contentArea.getHeight()); + + if (vBarVisible) + contentArea.setWidth (getWidth() - scrollbarWidth); + + if (hBarVisible) + contentArea.setHeight (getHeight() - scrollbarWidth); + + if (! contentArea.contains (contentComp->getBounds())) + { + hBarVisible = canShowHBar && (hBarVisible || contentComp->getRight() > contentArea.getWidth()); + vBarVisible = canShowVBar && (vBarVisible || contentComp->getBottom() > contentArea.getHeight()); + } } - horizontalScrollBar->setRangeLimits (0.0, contentComp->getWidth()); - horizontalScrollBar->setCurrentRange (newViewPos.getX(), getMaximumVisibleWidth()); - horizontalScrollBar->setSingleStepSize (singleStepX); + if (vBarVisible) + contentArea.setWidth (getWidth() - scrollbarWidth); - if (! (contentComp->getWidth() > 0 && showHScrollbar && getHeight() > getScrollBarThickness())) - horizontalScrollBar->setVisible (! horizontalScrollBar->autoHides()); + if (hBarVisible) + contentArea.setHeight (getHeight() - scrollbarWidth); - verticalScrollBar->setRangeLimits (0.0, contentComp->getHeight()); - verticalScrollBar->setCurrentRange (newViewPos.getY(), getMaximumVisibleHeight()); - verticalScrollBar->setSingleStepSize (singleStepY); + const Point visibleOrigin (-contentComp->getPosition()); - if (! (contentComp->getHeight() > 0 && showVScrollbar && getWidth() > getScrollBarThickness())) - verticalScrollBar->setVisible (! verticalScrollBar->autoHides()); - - if (verticalScrollBar->isVisible()) + if (hBarVisible) { - horizontalScrollBar->setCurrentRange (newViewPos.getX(), getMaximumVisibleWidth()); - verticalScrollBar->setCurrentRange (newViewPos.getY(), getMaximumVisibleHeight()); - - verticalScrollBar - ->setBounds (getMaximumVisibleWidth(), 0, - getScrollBarThickness(), getMaximumVisibleHeight()); + horizontalScrollBar->setBounds (0, contentArea.getHeight(), contentArea.getWidth(), scrollbarWidth); + horizontalScrollBar->setRangeLimits (0.0, contentComp->getWidth()); + horizontalScrollBar->setCurrentRange (visibleOrigin.getX(), contentArea.getWidth()); + horizontalScrollBar->setSingleStepSize (singleStepX); } - if (horizontalScrollBar->isVisible()) + if (vBarVisible) { - horizontalScrollBar->setCurrentRange (newViewPos.getX(), getMaximumVisibleWidth()); - - horizontalScrollBar - ->setBounds (0, getMaximumVisibleHeight(), - getMaximumVisibleWidth(), getScrollBarThickness()); + verticalScrollBar->setBounds (contentArea.getWidth(), 0, scrollbarWidth, contentArea.getHeight()); + verticalScrollBar->setRangeLimits (0.0, contentComp->getHeight()); + verticalScrollBar->setCurrentRange (visibleOrigin.getY(), contentArea.getHeight()); + verticalScrollBar->setSingleStepSize (singleStepY); } - contentHolder->setSize (getMaximumVisibleWidth(), - getMaximumVisibleHeight()); + // Force the visibility *after* setting the ranges to avoid flicker caused by edge conditions in the numbers. + horizontalScrollBar->setVisible (hBarVisible); + verticalScrollBar->setVisible (vBarVisible); - newViewPos.setSize (jmin (contentComp->getRight(), getMaximumVisibleWidth()), - jmin (contentComp->getBottom(), getMaximumVisibleHeight())); + contentHolder->setBounds (contentArea); - if (lastViewPos != newViewPos) + const Rectangle visibleArea (visibleOrigin.getX(), visibleOrigin.getY(), + jmin (contentComp->getWidth() - visibleOrigin.getX(), contentArea.getWidth()), + jmin (contentComp->getHeight() - visibleOrigin.getY(), contentArea.getHeight())); + + if (lastVisibleArea != visibleArea) { - lastViewPos = newViewPos; - visibleAreaChanged (newViewPos.getX(), newViewPos.getY(), newViewPos.getWidth(), newViewPos.getHeight()); + lastVisibleArea = visibleArea; + visibleAreaChanged (visibleArea.getX(), visibleArea.getY(), visibleArea.getWidth(), visibleArea.getHeight()); } horizontalScrollBar->handleUpdateNowIfNeeded(); @@ -237,17 +248,20 @@ void Viewport::updateVisibleRegion() } else { - horizontalScrollBar->setVisible (! horizontalScrollBar->autoHides()); - verticalScrollBar->setVisible (! verticalScrollBar->autoHides()); + horizontalScrollBar->setVisible (hBarVisible); + verticalScrollBar->setVisible (vBarVisible); } } //============================================================================== void Viewport::setSingleStepSizes (const int stepX, const int stepY) { - singleStepX = stepX; - singleStepY = stepY; - updateVisibleRegion(); + if (singleStepX != stepX || singleStepY != stepY) + { + singleStepX = stepX; + singleStepY = stepY; + updateVisibleArea(); + } } void Viewport::setScrollBarsShown (const bool showVerticalScrollbarIfNeeded, @@ -258,22 +272,23 @@ void Viewport::setScrollBarsShown (const bool showVerticalScrollbarIfNeeded, { showVScrollbar = showVerticalScrollbarIfNeeded; showHScrollbar = showHorizontalScrollbarIfNeeded; - horizontalScrollBar->setVisible (true); - verticalScrollBar->setVisible (true); - updateVisibleRegion(); + updateVisibleArea(); } } void Viewport::setScrollBarThickness (const int thickness) { - scrollBarThickness = thickness; - updateVisibleRegion(); + if (scrollBarThickness != thickness) + { + scrollBarThickness = thickness; + updateVisibleArea(); + } } -int Viewport::getScrollBarThickness() const throw() +int Viewport::getScrollBarThickness() const { - return (scrollBarThickness > 0) ? scrollBarThickness - : getLookAndFeel().getDefaultScrollbarWidth(); + return scrollBarThickness > 0 ? scrollBarThickness + : getLookAndFeel().getDefaultScrollbarWidth(); } void Viewport::setScrollBarButtonVisibility (const bool buttonsVisible) @@ -284,17 +299,19 @@ void Viewport::setScrollBarButtonVisibility (const bool buttonsVisible) void Viewport::scrollBarMoved (ScrollBar* scrollBarThatHasMoved, double newRangeStart) { + const int newRangeStartInt = roundToInt (newRangeStart); + if (scrollBarThatHasMoved == horizontalScrollBar) { - setViewPosition (roundToInt (newRangeStart), getViewPositionY()); + setViewPosition (newRangeStartInt, getViewPositionY()); } else if (scrollBarThatHasMoved == verticalScrollBar) { - setViewPosition (getViewPositionX(), roundToInt (newRangeStart)); + setViewPosition (getViewPositionX(), newRangeStartInt); } } -void Viewport::mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY) +void Viewport::mouseWheelMove (const MouseEvent& e, const float wheelIncrementX, const float wheelIncrementY) { if (! useMouseWheelMoveIfNeeded (e, wheelIncrementX, wheelIncrementY)) Component::mouseWheelMove (e, wheelIncrementX, wheelIncrementY); diff --git a/src/gui/components/layout/juce_Viewport.h b/src/gui/components/layout/juce_Viewport.h index 5ed7477904..4fb39eb599 100644 --- a/src/gui/components/layout/juce_Viewport.h +++ b/src/gui/components/layout/juce_Viewport.h @@ -121,45 +121,45 @@ public: /** Returns the position within the child component of the top-left of its visible area. */ - const Point getViewPosition() const throw() { return lastViewPos.getPosition(); } + const Point getViewPosition() const throw() { return lastVisibleArea.getPosition(); } /** Returns the position within the child component of the top-left of its visible area. @see getViewWidth, setViewPosition */ - int getViewPositionX() const throw() { return lastViewPos.getX(); } + int getViewPositionX() const throw() { return lastVisibleArea.getX(); } /** Returns the position within the child component of the top-left of its visible area. @see getViewHeight, setViewPosition */ - int getViewPositionY() const throw() { return lastViewPos.getY(); } + int getViewPositionY() const throw() { return lastVisibleArea.getY(); } /** Returns the width of the visible area of the child component. This may be less than the width of this Viewport if there's a vertical scrollbar or if the child component is itself smaller. */ - int getViewWidth() const throw() { return lastViewPos.getWidth(); } + int getViewWidth() const throw() { return lastVisibleArea.getWidth(); } /** Returns the height of the visible area of the child component. This may be less than the height of this Viewport if there's a horizontal scrollbar or if the child component is itself smaller. */ - int getViewHeight() const throw() { return lastViewPos.getHeight(); } + int getViewHeight() const throw() { return lastVisibleArea.getHeight(); } /** Returns the width available within this component for the contents. This will be the width of the viewport component minus the width of a vertical scrollbar (if visible). */ - int getMaximumVisibleWidth() const throw(); + int getMaximumVisibleWidth() const; /** Returns the height available within this component for the contents. This will be the height of the viewport component minus the space taken up by a horizontal scrollbar (if visible). */ - int getMaximumVisibleHeight() const throw(); + int getMaximumVisibleHeight() const; //============================================================================== /** Callback method that is called when the visible area changes. @@ -201,7 +201,7 @@ public: @see setScrollBarThickness */ - int getScrollBarThickness() const throw(); + int getScrollBarThickness() const; /** Changes the distance that a single-step click on a scrollbar button will move the viewport. @@ -245,7 +245,7 @@ public: private: Component::SafePointer contentComp; - Rectangle lastViewPos; + Rectangle lastVisibleArea; int scrollBarThickness; int singleStepX, singleStepY; bool showHScrollbar, showVScrollbar; @@ -253,7 +253,7 @@ private: ScrollBar* verticalScrollBar; ScrollBar* horizontalScrollBar; - void updateVisibleRegion(); + void updateVisibleArea(); Viewport (const Viewport&); Viewport& operator= (const Viewport&);