diff options
author | Upstream <upstream-import@none> | 1970-01-12 13:46:40 +0000 |
---|---|---|
committer | Upstream <upstream-import@none> | 1970-01-12 13:46:40 +0000 |
commit | d8543bb6618c17b12da906afa77d216f58cf4058 (patch) | |
tree | c58dc05ed86825bd0ef8d305d58c8205106b540f /WebKit/mac/WebView/WebDynamicScrollBarsView.m | |
download | external_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.zip external_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.tar.gz external_webkit-d8543bb6618c17b12da906afa77d216f58cf4058.tar.bz2 |
external/webkit r30707
Diffstat (limited to 'WebKit/mac/WebView/WebDynamicScrollBarsView.m')
-rw-r--r-- | WebKit/mac/WebView/WebDynamicScrollBarsView.m | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/WebKit/mac/WebView/WebDynamicScrollBarsView.m b/WebKit/mac/WebView/WebDynamicScrollBarsView.m new file mode 100644 index 0000000..8374725 --- /dev/null +++ b/WebKit/mac/WebView/WebDynamicScrollBarsView.m @@ -0,0 +1,350 @@ +/* + * Copyright (C) 2005 Apple Computer, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import <WebKit/WebDynamicScrollBarsView.h> + +#import <WebKit/WebDocument.h> +#import <WebKitSystemInterface.h> + +@implementation WebDynamicScrollBarsView + +- (void)setSuppressLayout: (BOOL)flag; +{ + suppressLayout = flag; +} + +- (void)setScrollBarsSuppressed:(BOOL)suppressed repaintOnUnsuppress:(BOOL)repaint +{ + suppressScrollers = suppressed; + + // This code was originally changes for a Leopard performance imporvement. We decided to + // ifdef it to fix correctness issues on Tiger documented in <rdar://problem/5441823>. +#ifndef BUILDING_ON_TIGER + if (suppressed) { + [[self verticalScroller] setNeedsDisplay:NO]; + [[self horizontalScroller] setNeedsDisplay:NO]; + } + + if (!suppressed && repaint) + [super reflectScrolledClipView:[self contentView]]; +#else + if (suppressed || repaint) { + [[self verticalScroller] setNeedsDisplay: !suppressed]; + [[self horizontalScroller] setNeedsDisplay: !suppressed]; + } +#endif +} + +- (void)updateScrollers +{ + // We need to do the work below twice in the case where a scroll bar disappears, + // making the second layout have a wider width than the first. Doing it more than + // twice would indicate some kind of infinite loop, so we do it at most twice. + // It's quite efficient to do this work twice in the normal case, so we don't bother + // trying to figure out of the second pass is needed or not. + if (inUpdateScrollers) + return; + + inUpdateScrollers = true; + + int pass; + BOOL hasVerticalScroller = [self hasVerticalScroller]; + BOOL hasHorizontalScroller = [self hasHorizontalScroller]; + BOOL oldHasVertical = hasVerticalScroller; + BOOL oldHasHorizontal = hasHorizontalScroller; + + for (pass = 0; pass < 2; pass++) { + BOOL scrollsVertically; + BOOL scrollsHorizontally; + + if (!suppressLayout && !suppressScrollers && (hScroll == WebCoreScrollbarAuto || vScroll == WebCoreScrollbarAuto)) { + // Do a layout if pending, before checking if scrollbars are needed. + // This fixes 2969367, although may introduce a slowdown in live resize performance. + NSView *documentView = [self documentView]; + if (!documentView) { + scrollsHorizontally = NO; + scrollsVertically = NO; + } else { + if ((hasVerticalScroller != oldHasVertical || + hasHorizontalScroller != oldHasHorizontal || [documentView inLiveResize]) && [documentView conformsToProtocol:@protocol(WebDocumentView)]) { + [(id <WebDocumentView>)documentView setNeedsLayout: YES]; + [(id <WebDocumentView>)documentView layout]; + } + + NSSize documentSize = [documentView frame].size; + NSSize frameSize = [self frame].size; + + scrollsVertically = (vScroll == WebCoreScrollbarAlwaysOn) || + (vScroll == WebCoreScrollbarAuto && documentSize.height > frameSize.height); + if (scrollsVertically) + scrollsHorizontally = (hScroll == WebCoreScrollbarAlwaysOn) || + (hScroll == WebCoreScrollbarAuto && documentSize.width + [NSScroller scrollerWidth] > frameSize.width); + else { + scrollsHorizontally = (hScroll == WebCoreScrollbarAlwaysOn) || + (hScroll == WebCoreScrollbarAuto && documentSize.width > frameSize.width); + if (scrollsHorizontally) + scrollsVertically = (vScroll == WebCoreScrollbarAlwaysOn) || + (vScroll == WebCoreScrollbarAuto && documentSize.height + [NSScroller scrollerWidth] > frameSize.height); + } + } + } else { + scrollsHorizontally = (hScroll == WebCoreScrollbarAuto) ? hasHorizontalScroller : (hScroll == WebCoreScrollbarAlwaysOn); + scrollsVertically = (vScroll == WebCoreScrollbarAuto) ? hasVerticalScroller : (vScroll == WebCoreScrollbarAlwaysOn); + } + + if (hasVerticalScroller != scrollsVertically) { + [self setHasVerticalScroller:scrollsVertically]; + hasVerticalScroller = scrollsVertically; + } + + if (hasHorizontalScroller != scrollsHorizontally) { + [self setHasHorizontalScroller:scrollsHorizontally]; + hasHorizontalScroller = scrollsHorizontally; + } + } + + if (suppressScrollers) { + [[self verticalScroller] setNeedsDisplay: NO]; + [[self horizontalScroller] setNeedsDisplay: NO]; + } + + inUpdateScrollers = false; +} + +// Make the horizontal and vertical scroll bars come and go as needed. +- (void)reflectScrolledClipView:(NSClipView *)clipView +{ + if (clipView == [self contentView]) { + // FIXME: This hack here prevents infinite recursion that takes place when we + // gyrate between having a vertical scroller and not having one. A reproducible + // case is clicking on the "the Policy Routing text" link at + // http://www.linuxpowered.com/archive/howto/Net-HOWTO-8.html. + // The underlying cause is some problem in the NSText machinery, but I was not + // able to pin it down. + if (!inUpdateScrollers && [[NSGraphicsContext currentContext] isDrawingToScreen]) + [self updateScrollers]; + } + + // This code was originally changed for a Leopard performance imporvement. We decided to + // ifdef it to fix correctness issues on Tiger documented in <rdar://problem/5441823>. +#ifndef BUILDING_ON_TIGER + // Update the scrollers if they're not being suppressed. + if (!suppressScrollers) + [super reflectScrolledClipView:clipView]; +#else + [super reflectScrolledClipView:clipView]; + + // Validate the scrollers if they're being suppressed. + if (suppressScrollers) { + [[self verticalScroller] setNeedsDisplay: NO]; + [[self horizontalScroller] setNeedsDisplay: NO]; + } +#endif +} + +- (void)setAllowsScrolling:(BOOL)flag +{ + if (hScrollModeLocked && vScrollModeLocked) + return; + + if (flag && vScroll == WebCoreScrollbarAlwaysOff) + vScroll = WebCoreScrollbarAuto; + else if (!flag && vScroll != WebCoreScrollbarAlwaysOff) + vScroll = WebCoreScrollbarAlwaysOff; + + if (flag && hScroll == WebCoreScrollbarAlwaysOff) + hScroll = WebCoreScrollbarAuto; + else if (!flag && hScroll != WebCoreScrollbarAlwaysOff) + hScroll = WebCoreScrollbarAlwaysOff; + + [self updateScrollers]; +} + +- (BOOL)allowsScrolling +{ + // Returns YES if either horizontal or vertical scrolling is allowed. + return hScroll != WebCoreScrollbarAlwaysOff || vScroll != WebCoreScrollbarAlwaysOff; +} + +- (void)setAllowsHorizontalScrolling:(BOOL)flag +{ + if (hScrollModeLocked) + return; + if (flag && hScroll == WebCoreScrollbarAlwaysOff) + hScroll = WebCoreScrollbarAuto; + else if (!flag && hScroll != WebCoreScrollbarAlwaysOff) + hScroll = WebCoreScrollbarAlwaysOff; + [self updateScrollers]; +} + +- (void)setAllowsVerticalScrolling:(BOOL)flag +{ + if (vScrollModeLocked) + return; + if (flag && vScroll == WebCoreScrollbarAlwaysOff) + vScroll = WebCoreScrollbarAuto; + else if (!flag && vScroll != WebCoreScrollbarAlwaysOff) + vScroll = WebCoreScrollbarAlwaysOff; + [self updateScrollers]; +} + +- (BOOL)allowsHorizontalScrolling +{ + return hScroll != WebCoreScrollbarAlwaysOff; +} + +- (BOOL)allowsVerticalScrolling +{ + return vScroll != WebCoreScrollbarAlwaysOff; +} + +-(WebCoreScrollbarMode)horizontalScrollingMode +{ + return hScroll; +} + +-(WebCoreScrollbarMode)verticalScrollingMode +{ + return vScroll; +} + +- (void)setHorizontalScrollingMode:(WebCoreScrollbarMode)mode +{ + [self setHorizontalScrollingMode:mode andLock:NO]; +} + +- (void)setHorizontalScrollingMode:(WebCoreScrollbarMode)mode andLock:(BOOL)lock +{ + if (mode == hScroll || hScrollModeLocked) + return; + + hScroll = mode; + + if (lock) + [self setHorizontalScrollingModeLocked:YES]; + + [self updateScrollers]; +} + +- (void)setVerticalScrollingMode:(WebCoreScrollbarMode)mode +{ + [self setVerticalScrollingMode:mode andLock:NO]; +} + +- (void)setVerticalScrollingMode:(WebCoreScrollbarMode)mode andLock:(BOOL)lock +{ + if (mode == vScroll || vScrollModeLocked) + return; + + vScroll = mode; + + if (lock) + [self setVerticalScrollingModeLocked:YES]; + + [self updateScrollers]; +} + +- (void)setScrollingMode:(WebCoreScrollbarMode)mode +{ + [self setScrollingMode:mode andLock:NO]; +} + +- (void)setScrollingMode:(WebCoreScrollbarMode)mode andLock:(BOOL)lock +{ + if ((mode == vScroll && mode == hScroll) || (vScrollModeLocked && hScrollModeLocked)) + return; + + BOOL update = NO; + if (mode != vScroll && !vScrollModeLocked) { + vScroll = mode; + update = YES; + } + + if (mode != hScroll && !hScrollModeLocked) { + hScroll = mode; + update = YES; + } + + if (lock) + [self setScrollingModesLocked:YES]; + + if (update) + [self updateScrollers]; +} + +- (void)setHorizontalScrollingModeLocked:(BOOL)locked +{ + hScrollModeLocked = locked; +} + +- (void)setVerticalScrollingModeLocked:(BOOL)locked +{ + vScrollModeLocked = locked; +} + +- (void)setScrollingModesLocked:(BOOL)locked +{ + hScrollModeLocked = vScrollModeLocked = locked; +} + +- (BOOL)horizontalScrollingModeLocked +{ + return hScrollModeLocked; +} + +- (BOOL)verticalScrollingModeLocked +{ + return vScrollModeLocked; +} + +- (BOOL)autoforwardsScrollWheelEvents +{ + return YES; +} + +- (void)scrollWheel:(NSEvent *)event +{ + float deltaX; + float deltaY; + BOOL isContinuous; + WKGetWheelEventDeltas(event, &deltaX, &deltaY, &isContinuous); + + if (fabsf(deltaY) > fabsf(deltaX)) { + if (![self allowsVerticalScrolling]) { + [[self nextResponder] scrollWheel:event]; + return; + } + } else if (![self allowsHorizontalScrolling]) { + [[self nextResponder] scrollWheel:event]; + return; + } + + [super scrollWheel:event]; +} + +@end |