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 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. 24 */ 25 26#import "config.h" 27#import "ScrollView.h" 28 29#import "BlockExceptions.h" 30#import "FloatRect.h" 31#import "IntRect.h" 32#import "Logging.h" 33#import "NotImplemented.h" 34#import "WebCoreFrameView.h" 35 36using namespace std; 37 38@interface NSWindow (WebWindowDetails) 39- (BOOL)_needsToResetDragMargins; 40- (void)_setNeedsToResetDragMargins:(BOOL)needs; 41@end 42 43namespace WebCore { 44 45inline NSScrollView<WebCoreFrameScrollView> *ScrollView::scrollView() const 46{ 47 ASSERT(!platformWidget() || [platformWidget() isKindOfClass:[NSScrollView class]]); 48 ASSERT(!platformWidget() || [platformWidget() conformsToProtocol:@protocol(WebCoreFrameScrollView)]); 49 return static_cast<NSScrollView<WebCoreFrameScrollView> *>(platformWidget()); 50} 51 52NSView *ScrollView::documentView() const 53{ 54 BEGIN_BLOCK_OBJC_EXCEPTIONS; 55 return [scrollView() documentView]; 56 END_BLOCK_OBJC_EXCEPTIONS; 57 return nil; 58} 59 60void ScrollView::platformAddChild(Widget* child) 61{ 62 BEGIN_BLOCK_OBJC_EXCEPTIONS; 63 NSView *parentView = documentView(); 64 NSView *childView = child->getOuterView(); 65 ASSERT(![parentView isDescendantOf:childView]); 66 67 // Suppress the resetting of drag margins since we know we can't affect them. 68 NSWindow *window = [parentView window]; 69 BOOL resetDragMargins = [window _needsToResetDragMargins]; 70 [window _setNeedsToResetDragMargins:NO]; 71 if ([childView superview] != parentView) 72 [parentView addSubview:childView]; 73 [window _setNeedsToResetDragMargins:resetDragMargins]; 74 END_BLOCK_OBJC_EXCEPTIONS; 75} 76 77void ScrollView::platformRemoveChild(Widget* child) 78{ 79 child->removeFromSuperview(); 80} 81 82void ScrollView::platformSetScrollbarModes() 83{ 84 BEGIN_BLOCK_OBJC_EXCEPTIONS; 85 [scrollView() setScrollingModes:m_horizontalScrollbarMode vertical:m_verticalScrollbarMode andLock:NO]; 86 END_BLOCK_OBJC_EXCEPTIONS; 87} 88 89void ScrollView::platformScrollbarModes(ScrollbarMode& horizontal, ScrollbarMode& vertical) const 90{ 91 BEGIN_BLOCK_OBJC_EXCEPTIONS; 92 [scrollView() scrollingModes:&horizontal vertical:&vertical]; 93 END_BLOCK_OBJC_EXCEPTIONS; 94} 95 96void ScrollView::platformSetCanBlitOnScroll(bool canBlitOnScroll) 97{ 98 BEGIN_BLOCK_OBJC_EXCEPTIONS; 99 [[scrollView() contentView] setCopiesOnScroll:canBlitOnScroll]; 100 END_BLOCK_OBJC_EXCEPTIONS; 101} 102 103bool ScrollView::platformCanBlitOnScroll() const 104{ 105 return [[scrollView() contentView] copiesOnScroll]; 106} 107 108IntRect ScrollView::platformVisibleContentRect(bool includeScrollbars) const 109{ 110 BEGIN_BLOCK_OBJC_EXCEPTIONS; 111 IntRect result = enclosingIntRect([scrollView() documentVisibleRect]); 112 if (includeScrollbars) 113 result.setSize(IntSize([scrollView() frame].size)); 114 return result; 115 END_BLOCK_OBJC_EXCEPTIONS; 116 return IntRect(); 117} 118 119IntSize ScrollView::platformContentsSize() const 120{ 121 BEGIN_BLOCK_OBJC_EXCEPTIONS; 122 if (NSView* documentView = this->documentView()) 123 return enclosingIntRect([documentView bounds]).size(); 124 END_BLOCK_OBJC_EXCEPTIONS; 125 return IntSize(); 126} 127 128void ScrollView::platformSetContentsSize() 129{ 130 BEGIN_BLOCK_OBJC_EXCEPTIONS; 131 int w = m_contentsSize.width(); 132 int h = m_contentsSize.height(); 133 LOG(Frames, "%p %@ at w %d h %d\n", documentView(), [(id)[documentView() class] className], w, h); 134 NSSize tempSize = { max(0, w), max(0, h) }; // workaround for 4213314 135 [documentView() setFrameSize:tempSize]; 136 END_BLOCK_OBJC_EXCEPTIONS; 137} 138 139void ScrollView::platformSetScrollbarsSuppressed(bool repaintOnUnsuppress) 140{ 141 BEGIN_BLOCK_OBJC_EXCEPTIONS; 142 [scrollView() setScrollBarsSuppressed:m_scrollbarsSuppressed 143 repaintOnUnsuppress:repaintOnUnsuppress]; 144 END_BLOCK_OBJC_EXCEPTIONS; 145} 146 147void ScrollView::platformSetScrollPosition(const IntPoint& scrollPoint) 148{ 149 BEGIN_BLOCK_OBJC_EXCEPTIONS; 150 NSPoint floatPoint = scrollPoint; 151 NSPoint tempPoint = { max(-[scrollView() scrollOrigin].x, floatPoint.x), max(-[scrollView() scrollOrigin].y, floatPoint.y) }; // Don't use NSMakePoint to work around 4213314. 152 [documentView() scrollPoint:tempPoint]; 153 END_BLOCK_OBJC_EXCEPTIONS; 154} 155 156bool ScrollView::platformScroll(ScrollDirection, ScrollGranularity) 157{ 158 // FIXME: It would be nice to implement this so that all of the code in WebFrameView could go away. 159 notImplemented(); 160 return false; 161} 162 163void ScrollView::platformRepaintContentRectangle(const IntRect& rect, bool now) 164{ 165 BEGIN_BLOCK_OBJC_EXCEPTIONS; 166 NSView *view = documentView(); 167 [view setNeedsDisplayInRect:rect]; 168 if (now) { 169 [[view window] displayIfNeeded]; 170 [[view window] flushWindowIfNeeded]; 171 } 172 END_BLOCK_OBJC_EXCEPTIONS; 173} 174 175// "Containing Window" means the NSWindow's coord system, which is origin lower left 176 177IntRect ScrollView::platformContentsToScreen(const IntRect& rect) const 178{ 179 BEGIN_BLOCK_OBJC_EXCEPTIONS; 180 if (NSView* documentView = this->documentView()) { 181 NSRect tempRect = rect; 182 tempRect = [documentView convertRect:tempRect toView:nil]; 183 tempRect.origin = [[documentView window] convertBaseToScreen:tempRect.origin]; 184 return enclosingIntRect(tempRect); 185 } 186 END_BLOCK_OBJC_EXCEPTIONS; 187 return IntRect(); 188} 189 190IntPoint ScrollView::platformScreenToContents(const IntPoint& point) const 191{ 192 BEGIN_BLOCK_OBJC_EXCEPTIONS; 193 if (NSView* documentView = this->documentView()) { 194 NSPoint windowCoord = [[documentView window] convertScreenToBase: point]; 195 return IntPoint([documentView convertPoint:windowCoord fromView:nil]); 196 } 197 END_BLOCK_OBJC_EXCEPTIONS; 198 return IntPoint(); 199} 200 201bool ScrollView::platformIsOffscreen() const 202{ 203 return ![platformWidget() window] || ![[platformWidget() window] isVisible]; 204} 205 206void ScrollView::platformSetScrollOrigin(const IntPoint& origin, bool updatePositionAtAll, bool updatePositionSynchronously) 207{ 208 BEGIN_BLOCK_OBJC_EXCEPTIONS; 209 [scrollView() setScrollOrigin:origin updatePositionAtAll:updatePositionAtAll immediately:updatePositionSynchronously]; 210 END_BLOCK_OBJC_EXCEPTIONS; 211} 212 213} // namespace WebCore 214