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

Side by Side Diff: Source/platform/mac/ThemeMac.mm

Issue 488353003: Specify clip rects when drawing Mac native widgets (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 6 years, 4 months 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008, 2010, 2011, 2012 Apple Inc. All Rights Reserved. 2 * Copyright (C) 2008, 2010, 2011, 2012 Apple Inc. All Rights Reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 if ([[self familyName] hasPrefix:@"."]) 84 if ([[self familyName] hasPrefix:@"."])
85 return [self fontName]; 85 return [self fontName];
86 86
87 return [self familyName]; 87 return [self familyName];
88 } 88 }
89 89
90 @end 90 @end
91 91
92 namespace blink { 92 namespace blink {
93 93
94 enum {
95 topMargin,
96 rightMargin,
97 bottomMargin,
98 leftMargin
99 };
100
101 Theme* platformTheme() 94 Theme* platformTheme()
102 { 95 {
103 DEFINE_STATIC_LOCAL(ThemeMac, themeMac, ()); 96 DEFINE_STATIC_LOCAL(ThemeMac, themeMac, ());
104 return &themeMac; 97 return &themeMac;
105 } 98 }
106 99
107 // Helper functions used by a bunch of different control parts. 100 // Helper functions used by a bunch of different control parts.
108 101
109 static NSControlSize controlSizeForFont(const FontDescription& fontDescription) 102 static NSControlSize controlSizeForFont(const FontDescription& fontDescription)
110 { 103 {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
197 190
198 // Do not process PressedState if !EnabledControlState or ReadOnlyControlSta te. 191 // Do not process PressedState if !EnabledControlState or ReadOnlyControlSta te.
199 if (states & PressedControlState) { 192 if (states & PressedControlState) {
200 if (kind == kThemeIncDecButton || kind == kThemeIncDecButtonSmall || kin d == kThemeIncDecButtonMini) 193 if (kind == kThemeIncDecButton || kind == kThemeIncDecButtonSmall || kin d == kThemeIncDecButtonMini)
201 return states & SpinUpControlState ? kThemeStatePressedUp : kThemeSt atePressedDown; 194 return states & SpinUpControlState ? kThemeStatePressedUp : kThemeSt atePressedDown;
202 return kThemeStatePressed; 195 return kThemeStatePressed;
203 } 196 }
204 return kThemeStateActive; 197 return kThemeStateActive;
205 } 198 }
206 199
207 static IntRect inflateRect(const IntRect& zoomedRect, const IntSize& zoomedSize, const int* margins, float zoomFactor) 200 // static
201 IntRect ThemeMac::inflateRect(const IntRect& zoomedRect, const IntSize& zoomedSi ze, const int* margins, float zoomFactor)
208 { 202 {
209 // Only do the inflation if the available width/height are too small. Other wise try to 203 // Only do the inflation if the available width/height are too small. Other wise try to
210 // fit the glow/check space into the available box's width/height. 204 // fit the glow/check space into the available box's width/height.
211 int widthDelta = zoomedRect.width() - (zoomedSize.width() + margins[leftMarg in] * zoomFactor + margins[rightMargin] * zoomFactor); 205 int widthDelta = zoomedRect.width() - (zoomedSize.width() + margins[LeftMarg in] * zoomFactor + margins[RightMargin] * zoomFactor);
212 int heightDelta = zoomedRect.height() - (zoomedSize.height() + margins[topMa rgin] * zoomFactor + margins[bottomMargin] * zoomFactor); 206 int heightDelta = zoomedRect.height() - (zoomedSize.height() + margins[TopMa rgin] * zoomFactor + margins[BottomMargin] * zoomFactor);
213 IntRect result(zoomedRect); 207 IntRect result(zoomedRect);
214 if (widthDelta < 0) { 208 if (widthDelta < 0) {
215 result.setX(result.x() - margins[leftMargin] * zoomFactor); 209 result.setX(result.x() - margins[LeftMargin] * zoomFactor);
216 result.setWidth(result.width() - widthDelta); 210 result.setWidth(result.width() - widthDelta);
217 } 211 }
218 if (heightDelta < 0) { 212 if (heightDelta < 0) {
219 result.setY(result.y() - margins[topMargin] * zoomFactor); 213 result.setY(result.y() - margins[TopMargin] * zoomFactor);
220 result.setHeight(result.height() - heightDelta); 214 result.setHeight(result.height() - heightDelta);
221 } 215 }
222 return result; 216 return result;
223 } 217 }
224 218
219 // static
220 IntRect ThemeMac::inflateRectForFocusRing(const IntRect& rect) {
221 #if BUTTON_CELL_DRAW_WITH_FRAME_DRAWS_FOCUS_RING
222 // Just put a margin of 16 units around the rect. The UI elements that use t his don't appropriately
223 // scale their focus rings appropriately (e.g, paint pickers), or switch to non-native widgets when
224 // scaled (e.g, check boxes and radio buttons).
225 const int margin = 16;
226 IntRect result;
227 result.setX(rect.x() - margin);
228 result.setY(rect.y() - margin);
229 result.setWidth(rect.width() + 2 * margin);
230 result.setHeight(rect.height() + 2 * margin);
231 return result;
232 #else
233 return rect;
234 #endif
235 }
236
225 // Checkboxes 237 // Checkboxes
226 238
227 static const IntSize* checkboxSizes() 239 static const IntSize* checkboxSizes()
228 { 240 {
229 static const IntSize sizes[3] = { IntSize(14, 14), IntSize(12, 12), IntSize( 10, 10) }; 241 static const IntSize sizes[3] = { IntSize(14, 14), IntSize(12, 12), IntSize( 10, 10) };
230 return sizes; 242 return sizes;
231 } 243 }
232 244
233 static const int* checkboxMargins(NSControlSize controlSize) 245 static const int* checkboxMargins(NSControlSize controlSize)
234 { 246 {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 BEGIN_BLOCK_OBJC_EXCEPTIONS 289 BEGIN_BLOCK_OBJC_EXCEPTIONS
278 290
279 // Determine the width and height needed for the control and prepare the cel l for painting. 291 // Determine the width and height needed for the control and prepare the cel l for painting.
280 NSButtonCell *checkboxCell = checkbox(states, zoomedRect, zoomFactor); 292 NSButtonCell *checkboxCell = checkbox(states, zoomedRect, zoomFactor);
281 GraphicsContextStateSaver stateSaver(*context); 293 GraphicsContextStateSaver stateSaver(*context);
282 294
283 NSControlSize controlSize = [checkboxCell controlSize]; 295 NSControlSize controlSize = [checkboxCell controlSize];
284 IntSize zoomedSize = checkboxSizes()[controlSize]; 296 IntSize zoomedSize = checkboxSizes()[controlSize];
285 zoomedSize.setWidth(zoomedSize.width() * zoomFactor); 297 zoomedSize.setWidth(zoomedSize.width() * zoomFactor);
286 zoomedSize.setHeight(zoomedSize.height() * zoomFactor); 298 zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
287 IntRect inflatedRect = inflateRect(zoomedRect, zoomedSize, checkboxMargins(c ontrolSize), zoomFactor); 299 IntRect inflatedRect = ThemeMac::inflateRect(zoomedRect, zoomedSize, checkbo xMargins(controlSize), zoomFactor);
288 300
289 if (zoomFactor != 1.0f) { 301 if (zoomFactor != 1.0f) {
290 inflatedRect.setWidth(inflatedRect.width() / zoomFactor); 302 inflatedRect.setWidth(inflatedRect.width() / zoomFactor);
291 inflatedRect.setHeight(inflatedRect.height() / zoomFactor); 303 inflatedRect.setHeight(inflatedRect.height() / zoomFactor);
292 context->translate(inflatedRect.x(), inflatedRect.y()); 304 context->translate(inflatedRect.x(), inflatedRect.y());
293 context->scale(zoomFactor, zoomFactor); 305 context->scale(zoomFactor, zoomFactor);
294 context->translate(-inflatedRect.x(), -inflatedRect.y()); 306 context->translate(-inflatedRect.x(), -inflatedRect.y());
295 } 307 }
296 308
297 LocalCurrentGraphicsContext localContext(context); 309 LocalCurrentGraphicsContext localContext(context, ThemeMac::inflateRectForFo cusRing(inflatedRect));
298 NSView *view = ThemeMac::ensuredView(scrollView); 310 NSView *view = ThemeMac::ensuredView(scrollView);
299 [checkboxCell drawWithFrame:NSRect(inflatedRect) inView:view]; 311 [checkboxCell drawWithFrame:NSRect(inflatedRect) inView:view];
300 #if !BUTTON_CELL_DRAW_WITH_FRAME_DRAWS_FOCUS_RING 312 #if !BUTTON_CELL_DRAW_WITH_FRAME_DRAWS_FOCUS_RING
301 if (states & FocusControlState) 313 if (states & FocusControlState)
302 [checkboxCell _web_drawFocusRingWithFrame:NSRect(inflatedRect) inView:vi ew]; 314 [checkboxCell _web_drawFocusRingWithFrame:NSRect(inflatedRect) inView:vi ew];
303 #endif 315 #endif
304 [checkboxCell setControlView:nil]; 316 [checkboxCell setControlView:nil];
305 317
306 END_BLOCK_OBJC_EXCEPTIONS 318 END_BLOCK_OBJC_EXCEPTIONS
307 } 319 }
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 static void paintRadio(ControlStates states, GraphicsContext* context, const Int Rect& zoomedRect, float zoomFactor, ScrollView* scrollView) 369 static void paintRadio(ControlStates states, GraphicsContext* context, const Int Rect& zoomedRect, float zoomFactor, ScrollView* scrollView)
358 { 370 {
359 // Determine the width and height needed for the control and prepare the cel l for painting. 371 // Determine the width and height needed for the control and prepare the cel l for painting.
360 NSButtonCell *radioCell = radio(states, zoomedRect, zoomFactor); 372 NSButtonCell *radioCell = radio(states, zoomedRect, zoomFactor);
361 GraphicsContextStateSaver stateSaver(*context); 373 GraphicsContextStateSaver stateSaver(*context);
362 374
363 NSControlSize controlSize = [radioCell controlSize]; 375 NSControlSize controlSize = [radioCell controlSize];
364 IntSize zoomedSize = radioSizes()[controlSize]; 376 IntSize zoomedSize = radioSizes()[controlSize];
365 zoomedSize.setWidth(zoomedSize.width() * zoomFactor); 377 zoomedSize.setWidth(zoomedSize.width() * zoomFactor);
366 zoomedSize.setHeight(zoomedSize.height() * zoomFactor); 378 zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
367 IntRect inflatedRect = inflateRect(zoomedRect, zoomedSize, radioMargins(cont rolSize), zoomFactor); 379 IntRect inflatedRect = ThemeMac::inflateRect(zoomedRect, zoomedSize, radioMa rgins(controlSize), zoomFactor);
368 380
369 if (zoomFactor != 1.0f) { 381 if (zoomFactor != 1.0f) {
370 inflatedRect.setWidth(inflatedRect.width() / zoomFactor); 382 inflatedRect.setWidth(inflatedRect.width() / zoomFactor);
371 inflatedRect.setHeight(inflatedRect.height() / zoomFactor); 383 inflatedRect.setHeight(inflatedRect.height() / zoomFactor);
372 context->translate(inflatedRect.x(), inflatedRect.y()); 384 context->translate(inflatedRect.x(), inflatedRect.y());
373 context->scale(zoomFactor, zoomFactor); 385 context->scale(zoomFactor, zoomFactor);
374 context->translate(-inflatedRect.x(), -inflatedRect.y()); 386 context->translate(-inflatedRect.x(), -inflatedRect.y());
375 } 387 }
376 388
377 LocalCurrentGraphicsContext localContext(context); 389 LocalCurrentGraphicsContext localContext(context, ThemeMac::inflateRectForFo cusRing(inflatedRect));
378 BEGIN_BLOCK_OBJC_EXCEPTIONS 390 BEGIN_BLOCK_OBJC_EXCEPTIONS
379 NSView *view = ThemeMac::ensuredView(scrollView); 391 NSView *view = ThemeMac::ensuredView(scrollView);
380 [radioCell drawWithFrame:NSRect(inflatedRect) inView:view]; 392 [radioCell drawWithFrame:NSRect(inflatedRect) inView:view];
381 #if !BUTTON_CELL_DRAW_WITH_FRAME_DRAWS_FOCUS_RING 393 #if !BUTTON_CELL_DRAW_WITH_FRAME_DRAWS_FOCUS_RING
382 if (states & FocusControlState) 394 if (states & FocusControlState)
383 [radioCell _web_drawFocusRingWithFrame:NSRect(inflatedRect) inView:view] ; 395 [radioCell _web_drawFocusRingWithFrame:NSRect(inflatedRect) inView:view] ;
384 #endif 396 #endif
385 [radioCell setControlView:nil]; 397 [radioCell setControlView:nil];
386 END_BLOCK_OBJC_EXCEPTIONS 398 END_BLOCK_OBJC_EXCEPTIONS
387 } 399 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 zoomedSize.setHeight(zoomedSize.height() * zoomFactor); 461 zoomedSize.setHeight(zoomedSize.height() * zoomFactor);
450 IntRect inflatedRect = zoomedRect; 462 IntRect inflatedRect = zoomedRect;
451 if ([buttonCell bezelStyle] == NSRoundedBezelStyle) { 463 if ([buttonCell bezelStyle] == NSRoundedBezelStyle) {
452 // Center the button within the available space. 464 // Center the button within the available space.
453 if (inflatedRect.height() > zoomedSize.height()) { 465 if (inflatedRect.height() > zoomedSize.height()) {
454 inflatedRect.setY(inflatedRect.y() + (inflatedRect.height() - zoomed Size.height()) / 2); 466 inflatedRect.setY(inflatedRect.y() + (inflatedRect.height() - zoomed Size.height()) / 2);
455 inflatedRect.setHeight(zoomedSize.height()); 467 inflatedRect.setHeight(zoomedSize.height());
456 } 468 }
457 469
458 // Now inflate it to account for the shadow. 470 // Now inflate it to account for the shadow.
459 inflatedRect = inflateRect(inflatedRect, zoomedSize, buttonMargins(contr olSize), zoomFactor); 471 inflatedRect = ThemeMac::inflateRect(inflatedRect, zoomedSize, buttonMar gins(controlSize), zoomFactor);
460 472
461 if (zoomFactor != 1.0f) { 473 if (zoomFactor != 1.0f) {
462 inflatedRect.setWidth(inflatedRect.width() / zoomFactor); 474 inflatedRect.setWidth(inflatedRect.width() / zoomFactor);
463 inflatedRect.setHeight(inflatedRect.height() / zoomFactor); 475 inflatedRect.setHeight(inflatedRect.height() / zoomFactor);
464 context->translate(inflatedRect.x(), inflatedRect.y()); 476 context->translate(inflatedRect.x(), inflatedRect.y());
465 context->scale(zoomFactor, zoomFactor); 477 context->scale(zoomFactor, zoomFactor);
466 context->translate(-inflatedRect.x(), -inflatedRect.y()); 478 context->translate(-inflatedRect.x(), -inflatedRect.y());
467 } 479 }
468 } 480 }
469 481
470 LocalCurrentGraphicsContext localContext(context); 482 LocalCurrentGraphicsContext localContext(context, ThemeMac::inflateRectForFo cusRing(inflatedRect));
471 NSView *view = ThemeMac::ensuredView(scrollView); 483 NSView *view = ThemeMac::ensuredView(scrollView);
472 484
473 [buttonCell drawWithFrame:NSRect(inflatedRect) inView:view]; 485 [buttonCell drawWithFrame:NSRect(inflatedRect) inView:view];
474 #if !BUTTON_CELL_DRAW_WITH_FRAME_DRAWS_FOCUS_RING 486 #if !BUTTON_CELL_DRAW_WITH_FRAME_DRAWS_FOCUS_RING
475 if (states & FocusControlState) 487 if (states & FocusControlState)
476 [buttonCell _web_drawFocusRingWithFrame:NSRect(inflatedRect) inView:view ]; 488 [buttonCell _web_drawFocusRingWithFrame:NSRect(inflatedRect) inView:view ];
477 #endif 489 #endif
478 [buttonCell setControlView:nil]; 490 [buttonCell setControlView:nil];
479 491
480 END_BLOCK_OBJC_EXCEPTIONS 492 END_BLOCK_OBJC_EXCEPTIONS
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 CGRect bounds(rect); 541 CGRect bounds(rect);
530 CGRect backgroundBounds; 542 CGRect backgroundBounds;
531 HIThemeGetButtonBackgroundBounds(&bounds, &drawInfo, &backgroundBounds); 543 HIThemeGetButtonBackgroundBounds(&bounds, &drawInfo, &backgroundBounds);
532 // Center the stepper rectangle in the specified area. 544 // Center the stepper rectangle in the specified area.
533 backgroundBounds.origin.x = bounds.origin.x + (bounds.size.width - backgroun dBounds.size.width) / 2; 545 backgroundBounds.origin.x = bounds.origin.x + (bounds.size.width - backgroun dBounds.size.width) / 2;
534 if (backgroundBounds.size.height < bounds.size.height) { 546 if (backgroundBounds.size.height < bounds.size.height) {
535 int heightDiff = clampToInteger(bounds.size.height - backgroundBounds.si ze.height); 547 int heightDiff = clampToInteger(bounds.size.height - backgroundBounds.si ze.height);
536 backgroundBounds.origin.y = bounds.origin.y + (heightDiff / 2) + 1; 548 backgroundBounds.origin.y = bounds.origin.y + (heightDiff / 2) + 1;
537 } 549 }
538 550
539 LocalCurrentGraphicsContext localContext(context); 551 LocalCurrentGraphicsContext localContext(context, rect);
540 HIThemeDrawButton(&backgroundBounds, &drawInfo, localContext.cgContext(), kH IThemeOrientationNormal, 0); 552 HIThemeDrawButton(&backgroundBounds, &drawInfo, localContext.cgContext(), kH IThemeOrientationNormal, 0);
541 } 553 }
542 554
543 // This will ensure that we always return a valid NSView, even if ScrollView doe sn't have an associated document NSView. 555 // This will ensure that we always return a valid NSView, even if ScrollView doe sn't have an associated document NSView.
544 // If the ScrollView doesn't have an NSView, we will return a fake NSView whose sole purpose is to tell AppKit that it's flipped. 556 // If the ScrollView doesn't have an NSView, we will return a fake NSView whose sole purpose is to tell AppKit that it's flipped.
545 NSView *ThemeMac::ensuredView(ScrollView* scrollView) 557 NSView *ThemeMac::ensuredView(ScrollView* scrollView)
546 { 558 {
547 559
548 // Use a fake flipped view. 560 // Use a fake flipped view.
549 static NSView *flippedView = [[WebCoreFlippedView alloc] init]; 561 static NSView *flippedView = [[WebCoreFlippedView alloc] init];
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 break; 731 break;
720 case InnerSpinButtonPart: 732 case InnerSpinButtonPart:
721 paintStepper(states, context, zoomedRect, zoomFactor, scrollView); 733 paintStepper(states, context, zoomedRect, zoomFactor, scrollView);
722 break; 734 break;
723 default: 735 default:
724 break; 736 break;
725 } 737 }
726 } 738 }
727 739
728 } 740 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698