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 36 using namespace std; 37 38 @interface NSWindow (WebWindowDetails) 39 - (BOOL)_needsToResetDragMargins; 40 - (void)_setNeedsToResetDragMargins:(BOOL)needs; 41 @end 42 43 namespace WebCore { 44 45 inline 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 52 NSView *ScrollView::documentView() const 53 { 54 BEGIN_BLOCK_OBJC_EXCEPTIONS; 55 return [scrollView() documentView]; 56 END_BLOCK_OBJC_EXCEPTIONS; 57 return nil; 58 } 59 60 void 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 77 void ScrollView::platformRemoveChild(Widget* child) 78 { 79 child->removeFromSuperview(); 80 } 81 82 void 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 89 void 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 96 void ScrollView::platformSetCanBlitOnScroll(bool canBlitOnScroll) 97 { 98 BEGIN_BLOCK_OBJC_EXCEPTIONS; 99 [[scrollView() contentView] setCopiesOnScroll:canBlitOnScroll]; 100 END_BLOCK_OBJC_EXCEPTIONS; 101 } 102 103 bool ScrollView::platformCanBlitOnScroll() const 104 { 105 return [[scrollView() contentView] copiesOnScroll]; 106 } 107 108 IntRect 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 119 IntSize 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 128 void 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 139 void 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 147 void 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 156 bool 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 163 void 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 177 IntRect 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 190 IntPoint 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 201 bool ScrollView::platformIsOffscreen() const 202 { 203 return ![platformWidget() window] || ![[platformWidget() window] isVisible]; 204 } 205 206 void 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