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

Side by Side Diff: Source/core/platform/ScrollbarThemeMacNonOverlayAPI.mm

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
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2013 Google 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 are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32 #include "core/platform/ScrollbarThemeMacNonOverlayAPI.h"
33
34 #include <Carbon/Carbon.h>
35 #include "platform/scroll/ScrollbarThemeClient.h"
36 #include "public/platform/mac/WebThemeEngine.h"
37 #include "public/platform/Platform.h"
38 #include "public/platform/WebRect.h"
39 #include "skia/ext/skia_utils_mac.h"
40
41 namespace WebCore {
42
43 // FIXME: Get these numbers from CoreUI.
44 static int cRealButtonLength[] = { 28, 21 };
45 static int cButtonHitInset[] = { 3, 2 };
46 // cRealButtonLength - cButtonInset
47 static int cButtonLength[] = { 14, 10 };
48 static int cScrollbarThickness[] = { 15, 11 };
49 static int cButtonInset[] = { 14, 11 };
50 static int cThumbMinLength[] = { 26, 20 };
51
52 static int cOuterButtonLength[] = { 16, 14 }; // The outer button in a double bu tton pair is a bit bigger.
53 static int cOuterButtonOverlap = 2;
54
55 static ScrollbarButtonsPlacement gButtonPlacement = ScrollbarButtonsDoubleEnd;
56
57 void ScrollbarThemeMacNonOverlayAPI::updateButtonPlacement()
58 {
59 NSString *buttonPlacement = [[NSUserDefaults standardUserDefaults] objectFor Key:@"AppleScrollBarVariant"];
60 if ([buttonPlacement isEqualToString:@"Single"])
61 gButtonPlacement = ScrollbarButtonsSingle;
62 else if ([buttonPlacement isEqualToString:@"DoubleMin"])
63 gButtonPlacement = ScrollbarButtonsDoubleStart;
64 else if ([buttonPlacement isEqualToString:@"DoubleBoth"])
65 gButtonPlacement = ScrollbarButtonsDoubleBoth;
66 else {
67 gButtonPlacement = ScrollbarButtonsDoubleEnd;
68 }
69 }
70
71 static blink::WebThemeEngine::State scrollbarStateToThemeState(ScrollbarThemeCli ent* scrollbar)
72 {
73 if (!scrollbar->enabled())
74 return blink::WebThemeEngine::StateDisabled;
75 if (!scrollbar->isScrollableAreaActive())
76 return blink::WebThemeEngine::StateInactive;
77 if (scrollbar->pressedPart() == ThumbPart)
78 return blink::WebThemeEngine::StatePressed;
79
80 return blink::WebThemeEngine::StateActive;
81 }
82
83 // Override ScrollbarThemeMacCommon::paint() to add support for the following:
84 // - drawing using WebThemeEngine functions
85 // - drawing tickmarks
86 // - Skia specific changes
87 bool ScrollbarThemeMacNonOverlayAPI::paint(ScrollbarThemeClient* scrollbar, Grap hicsContext* context, const IntRect& damageRect)
88 {
89 // Get the tickmarks for the frameview.
90 Vector<IntRect> tickmarks;
91 scrollbar->getTickmarks(tickmarks);
92
93 HIThemeTrackDrawInfo trackInfo;
94 trackInfo.version = 0;
95 trackInfo.kind = scrollbar->controlSize() == RegularScrollbar ? kThemeMedium ScrollBar : kThemeSmallScrollBar;
96 trackInfo.bounds = scrollbar->frameRect();
97 trackInfo.min = 0;
98 trackInfo.max = scrollbar->maximum();
99 trackInfo.value = scrollbar->currentPos();
100 trackInfo.trackInfo.scrollbar.viewsize = scrollbar->visibleSize();
101 trackInfo.attributes = 0;
102 if (scrollbar->orientation() == HorizontalScrollbar)
103 trackInfo.attributes |= kThemeTrackHorizontal;
104
105 if (!scrollbar->enabled())
106 trackInfo.enableState = kThemeTrackDisabled;
107 else
108 trackInfo.enableState = scrollbar->isScrollableAreaActive() ? kThemeTrac kActive : kThemeTrackInactive;
109
110 if (!hasButtons(scrollbar))
111 trackInfo.enableState = kThemeTrackNothingToScroll;
112 trackInfo.trackInfo.scrollbar.pressState = scrollbarPartToHIPressedState(scr ollbar->pressedPart());
113
114 SkCanvas* canvas = context->canvas();
115 CGAffineTransform currentCTM = gfx::SkMatrixToCGAffineTransform(canvas->getT otalMatrix());
116
117 // The Aqua scrollbar is buggy when rotated and scaled. We will just draw i nto a bitmap if we detect a scale or rotation.
118 bool canDrawDirectly = currentCTM.a == 1.0f && currentCTM.b == 0.0f && curre ntCTM.c == 0.0f && (currentCTM.d == 1.0f || currentCTM.d == -1.0f);
119 GraphicsContext* drawingContext = context;
120 OwnPtr<ImageBuffer> imageBuffer;
121 if (!canDrawDirectly) {
122 trackInfo.bounds = IntRect(IntPoint(), scrollbar->frameRect().size());
123
124 IntRect bufferRect(scrollbar->frameRect());
125 bufferRect.intersect(damageRect);
126 bufferRect.move(-scrollbar->frameRect().x(), -scrollbar->frameRect().y() );
127
128 imageBuffer = ImageBuffer::create(bufferRect.size());
129 if (!imageBuffer)
130 return true;
131
132 drawingContext = imageBuffer->context();
133 }
134
135 // Draw thumbless.
136 gfx::SkiaBitLocker bitLocker(drawingContext->canvas());
137 CGContextRef cgContext = bitLocker.cgContext();
138 HIThemeDrawTrack(&trackInfo, 0, cgContext, kHIThemeOrientationNormal);
139
140 IntRect tickmarkTrackRect = trackRect(scrollbar, false);
141 if (!canDrawDirectly) {
142 tickmarkTrackRect.setX(0);
143 tickmarkTrackRect.setY(0);
144 }
145 // The ends are rounded and the thumb doesn't go there.
146 tickmarkTrackRect.inflateY(-tickmarkTrackRect.width());
147 // Inset a bit.
148 tickmarkTrackRect.setX(tickmarkTrackRect.x() + 2);
149 tickmarkTrackRect.setWidth(tickmarkTrackRect.width() - 5);
150 paintGivenTickmarks(drawingContext, scrollbar, tickmarkTrackRect, tickmarks) ;
151
152 if (hasThumb(scrollbar)) {
153 blink::WebThemeEngine::ScrollbarInfo scrollbarInfo;
154 scrollbarInfo.orientation = scrollbar->orientation() == HorizontalScroll bar ? blink::WebThemeEngine::ScrollbarOrientationHorizontal : blink::WebThemeEng ine::ScrollbarOrientationVertical;
155 scrollbarInfo.parent = scrollbar->isScrollViewScrollbar() ? blink::WebTh emeEngine::ScrollbarParentScrollView : blink::WebThemeEngine::ScrollbarParentRen derLayer;
156 scrollbarInfo.maxValue = scrollbar->maximum();
157 scrollbarInfo.currentValue = scrollbar->currentPos();
158 scrollbarInfo.visibleSize = scrollbar->visibleSize();
159 scrollbarInfo.totalSize = scrollbar->totalSize();
160
161 blink::WebCanvas* webCanvas = drawingContext->canvas();
162 blink::Platform::current()->themeEngine()->paintScrollbarThumb(
163 webCanvas,
164 scrollbarStateToThemeState(scrollbar),
165 scrollbar->controlSize() == RegularScrollbar ? blink::WebThemeEngine ::SizeRegular : blink::WebThemeEngine::SizeSmall,
166 blink::WebRect(scrollbar->frameRect()),
167 scrollbarInfo);
168 }
169
170 if (!canDrawDirectly)
171 context->drawImageBuffer(imageBuffer.get(), scrollbar->frameRect().locat ion());
172
173 return true;
174 }
175
176 int ScrollbarThemeMacNonOverlayAPI::scrollbarThickness(ScrollbarControlSize cont rolSize)
177 {
178 return cScrollbarThickness[controlSize];
179 }
180
181 ScrollbarButtonsPlacement ScrollbarThemeMacNonOverlayAPI::buttonsPlacement() con st
182 {
183 return gButtonPlacement;
184 }
185
186 bool ScrollbarThemeMacNonOverlayAPI::hasButtons(ScrollbarThemeClient* scrollbar)
187 {
188 return scrollbar->enabled() && buttonsPlacement() != ScrollbarButtonsNone
189 && (scrollbar->orientation() == HorizontalScrollbar
190 ? scrollbar->width()
191 : scrollbar->height()) >= 2 * (cRealButtonLength[scrollbar->control Size()] - cButtonHitInset[scrollbar->controlSize()]);
192 }
193
194 bool ScrollbarThemeMacNonOverlayAPI::hasThumb(ScrollbarThemeClient* scrollbar)
195 {
196 int minLengthForThumb = 2 * cButtonInset[scrollbar->controlSize()] + cThumbM inLength[scrollbar->controlSize()] + 1;
197 return scrollbar->enabled() && (scrollbar->orientation() == HorizontalScroll bar ?
198 scrollbar->width() :
199 scrollbar->height()) >= minLengthForThumb;
200 }
201
202 static IntRect buttonRepaintRect(const IntRect& buttonRect, ScrollbarOrientation orientation, ScrollbarControlSize controlSize, bool start)
203 {
204 ASSERT(gButtonPlacement != ScrollbarButtonsNone);
205
206 IntRect paintRect(buttonRect);
207 if (orientation == HorizontalScrollbar) {
208 paintRect.setWidth(cRealButtonLength[controlSize]);
209 if (!start)
210 paintRect.setX(buttonRect.x() - (cRealButtonLength[controlSize] - bu ttonRect.width()));
211 } else {
212 paintRect.setHeight(cRealButtonLength[controlSize]);
213 if (!start)
214 paintRect.setY(buttonRect.y() - (cRealButtonLength[controlSize] - bu ttonRect.height()));
215 }
216
217 return paintRect;
218 }
219
220 IntRect ScrollbarThemeMacNonOverlayAPI::backButtonRect(ScrollbarThemeClient* scr ollbar, ScrollbarPart part, bool painting)
221 {
222 IntRect result;
223
224 if (part == BackButtonStartPart && (buttonsPlacement() == ScrollbarButtonsNo ne || buttonsPlacement() == ScrollbarButtonsDoubleEnd))
225 return result;
226
227 if (part == BackButtonEndPart && (buttonsPlacement() == ScrollbarButtonsNone || buttonsPlacement() == ScrollbarButtonsDoubleStart || buttonsPlacement() == S crollbarButtonsSingle))
228 return result;
229
230 int thickness = scrollbarThickness(scrollbar->controlSize());
231 bool outerButton = part == BackButtonStartPart && (buttonsPlacement() == Scr ollbarButtonsDoubleStart || buttonsPlacement() == ScrollbarButtonsDoubleBoth);
232 if (outerButton) {
233 if (scrollbar->orientation() == HorizontalScrollbar)
234 result = IntRect(scrollbar->x(), scrollbar->y(), cOuterButtonLength[ scrollbar->controlSize()] + (painting ? cOuterButtonOverlap : 0), thickness);
235 else
236 result = IntRect(scrollbar->x(), scrollbar->y(), thickness, cOuterBu ttonLength[scrollbar->controlSize()] + (painting ? cOuterButtonOverlap : 0));
237 return result;
238 }
239
240 // Our repaint rect is slightly larger, since we are a button that is adjace nt to the track.
241 if (scrollbar->orientation() == HorizontalScrollbar) {
242 int start = part == BackButtonStartPart ? scrollbar->x() : scrollbar->x( ) + scrollbar->width() - cOuterButtonLength[scrollbar->controlSize()] - cButtonL ength[scrollbar->controlSize()];
243 result = IntRect(start, scrollbar->y(), cButtonLength[scrollbar->control Size()], thickness);
244 } else {
245 int start = part == BackButtonStartPart ? scrollbar->y() : scrollbar->y( ) + scrollbar->height() - cOuterButtonLength[scrollbar->controlSize()] - cButton Length[scrollbar->controlSize()];
246 result = IntRect(scrollbar->x(), start, thickness, cButtonLength[scrollb ar->controlSize()]);
247 }
248
249 if (painting)
250 return buttonRepaintRect(result, scrollbar->orientation(), scrollbar->co ntrolSize(), part == BackButtonStartPart);
251 return result;
252 }
253
254 IntRect ScrollbarThemeMacNonOverlayAPI::forwardButtonRect(ScrollbarThemeClient* scrollbar, ScrollbarPart part, bool painting)
255 {
256 IntRect result;
257
258 if (part == ForwardButtonEndPart && (buttonsPlacement() == ScrollbarButtonsN one || buttonsPlacement() == ScrollbarButtonsDoubleStart))
259 return result;
260
261 if (part == ForwardButtonStartPart && (buttonsPlacement() == ScrollbarButton sNone || buttonsPlacement() == ScrollbarButtonsDoubleEnd || buttonsPlacement() = = ScrollbarButtonsSingle))
262 return result;
263
264 int thickness = scrollbarThickness(scrollbar->controlSize());
265 int outerButtonLength = cOuterButtonLength[scrollbar->controlSize()];
266 int buttonLength = cButtonLength[scrollbar->controlSize()];
267
268 bool outerButton = part == ForwardButtonEndPart && (buttonsPlacement() == Sc rollbarButtonsDoubleEnd || buttonsPlacement() == ScrollbarButtonsDoubleBoth);
269 if (outerButton) {
270 if (scrollbar->orientation() == HorizontalScrollbar) {
271 result = IntRect(scrollbar->x() + scrollbar->width() - outerButtonLe ngth, scrollbar->y(), outerButtonLength, thickness);
272 if (painting)
273 result.inflateX(cOuterButtonOverlap);
274 } else {
275 result = IntRect(scrollbar->x(), scrollbar->y() + scrollbar->height( ) - outerButtonLength, thickness, outerButtonLength);
276 if (painting)
277 result.inflateY(cOuterButtonOverlap);
278 }
279 return result;
280 }
281
282 if (scrollbar->orientation() == HorizontalScrollbar) {
283 int start = part == ForwardButtonEndPart ? scrollbar->x() + scrollbar->w idth() - buttonLength : scrollbar->x() + outerButtonLength;
284 result = IntRect(start, scrollbar->y(), buttonLength, thickness);
285 } else {
286 int start = part == ForwardButtonEndPart ? scrollbar->y() + scrollbar->h eight() - buttonLength : scrollbar->y() + outerButtonLength;
287 result = IntRect(scrollbar->x(), start, thickness, buttonLength);
288 }
289 if (painting)
290 return buttonRepaintRect(result, scrollbar->orientation(), scrollbar->co ntrolSize(), part == ForwardButtonStartPart);
291 return result;
292 }
293
294 IntRect ScrollbarThemeMacNonOverlayAPI::trackRect(ScrollbarThemeClient* scrollba r, bool painting)
295 {
296 if (painting || !hasButtons(scrollbar))
297 return scrollbar->frameRect();
298
299 IntRect result;
300 int thickness = scrollbarThickness(scrollbar->controlSize());
301 int startWidth = 0;
302 int endWidth = 0;
303 int outerButtonLength = cOuterButtonLength[scrollbar->controlSize()];
304 int buttonLength = cButtonLength[scrollbar->controlSize()];
305 int doubleButtonLength = outerButtonLength + buttonLength;
306 switch (buttonsPlacement()) {
307 case ScrollbarButtonsSingle:
308 startWidth = buttonLength;
309 endWidth = buttonLength;
310 break;
311 case ScrollbarButtonsDoubleStart:
312 startWidth = doubleButtonLength;
313 break;
314 case ScrollbarButtonsDoubleEnd:
315 endWidth = doubleButtonLength;
316 break;
317 case ScrollbarButtonsDoubleBoth:
318 startWidth = doubleButtonLength;
319 endWidth = doubleButtonLength;
320 break;
321 default:
322 break;
323 }
324
325 int totalWidth = startWidth + endWidth;
326 if (scrollbar->orientation() == HorizontalScrollbar)
327 return IntRect(scrollbar->x() + startWidth, scrollbar->y(), scrollbar->w idth() - totalWidth, thickness);
328 return IntRect(scrollbar->x(), scrollbar->y() + startWidth, thickness, scrol lbar->height() - totalWidth);
329 }
330
331 int ScrollbarThemeMacNonOverlayAPI::minimumThumbLength(ScrollbarThemeClient* scr ollbar)
332 {
333 return cThumbMinLength[scrollbar->controlSize()];
334 }
335
336 }
OLDNEW
« no previous file with comments | « Source/core/platform/ScrollbarThemeMacNonOverlayAPI.h ('k') | Source/core/platform/ScrollbarThemeMacOverlayAPI.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698