[WTF] Move currentCPUTime and sleep(Seconds) to CPUTime.h and Seconds.h respectively
[WebKit-https.git] / Source / WebCore / platform / ios / ScrollViewIOS.mm
1 /*
2  * Copyright (C) 2004, 2006, 2007, 2008 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 #import "config.h"
27 #import "ScrollView.h"
28
29 #if PLATFORM(IOS)
30
31 #import "FloatRect.h"
32 #import "IntRect.h"
33 #import "Logging.h"
34 #import "NotImplemented.h"
35 #import "WAKAppKitStubs.h"
36 #import "WAKClipView.h"
37 #import "WAKScrollView.h"
38 #import "WAKViewInternal.h"
39 #import "WAKWindow.h"
40 #import "WKViewPrivate.h"
41 #import "WebCoreFrameView.h"
42 #import <wtf/BlockObjCExceptions.h>
43
44 using namespace std;
45
46 namespace WebCore {
47
48 inline NSScrollView<WebCoreFrameScrollView> *ScrollView::scrollView() const
49 {
50     ASSERT(!platformWidget() || [platformWidget() isKindOfClass:[NSScrollView class]]);
51     ASSERT(!platformWidget() || [platformWidget() conformsToProtocol:@protocol(WebCoreFrameScrollView)]);
52     return static_cast<NSScrollView<WebCoreFrameScrollView> *>(platformWidget());
53 }
54
55 NSView *ScrollView::documentView() const
56 {
57     BEGIN_BLOCK_OBJC_EXCEPTIONS;
58     return [scrollView() documentView];
59     END_BLOCK_OBJC_EXCEPTIONS;
60     return nil;
61 }
62
63 void ScrollView::platformAddChild(Widget* child)
64 {
65     ASSERT(child != this);
66
67     child->addToSuperview(documentView());
68 }
69
70 void ScrollView::platformRemoveChild(Widget* child)
71 {
72     child->removeFromSuperview();
73 }
74
75 void ScrollView::platformSetScrollbarModes()
76 {
77     BEGIN_BLOCK_OBJC_EXCEPTIONS;
78     [scrollView() setScrollingModes:m_horizontalScrollbarMode vertical:m_verticalScrollbarMode andLock:NO];
79     END_BLOCK_OBJC_EXCEPTIONS;
80 }
81
82 void ScrollView::platformScrollbarModes(ScrollbarMode& horizontal, ScrollbarMode& vertical) const
83 {
84     BEGIN_BLOCK_OBJC_EXCEPTIONS;
85     [scrollView() scrollingModes:&horizontal vertical:&vertical];
86     END_BLOCK_OBJC_EXCEPTIONS;
87 }
88
89 void ScrollView::platformSetCanBlitOnScroll(bool canBlitOnScroll)
90 {
91     BEGIN_BLOCK_OBJC_EXCEPTIONS;
92     [[scrollView() contentView] setCopiesOnScroll:canBlitOnScroll];
93     END_BLOCK_OBJC_EXCEPTIONS;
94 }
95
96 bool ScrollView::platformCanBlitOnScroll() const
97 {
98     return [[scrollView() contentView] copiesOnScroll];
99 }
100
101 IntRect ScrollView::unobscuredContentRect(VisibleContentRectIncludesScrollbars) const
102 {
103     if (WAKScrollView *view = static_cast<WAKScrollView *>(platformWidget())) {
104         CGRect r = CGRectZero;
105         BEGIN_BLOCK_OBJC_EXCEPTIONS;
106         r = [view unobscuredContentRect];
107         END_BLOCK_OBJC_EXCEPTIONS;
108         return enclosingIntRect(r);
109     }
110
111     if (!m_unobscuredContentSize.isEmpty())
112         return IntRect(m_scrollPosition, roundedIntSize(m_unobscuredContentSize));
113
114     return unobscuredContentRectInternal();
115 }
116
117 void ScrollView::setUnobscuredContentSize(const FloatSize& size)
118 {
119     ASSERT(!platformWidget());
120     if (size == m_unobscuredContentSize)
121         return;
122
123     m_unobscuredContentSize = size;
124     unobscuredContentSizeChanged();
125 }
126
127 FloatRect ScrollView::exposedContentRect() const
128 {
129     if (NSScrollView *view = static_cast<NSScrollView *>(platformWidget())) {
130         CGRect r = CGRectZero;
131         BEGIN_BLOCK_OBJC_EXCEPTIONS;
132         if ([view isKindOfClass:[NSScrollView class]])
133             r = [view exposedContentRect];
134         else {
135             r.origin = [view visibleRect].origin;
136             r.size = [view bounds].size;
137         }
138
139         END_BLOCK_OBJC_EXCEPTIONS;
140         return r;
141     }
142
143     const ScrollView* parent = this->parent();
144     if (!parent)
145         return m_exposedContentRect;
146
147     IntRect parentViewExtentContentRect = enclosingIntRect(parent->exposedContentRect());
148     IntRect selfExtentContentRect = rootViewToContents(parentViewExtentContentRect);
149     selfExtentContentRect.intersect(boundsRect());
150     return selfExtentContentRect;
151 }
152
153 void ScrollView::setExposedContentRect(const FloatRect& rect)
154 {
155     ASSERT(!platformWidget());
156     m_exposedContentRect = rect;
157 }
158
159 void ScrollView::setActualScrollPosition(const IntPoint& position)
160 {
161     NSScrollView *view = static_cast<NSScrollView *>(platformWidget());
162
163     BEGIN_BLOCK_OBJC_EXCEPTIONS;
164     if ([view isKindOfClass:[NSScrollView class]])
165         [view setActualScrollPosition:position];
166     END_BLOCK_OBJC_EXCEPTIONS;
167 }
168
169 float ScrollView::platformTopContentInset() const
170 {
171     return 0;
172 }
173
174 void ScrollView::platformSetTopContentInset(float)
175 {
176 }
177
178 IntRect ScrollView::platformVisibleContentRect(bool includeScrollbars) const
179 {
180     BEGIN_BLOCK_OBJC_EXCEPTIONS;
181     if (includeScrollbars) {
182         if (NSView* documentView = this->documentView())
183             return enclosingIntRect([documentView visibleRect]);
184     }
185     return enclosingIntRect([scrollView() documentVisibleRect]);
186     END_BLOCK_OBJC_EXCEPTIONS;
187     return IntRect();
188 }
189
190 IntSize ScrollView::platformVisibleContentSize(bool includeScrollbars) const
191 {
192     BEGIN_BLOCK_OBJC_EXCEPTIONS;
193     if (includeScrollbars) {
194         if (NSView* documentView = this->documentView())
195             return IntSize([documentView visibleRect].size);
196     }
197
198     return expandedIntSize(FloatSize([scrollView() documentVisibleRect].size));
199     END_BLOCK_OBJC_EXCEPTIONS;
200     return IntSize();
201 }
202
203 IntRect ScrollView::platformVisibleContentRectIncludingObscuredArea(bool includeScrollbars) const
204 {
205     return platformVisibleContentRect(includeScrollbars);
206 }
207
208 IntSize ScrollView::platformVisibleContentSizeIncludingObscuredArea(bool includeScrollbars) const
209 {
210     return platformVisibleContentSize(includeScrollbars);
211 }
212
213 LegacyTileCache* ScrollView::legacyTileCache()
214 {
215     // Make tile cache pointer available via the main frame only. Tile cache interaction should be managed by
216     // the main frame and this avoids having to add parent checks to all call sites.
217     if (parent())
218         return 0;
219     BEGIN_BLOCK_OBJC_EXCEPTIONS;
220     WAKScrollView *view = static_cast<WAKScrollView *>(platformWidget());
221     return [[view window] tileCache];
222     END_BLOCK_OBJC_EXCEPTIONS;
223 }
224
225 void ScrollView::platformSetContentsSize()
226 {
227     BEGIN_BLOCK_OBJC_EXCEPTIONS;
228     int w = m_contentsSize.width();
229     int h = m_contentsSize.height();
230 #if !PLATFORM(IOS)
231     LOG(Frames, "%p %@ at w %d h %d\n", documentView(), [(id)[documentView() class] className], w, h);            
232 #else
233     LOG(Frames, "%p %@ at w %d h %d\n", documentView(), NSStringFromClass([documentView() class]), w, h);
234 #endif
235     NSSize tempSize = { static_cast<CGFloat>(max(0, w)), static_cast<CGFloat>(max(0, h)) }; // workaround for 4213314
236     [documentView() setBoundsSize:tempSize];
237     END_BLOCK_OBJC_EXCEPTIONS;
238 }
239
240 void ScrollView::platformSetScrollbarsSuppressed(bool repaintOnUnsuppress)
241 {
242     BEGIN_BLOCK_OBJC_EXCEPTIONS;
243     [scrollView() setScrollBarsSuppressed:m_scrollbarsSuppressed
244                       repaintOnUnsuppress:repaintOnUnsuppress];
245     END_BLOCK_OBJC_EXCEPTIONS;
246 }
247
248 void ScrollView::platformSetScrollPosition(const IntPoint& scrollPoint)
249 {
250     BEGIN_BLOCK_OBJC_EXCEPTIONS;
251     NSPoint floatPoint = scrollPoint;
252     NSPoint tempPoint = { max(-[scrollView() scrollOrigin].x, floatPoint.x), max(-[scrollView() scrollOrigin].y, floatPoint.y) };  // Don't use NSMakePoint to work around 4213314.
253     [documentView() scrollPoint:tempPoint];
254     END_BLOCK_OBJC_EXCEPTIONS;
255 }
256
257 bool ScrollView::platformScroll(ScrollDirection, ScrollGranularity)
258 {
259     // FIXME: It would be nice to implement this so that all of the code in WebFrameView could go away.
260     notImplemented();
261     return false;
262 }
263
264 void ScrollView::platformRepaintContentRectangle(const IntRect& rect)
265 {
266     BEGIN_BLOCK_OBJC_EXCEPTIONS;
267
268     NSView *view = documentView();
269
270     [view setNeedsDisplayInRect:rect];    
271
272     END_BLOCK_OBJC_EXCEPTIONS;
273 }
274
275 // "Containing Window" means the NSWindow's coord system, which is origin lower left
276
277 IntRect ScrollView::platformContentsToScreen(const IntRect& rect) const
278 {
279     BEGIN_BLOCK_OBJC_EXCEPTIONS;
280     if (NSView* documentView = this->documentView()) {
281         NSRect tempRect = rect;
282         tempRect = [documentView convertRect:tempRect toView:nil];
283         tempRect.origin = [[documentView window] convertBaseToScreen:tempRect.origin];
284         return enclosingIntRect(tempRect);
285     }
286     END_BLOCK_OBJC_EXCEPTIONS;
287     return IntRect();
288 }
289
290 IntPoint ScrollView::platformScreenToContents(const IntPoint& point) const
291 {
292     BEGIN_BLOCK_OBJC_EXCEPTIONS;
293     if (NSView* documentView = this->documentView()) {
294         NSPoint windowCoord = [[documentView window] convertScreenToBase: point];
295         return IntPoint([documentView convertPoint:windowCoord fromView:nil]);
296     }
297     END_BLOCK_OBJC_EXCEPTIONS;
298     return IntPoint();
299 }
300
301 bool ScrollView::platformIsOffscreen() const
302 {
303     // FIXME: DDK: ScrollViewMac.mm also checks: ![[platformWidget() window] isVisible]
304     // but -[WAKWindow isVisible] doesn't exist.
305     return ![platformWidget() window];
306 }
307
308 void ScrollView::platformSetScrollbarOverlayStyle(ScrollbarOverlayStyle)
309 {
310 }
311
312 void ScrollView::platformSetScrollOrigin(const IntPoint& origin, bool updatePositionAll, bool updatePositionSynchronously)
313 {
314     BEGIN_BLOCK_OBJC_EXCEPTIONS;
315     [scrollView() setScrollOrigin:static_cast<CGPoint>(origin) updatePositionAtAll:updatePositionAll immediately:updatePositionSynchronously];
316     END_BLOCK_OBJC_EXCEPTIONS;
317 }
318
319 }
320
321 #endif // PLATFORM(IOS)