Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(276)

Side by Side Diff: Source/core/platform/ScrollbarTheme.cpp

Issue 99103006: Moving GraphicsContext and dependencies from core to platform. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Final patch - fixes Android Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/platform/ScrollbarTheme.h ('k') | Source/core/platform/ScrollbarThemeAndroid.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2011 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 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 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 #include "config.h"
27 #include "core/platform/ScrollbarTheme.h"
28
29 #include "RuntimeEnabledFeatures.h"
30 #include "core/platform/mock/ScrollbarThemeMock.h"
31 #include "core/platform/mock/ScrollbarThemeOverlayMock.h"
32 #include "platform/scroll/ScrollbarThemeClient.h"
33
34 namespace WebCore {
35
36 ScrollbarTheme* ScrollbarTheme::theme()
37 {
38 if (ScrollbarTheme::mockScrollbarsEnabled()) {
39 if (RuntimeEnabledFeatures::overlayScrollbarsEnabled()) {
40 DEFINE_STATIC_LOCAL(ScrollbarThemeOverlayMock, overlayMockTheme, ()) ;
41 return &overlayMockTheme;
42 }
43
44 DEFINE_STATIC_LOCAL(ScrollbarThemeMock, mockTheme, ());
45 return &mockTheme;
46 }
47 return nativeTheme();
48 }
49
50 bool ScrollbarTheme::gMockScrollbarsEnabled = false;
51
52 void ScrollbarTheme::setMockScrollbarsEnabled(bool flag)
53 {
54 gMockScrollbarsEnabled = flag;
55 }
56
57 bool ScrollbarTheme::mockScrollbarsEnabled()
58 {
59 return gMockScrollbarsEnabled;
60 }
61
62 bool ScrollbarTheme::paint(ScrollbarThemeClient* scrollbar, GraphicsContext* gra phicsContext, const IntRect& damageRect)
63 {
64 // Create the ScrollbarControlPartMask based on the damageRect
65 ScrollbarControlPartMask scrollMask = NoPart;
66
67 IntRect backButtonStartPaintRect;
68 IntRect backButtonEndPaintRect;
69 IntRect forwardButtonStartPaintRect;
70 IntRect forwardButtonEndPaintRect;
71 if (hasButtons(scrollbar)) {
72 backButtonStartPaintRect = backButtonRect(scrollbar, BackButtonStartPart , true);
73 if (damageRect.intersects(backButtonStartPaintRect))
74 scrollMask |= BackButtonStartPart;
75 backButtonEndPaintRect = backButtonRect(scrollbar, BackButtonEndPart, tr ue);
76 if (damageRect.intersects(backButtonEndPaintRect))
77 scrollMask |= BackButtonEndPart;
78 forwardButtonStartPaintRect = forwardButtonRect(scrollbar, ForwardButton StartPart, true);
79 if (damageRect.intersects(forwardButtonStartPaintRect))
80 scrollMask |= ForwardButtonStartPart;
81 forwardButtonEndPaintRect = forwardButtonRect(scrollbar, ForwardButtonEn dPart, true);
82 if (damageRect.intersects(forwardButtonEndPaintRect))
83 scrollMask |= ForwardButtonEndPart;
84 }
85
86 IntRect startTrackRect;
87 IntRect thumbRect;
88 IntRect endTrackRect;
89 IntRect trackPaintRect = trackRect(scrollbar, true);
90 if (damageRect.intersects(trackPaintRect))
91 scrollMask |= TrackBGPart;
92 bool thumbPresent = hasThumb(scrollbar);
93 if (thumbPresent) {
94 IntRect track = trackRect(scrollbar);
95 splitTrack(scrollbar, track, startTrackRect, thumbRect, endTrackRect);
96 if (damageRect.intersects(thumbRect))
97 scrollMask |= ThumbPart;
98 if (damageRect.intersects(startTrackRect))
99 scrollMask |= BackTrackPart;
100 if (damageRect.intersects(endTrackRect))
101 scrollMask |= ForwardTrackPart;
102 }
103
104 // Paint the scrollbar background (only used by custom CSS scrollbars).
105 paintScrollbarBackground(graphicsContext, scrollbar);
106
107 // Paint the back and forward buttons.
108 if (scrollMask & BackButtonStartPart)
109 paintButton(graphicsContext, scrollbar, backButtonStartPaintRect, BackBu ttonStartPart);
110 if (scrollMask & BackButtonEndPart)
111 paintButton(graphicsContext, scrollbar, backButtonEndPaintRect, BackButt onEndPart);
112 if (scrollMask & ForwardButtonStartPart)
113 paintButton(graphicsContext, scrollbar, forwardButtonStartPaintRect, For wardButtonStartPart);
114 if (scrollMask & ForwardButtonEndPart)
115 paintButton(graphicsContext, scrollbar, forwardButtonEndPaintRect, Forwa rdButtonEndPart);
116
117 if (scrollMask & TrackBGPart)
118 paintTrackBackground(graphicsContext, scrollbar, trackPaintRect);
119
120 if ((scrollMask & ForwardTrackPart) || (scrollMask & BackTrackPart)) {
121 // Paint the track pieces above and below the thumb.
122 if (scrollMask & BackTrackPart)
123 paintTrackPiece(graphicsContext, scrollbar, startTrackRect, BackTrac kPart);
124 if (scrollMask & ForwardTrackPart)
125 paintTrackPiece(graphicsContext, scrollbar, endTrackRect, ForwardTra ckPart);
126
127 paintTickmarks(graphicsContext, scrollbar, trackPaintRect);
128 }
129
130 // Paint the thumb.
131 if (scrollMask & ThumbPart)
132 paintThumb(graphicsContext, scrollbar, thumbRect);
133
134 return true;
135 }
136
137 ScrollbarPart ScrollbarTheme::hitTest(ScrollbarThemeClient* scrollbar, const Int Point& position)
138 {
139 ScrollbarPart result = NoPart;
140 if (!scrollbar->enabled())
141 return result;
142
143 IntPoint testPosition = scrollbar->convertFromContainingWindow(position);
144 testPosition.move(scrollbar->x(), scrollbar->y());
145
146 if (!scrollbar->frameRect().contains(testPosition))
147 return NoPart;
148
149 result = ScrollbarBGPart;
150
151 IntRect track = trackRect(scrollbar);
152 if (track.contains(testPosition)) {
153 IntRect beforeThumbRect;
154 IntRect thumbRect;
155 IntRect afterThumbRect;
156 splitTrack(scrollbar, track, beforeThumbRect, thumbRect, afterThumbRect) ;
157 if (thumbRect.contains(testPosition))
158 result = ThumbPart;
159 else if (beforeThumbRect.contains(testPosition))
160 result = BackTrackPart;
161 else if (afterThumbRect.contains(testPosition))
162 result = ForwardTrackPart;
163 else
164 result = TrackBGPart;
165 } else if (backButtonRect(scrollbar, BackButtonStartPart).contains(testPosit ion)) {
166 result = BackButtonStartPart;
167 } else if (backButtonRect(scrollbar, BackButtonEndPart).contains(testPositio n)) {
168 result = BackButtonEndPart;
169 } else if (forwardButtonRect(scrollbar, ForwardButtonStartPart).contains(tes tPosition)) {
170 result = ForwardButtonStartPart;
171 } else if (forwardButtonRect(scrollbar, ForwardButtonEndPart).contains(testP osition)) {
172 result = ForwardButtonEndPart;
173 }
174 return result;
175 }
176
177 void ScrollbarTheme::invalidatePart(ScrollbarThemeClient* scrollbar, ScrollbarPa rt part)
178 {
179 if (part == NoPart)
180 return;
181
182 IntRect result;
183 switch (part) {
184 case BackButtonStartPart:
185 result = backButtonRect(scrollbar, BackButtonStartPart, true);
186 break;
187 case BackButtonEndPart:
188 result = backButtonRect(scrollbar, BackButtonEndPart, true);
189 break;
190 case ForwardButtonStartPart:
191 result = forwardButtonRect(scrollbar, ForwardButtonStartPart, true);
192 break;
193 case ForwardButtonEndPart:
194 result = forwardButtonRect(scrollbar, ForwardButtonEndPart, true);
195 break;
196 case TrackBGPart:
197 result = trackRect(scrollbar, true);
198 break;
199 case ScrollbarBGPart:
200 result = scrollbar->frameRect();
201 break;
202 default: {
203 IntRect beforeThumbRect, thumbRect, afterThumbRect;
204 splitTrack(scrollbar, trackRect(scrollbar), beforeThumbRect, thumbRect, afterThumbRect);
205 if (part == BackTrackPart)
206 result = beforeThumbRect;
207 else if (part == ForwardTrackPart)
208 result = afterThumbRect;
209 else
210 result = thumbRect;
211 }
212 }
213 result.moveBy(-scrollbar->location());
214 scrollbar->invalidateRect(result);
215 }
216
217 void ScrollbarTheme::splitTrack(ScrollbarThemeClient* scrollbar, const IntRect& unconstrainedTrackRect, IntRect& beforeThumbRect, IntRect& thumbRect, IntRect& a fterThumbRect)
218 {
219 // This function won't even get called unless we're big enough to have some combination of these three rects where at least
220 // one of them is non-empty.
221 IntRect trackRect = constrainTrackRectToTrackPieces(scrollbar, unconstrained TrackRect);
222 int thumbPos = thumbPosition(scrollbar);
223 if (scrollbar->orientation() == HorizontalScrollbar) {
224 thumbRect = IntRect(trackRect.x() + thumbPos, trackRect.y(), thumbLength (scrollbar), scrollbar->height());
225 beforeThumbRect = IntRect(trackRect.x(), trackRect.y(), thumbPos + thumb Rect.width() / 2, trackRect.height());
226 afterThumbRect = IntRect(trackRect.x() + beforeThumbRect.width(), trackR ect.y(), trackRect.maxX() - beforeThumbRect.maxX(), trackRect.height());
227 } else {
228 thumbRect = IntRect(trackRect.x(), trackRect.y() + thumbPos, scrollbar-> width(), thumbLength(scrollbar));
229 beforeThumbRect = IntRect(trackRect.x(), trackRect.y(), trackRect.width( ), thumbPos + thumbRect.height() / 2);
230 afterThumbRect = IntRect(trackRect.x(), trackRect.y() + beforeThumbRect. height(), trackRect.width(), trackRect.maxY() - beforeThumbRect.maxY());
231 }
232 }
233
234 // Returns the size represented by track taking into account scrolling past
235 // the end of the document.
236 static float usedTotalSize(ScrollbarThemeClient* scrollbar)
237 {
238 float overhangAtStart = -scrollbar->currentPos();
239 float overhangAtEnd = scrollbar->currentPos() + scrollbar->visibleSize() - s crollbar->totalSize();
240 float overhang = std::max(0.0f, std::max(overhangAtStart, overhangAtEnd));
241 return scrollbar->totalSize() + overhang;
242 }
243
244 int ScrollbarTheme::thumbPosition(ScrollbarThemeClient* scrollbar)
245 {
246 if (scrollbar->enabled()) {
247 float size = usedTotalSize(scrollbar) - scrollbar->visibleSize();
248 // Avoid doing a floating point divide by zero and return 1 when usedTot alSize == visibleSize.
249 if (!size)
250 return 1;
251 float pos = std::max(0.0f, scrollbar->currentPos()) * (trackLength(scrol lbar) - thumbLength(scrollbar)) / size;
252 return (pos < 1 && pos > 0) ? 1 : pos;
253 }
254 return 0;
255 }
256
257 int ScrollbarTheme::thumbLength(ScrollbarThemeClient* scrollbar)
258 {
259 if (!scrollbar->enabled())
260 return 0;
261
262 float overhang = 0;
263 if (scrollbar->currentPos() < 0)
264 overhang = -scrollbar->currentPos();
265 else if (scrollbar->visibleSize() + scrollbar->currentPos() > scrollbar->tot alSize())
266 overhang = scrollbar->currentPos() + scrollbar->visibleSize() - scrollba r->totalSize();
267 float proportion = (scrollbar->visibleSize() - overhang) / usedTotalSize(scr ollbar);
268 int trackLen = trackLength(scrollbar);
269 int length = round(proportion * trackLen);
270 length = std::max(length, minimumThumbLength(scrollbar));
271 if (length > trackLen)
272 length = 0; // Once the thumb is below the track length, it just goes aw ay (to make more room for the track).
273 return length;
274 }
275
276 int ScrollbarTheme::minimumThumbLength(ScrollbarThemeClient* scrollbar)
277 {
278 return scrollbarThickness(scrollbar->controlSize());
279 }
280
281 int ScrollbarTheme::trackPosition(ScrollbarThemeClient* scrollbar)
282 {
283 IntRect constrainedTrackRect = constrainTrackRectToTrackPieces(scrollbar, tr ackRect(scrollbar));
284 return (scrollbar->orientation() == HorizontalScrollbar) ? constrainedTrackR ect.x() - scrollbar->x() : constrainedTrackRect.y() - scrollbar->y();
285 }
286
287 int ScrollbarTheme::trackLength(ScrollbarThemeClient* scrollbar)
288 {
289 IntRect constrainedTrackRect = constrainTrackRectToTrackPieces(scrollbar, tr ackRect(scrollbar));
290 return (scrollbar->orientation() == HorizontalScrollbar) ? constrainedTrackR ect.width() : constrainedTrackRect.height();
291 }
292
293 void ScrollbarTheme::paintScrollCorner(GraphicsContext* context, const IntRect& cornerRect)
294 {
295 context->fillRect(cornerRect, Color::white);
296 }
297
298 IntRect ScrollbarTheme::thumbRect(ScrollbarThemeClient* scrollbar)
299 {
300 if (!hasThumb(scrollbar))
301 return IntRect();
302
303 IntRect track = trackRect(scrollbar);
304 IntRect startTrackRect;
305 IntRect thumbRect;
306 IntRect endTrackRect;
307 splitTrack(scrollbar, track, startTrackRect, thumbRect, endTrackRect);
308
309 return thumbRect;
310 }
311
312 int ScrollbarTheme::thumbThickness(ScrollbarThemeClient* scrollbar)
313 {
314 IntRect track = trackRect(scrollbar);
315 return scrollbar->orientation() == HorizontalScrollbar ? track.height() : tr ack.width();
316 }
317
318 void ScrollbarTheme::paintOverhangBackground(GraphicsContext* context, const Int Rect& horizontalOverhangRect, const IntRect& verticalOverhangRect, const IntRect & dirtyRect)
319 {
320 context->setFillColor(Color::white);
321 if (!horizontalOverhangRect.isEmpty())
322 context->fillRect(intersection(horizontalOverhangRect, dirtyRect));
323 if (!verticalOverhangRect.isEmpty())
324 context->fillRect(intersection(verticalOverhangRect, dirtyRect));
325 }
326
327 }
OLDNEW
« no previous file with comments | « Source/core/platform/ScrollbarTheme.h ('k') | Source/core/platform/ScrollbarThemeAndroid.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698