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 "Scrollbar.h"
30 #include <wtf/Vector.h>
35 class GraphicsContext;
36 class PlatformGestureEvent;
37 class PlatformWheelEvent;
39 #if USE(ACCELERATED_COMPOSITING)
43 class ScrollableArea {
45 enum ZoomAnimationState { ZoomAnimationContinuing, ZoomAnimationFinishing };
48 virtual ~ScrollableArea();
50 bool scroll(ScrollDirection, ScrollGranularity, float multiplier = 1);
51 void scrollToOffsetWithoutAnimation(const FloatPoint&);
52 void scrollToOffsetWithoutAnimation(ScrollbarOrientation, float offset);
53 void scrollToXOffsetWithoutAnimation(float x);
54 void scrollToYOffsetWithoutAnimation(float x);
56 virtual void zoomAnimatorTransformChanged(float, float, float, ZoomAnimationState);
58 bool handleWheelEvent(const PlatformWheelEvent&);
59 #if ENABLE(GESTURE_EVENTS)
60 void handleGestureEvent(const PlatformGestureEvent&);
63 // Functions for controlling if you can scroll past the end of the document.
64 bool constrainsScrollingToContentEdge() const { return m_constrainsScrollingToContentEdge; }
65 void setConstrainsScrollingToContentEdge(bool constrainsScrollingToContentEdge) { m_constrainsScrollingToContentEdge = constrainsScrollingToContentEdge; }
67 void setVerticalScrollElasticity(ScrollElasticity scrollElasticity) { m_verticalScrollElasticity = scrollElasticity; }
68 ScrollElasticity verticalScrollElasticity() const { return static_cast<ScrollElasticity>(m_verticalScrollElasticity); }
70 void setHorizontalScrollElasticity(ScrollElasticity scrollElasticity) { m_horizontalScrollElasticity = scrollElasticity; }
71 ScrollElasticity horizontalScrollElasticity() const { return static_cast<ScrollElasticity>(m_horizontalScrollElasticity); }
73 bool inLiveResize() const { return m_inLiveResize; }
74 void willStartLiveResize();
75 void willEndLiveResize();
77 void didAddVerticalScrollbar(Scrollbar*);
78 void willRemoveVerticalScrollbar(Scrollbar*);
79 virtual void didAddHorizontalScrollbar(Scrollbar*);
80 virtual void willRemoveHorizontalScrollbar(Scrollbar*);
82 bool hasOverlayScrollbars() const;
83 virtual void setScrollbarOverlayStyle(ScrollbarOverlayStyle);
84 ScrollbarOverlayStyle scrollbarOverlayStyle() const { return static_cast<ScrollbarOverlayStyle>(m_scrollbarOverlayStyle); }
86 ScrollAnimator* scrollAnimator() const;
87 const IntPoint& scrollOrigin() const { return m_scrollOrigin; }
88 bool scrollOriginChanged() const { return m_scrollOriginChanged; }
90 virtual bool isActive() const = 0;
91 virtual int scrollSize(ScrollbarOrientation) const = 0;
92 virtual int scrollPosition(Scrollbar*) const = 0;
93 void invalidateScrollbar(Scrollbar*, const IntRect&);
94 virtual bool isScrollCornerVisible() const = 0;
95 virtual IntRect scrollCornerRect() const = 0;
96 void invalidateScrollCorner(const IntRect&);
97 virtual void getTickmarks(Vector<IntRect>&) const { }
99 // This function should be overriden by subclasses to perform the actual
100 // scroll of the content.
101 virtual void setScrollOffset(const IntPoint&) = 0;
103 // Convert points and rects between the scrollbar and its containing view.
104 // The client needs to implement these in order to be aware of layout effects
105 // like CSS transforms.
106 virtual IntRect convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& scrollbarRect) const
108 return scrollbar->Widget::convertToContainingView(scrollbarRect);
110 virtual IntRect convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntRect& parentRect) const
112 return scrollbar->Widget::convertFromContainingView(parentRect);
114 virtual IntPoint convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntPoint& scrollbarPoint) const
116 return scrollbar->Widget::convertToContainingView(scrollbarPoint);
118 virtual IntPoint convertFromContainingViewToScrollbar(const Scrollbar* scrollbar, const IntPoint& parentPoint) const
120 return scrollbar->Widget::convertFromContainingView(parentPoint);
123 virtual Scrollbar* horizontalScrollbar() const { return 0; }
124 virtual Scrollbar* verticalScrollbar() const { return 0; }
126 virtual IntPoint scrollPosition() const { ASSERT_NOT_REACHED(); return IntPoint(); }
127 virtual IntPoint minimumScrollPosition() const { ASSERT_NOT_REACHED(); return IntPoint(); }
128 virtual IntPoint maximumScrollPosition() const { ASSERT_NOT_REACHED(); return IntPoint(); }
129 virtual IntRect visibleContentRect(bool /*includeScrollbars*/ = false) const { ASSERT_NOT_REACHED(); return IntRect(); }
130 virtual int visibleHeight() const { ASSERT_NOT_REACHED(); return 0; }
131 virtual int visibleWidth() const { ASSERT_NOT_REACHED(); return 0; }
132 virtual IntSize contentsSize() const { ASSERT_NOT_REACHED(); return IntSize(); }
133 virtual IntSize overhangAmount() const { ASSERT_NOT_REACHED(); return IntSize(); }
134 virtual IntPoint currentMousePosition() const { return IntPoint(); }
136 virtual void didStartRubberBand(const IntSize&) const { ASSERT_NOT_REACHED(); }
137 virtual void didCompleteRubberBand(const IntSize&) const { ASSERT_NOT_REACHED(); }
138 virtual void didStartAnimatedScroll() const { }
139 virtual void didCompleteAnimatedScroll() const { }
141 virtual bool shouldSuspendScrollAnimations() const { return true; }
142 virtual void scrollbarStyleChanged(int /*newStyle*/, bool /*forceUpdate*/) { }
143 virtual void setVisibleScrollerThumbRect(const IntRect&) { }
145 virtual bool isOnActivePage() const { ASSERT_NOT_REACHED(); return true; }
147 bool isHorizontalScrollerPinnedToMinimumPosition() const { return !horizontalScrollbar() || scrollPosition(horizontalScrollbar()) <= minimumScrollPosition().x(); }
148 bool isHorizontalScrollerPinnedToMaximumPosition() const { return !horizontalScrollbar() || scrollPosition(horizontalScrollbar()) >= maximumScrollPosition().x(); }
149 bool isVerticalScrollerPinnedToMinimumPosition() const { return !verticalScrollbar() || scrollPosition(verticalScrollbar()) <= minimumScrollPosition().y(); }
150 bool isVerticalScrollerPinnedToMaximumPosition() const { return !verticalScrollbar() || scrollPosition(verticalScrollbar()) >= maximumScrollPosition().y(); }
152 // Note that this only returns scrollable areas that can actually be scrolled.
153 virtual ScrollableArea* enclosingScrollableArea() const = 0;
155 bool isPinnedInBothDirections(const IntSize&) const;
156 bool isPinnedHorizontallyInDirection(int horizontalScrollDelta) const;
157 bool isPinnedVerticallyInDirection(int verticalScrollDelta) const;
159 virtual bool shouldRubberBandInDirection(ScrollDirection) const { return true; }
161 virtual void disconnectFromPage() { }
163 virtual bool scrollAnimatorEnabled() const { return false; }
165 // NOTE: Only called from Internals for testing.
166 void setScrollOffsetFromInternals(const IntPoint&);
169 void setScrollOrigin(const IntPoint&);
170 void setScrollOriginX(int);
171 void setScrollOriginY(int);
172 void resetScrollOriginChanged() { m_scrollOriginChanged = false; }
174 virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) = 0;
175 virtual void invalidateScrollCornerRect(const IntRect&) = 0;
177 #if USE(ACCELERATED_COMPOSITING)
178 virtual GraphicsLayer* layerForHorizontalScrollbar() const { return 0; }
179 virtual GraphicsLayer* layerForVerticalScrollbar() const { return 0; }
180 virtual GraphicsLayer* layerForScrollCorner() const { return 0; }
181 #if PLATFORM(CHROMIUM) && ENABLE(RUBBER_BANDING)
182 virtual GraphicsLayer* layerForOverhangAreas() const { return 0; }
185 bool hasLayerForHorizontalScrollbar() const;
186 bool hasLayerForVerticalScrollbar() const;
187 bool hasLayerForScrollCorner() const;
190 // NOTE: Only called from the ScrollAnimator.
191 friend class ScrollAnimator;
192 void setScrollOffsetFromAnimation(const IntPoint&);
194 mutable OwnPtr<ScrollAnimator> m_scrollAnimator;
195 bool m_constrainsScrollingToContentEdge : 1;
197 bool m_inLiveResize : 1;
199 unsigned m_verticalScrollElasticity : 2; // ScrollElasticity
200 unsigned m_horizontalScrollElasticity : 2; // ScrollElasticity
202 unsigned m_scrollbarOverlayStyle : 2; // ScrollbarOverlayStyle
204 // There are 8 possible combinations of writing mode and direction. Scroll origin will be non-zero in the x or y axis
205 // if there is any reversed direction or writing-mode. The combinations are:
206 // writing-mode / direction scrollOrigin.x() set scrollOrigin.y() set
207 // horizontal-tb / ltr NO NO
208 // horizontal-tb / rtl YES NO
209 // horizontal-bt / ltr NO YES
210 // horizontal-bt / rtl YES YES
211 // vertical-lr / ltr NO NO
212 // vertical-lr / rtl NO YES
213 // vertical-rl / ltr YES NO
214 // vertical-rl / rtl YES YES
215 IntPoint m_scrollOrigin;
217 bool m_scrollOriginChanged;
220 } // namespace WebCore
222 #endif // ScrollableArea_h