1/* 2 * Copyright (C) 2008, 2011 Apple Inc. All Rights Reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef ScrollableArea_h 27#define ScrollableArea_h 28 29#include "Scrollbar.h" 30#include <wtf/Vector.h> 31 32namespace WebCore { 33 34class FloatPoint; 35class GraphicsContext; 36class PlatformGestureEvent; 37class PlatformWheelEvent; 38class ScrollAnimator; 39#if USE(ACCELERATED_COMPOSITING) 40class GraphicsLayer; 41class TiledBacking; 42#endif 43 44class ScrollableArea { 45public: 46 bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1); 47 void scrollToOffsetWithoutAnimation(const FloatPoint&); 48 void scrollToOffsetWithoutAnimation(ScrollbarOrientation, float offset); 49 50 // Should be called when the scroll position changes externally, for example if the scroll layer position 51 // is updated on the scrolling thread and we need to notify the main thread. 52 void notifyScrollPositionChanged(const IntPoint&); 53 54 // Allows subclasses to handle scroll position updates themselves. If this member function 55 // returns true, the scrollable area won't actually update the scroll position and instead 56 // expect it to happen sometime in the future. 57 virtual bool requestScrollPositionUpdate(const IntPoint&) { return false; } 58 59 bool handleWheelEvent(const PlatformWheelEvent&); 60 61 // Functions for controlling if you can scroll past the end of the document. 62 bool constrainsScrollingToContentEdge() const { return m_constrainsScrollingToContentEdge; } 63 void setConstrainsScrollingToContentEdge(bool constrainsScrollingToContentEdge) { m_constrainsScrollingToContentEdge = constrainsScrollingToContentEdge; } 64 65 void setVerticalScrollElasticity(ScrollElasticity scrollElasticity) { m_verticalScrollElasticity = scrollElasticity; } 66 ScrollElasticity verticalScrollElasticity() const { return static_cast<ScrollElasticity>(m_verticalScrollElasticity); } 67 68 void setHorizontalScrollElasticity(ScrollElasticity scrollElasticity) { m_horizontalScrollElasticity = scrollElasticity; } 69 ScrollElasticity horizontalScrollElasticity() const { return static_cast<ScrollElasticity>(m_horizontalScrollElasticity); } 70 71 bool inLiveResize() const { return m_inLiveResize; } 72 virtual void willStartLiveResize(); 73 virtual void willEndLiveResize(); 74 75 void contentAreaWillPaint() const; 76 void mouseEnteredContentArea() const; 77 void mouseExitedContentArea() const; 78 void mouseMovedInContentArea() const; 79 void mouseEnteredScrollbar(Scrollbar*) const; 80 void mouseExitedScrollbar(Scrollbar*) const; 81 void contentAreaDidShow() const; 82 void contentAreaDidHide() const; 83 84 void finishCurrentScrollAnimations() const; 85 virtual bool scrollbarAnimationsAreSuppressed() const { return false; } 86 87 virtual void didAddScrollbar(Scrollbar*, ScrollbarOrientation); 88 virtual void willRemoveScrollbar(Scrollbar*, ScrollbarOrientation); 89 90 virtual void contentsResized(); 91 92 bool hasOverlayScrollbars() const; 93 virtual void setScrollbarOverlayStyle(ScrollbarOverlayStyle); 94 ScrollbarOverlayStyle scrollbarOverlayStyle() const { return static_cast<ScrollbarOverlayStyle>(m_scrollbarOverlayStyle); } 95 96 // This getter will create a ScrollAnimator if it doesn't already exist. 97 ScrollAnimator* scrollAnimator() const; 98 99 // This getter will return null if the ScrollAnimator hasn't been created yet. 100 ScrollAnimator* existingScrollAnimator() const { return m_scrollAnimator.get(); } 101 102 const IntPoint& scrollOrigin() const { return m_scrollOrigin; } 103 bool scrollOriginChanged() const { return m_scrollOriginChanged; } 104 105 virtual bool isActive() const = 0; 106 virtual int scrollSize(ScrollbarOrientation) const = 0; 107 virtual int scrollPosition(Scrollbar*) const = 0; 108 virtual void invalidateScrollbar(Scrollbar*, const IntRect&); 109 virtual bool isScrollCornerVisible() const = 0; 110 virtual IntRect scrollCornerRect() const = 0; 111 virtual void invalidateScrollCorner(const IntRect&); 112 virtual void getTickmarks(Vector<IntRect>&) const { } 113 114 // Convert points and rects between the scrollbar and its containing view. 115 // The client needs to implement these in order to be aware of layout effects 116 // like CSS transforms. 117 virtual IntRect convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& scrollbarRect) const 118 { 119 return scrollbar->Widget::convertToContainingView(scrollbarRect); 120 } 121 virtual IntRect convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const 122 { 123 return scrollbar->Widget::convertFromContainingView(parentRect); 124 } 125 virtual IntPoint convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& scrollbarPoint) const 126 { 127 return scrollbar->Widget::convertToContainingView(scrollbarPoint); 128 } 129 virtual IntPoint convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const 130 { 131 return scrollbar->Widget::convertFromContainingView(parentPoint); 132 } 133 134 virtual Scrollbar* horizontalScrollbar() const { return 0; } 135 virtual Scrollbar* verticalScrollbar() const { return 0; } 136 137 virtual IntPoint scrollPosition() const; 138 virtual IntPoint minimumScrollPosition() const; 139 virtual IntPoint maximumScrollPosition() const; 140 141 enum VisibleContentRectIncludesScrollbars { ExcludeScrollbars, IncludeScrollbars }; 142 virtual IntRect visibleContentRect(VisibleContentRectIncludesScrollbars = ExcludeScrollbars) const; 143 virtual int visibleHeight() const = 0; 144 virtual int visibleWidth() const = 0; 145 virtual IntSize contentsSize() const = 0; 146 virtual IntSize overhangAmount() const { return IntSize(); } 147 virtual IntPoint lastKnownMousePosition() const { return IntPoint(); } 148 virtual bool isHandlingWheelEvent() const { return false; } 149 150 virtual int headerHeight() const { return 0; } 151 virtual int footerHeight() const { return 0; } 152 153 // The totalContentsSize() is equivalent to the contentsSize() plus the header and footer heights. 154 IntSize totalContentsSize() const; 155 156 virtual bool shouldSuspendScrollAnimations() const { return true; } 157 virtual void scrollbarStyleChanged(int /*newStyle*/, bool /*forceUpdate*/) { } 158 virtual void setVisibleScrollerThumbRect(const IntRect&) { } 159 160 virtual bool scrollbarsCanBeActive() const = 0; 161 162 // Note that this only returns scrollable areas that can actually be scrolled. 163 virtual ScrollableArea* enclosingScrollableArea() const = 0; 164 165 // Returns the bounding box of this scrollable area, in the coordinate system of the enclosing scroll view. 166 virtual IntRect scrollableAreaBoundingBox() const = 0; 167 168 virtual bool shouldRubberBandInDirection(ScrollDirection) const { return true; } 169 virtual bool isRubberBandInProgress() const { return false; } 170 171 virtual bool scrollAnimatorEnabled() const { return false; } 172 173 // NOTE: Only called from Internals for testing. 174 void setScrollOffsetFromInternals(const IntPoint&); 175 176 static IntPoint constrainScrollPositionForOverhang(const IntRect& visibleContentRect, const IntSize& totalContentsSize, const IntPoint& scrollPosition, const IntPoint& scrollOrigin, int headerHeight, int footetHeight); 177 IntPoint constrainScrollPositionForOverhang(const IntPoint& scrollPosition); 178 179 // Let subclasses provide a way of asking for and servicing scroll 180 // animations. 181 virtual bool scheduleAnimation() { return false; } 182 void serviceScrollAnimations(); 183 184#if USE(ACCELERATED_COMPOSITING) 185 virtual TiledBacking* tiledBacking() { return 0; } 186 virtual bool usesCompositedScrolling() const { return false; } 187#endif 188 189protected: 190 ScrollableArea(); 191 virtual ~ScrollableArea(); 192 193 void setScrollOrigin(const IntPoint&); 194 void resetScrollOriginChanged() { m_scrollOriginChanged = false; } 195 196 virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) = 0; 197 virtual void invalidateScrollCornerRect(const IntRect&) = 0; 198 199#if USE(ACCELERATED_COMPOSITING) 200 friend class ScrollingCoordinator; 201 virtual GraphicsLayer* layerForScrolling() const { return 0; } 202 virtual GraphicsLayer* layerForHorizontalScrollbar() const { return 0; } 203 virtual GraphicsLayer* layerForVerticalScrollbar() const { return 0; } 204 virtual GraphicsLayer* layerForScrollCorner() const { return 0; } 205#if ENABLE(RUBBER_BANDING) 206 virtual GraphicsLayer* layerForOverhangAreas() const { return 0; } 207#endif 208#endif 209 bool hasLayerForHorizontalScrollbar() const; 210 bool hasLayerForVerticalScrollbar() const; 211 bool hasLayerForScrollCorner() const; 212 213private: 214 void scrollPositionChanged(const IntPoint&); 215 216 // NOTE: Only called from the ScrollAnimator. 217 friend class ScrollAnimator; 218 void setScrollOffsetFromAnimation(const IntPoint&); 219 220 // This function should be overriden by subclasses to perform the actual 221 // scroll of the content. 222 virtual void setScrollOffset(const IntPoint&) = 0; 223 224 mutable OwnPtr<ScrollAnimator> m_scrollAnimator; 225 unsigned m_constrainsScrollingToContentEdge : 1; 226 227 unsigned m_inLiveResize : 1; 228 229 unsigned m_verticalScrollElasticity : 2; // ScrollElasticity 230 unsigned m_horizontalScrollElasticity : 2; // ScrollElasticity 231 232 unsigned m_scrollbarOverlayStyle : 2; // ScrollbarOverlayStyle 233 234 unsigned m_scrollOriginChanged : 1; 235 236 // There are 8 possible combinations of writing mode and direction. Scroll origin will be non-zero in the x or y axis 237 // if there is any reversed direction or writing-mode. The combinations are: 238 // writing-mode / direction scrollOrigin.x() set scrollOrigin.y() set 239 // horizontal-tb / ltr NO NO 240 // horizontal-tb / rtl YES NO 241 // horizontal-bt / ltr NO YES 242 // horizontal-bt / rtl YES YES 243 // vertical-lr / ltr NO NO 244 // vertical-lr / rtl NO YES 245 // vertical-rl / ltr YES NO 246 // vertical-rl / rtl YES YES 247 IntPoint m_scrollOrigin; 248}; 249 250} // namespace WebCore 251 252#endif // ScrollableArea_h 253