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 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.
27 #import "ScrollView.h"
29 #import "BlockExceptions.h"
33 #import "NotImplemented.h"
34 #import "WAKAppKitStubs.h"
35 #import "WAKClipView.h"
36 #import "WAKScrollView.h"
37 #import "WAKViewInternal.h"
39 #import "WKViewPrivate.h"
40 #import "WebCoreFrameView.h"
41 #import <wtf/CurrentTime.h>
47 inline NSScrollView<WebCoreFrameScrollView> *ScrollView::scrollView() const
49 ASSERT(!platformWidget() || [platformWidget() isKindOfClass:[NSScrollView class]]);
50 ASSERT(!platformWidget() || [platformWidget() conformsToProtocol:@protocol(WebCoreFrameScrollView)]);
51 return static_cast<NSScrollView<WebCoreFrameScrollView> *>(platformWidget());
54 NSView *ScrollView::documentView() const
56 BEGIN_BLOCK_OBJC_EXCEPTIONS;
57 return [scrollView() documentView];
58 END_BLOCK_OBJC_EXCEPTIONS;
62 void ScrollView::platformAddChild(Widget* child)
64 ASSERT(child != this);
66 child->addToSuperview(documentView());
69 void ScrollView::platformRemoveChild(Widget* child)
71 child->removeFromSuperview();
74 void ScrollView::platformSetScrollbarModes()
76 BEGIN_BLOCK_OBJC_EXCEPTIONS;
77 [scrollView() setScrollingModes:m_horizontalScrollbarMode vertical:m_verticalScrollbarMode andLock:NO];
78 END_BLOCK_OBJC_EXCEPTIONS;
81 void ScrollView::platformScrollbarModes(ScrollbarMode& horizontal, ScrollbarMode& vertical) const
83 BEGIN_BLOCK_OBJC_EXCEPTIONS;
84 [scrollView() scrollingModes:&horizontal vertical:&vertical];
85 END_BLOCK_OBJC_EXCEPTIONS;
88 void ScrollView::platformSetCanBlitOnScroll(bool canBlitOnScroll)
90 BEGIN_BLOCK_OBJC_EXCEPTIONS;
91 [[scrollView() contentView] setCopiesOnScroll:canBlitOnScroll];
92 END_BLOCK_OBJC_EXCEPTIONS;
95 bool ScrollView::platformCanBlitOnScroll() const
97 return [[scrollView() contentView] copiesOnScroll];
100 IntRect ScrollView::unobscuredContentRect(VisibleContentRectIncludesScrollbars) const
102 if (WAKScrollView *view = static_cast<WAKScrollView *>(platformWidget())) {
103 CGRect r = CGRectZero;
104 BEGIN_BLOCK_OBJC_EXCEPTIONS;
105 r = [view unobscuredContentRect];
106 END_BLOCK_OBJC_EXCEPTIONS;
107 return enclosingIntRect(r);
110 if (!m_unobscuredContentSize.isEmpty())
111 return IntRect(m_scrollPosition, roundedIntSize(m_unobscuredContentSize));
113 return unobscuredContentRectInternal();
116 void ScrollView::setUnobscuredContentSize(const FloatSize& size)
118 ASSERT(!platformWidget());
119 if (size == m_unobscuredContentSize)
122 m_unobscuredContentSize = size;
123 unobscuredContentSizeChanged();
126 FloatRect ScrollView::exposedContentRect() const
128 if (NSScrollView *view = static_cast<NSScrollView *>(platformWidget())) {
129 CGRect r = CGRectZero;
130 BEGIN_BLOCK_OBJC_EXCEPTIONS;
131 if ([view isKindOfClass:[NSScrollView class]])
132 r = [view exposedContentRect];
134 r.origin = [view visibleRect].origin;
135 r.size = [view bounds].size;
138 END_BLOCK_OBJC_EXCEPTIONS;
142 const ScrollView* parent = this->parent();
144 return m_exposedContentRect;
146 IntRect parentViewExtentContentRect = enclosingIntRect(parent->exposedContentRect());
147 IntRect selfExtentContentRect = rootViewToContents(parentViewExtentContentRect);
148 selfExtentContentRect.intersect(boundsRect());
149 return selfExtentContentRect;
152 void ScrollView::setExposedContentRect(const FloatRect& rect)
154 ASSERT(!platformWidget());
155 m_exposedContentRect = rect;
158 void ScrollView::setActualScrollPosition(const IntPoint& position)
160 NSScrollView *view = static_cast<NSScrollView *>(platformWidget());
162 BEGIN_BLOCK_OBJC_EXCEPTIONS;
163 if ([view isKindOfClass:[NSScrollView class]])
164 [view setActualScrollPosition:position];
165 END_BLOCK_OBJC_EXCEPTIONS;
168 float ScrollView::platformTopContentInset() const
173 void ScrollView::platformSetTopContentInset(float)
177 IntRect ScrollView::platformVisibleContentRect(bool includeScrollbars) const
179 BEGIN_BLOCK_OBJC_EXCEPTIONS;
180 if (includeScrollbars) {
181 if (NSView* documentView = this->documentView())
182 return enclosingIntRect([documentView visibleRect]);
184 return enclosingIntRect([scrollView() documentVisibleRect]);
185 END_BLOCK_OBJC_EXCEPTIONS;
189 IntSize ScrollView::platformVisibleContentSize(bool includeScrollbars) const
191 BEGIN_BLOCK_OBJC_EXCEPTIONS;
192 if (includeScrollbars) {
193 if (NSView* documentView = this->documentView())
194 return IntSize([documentView visibleRect].size);
197 return expandedIntSize(FloatSize([scrollView() documentVisibleRect].size));
198 END_BLOCK_OBJC_EXCEPTIONS;
202 IntRect ScrollView::platformVisibleContentRectIncludingObscuredArea(bool includeScrollbars) const
204 return platformVisibleContentRect(includeScrollbars);
207 IntSize ScrollView::platformVisibleContentSizeIncludingObscuredArea(bool includeScrollbars) const
209 return platformVisibleContentSize(includeScrollbars);
212 LegacyTileCache* ScrollView::legacyTileCache()
214 // Make tile cache pointer available via the main frame only. Tile cache interaction should be managed by
215 // the main frame and this avoids having to add parent checks to all call sites.
218 BEGIN_BLOCK_OBJC_EXCEPTIONS;
219 WAKScrollView *view = static_cast<WAKScrollView *>(platformWidget());
220 return [[view window] tileCache];
221 END_BLOCK_OBJC_EXCEPTIONS;
224 void ScrollView::platformSetContentsSize()
226 BEGIN_BLOCK_OBJC_EXCEPTIONS;
227 int w = m_contentsSize.width();
228 int h = m_contentsSize.height();
230 LOG(Frames, "%p %@ at w %d h %d\n", documentView(), [(id)[documentView() class] className], w, h);
232 LOG(Frames, "%p %@ at w %d h %d\n", documentView(), NSStringFromClass([documentView() class]), w, h);
234 NSSize tempSize = { static_cast<CGFloat>(max(0, w)), static_cast<CGFloat>(max(0, h)) }; // workaround for 4213314
235 [documentView() setBoundsSize:tempSize];
236 END_BLOCK_OBJC_EXCEPTIONS;
239 void ScrollView::platformSetScrollbarsSuppressed(bool repaintOnUnsuppress)
241 BEGIN_BLOCK_OBJC_EXCEPTIONS;
242 [scrollView() setScrollBarsSuppressed:m_scrollbarsSuppressed
243 repaintOnUnsuppress:repaintOnUnsuppress];
244 END_BLOCK_OBJC_EXCEPTIONS;
247 void ScrollView::platformSetScrollPosition(const IntPoint& scrollPoint)
249 BEGIN_BLOCK_OBJC_EXCEPTIONS;
250 NSPoint floatPoint = scrollPoint;
251 NSPoint tempPoint = { max(-[scrollView() scrollOrigin].x, floatPoint.x), max(-[scrollView() scrollOrigin].y, floatPoint.y) }; // Don't use NSMakePoint to work around 4213314.
252 [documentView() scrollPoint:tempPoint];
253 END_BLOCK_OBJC_EXCEPTIONS;
256 bool ScrollView::platformScroll(ScrollDirection, ScrollGranularity)
258 // FIXME: It would be nice to implement this so that all of the code in WebFrameView could go away.
263 void ScrollView::platformRepaintContentRectangle(const IntRect& rect)
265 BEGIN_BLOCK_OBJC_EXCEPTIONS;
267 NSView *view = documentView();
269 [view setNeedsDisplayInRect:rect];
271 END_BLOCK_OBJC_EXCEPTIONS;
274 // "Containing Window" means the NSWindow's coord system, which is origin lower left
276 IntRect ScrollView::platformContentsToScreen(const IntRect& rect) const
278 BEGIN_BLOCK_OBJC_EXCEPTIONS;
279 if (NSView* documentView = this->documentView()) {
280 NSRect tempRect = rect;
281 tempRect = [documentView convertRect:tempRect toView:nil];
282 tempRect.origin = [[documentView window] convertBaseToScreen:tempRect.origin];
283 return enclosingIntRect(tempRect);
285 END_BLOCK_OBJC_EXCEPTIONS;
289 IntPoint ScrollView::platformScreenToContents(const IntPoint& point) const
291 BEGIN_BLOCK_OBJC_EXCEPTIONS;
292 if (NSView* documentView = this->documentView()) {
293 NSPoint windowCoord = [[documentView window] convertScreenToBase: point];
294 return IntPoint([documentView convertPoint:windowCoord fromView:nil]);
296 END_BLOCK_OBJC_EXCEPTIONS;
300 bool ScrollView::platformIsOffscreen() const
302 // FIXME: DDK: ScrollViewMac.mm also checks: ![[platformWidget() window] isVisible]
303 // but -[WAKWindow isVisible] doesn't exist.
304 return ![platformWidget() window];
307 void ScrollView::platformSetScrollbarOverlayStyle(ScrollbarOverlayStyle)
311 void ScrollView::platformSetScrollOrigin(const IntPoint& origin, bool updatePositionAll, bool updatePositionSynchronously)
313 BEGIN_BLOCK_OBJC_EXCEPTIONS;
314 [scrollView() setScrollOrigin:static_cast<CGPoint>(origin) updatePositionAtAll:updatePositionAll immediately:updatePositionSynchronously];
315 END_BLOCK_OBJC_EXCEPTIONS;