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.
36 if (inUpdateScrollers)
39 inUpdateScrollers = true;
42 BOOL hasVerticalScroller = [self hasVerticalScroller];
43 BOOL hasHorizontalScroller = [self hasHorizontalScroller];
44 BOOL oldHasVertical = hasVerticalScroller;
45 BOOL oldHasHorizontal = hasHorizontalScroller;
47 for (pass = 0; pass < 2; pass++) {
48 BOOL scrollsVertically;
49 BOOL scrollsHorizontally;
51 if (!suppressLayout && !suppressScrollers &&
52 (hScroll == WebCoreScrollBarAuto || vScroll == WebCoreScrollBarAuto))
54 // Do a layout if pending, before checking if scrollbars are needed.
55 // This fixes 2969367, although may introduce a slowdown in live resize performance.
56 NSView *documentView = [self documentView];
57 if ((hasVerticalScroller != oldHasVertical ||
58 hasHorizontalScroller != oldHasHorizontal || [documentView inLiveResize]) && [documentView conformsToProtocol:@protocol(WebDocumentView)]) {
59 [(id <WebDocumentView>)documentView setNeedsLayout: YES];
60 [(id <WebDocumentView>)documentView layout];
63 NSSize documentSize = [documentView frame].size;
64 NSSize frameSize = [self frame].size;
66 scrollsVertically = (vScroll == WebCoreScrollBarAlwaysOn) ||
67 (vScroll == WebCoreScrollBarAuto && documentSize.height > frameSize.height);
68 if (scrollsVertically)
69 scrollsHorizontally = (hScroll == WebCoreScrollBarAlwaysOn) ||
70 (hScroll == WebCoreScrollBarAuto && documentSize.width + [NSScroller scrollerWidth] > frameSize.width);
72 scrollsHorizontally = (hScroll == WebCoreScrollBarAlwaysOn) ||
73 (hScroll == WebCoreScrollBarAuto && documentSize.width > frameSize.width);
74 if (scrollsHorizontally)
75 scrollsVertically = (vScroll == WebCoreScrollBarAlwaysOn) ||
76 (vScroll == WebCoreScrollBarAuto && documentSize.height + [NSScroller scrollerWidth] > frameSize.height);
80 scrollsHorizontally = (hScroll == WebCoreScrollBarAuto) ? hasHorizontalScroller : (hScroll == WebCoreScrollBarAlwaysOn);
81 scrollsVertically = (vScroll == WebCoreScrollBarAuto) ? hasVerticalScroller : (vScroll == WebCoreScrollBarAlwaysOn);
84 if (hasVerticalScroller != scrollsVertically) {
85 [self setHasVerticalScroller:scrollsVertically];
86 hasVerticalScroller = scrollsVertically;
89 if (hasHorizontalScroller != scrollsHorizontally) {
90 [self setHasHorizontalScroller:scrollsHorizontally];
91 hasHorizontalScroller = scrollsHorizontally;
95 if (suppressScrollers) {
96 [[self verticalScroller] setNeedsDisplay: NO];
97 [[self horizontalScroller] setNeedsDisplay: NO];
100 inUpdateScrollers = false;
103 // Make the horizontal and vertical scroll bars come and go as needed.
104 - (void)reflectScrolledClipView:(NSClipView *)clipView
106 if (clipView == [self contentView]) {
107 // FIXME: This hack here prevents infinite recursion that takes place when we
108 // gyrate between having a vertical scroller and not having one. A reproducible
109 // case is clicking on the "the Policy Routing text" link at
110 // http://www.linuxpowered.com/archive/howto/Net-HOWTO-8.html.
111 // The underlying cause is some problem in the NSText machinery, but I was not
112 // able to pin it down.
113 if (!inUpdateScrollers && [[NSGraphicsContext currentContext] isDrawingToScreen])
114 [self updateScrollers];
116 [super reflectScrolledClipView:clipView];
118 // Validate the scrollers if they're being suppressed.
119 if (suppressScrollers) {
120 [[self verticalScroller] setNeedsDisplay: NO];
121 [[self horizontalScroller] setNeedsDisplay: NO];
125 - (void)setAllowsScrolling:(BOOL)flag
127 hScroll = vScroll = (flag ? WebCoreScrollBarAuto : WebCoreScrollBarAlwaysOff);
128 [self updateScrollers];
131 - (BOOL)allowsScrolling
133 return hScroll != WebCoreScrollBarAlwaysOff && vScroll != WebCoreScrollBarAlwaysOff;
136 - (void)setAllowsHorizontalScrolling:(BOOL)flag
138 hScroll = (flag ? WebCoreScrollBarAuto : WebCoreScrollBarAlwaysOff);
139 [self updateScrollers];
142 - (void)setAllowsVerticalScrolling:(BOOL)flag
144 vScroll = (flag ? WebCoreScrollBarAuto : WebCoreScrollBarAlwaysOff);
145 [self updateScrollers];
148 - (BOOL)allowsHorizontalScrolling
150 return hScroll != WebCoreScrollBarAlwaysOff;
153 - (BOOL)allowsVerticalScrolling
155 return vScroll != WebCoreScrollBarAlwaysOff;
158 -(WebCoreScrollBarMode)horizontalScrollingMode
163 -(WebCoreScrollBarMode)verticalScrollingMode
168 - (void)setHorizontalScrollingMode:(WebCoreScrollBarMode)mode
173 [self updateScrollers];
176 - (void)setVerticalScrollingMode:(WebCoreScrollBarMode)mode
181 [self updateScrollers];
184 - (void)setScrollingMode:(WebCoreScrollBarMode)mode
186 if (mode == vScroll && mode == hScroll)
188 vScroll = hScroll = mode;
189 [self updateScrollers];