2 * Copyright (C) 2004, 2006, 2007, 2008 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 COMPUTER, 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 COMPUTER, 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.
30 #include "Scrollbar.h"
31 #include "ScrollbarClient.h"
32 #include "ScrollTypes.h"
35 #include <wtf/HashSet.h>
44 #define NSView WAKView
47 #if PLATFORM(MAC) && defined __OBJC__
48 @protocol WebCoreFrameScrollView
;
52 typedef struct _GtkAdjustment GtkAdjustment
;
56 class wxScrollWinEvent
;
59 // DANGER WILL ROBINSON! THIS FILE IS UNDERGOING HEAVY REFACTORING.
60 // Everything is changing!
61 // Port authors should wait until this refactoring is complete before attempting to implement this interface.
65 class PlatformWheelEvent
;
68 class ScrollView
: public Widget
, public ScrollbarClient
{
73 // ScrollbarClient method. FrameView overrides the other two.
74 virtual void valueChanged(Scrollbar
*);
76 // The window thats hosts the ScrollView. The ScrollView will communicate scrolls and repaints to the
77 // host window in the window's coordinate space.
78 virtual HostWindow
* hostWindow() const = 0;
80 // Returns a clip rect in host window coordinates. Used to clip the blit on a scroll.
81 virtual IntRect
windowClipRect(bool clipToContents
= true) const = 0;
83 // Methods for child manipulation and inspection.
84 const HashSet
<Widget
*>* children() const { return &m_children
; }
85 void addChild(Widget
*);
86 void removeChild(Widget
*);
88 // If the scroll view does not use a native widget, then it will have cross-platform Scrollbars. These methods
89 // can be used to obtain those scrollbars.
90 Scrollbar
* horizontalScrollbar() const { return m_horizontalScrollbar
.get(); }
91 Scrollbar
* verticalScrollbar() const { return m_verticalScrollbar
.get(); }
92 bool isScrollViewScrollbar(const Widget
* child
) const { return horizontalScrollbar() == child
|| verticalScrollbar() == child
; }
94 // Methods for setting and retrieving the scrolling mode in each axis (horizontal/vertical). The mode has values of
95 // AlwaysOff, AlwaysOn, and Auto. AlwaysOff means never show a scrollbar, AlwaysOn means always show a scrollbar.
96 // Auto means show a scrollbar only when one is needed.
97 // Note that for platforms with native widgets, these modes are considered advisory. In other words the underlying native
98 // widget may choose not to honor the requested modes.
99 void setScrollbarModes(ScrollbarMode horizontalMode
, ScrollbarMode verticalMode
);
100 void setHorizontalScrollbarMode(ScrollbarMode mode
) { setScrollbarModes(mode
, verticalScrollbarMode()); }
101 void setVerticalScrollbarMode(ScrollbarMode mode
) { setScrollbarModes(horizontalScrollbarMode(), mode
); }
102 void scrollbarModes(ScrollbarMode
& horizontalMode
, ScrollbarMode
& verticalMode
) const;
103 ScrollbarMode
horizontalScrollbarMode() const { ScrollbarMode horizontal
, vertical
; scrollbarModes(horizontal
, vertical
); return horizontal
; }
104 ScrollbarMode
verticalScrollbarMode() const { ScrollbarMode horizontal
, vertical
; scrollbarModes(horizontal
, vertical
); return vertical
; }
105 virtual void setCanHaveScrollbars(bool flag
);
106 bool canHaveScrollbars() const { return horizontalScrollbarMode() != ScrollbarAlwaysOff
|| verticalScrollbarMode() != ScrollbarAlwaysOff
; }
108 // Overridden by FrameView to create custom CSS scrollbars if applicable.
109 virtual PassRefPtr
<Scrollbar
> createScrollbar(ScrollbarOrientation
);
111 // If the prohibits scrolling flag is set, then all scrolling in the view (even programmatic scrolling) is turned off.
112 void setProhibitsScrolling(bool b
) { m_prohibitsScrolling
= b
; }
113 bool prohibitsScrolling() const { return m_prohibitsScrolling
; }
115 // Whether or not a scroll view will blit visible contents when it is scrolled. Blitting is disabled in situations
116 // where it would cause rendering glitches (such as with fixed backgrounds or when the view is partially transparent).
117 void setCanBlitOnScroll(bool);
118 bool canBlitOnScroll() const;
120 // The visible content rect has a location that is the scrolled offset of the document. The width and height are the viewport width
121 // and height. By default the scrollbars themselves are excluded from this rectangle, but an optional boolean argument allows them to be
123 IntRect
visibleContentRect(bool includeScrollbars
= false) const;
124 int visibleWidth() const { return visibleContentRect().width(); }
125 int visibleHeight() const { return visibleContentRect().height(); }
126 IntRect
actualVisualContentRect() const;
128 // Methods for getting/setting the size webkit should use to layout the contents. By default this is the same as the visible
129 // content size. Explicitly setting a layout size value will cause webkit to layout the contents using this size instead.
130 int layoutWidth() const;
131 int layoutHeight() const;
132 IntSize
fixedLayoutSize() const;
133 void setFixedLayoutSize(const IntSize
&);
134 bool useFixedLayout() const;
135 void setUseFixedLayout(bool enable
);
137 // Methods for getting/setting the size of the document contained inside the ScrollView (as an IntSize or as individual width and height
139 IntSize
contentsSize() const;
140 int contentsWidth() const { return contentsSize().width(); }
141 int contentsHeight() const { return contentsSize().height(); }
142 virtual void setContentsSize(const IntSize
&);
144 // Methods for querying the current scrolled position (both as a point, a size, or as individual X and Y values).
145 IntPoint
scrollPosition() const { return visibleContentRect().location(); }
146 IntSize
scrollOffset() const { return visibleContentRect().location() - IntPoint(); } // Gets the scrolled position as an IntSize. Convenient for adding to other sizes.
147 IntPoint
maximumScrollPosition() const; // The maximum position we can be scrolled to.
148 int scrollX() const { return scrollPosition().x(); }
149 int scrollY() const { return scrollPosition().y(); }
151 // Methods for scrolling the view. setScrollPosition is the only method that really scrolls the view. The other two methods are helper functions
152 // that ultimately end up calling setScrollPosition.
153 void setScrollPosition(const IntPoint
&);
154 void scrollBy(const IntSize
& s
) { return setScrollPosition(scrollPosition() + s
); }
155 void scrollRectIntoViewRecursively(const IntRect
&);
157 // This method scrolls by lines, pages or pixels.
158 bool scroll(ScrollDirection
, ScrollGranularity
);
160 // Scroll the actual contents of the view (either blitting or invalidating as needed).
161 void scrollContents(const IntSize
& scrollDelta
);
163 // This gives us a means of blocking painting on our scrollbars until the first layout has occurred.
164 void setScrollbarsSuppressed(bool suppressed
, bool repaintOnUnsuppress
= false);
165 bool scrollbarsSuppressed() const { return m_scrollbarsSuppressed
; }
167 // Event coordinates are assumed to be in the coordinate space of a window that contains
168 // the entire widget hierarchy. It is up to the platform to decide what the precise definition
169 // of containing window is. (For example on Mac it is the containing NSWindow.)
170 IntPoint
windowToContents(const IntPoint
&) const;
171 IntPoint
contentsToWindow(const IntPoint
&) const;
172 IntRect
windowToContents(const IntRect
&) const;
173 IntRect
contentsToWindow(const IntRect
&) const;
175 // Methods for converting to and from screen coordinates.
176 IntRect
contentsToScreen(const IntRect
&) const;
177 IntPoint
screenToContents(const IntPoint
&) const;
179 // The purpose of this method is to answer whether or not the scroll view is currently visible. Animations and painting updates can be suspended if
180 // we know that we are either not in a window right now or if that window is not visible.
181 bool isOffscreen() const;
183 // These methods are used to enable scrollbars to avoid window resizer controls that overlap the scroll view. This happens on Mac
185 virtual IntRect
windowResizerRect() const { return IntRect(); }
186 bool containsScrollbarsAvoidingResizer() const;
187 void adjustScrollbarsAvoidingResizerCount(int overlapDelta
);
188 virtual void setParent(ScrollView
*); // Overridden to update the overlapping scrollbar count.
190 // Called when our frame rect changes (or the rect/scroll position of an ancestor changes).
191 virtual void frameRectsChanged();
193 // Widget override to update our scrollbars and notify our contents of the resize.
194 virtual void setFrameRect(const IntRect
&);
196 // For platforms that need to hit test scrollbars from within the engine's event handlers (like Win32).
197 Scrollbar
* scrollbarUnderMouse(const PlatformMouseEvent
& mouseEvent
);
199 // This method exists for scrollviews that need to handle wheel events manually.
200 // On Mac the underlying NSScrollView just does the scrolling, but on other platforms
201 // (like Windows), we need this method in order to do the scroll ourselves.
202 void wheelEvent(PlatformWheelEvent
&);
204 IntPoint
convertChildToSelf(const Widget
* child
, const IntPoint
& point
) const
206 IntPoint newPoint
= point
;
207 if (!isScrollViewScrollbar(child
))
208 newPoint
= point
- scrollOffset();
209 newPoint
.move(child
->x(), child
->y());
213 IntPoint
convertSelfToChild(const Widget
* child
, const IntPoint
& point
) const
215 IntPoint newPoint
= point
;
216 if (!isScrollViewScrollbar(child
))
217 newPoint
= point
+ scrollOffset();
218 newPoint
.move(-child
->x(), -child
->y());
222 // Widget override. Handles painting of the contents of the view as well as the scrollbars.
223 virtual void paint(GraphicsContext
*, const IntRect
&);
225 // Widget overrides to ensure that our children's visibility status is kept up to date when we get shown and hidden.
228 virtual void setParentVisible(bool);
230 // Pan scrolling methods.
231 void addPanScrollIcon(const IntPoint
&);
232 void removePanScrollIcon();
234 virtual bool scrollbarCornerPresent() const;
237 virtual void repaintContentRectangle(const IntRect
&, bool now
= false);
238 virtual void paintContents(GraphicsContext
*, const IntRect
& damageRect
) = 0;
240 virtual void contentsResized() = 0;
241 virtual void visibleContentsResized() = 0;
243 // These methods are used to create/destroy scrollbars.
244 void setHasHorizontalScrollbar(bool);
245 void setHasVerticalScrollbar(bool);
248 RefPtr
<Scrollbar
> m_horizontalScrollbar
;
249 RefPtr
<Scrollbar
> m_verticalScrollbar
;
250 ScrollbarMode m_horizontalScrollbarMode
;
251 ScrollbarMode m_verticalScrollbarMode
;
252 bool m_prohibitsScrolling
;
254 HashSet
<Widget
*> m_children
;
256 // This bool is unused on Mac OS because we directly ask the platform widget
257 // whether it is safe to blit on scroll.
258 bool m_canBlitOnScroll
;
260 IntSize m_scrollOffset
; // FIXME: Would rather store this as a position, but we will wait to make this change until more code is shared.
261 IntSize m_fixedLayoutSize
;
262 IntSize m_contentsSize
;
264 int m_scrollbarsAvoidingResizer
;
265 bool m_scrollbarsSuppressed
;
267 bool m_inUpdateScrollbars
;
269 IntPoint m_panScrollIconPoint
;
270 bool m_drawPanScrollIcon
;
271 bool m_useFixedLayout
;
276 // Called to update the scrollbars to accurately reflect the state of the view.
277 void updateScrollbars(const IntSize
& desiredOffset
);
280 void platformDestroy();
281 void platformAddChild(Widget
*);
282 void platformRemoveChild(Widget
*);
283 void platformSetScrollbarModes();
284 void platformScrollbarModes(ScrollbarMode
& horizontal
, ScrollbarMode
& vertical
) const;
285 void platformSetCanBlitOnScroll(bool);
286 bool platformCanBlitOnScroll() const;
287 IntRect
platformVisibleContentRect(bool includeScrollbars
) const;
288 IntSize
platformContentsSize() const;
289 void platformSetContentsSize();
290 IntRect
platformContentsToScreen(const IntRect
&) const;
291 IntPoint
platformScreenToContents(const IntPoint
&) const;
292 void platformSetScrollPosition(const IntPoint
&);
293 bool platformScroll(ScrollDirection
, ScrollGranularity
);
294 void platformSetScrollbarsSuppressed(bool repaintOnUnsuppress
);
295 void platformRepaintContentRectangle(const IntRect
&, bool now
);
296 bool platformIsOffscreen() const;
297 bool platformHandleHorizontalAdjustment(const IntSize
&);
298 bool platformHandleVerticalAdjustment(const IntSize
&);
299 bool platformHasHorizontalAdjustment() const;
300 bool platformHasVerticalAdjustment() const;
302 #if PLATFORM(MAC) && defined __OBJC__
304 NSView
* documentView() const;
307 NSScrollView
<WebCoreFrameScrollView
>* scrollView() const;
312 bool rootPreventsBlitting() const { return root()->m_widgetsThatPreventBlitting
> 0; }
313 unsigned m_widgetsThatPreventBlitting
;
315 bool rootPreventsBlitting() const { return false; }
320 void setGtkAdjustments(GtkAdjustment
* hadj
, GtkAdjustment
* vadj
);
321 GtkAdjustment
* m_horizontalAdjustment
;
322 GtkAdjustment
* m_verticalAdjustment
;
323 void setScrollOffset(const IntSize
& offset
) { m_scrollOffset
= offset
; }
328 virtual void setPlatformWidget(wxWindow
*);
329 void adjustScrollbars(int x
= -1, int y
= -1, bool refresh
= true);
331 class ScrollViewPrivate
;
332 ScrollViewPrivate
* m_data
;
335 }; // class ScrollView
337 } // namespace WebCore
339 #endif // ScrollView_h