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"
34 #import "NotImplemented.h"
35 #import "WebCoreFrameView.h"
37 @interface NSScrollView (Details)
38 - (NSEdgeInsets)contentInsets;
41 @interface NSWindow (WebWindowDetails)
42 - (BOOL)_needsToResetDragMargins;
43 - (void)_setNeedsToResetDragMargins:(BOOL)needs;
48 inline NSScrollView<WebCoreFrameScrollView> *ScrollView::scrollView() const
50 ASSERT(!platformWidget() || [platformWidget() isKindOfClass:[NSScrollView class]]);
51 ASSERT(!platformWidget() || [platformWidget() conformsToProtocol:@protocol(WebCoreFrameScrollView)]);
52 return static_cast<NSScrollView<WebCoreFrameScrollView> *>(platformWidget());
55 NSView *ScrollView::documentView() const
57 BEGIN_BLOCK_OBJC_EXCEPTIONS;
58 return [scrollView() documentView];
59 END_BLOCK_OBJC_EXCEPTIONS;
63 void ScrollView::platformAddChild(Widget* child)
65 BEGIN_BLOCK_OBJC_EXCEPTIONS;
66 NSView *parentView = documentView();
67 NSView *childView = child->getOuterView();
68 ASSERT(![parentView isDescendantOf:childView]);
70 // Suppress the resetting of drag margins since we know we can't affect them.
71 NSWindow *window = [parentView window];
72 BOOL resetDragMargins = [window _needsToResetDragMargins];
73 [window _setNeedsToResetDragMargins:NO];
74 if ([childView superview] != parentView)
75 [parentView addSubview:childView];
76 [window _setNeedsToResetDragMargins:resetDragMargins];
77 END_BLOCK_OBJC_EXCEPTIONS;
80 void ScrollView::platformRemoveChild(Widget* child)
82 child->removeFromSuperview();
85 void ScrollView::platformSetScrollbarModes()
87 BEGIN_BLOCK_OBJC_EXCEPTIONS;
88 [scrollView() setScrollingModes:m_horizontalScrollbarMode vertical:m_verticalScrollbarMode andLock:NO];
89 END_BLOCK_OBJC_EXCEPTIONS;
92 void ScrollView::platformScrollbarModes(ScrollbarMode& horizontal, ScrollbarMode& vertical) const
94 BEGIN_BLOCK_OBJC_EXCEPTIONS;
95 [scrollView() scrollingModes:&horizontal vertical:&vertical];
96 END_BLOCK_OBJC_EXCEPTIONS;
99 void ScrollView::platformSetCanBlitOnScroll(bool canBlitOnScroll)
101 BEGIN_BLOCK_OBJC_EXCEPTIONS;
102 [[scrollView() contentView] setCopiesOnScroll:canBlitOnScroll];
103 END_BLOCK_OBJC_EXCEPTIONS;
106 bool ScrollView::platformCanBlitOnScroll() const
108 return [[scrollView() contentView] copiesOnScroll];
111 float ScrollView::platformTopContentInset() const
113 BEGIN_BLOCK_OBJC_EXCEPTIONS;
114 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
115 return scrollView().contentInsets.top;
117 END_BLOCK_OBJC_EXCEPTIONS;
122 void ScrollView::platformSetTopContentInset(float topContentInset)
124 BEGIN_BLOCK_OBJC_EXCEPTIONS;
125 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
127 scrollView().automaticallyAdjustsContentInsets = NO;
129 scrollView().automaticallyAdjustsContentInsets = YES;
131 NSEdgeInsets contentInsets = scrollView().contentInsets;
132 contentInsets.top = topContentInset;
133 scrollView().contentInsets = contentInsets;
135 UNUSED_PARAM(topContentInset);
137 END_BLOCK_OBJC_EXCEPTIONS;
140 IntRect ScrollView::platformVisibleContentRect(bool includeScrollbars) const
142 BEGIN_BLOCK_OBJC_EXCEPTIONS;
144 IntRect visibleContentRect = enclosingIntRect([scrollView() documentVisibleRect]);
145 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
146 visibleContentRect.move(scrollView().contentInsets.left, scrollView().contentInsets.top);
147 visibleContentRect.contract(scrollView().contentInsets.left + scrollView().contentInsets.right, scrollView().contentInsets.top + scrollView().contentInsets.bottom);
150 if (includeScrollbars) {
151 IntSize frameSize = IntSize([scrollView() frame].size);
152 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
153 frameSize.contract(scrollView().contentInsets.left + scrollView().contentInsets.right, scrollView().contentInsets.top + scrollView().contentInsets.bottom);
155 visibleContentRect.setSize(frameSize);
158 return visibleContentRect;
159 END_BLOCK_OBJC_EXCEPTIONS;
164 IntSize ScrollView::platformVisibleContentSize(bool includeScrollbars) const
166 return platformVisibleContentRect(includeScrollbars).size();
169 void ScrollView::platformSetContentsSize()
171 BEGIN_BLOCK_OBJC_EXCEPTIONS;
172 int w = m_contentsSize.width();
173 int h = m_contentsSize.height();
174 LOG(Frames, "%p %@ at w %d h %d\n", documentView(), [(id)[documentView() class] className], w, h);
175 [documentView() setFrameSize:NSMakeSize(std::max(0, w), std::max(0, h))];
176 END_BLOCK_OBJC_EXCEPTIONS;
179 void ScrollView::platformSetScrollbarsSuppressed(bool repaintOnUnsuppress)
181 BEGIN_BLOCK_OBJC_EXCEPTIONS;
182 [scrollView() setScrollBarsSuppressed:m_scrollbarsSuppressed
183 repaintOnUnsuppress:repaintOnUnsuppress];
184 END_BLOCK_OBJC_EXCEPTIONS;
187 void ScrollView::platformSetScrollPosition(const IntPoint& scrollPoint)
189 BEGIN_BLOCK_OBJC_EXCEPTIONS;
190 NSPoint floatPoint = scrollPoint;
191 NSPoint tempPoint = { std::max(-[scrollView() scrollOrigin].x, floatPoint.x), std::max(-[scrollView() scrollOrigin].y, floatPoint.y) }; // Don't use NSMakePoint to work around 4213314.
193 #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
194 // AppKit has the inset factored into all of its scroll positions. In WebCore, we use positions that ignore
195 // the insets so that they are equivalent whether or not there is an inset.
196 tempPoint.x = tempPoint.x - scrollView().contentInsets.left;
197 tempPoint.y = tempPoint.y - scrollView().contentInsets.top;
200 [documentView() scrollPoint:tempPoint];
201 END_BLOCK_OBJC_EXCEPTIONS;
204 bool ScrollView::platformScroll(ScrollDirection, ScrollGranularity)
206 // FIXME: It would be nice to implement this so that all of the code in WebFrameView could go away.
211 void ScrollView::platformRepaintContentRectangle(const IntRect& rect)
213 BEGIN_BLOCK_OBJC_EXCEPTIONS;
214 NSView *view = documentView();
215 [view setNeedsDisplayInRect:rect];
217 END_BLOCK_OBJC_EXCEPTIONS;
220 // "Containing Window" means the NSWindow's coord system, which is origin lower left
222 IntRect ScrollView::platformContentsToScreen(const IntRect& rect) const
224 BEGIN_BLOCK_OBJC_EXCEPTIONS;
225 if (NSView* documentView = this->documentView()) {
226 NSRect tempRect = rect;
227 tempRect = [documentView convertRect:tempRect toView:nil];
228 #pragma clang diagnostic push
229 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
230 tempRect.origin = [[documentView window] convertBaseToScreen:tempRect.origin];
231 #pragma clang diagnostic pop
232 return enclosingIntRect(tempRect);
234 END_BLOCK_OBJC_EXCEPTIONS;
238 IntPoint ScrollView::platformScreenToContents(const IntPoint& point) const
240 BEGIN_BLOCK_OBJC_EXCEPTIONS;
241 if (NSView* documentView = this->documentView()) {
242 #pragma clang diagnostic push
243 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
244 NSPoint windowCoord = [[documentView window] convertScreenToBase: point];
245 #pragma clang diagnostic pop
246 return IntPoint([documentView convertPoint:windowCoord fromView:nil]);
248 END_BLOCK_OBJC_EXCEPTIONS;
252 bool ScrollView::platformIsOffscreen() const
254 return ![platformWidget() window] || ![[platformWidget() window] isVisible];
257 static inline NSScrollerKnobStyle toNSScrollerKnobStyle(ScrollbarOverlayStyle style)
260 case ScrollbarOverlayStyleDark:
261 return NSScrollerKnobStyleDark;
262 case ScrollbarOverlayStyleLight:
263 return NSScrollerKnobStyleLight;
265 return NSScrollerKnobStyleDefault;
269 void ScrollView::platformSetScrollbarOverlayStyle(ScrollbarOverlayStyle overlayStyle)
271 [scrollView() setScrollerKnobStyle:toNSScrollerKnobStyle(overlayStyle)];
274 void ScrollView::platformSetScrollOrigin(const IntPoint& origin, bool updatePositionAtAll, bool updatePositionSynchronously)
276 BEGIN_BLOCK_OBJC_EXCEPTIONS;
277 [scrollView() setScrollOrigin:origin updatePositionAtAll:updatePositionAtAll immediately:updatePositionSynchronously];
278 END_BLOCK_OBJC_EXCEPTIONS;
281 } // namespace WebCore