Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / scroll / ScrollableArea.h
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 "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"
34
35 namespace blink {
36
37 class FloatPoint;
38 class GraphicsContext;
39 class GraphicsLayer;
40 class PlatformGestureEvent;
41 class PlatformWheelEvent;
42 class ProgrammaticScrollAnimator;
43 class ScrollAnimator;
44
45 enum ScrollBehavior {
46     ScrollBehaviorAuto,
47     ScrollBehaviorInstant,
48     ScrollBehaviorSmooth,
49 };
50
51 enum IncludeScrollbarsInRect {
52     ExcludeScrollbars,
53     IncludeScrollbars,
54 };
55
56 class PLATFORM_EXPORT ScrollableArea {
57     WTF_MAKE_NONCOPYABLE(ScrollableArea);
58 public:
59     static int pixelsPerLineStep();
60     static float minFractionToStepWhenPaging();
61     static int maxOverlapBetweenPages();
62
63     bool scroll(ScrollDirection, ScrollGranularity, float delta = 1);
64     void scrollToOffsetWithoutAnimation(const FloatPoint&);
65     void scrollToOffsetWithoutAnimation(ScrollbarOrientation, float offset);
66
67     void programmaticallyScrollSmoothlyToOffset(const FloatPoint&);
68
69     // Should be called when the scroll position changes externally, for example if the scroll layer position
70     // is updated on the scrolling thread and we need to notify the main thread.
71     void notifyScrollPositionChanged(const IntPoint&);
72
73     static bool scrollBehaviorFromString(const String&, ScrollBehavior&);
74
75     bool handleWheelEvent(const PlatformWheelEvent&);
76
77     // Functions for controlling if you can scroll past the end of the document.
78     bool constrainsScrollingToContentEdge() const { return m_constrainsScrollingToContentEdge; }
79     void setConstrainsScrollingToContentEdge(bool constrainsScrollingToContentEdge) { m_constrainsScrollingToContentEdge = constrainsScrollingToContentEdge; }
80
81     void setVerticalScrollElasticity(ScrollElasticity scrollElasticity) { m_verticalScrollElasticity = scrollElasticity; }
82     ScrollElasticity verticalScrollElasticity() const { return static_cast<ScrollElasticity>(m_verticalScrollElasticity); }
83
84     void setHorizontalScrollElasticity(ScrollElasticity scrollElasticity) { m_horizontalScrollElasticity = scrollElasticity; }
85     ScrollElasticity horizontalScrollElasticity() const { return static_cast<ScrollElasticity>(m_horizontalScrollElasticity); }
86
87     bool inLiveResize() const { return m_inLiveResize; }
88     void willStartLiveResize();
89     void willEndLiveResize();
90
91     void contentAreaWillPaint() const;
92     void mouseEnteredContentArea() const;
93     void mouseExitedContentArea() const;
94     void mouseMovedInContentArea() const;
95     void mouseEnteredScrollbar(Scrollbar*) const;
96     void mouseExitedScrollbar(Scrollbar*) const;
97     void contentAreaDidShow() const;
98     void contentAreaDidHide() const;
99
100     void finishCurrentScrollAnimations() const;
101
102     virtual void didAddScrollbar(Scrollbar*, ScrollbarOrientation);
103     virtual void willRemoveScrollbar(Scrollbar*, ScrollbarOrientation);
104
105     virtual void contentsResized();
106
107     bool hasOverlayScrollbars() const;
108     void setScrollbarOverlayStyle(ScrollbarOverlayStyle);
109     ScrollbarOverlayStyle scrollbarOverlayStyle() const { return static_cast<ScrollbarOverlayStyle>(m_scrollbarOverlayStyle); }
110
111     // This getter will create a ScrollAnimator if it doesn't already exist.
112     ScrollAnimator* scrollAnimator() const;
113
114     // This getter will return null if the ScrollAnimator hasn't been created yet.
115     ScrollAnimator* existingScrollAnimator() const { return m_animators ? m_animators->scrollAnimator.get() : 0; }
116
117     ProgrammaticScrollAnimator* programmaticScrollAnimator() const;
118     ProgrammaticScrollAnimator* existingProgrammaticScrollAnimator() const
119     {
120         return m_animators ? m_animators->programmaticScrollAnimator.get() : 0;
121     }
122
123     const IntPoint& scrollOrigin() const { return m_scrollOrigin; }
124     bool scrollOriginChanged() const { return m_scrollOriginChanged; }
125
126     // FIXME(bokan): Meaningless name, rename to isActiveFocus
127     virtual bool isActive() const = 0;
128     virtual int scrollSize(ScrollbarOrientation) const = 0;
129     virtual void invalidateScrollbar(Scrollbar*, const IntRect&);
130     virtual bool isScrollCornerVisible() const = 0;
131     virtual IntRect scrollCornerRect() const = 0;
132     virtual void invalidateScrollCorner(const IntRect&);
133     virtual void getTickmarks(Vector<IntRect>&) const { }
134
135     // Convert points and rects between the scrollbar and its containing view.
136     // The client needs to implement these in order to be aware of layout effects
137     // like CSS transforms.
138     virtual IntRect convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& scrollbarRect) const
139     {
140         return scrollbar->Widget::convertToContainingView(scrollbarRect);
141     }
142     virtual IntRect convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const
143     {
144         return scrollbar->Widget::convertFromContainingView(parentRect);
145     }
146     virtual IntPoint convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& scrollbarPoint) const
147     {
148         return scrollbar->Widget::convertToContainingView(scrollbarPoint);
149     }
150     virtual IntPoint convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
151     {
152         return scrollbar->Widget::convertFromContainingView(parentPoint);
153     }
154
155     virtual Scrollbar* horizontalScrollbar() const { return 0; }
156     virtual Scrollbar* verticalScrollbar() const { return 0; }
157
158     // scrollPosition is relative to the scrollOrigin. i.e. If the page is RTL
159     // then scrollPosition will be negative.
160     virtual IntPoint scrollPosition() const = 0;
161     virtual IntPoint minimumScrollPosition() const = 0;
162     virtual IntPoint maximumScrollPosition() const = 0;
163
164     virtual IntRect visibleContentRect(IncludeScrollbarsInRect = ExcludeScrollbars) const;
165     virtual int visibleHeight() const = 0;
166     virtual int visibleWidth() const = 0;
167     virtual IntSize contentsSize() const = 0;
168     virtual IntSize overhangAmount() const { return IntSize(); }
169     virtual IntPoint lastKnownMousePosition() const { return IntPoint(); }
170
171     virtual bool shouldSuspendScrollAnimations() const { return true; }
172     virtual void scrollbarStyleChanged() { }
173
174     virtual bool scrollbarsCanBeActive() const = 0;
175
176     // Returns the bounding box of this scrollable area, in the coordinate system of the enclosing scroll view.
177     virtual IntRect scrollableAreaBoundingBox() const = 0;
178
179     virtual bool isRubberBandInProgress() const { return false; }
180
181     virtual bool scrollAnimatorEnabled() const { return false; }
182
183     // NOTE: Only called from Internals for testing.
184     void setScrollOffsetFromInternals(const IntPoint&);
185
186     IntPoint clampScrollPosition(const IntPoint&) const;
187
188     // Let subclasses provide a way of asking for and servicing scroll
189     // animations.
190     virtual bool scheduleAnimation() { return false; }
191     void serviceScrollAnimations(double monotonicTime);
192
193     virtual bool usesCompositedScrolling() const { return false; }
194
195     // Returns true if the GraphicsLayer tree needs to be rebuilt.
196     virtual bool updateAfterCompositingChange() { return false; }
197
198     virtual bool userInputScrollable(ScrollbarOrientation) const = 0;
199     virtual bool shouldPlaceVerticalScrollbarOnLeft() const = 0;
200
201     // Convenience functions
202     int scrollPosition(ScrollbarOrientation orientation) { return orientation == HorizontalScrollbar ? scrollPosition().x() : scrollPosition().y(); }
203     int minimumScrollPosition(ScrollbarOrientation orientation) { return orientation == HorizontalScrollbar ? minimumScrollPosition().x() : minimumScrollPosition().y(); }
204     int maximumScrollPosition(ScrollbarOrientation orientation) { return orientation == HorizontalScrollbar ? maximumScrollPosition().x() : maximumScrollPosition().y(); }
205     int clampScrollPosition(ScrollbarOrientation orientation, int pos)  { return std::max(std::min(pos, maximumScrollPosition(orientation)), minimumScrollPosition(orientation)); }
206
207     bool hasVerticalBarDamage() const { return !m_verticalBarDamage.isEmpty(); }
208     bool hasHorizontalBarDamage() const { return !m_horizontalBarDamage.isEmpty(); }
209     const IntRect& verticalBarDamage() const { return m_verticalBarDamage; }
210     const IntRect& horizontalBarDamage() const { return m_horizontalBarDamage; }
211
212     void addScrollbarDamage(Scrollbar* scrollbar, const IntRect& rect)
213     {
214         if (scrollbar == horizontalScrollbar())
215             m_horizontalBarDamage.unite(rect);
216         else
217             m_verticalBarDamage.unite(rect);
218     }
219
220     void resetScrollbarDamage()
221     {
222         m_verticalBarDamage = IntRect();
223         m_horizontalBarDamage = IntRect();
224     }
225
226     virtual GraphicsLayer* layerForContainer() const;
227     virtual GraphicsLayer* layerForScrolling() const { return 0; }
228     virtual GraphicsLayer* layerForHorizontalScrollbar() const { return 0; }
229     virtual GraphicsLayer* layerForVerticalScrollbar() const { return 0; }
230     virtual GraphicsLayer* layerForScrollCorner() const { return 0; }
231     bool hasLayerForHorizontalScrollbar() const;
232     bool hasLayerForVerticalScrollbar() const;
233     bool hasLayerForScrollCorner() const;
234
235     void cancelProgrammaticScrollAnimation();
236
237 protected:
238     ScrollableArea();
239     virtual ~ScrollableArea();
240
241     void setScrollOrigin(const IntPoint&);
242     void resetScrollOriginChanged() { m_scrollOriginChanged = false; }
243
244     virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) = 0;
245     virtual void invalidateScrollCornerRect(const IntRect&) = 0;
246
247 private:
248     void scrollPositionChanged(const IntPoint&);
249
250     // NOTE: Only called from the ScrollAnimator.
251     friend class ScrollAnimator;
252     void setScrollOffsetFromAnimation(const IntPoint&);
253
254     // This function should be overriden by subclasses to perform the actual
255     // scroll of the content.
256     virtual void setScrollOffset(const IntPoint&) = 0;
257
258     virtual int lineStep(ScrollbarOrientation) const;
259     virtual int pageStep(ScrollbarOrientation) const;
260     virtual int documentStep(ScrollbarOrientation) const;
261     virtual float pixelStep(ScrollbarOrientation) const;
262
263     // Stores the paint invalidations for the scrollbars during layout.
264     IntRect m_horizontalBarDamage;
265     IntRect m_verticalBarDamage;
266
267     struct ScrollableAreaAnimators {
268         OwnPtr<ScrollAnimator> scrollAnimator;
269         OwnPtr<ProgrammaticScrollAnimator> programmaticScrollAnimator;
270     };
271
272     mutable OwnPtr<ScrollableAreaAnimators> m_animators;
273     unsigned m_constrainsScrollingToContentEdge : 1;
274
275     unsigned m_inLiveResize : 1;
276
277     unsigned m_verticalScrollElasticity : 2; // ScrollElasticity
278     unsigned m_horizontalScrollElasticity : 2; // ScrollElasticity
279
280     unsigned m_scrollbarOverlayStyle : 2; // ScrollbarOverlayStyle
281
282     unsigned m_scrollOriginChanged : 1;
283
284     // There are 8 possible combinations of writing mode and direction. Scroll origin will be non-zero in the x or y axis
285     // if there is any reversed direction or writing-mode. The combinations are:
286     // writing-mode / direction     scrollOrigin.x() set    scrollOrigin.y() set
287     // horizontal-tb / ltr          NO                      NO
288     // horizontal-tb / rtl          YES                     NO
289     // horizontal-bt / ltr          NO                      YES
290     // horizontal-bt / rtl          YES                     YES
291     // vertical-lr / ltr            NO                      NO
292     // vertical-lr / rtl            NO                      YES
293     // vertical-rl / ltr            YES                     NO
294     // vertical-rl / rtl            YES                     YES
295     IntPoint m_scrollOrigin;
296 };
297
298 } // namespace blink
299
300 #endif // ScrollableArea_h