2 // WebDynamicScrollBarsView.m
5 // Created by John Sullivan on Tue Jan 22 2002.
6 // Copyright (c) 2001, 2002 Apple Computer, Inc. All rights reserved.
9 #import <WebKit/WebDynamicScrollBarsView.h>
11 #import <WebKit/WebDocument.h>
13 @implementation WebDynamicScrollBarsView
15 - (void)setSuppressLayout: (BOOL)flag;
17 suppressLayout = flag;
20 - (void)setScrollBarsSuppressed:(BOOL)suppressed repaintOnUnsuppress:(BOOL)repaint
22 suppressScrollers = suppressed;
23 if (suppressed || repaint) {
24 [[self verticalScroller] setNeedsDisplay: !suppressed];
25 [[self horizontalScroller] setNeedsDisplay: !suppressed];
29 - (void)updateScrollers
31 // We need to do the work below twice in the case where a scroll bar disappears,
32 // making the second layout have a wider width than the first. Doing it more than
33 // twice would indicate some kind of infinite loop, so we do it at most twice.
34 // It's quite efficient to do this work twice in the normal case, so we don't bother
35 // trying to figure out of the second pass is needed or not.
38 BOOL hasVerticalScroller = [self hasVerticalScroller];
39 BOOL hasHorizontalScroller = [self hasHorizontalScroller];
40 BOOL oldHasVertical = hasVerticalScroller;
41 BOOL oldHasHorizontal = hasHorizontalScroller;
43 for (pass = 0; pass < 2; pass++) {
44 BOOL scrollsVertically;
45 BOOL scrollsHorizontally;
47 if (!suppressLayout && !suppressScrollers &&
48 (hScroll == WebCoreScrollBarAuto || vScroll == WebCoreScrollBarAuto))
50 // Do a layout if pending, before checking if scrollbars are needed.
51 // This fixes 2969367, although may introduce a slowdown in live resize performance.
52 NSView *documentView = [self documentView];
53 if ((hasVerticalScroller != oldHasVertical ||
54 hasHorizontalScroller != oldHasHorizontal || [documentView inLiveResize]) && [documentView conformsToProtocol:@protocol(WebDocumentView)]) {
55 [(id <WebDocumentView>)documentView setNeedsLayout: YES];
56 [(id <WebDocumentView>)documentView layout];
59 NSSize documentSize = [documentView frame].size;
60 NSSize frameSize = [self frame].size;
62 scrollsVertically = (vScroll == WebCoreScrollBarAlwaysOn) ||
63 (vScroll == WebCoreScrollBarAuto && documentSize.height > frameSize.height);
64 if (scrollsVertically)
65 scrollsHorizontally = (hScroll == WebCoreScrollBarAlwaysOn) ||
66 (hScroll == WebCoreScrollBarAuto && documentSize.width + [NSScroller scrollerWidth] > frameSize.width);
68 scrollsHorizontally = (hScroll == WebCoreScrollBarAlwaysOn) ||
69 (hScroll == WebCoreScrollBarAuto && documentSize.width > frameSize.width);
70 if (scrollsHorizontally)
71 scrollsVertically = (vScroll == WebCoreScrollBarAlwaysOn) ||
72 (vScroll == WebCoreScrollBarAuto && documentSize.height + [NSScroller scrollerWidth] > frameSize.height);
76 scrollsHorizontally = (hScroll == WebCoreScrollBarAuto) ? hasHorizontalScroller : (hScroll == WebCoreScrollBarAlwaysOn);
77 scrollsVertically = (vScroll == WebCoreScrollBarAuto) ? hasVerticalScroller : (vScroll == WebCoreScrollBarAlwaysOn);
80 if (hasVerticalScroller != scrollsVertically) {
81 [self setHasVerticalScroller:scrollsVertically];
82 hasVerticalScroller = scrollsVertically;
85 if (hasHorizontalScroller != scrollsHorizontally) {
86 [self setHasHorizontalScroller:scrollsHorizontally];
87 hasHorizontalScroller = scrollsHorizontally;
91 if (suppressScrollers) {
92 [[self verticalScroller] setNeedsDisplay: NO];
93 [[self horizontalScroller] setNeedsDisplay: NO];
97 // Make the horizontal and vertical scroll bars come and go as needed.
98 - (void)reflectScrolledClipView:(NSClipView *)clipView
100 if (clipView == [self contentView]) {
101 // FIXME: This hack here prevents infinite recursion that takes place when we
102 // gyrate between having a vertical scroller and not having one. A reproducible
103 // case is clicking on the "the Policy Routing text" link at
104 // http://www.linuxpowered.com/archive/howto/Net-HOWTO-8.html.
105 // The underlying cause is some problem in the NSText machinery, but I was not
106 // able to pin it down.
107 if (!inUpdateScrollers && [[NSGraphicsContext currentContext] isDrawingToScreen]) {
108 inUpdateScrollers = YES;
109 [self updateScrollers];
110 inUpdateScrollers = NO;
113 [super reflectScrolledClipView:clipView];
115 // Validate the scrollers if they're being suppressed.
116 if (suppressScrollers) {
117 [[self verticalScroller] setNeedsDisplay: NO];
118 [[self horizontalScroller] setNeedsDisplay: NO];
122 - (void)setAllowsScrolling:(BOOL)flag
124 hScroll = vScroll = (flag ? WebCoreScrollBarAuto : WebCoreScrollBarAlwaysOff);
125 [self updateScrollers];
128 - (BOOL)allowsScrolling
130 return hScroll != WebCoreScrollBarAlwaysOff && vScroll != WebCoreScrollBarAlwaysOff;
133 - (void)setAllowsHorizontalScrolling:(BOOL)flag
135 hScroll = (flag ? WebCoreScrollBarAuto : WebCoreScrollBarAlwaysOff);
136 [self updateScrollers];
139 - (void)setAllowsVerticalScrolling:(BOOL)flag
141 vScroll = (flag ? WebCoreScrollBarAuto : WebCoreScrollBarAlwaysOff);
142 [self updateScrollers];
145 - (BOOL)allowsHorizontalScrolling
147 return hScroll != WebCoreScrollBarAlwaysOff;
150 - (BOOL)allowsVerticalScrolling
152 return vScroll != WebCoreScrollBarAlwaysOff;
155 -(WebCoreScrollBarMode)horizontalScrollingMode
160 -(WebCoreScrollBarMode)verticalScrollingMode
165 - (void)setHorizontalScrollingMode:(WebCoreScrollBarMode)mode
170 [self updateScrollers];
173 - (void)setVerticalScrollingMode:(WebCoreScrollBarMode)mode
178 [self updateScrollers];
181 - (void)setScrollingMode:(WebCoreScrollBarMode)mode
183 if (mode == vScroll && mode == hScroll)
185 vScroll = hScroll = mode;
186 [self updateScrollers];