2 * Copyright (C) 2008, 2011 Apple Inc. All Rights Reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef ScrollableArea_h
27 #define ScrollableArea_h
29 #include "platform/PlatformExport.h"
30 #include "platform/scroll/ScrollAnimator.h"
31 #include "platform/scroll/Scrollbar.h"
32 #include "wtf/Noncopyable.h"
33 #include "wtf/Vector.h"
38 class GraphicsContext;
40 class PlatformGestureEvent;
41 class PlatformWheelEvent;
46 ScrollBehaviorInstant,
50 class PLATFORM_EXPORT ScrollableArea {
51 WTF_MAKE_NONCOPYABLE(ScrollableArea);
53 static int pixelsPerLineStep();
54 static float minFractionToStepWhenPaging();
55 static int maxOverlapBetweenPages();
57 bool scroll(ScrollDirection, ScrollGranularity, float delta = 1);
58 void scrollToOffsetWithoutAnimation(const FloatPoint&);
59 void scrollToOffsetWithoutAnimation(ScrollbarOrientation, float offset);
61 // Should be called when the scroll position changes externally, for example if the scroll layer position
62 // is updated on the scrolling thread and we need to notify the main thread.
63 void notifyScrollPositionChanged(const IntPoint&);
65 static bool scrollBehaviorFromString(const String&, ScrollBehavior&);
67 bool handleWheelEvent(const PlatformWheelEvent&);
69 // Functions for controlling if you can scroll past the end of the document.
70 bool constrainsScrollingToContentEdge() const { return m_constrainsScrollingToContentEdge; }
71 void setConstrainsScrollingToContentEdge(bool constrainsScrollingToContentEdge) { m_constrainsScrollingToContentEdge = constrainsScrollingToContentEdge; }
73 void setVerticalScrollElasticity(ScrollElasticity scrollElasticity) { m_verticalScrollElasticity = scrollElasticity; }
74 ScrollElasticity verticalScrollElasticity() const { return static_cast<ScrollElasticity>(m_verticalScrollElasticity); }
76 void setHorizontalScrollElasticity(ScrollElasticity scrollElasticity) { m_horizontalScrollElasticity = scrollElasticity; }
77 ScrollElasticity horizontalScrollElasticity() const { return static_cast<ScrollElasticity>(m_horizontalScrollElasticity); }
79 bool inLiveResize() const { return m_inLiveResize; }
80 void willStartLiveResize();
81 void willEndLiveResize();
83 void contentAreaWillPaint() const;
84 void mouseEnteredContentArea() const;
85 void mouseExitedContentArea() const;
86 void mouseMovedInContentArea() const;
87 void mouseEnteredScrollbar(Scrollbar*) const;
88 void mouseExitedScrollbar(Scrollbar*) const;
89 void contentAreaDidShow() const;
90 void contentAreaDidHide() const;
92 void finishCurrentScrollAnimations() const;
94 virtual void didAddScrollbar(Scrollbar*, ScrollbarOrientation);
95 virtual void willRemoveScrollbar(Scrollbar*, ScrollbarOrientation);
97 virtual void contentsResized();
99 bool hasOverlayScrollbars() const;
100 void setScrollbarOverlayStyle(ScrollbarOverlayStyle);
101 ScrollbarOverlayStyle scrollbarOverlayStyle() const { return static_cast<ScrollbarOverlayStyle>(m_scrollbarOverlayStyle); }
103 // This getter will create a ScrollAnimator if it doesn't already exist.
104 ScrollAnimator* scrollAnimator() const;
106 // This getter will return null if the ScrollAnimator hasn't been created yet.
107 ScrollAnimator* existingScrollAnimator() const { return m_scrollAnimator.get(); }
109 const IntPoint& scrollOrigin() const { return m_scrollOrigin; }
110 bool scrollOriginChanged() const { return m_scrollOriginChanged; }
112 virtual bool isActive() const = 0;
113 virtual int scrollSize(ScrollbarOrientation) const = 0;
114 virtual void invalidateScrollbar(Scrollbar*, const IntRect&);
115 virtual bool isScrollCornerVisible() const = 0;
116 virtual IntRect scrollCornerRect() const = 0;
117 virtual void invalidateScrollCorner(const IntRect&);
118 virtual void getTickmarks(Vector<IntRect>&) const { }
120 // Convert points and rects between the scrollbar and its containing view.
121 // The client needs to implement these in order to be aware of layout effects
122 // like CSS transforms.
123 virtual IntRect convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& scrollbarRect) const
125 return scrollbar->Widget::convertToContainingView(scrollbarRect);
127 virtual IntRect convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const
129 return scrollbar->Widget::convertFromContainingView(parentRect);
131 virtual IntPoint convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& scrollbarPoint) const
133 return scrollbar->Widget::convertToContainingView(scrollbarPoint);
135 virtual IntPoint convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
137 return scrollbar->Widget::convertFromContainingView(parentPoint);
140 virtual Scrollbar* horizontalScrollbar() const { return 0; }
141 virtual Scrollbar* verticalScrollbar() const { return 0; }
143 // scrollPosition is relative to the scrollOrigin. i.e. If the page is RTL
144 // then scrollPosition will be negative.
145 virtual IntPoint scrollPosition() const = 0;
146 virtual IntPoint minimumScrollPosition() const = 0;
147 virtual IntPoint maximumScrollPosition() const = 0;
149 enum IncludeScrollbarsInRect { ExcludeScrollbars, IncludeScrollbars };
150 virtual IntRect visibleContentRect(IncludeScrollbarsInRect = ExcludeScrollbars) const;
151 virtual int visibleHeight() const = 0;
152 virtual int visibleWidth() const = 0;
153 virtual IntSize contentsSize() const = 0;
154 virtual IntSize overhangAmount() const { return IntSize(); }
155 virtual IntPoint lastKnownMousePosition() const { return IntPoint(); }
157 virtual bool shouldSuspendScrollAnimations() const { return true; }
158 virtual void scrollbarStyleChanged(int /*newStyle*/, bool /*forceUpdate*/) { }
160 virtual bool scrollbarsCanBeActive() const = 0;
162 // Note that this only returns scrollable areas that can actually be scrolled.
163 virtual ScrollableArea* enclosingScrollableArea() const = 0;
165 // Returns the bounding box of this scrollable area, in the coordinate system of the enclosing scroll view.
166 virtual IntRect scrollableAreaBoundingBox() const = 0;
168 virtual bool shouldRubberBandInDirection(ScrollDirection) const { return true; }
169 virtual bool isRubberBandInProgress() const { return false; }
171 virtual bool scrollAnimatorEnabled() const { return false; }
173 // NOTE: Only called from Internals for testing.
174 void setScrollOffsetFromInternals(const IntPoint&);
176 IntPoint clampScrollPosition(const IntPoint&) const;
178 // Let subclasses provide a way of asking for and servicing scroll
180 virtual bool scheduleAnimation() { return false; }
181 void serviceScrollAnimations();
183 virtual bool usesCompositedScrolling() const { return false; }
184 virtual void updateNeedsCompositedScrolling() { }
185 virtual void updateHasVisibleNonLayerContent() { }
187 virtual bool userInputScrollable(ScrollbarOrientation) const = 0;
188 virtual bool shouldPlaceVerticalScrollbarOnLeft() const = 0;
190 // Convenience functions
191 int scrollPosition(ScrollbarOrientation orientation) { return orientation == HorizontalScrollbar ? scrollPosition().x() : scrollPosition().y(); }
192 int minimumScrollPosition(ScrollbarOrientation orientation) { return orientation == HorizontalScrollbar ? minimumScrollPosition().x() : minimumScrollPosition().y(); }
193 int maximumScrollPosition(ScrollbarOrientation orientation) { return orientation == HorizontalScrollbar ? maximumScrollPosition().x() : maximumScrollPosition().y(); }
194 int clampScrollPosition(ScrollbarOrientation orientation, int pos) { return std::max(std::min(pos, maximumScrollPosition(orientation)), minimumScrollPosition(orientation)); }
196 bool hasVerticalBarDamage() const { return m_hasVerticalBarDamage; }
197 bool hasHorizontalBarDamage() const { return m_hasHorizontalBarDamage; }
199 const IntRect& verticalBarDamage() const
201 ASSERT(m_hasVerticalBarDamage);
202 return m_verticalBarDamage;
205 const IntRect& horizontalBarDamage() const
207 ASSERT(m_hasHorizontalBarDamage);
208 return m_horizontalBarDamage;
211 void resetScrollbarDamage()
213 m_hasVerticalBarDamage = false;
214 m_hasHorizontalBarDamage = false;
219 virtual ~ScrollableArea();
221 void setScrollOrigin(const IntPoint&);
222 void resetScrollOriginChanged() { m_scrollOriginChanged = false; }
224 virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) = 0;
225 virtual void invalidateScrollCornerRect(const IntRect&) = 0;
227 friend class ScrollingCoordinator;
228 virtual GraphicsLayer* layerForScrolling() const { return 0; }
229 virtual GraphicsLayer* layerForHorizontalScrollbar() const { return 0; }
230 virtual GraphicsLayer* layerForVerticalScrollbar() const { return 0; }
231 virtual GraphicsLayer* layerForScrollCorner() const { return 0; }
232 bool hasLayerForHorizontalScrollbar() const;
233 bool hasLayerForVerticalScrollbar() const;
234 bool hasLayerForScrollCorner() const;
236 // For repaint after layout, stores the damage to be repainted for the
238 unsigned m_hasHorizontalBarDamage : 1;
239 unsigned m_hasVerticalBarDamage : 1;
240 IntRect m_horizontalBarDamage;
241 IntRect m_verticalBarDamage;
244 void scrollPositionChanged(const IntPoint&);
246 // NOTE: Only called from the ScrollAnimator.
247 friend class ScrollAnimator;
248 void setScrollOffsetFromAnimation(const IntPoint&);
250 // This function should be overriden by subclasses to perform the actual
251 // scroll of the content.
252 virtual void setScrollOffset(const IntPoint&) = 0;
254 virtual int lineStep(ScrollbarOrientation) const;
255 virtual int pageStep(ScrollbarOrientation) const = 0;
256 virtual int documentStep(ScrollbarOrientation) const;
257 virtual float pixelStep(ScrollbarOrientation) const;
259 mutable OwnPtr<ScrollAnimator> m_scrollAnimator;
260 unsigned m_constrainsScrollingToContentEdge : 1;
262 unsigned m_inLiveResize : 1;
264 unsigned m_verticalScrollElasticity : 2; // ScrollElasticity
265 unsigned m_horizontalScrollElasticity : 2; // ScrollElasticity
267 unsigned m_scrollbarOverlayStyle : 2; // ScrollbarOverlayStyle
269 unsigned m_scrollOriginChanged : 1;
271 // There are 8 possible combinations of writing mode and direction. Scroll origin will be non-zero in the x or y axis
272 // if there is any reversed direction or writing-mode. The combinations are:
273 // writing-mode / direction scrollOrigin.x() set scrollOrigin.y() set
274 // horizontal-tb / ltr NO NO
275 // horizontal-tb / rtl YES NO
276 // horizontal-bt / ltr NO YES
277 // horizontal-bt / rtl YES YES
278 // vertical-lr / ltr NO NO
279 // vertical-lr / rtl NO YES
280 // vertical-rl / ltr YES NO
281 // vertical-rl / rtl YES YES
282 IntPoint m_scrollOrigin;
285 } // namespace WebCore
287 #endif // ScrollableArea_h