Home | History | Annotate | Download | only in mac
      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