OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (C) 2008 Apple Inc. All Rights Reserved. |
| 3 * Copyright (C) 2009 Google Inc. All Rights Reserved. |
| 4 * |
| 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions |
| 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright |
| 11 * notice, this list of conditions and the following disclaimer in the |
| 12 * documentation and/or other materials provided with the distribution. |
| 13 * |
| 14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
| 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
| 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 25 */ |
| 26 |
| 27 #import "config.h" |
| 28 #import "ThemeChromiumMac.h" |
| 29 |
| 30 #import "BlockExceptions.h" |
| 31 #import "GraphicsContext.h" |
| 32 #import "LocalCurrentGraphicsContext.h" |
| 33 #import "ScrollView.h" |
| 34 #import "WebCoreSystemInterface.h" |
| 35 #include <wtf/StdLibExtras.h> |
| 36 |
| 37 using namespace std; |
| 38 |
| 39 // This file (and its associated .h file) is a clone of ThemeMac.mm. |
| 40 // Because the original file is designed to run in-process inside a Cocoa view, |
| 41 // we must maintain a fork. Please maintain this file by performing parallel |
| 42 // changes to it. |
| 43 // |
| 44 // The only changes from ThemeMac should be: |
| 45 // - The classname change from ThemeMac to ThemeChromiumMac. |
| 46 // - The import of FlippedView() and its use as the parent view for cell |
| 47 // rendering. |
| 48 // - In updateStates() the code to update the cells' inactive state. |
| 49 // - In paintButton() the code to save/restore the window's default button cell. |
| 50 // |
| 51 // For all other differences, if it was introduced in this file, then the |
| 52 // maintainer forgot to include it in the list; otherwise it is an update that |
| 53 // should have been applied to this file but was not. |
| 54 |
| 55 // FIXME: Default buttons really should be more like push buttons and not like b
uttons. |
| 56 |
| 57 namespace WebCore { |
| 58 |
| 59 // Pick up utility function from RenderThemeChromiumMac. |
| 60 extern NSView* FlippedView(); |
| 61 |
| 62 enum { |
| 63 topMargin, |
| 64 rightMargin, |
| 65 bottomMargin, |
| 66 leftMargin |
| 67 }; |
| 68 |
| 69 Theme* platformTheme() |
| 70 { |
| 71 DEFINE_STATIC_LOCAL(ThemeChromiumMac, themeMac, ()); |
| 72 return &themeMac; |
| 73 } |
| 74 |
| 75 // Helper functions used by a bunch of different control parts. |
| 76 |
| 77 static NSControlSize controlSizeForFont(const Font& font) |
| 78 { |
| 79 int fontSize = font.pixelSize(); |
| 80 if (fontSize >= 16) |
| 81 return NSRegularControlSize; |
| 82 if (fontSize >= 11) |
| 83 return NSSmallControlSize; |
| 84 return NSMiniControlSize; |
| 85 } |
| 86 |
| 87 static LengthSize sizeFromFont(const Font& font, const LengthSize& zoomedSize, f
loat zoomFactor, const IntSize* sizes) |
| 88 { |
| 89 IntSize controlSize = sizes[controlSizeForFont(font)]; |
| 90 if (zoomFactor != 1.0f) |
| 91 controlSize = IntSize(controlSize.width() * zoomFactor, controlSize.heig
ht() * zoomFactor); |
| 92 LengthSize result = zoomedSize; |
| 93 if (zoomedSize.width().isIntrinsicOrAuto() && controlSize.width() > 0) |
| 94 result.setWidth(Length(controlSize.width(), Fixed)); |
| 95 if (zoomedSize.height().isIntrinsicOrAuto() && controlSize.height() > 0) |
| 96 result.setHeight(Length(controlSize.height(), Fixed)); |
| 97 return result; |
| 98 } |
| 99 |
| 100 static void setControlSize(NSCell* cell, const IntSize* sizes, const IntSize& mi
nZoomedSize, float zoomFactor) |
| 101 { |
| 102 NSControlSize size; |
| 103 if (minZoomedSize.width() >= static_cast<int>(sizes[NSRegularControlSize].wi
dth() * zoomFactor) && |
| 104 minZoomedSize.height() >= static_cast<int>(sizes[NSRegularControlSize].h
eight() * zoomFactor)) |
| 105 size = NSRegularControlSize; |
| 106 else if (minZoomedSize.width() >= static_cast<int>(sizes[NSSmallControlSize]
.width() * zoomFactor) && |
| 107 minZoomedSize.height() >= static_cast<int>(sizes[NSSmallControlSize
].height() * zoomFactor)) |
| 108 size = NSSmallControlSize; |
| 109 else |
| 110 size = NSMiniControlSize; |
| 111 if (size != [cell controlSize]) // Only update if we have to, since AppKit d
oes work even if the size is the same. |
| 112 [cell setControlSize:size]; |
| 113 } |
| 114 |
| 115 static void updateStates(NSCell* cell, ControlStates states) |
| 116 { |
| 117 // Hover state is not supported by Aqua. |
| 118 |
| 119 // Pressed state |
| 120 bool oldPressed = [cell isHighlighted]; |
| 121 bool pressed = states & PressedState; |
| 122 if (pressed != oldPressed) |
| 123 [cell setHighlighted:pressed]; |
| 124 |
| 125 // Enabled state |
| 126 bool oldEnabled = [cell isEnabled]; |
| 127 bool enabled = states & EnabledState; |
| 128 if (enabled != oldEnabled) |
| 129 [cell setEnabled:enabled]; |
| 130 |
| 131 // Focused state |
| 132 bool oldFocused = [cell showsFirstResponder]; |
| 133 bool focused = states & FocusState; |
| 134 if (focused != oldFocused) |
| 135 [cell setShowsFirstResponder:focused]; |
| 136 |
| 137 // Checked and Indeterminate |
| 138 bool oldIndeterminate = [cell state] == NSMixedState; |
| 139 bool indeterminate = (states & IndeterminateState); |
| 140 bool checked = states & CheckedState; |
| 141 bool oldChecked = [cell state] == NSOnState; |
| 142 if (oldIndeterminate != indeterminate || checked != oldChecked) |
| 143 [cell setState:indeterminate ? NSMixedState : (checked ? NSOnState : NSO
ffState)]; |
| 144 |
| 145 // Window Inactive state |
| 146 NSControlTint oldTint = [cell controlTint]; |
| 147 bool windowInactive = (states & WindowInactiveState); |
| 148 NSControlTint tint = windowInactive ? NSClearControlTint : [NSColor currentC
ontrolTint]; |
| 149 if (tint != oldTint) |
| 150 [cell setControlTint:tint]; |
| 151 } |
| 152 |
| 153 static IntRect inflateRect(const IntRect& zoomedRect, const IntSize& zoomedSize,
const int* margins, float zoomFactor) |
| 154 { |
| 155 // Only do the inflation if the available width/height are too small. Other
wise try to |
| 156 // fit the glow/check space into the available box's width/height. |
| 157 int widthDelta = zoomedRect.width() - (zoomedSize.width() + margins[leftMarg
in] * zoomFactor + margins[rightMargin] * zoomFactor); |
| 158 int heightDelta = zoomedRect.height() - (zoomedSize.height() + margins[topMa
rgin] * zoomFactor + margins[bottomMargin] * zoomFactor); |
| 159 IntRect result(zoomedRect); |
| 160 if (widthDelta < 0) { |
| 161 result.setX(result.x() - margins[leftMargin] * zoomFactor); |
| 162 result.setWidth(result.width() - widthDelta); |
| 163 } |
| 164 if (heightDelta < 0) { |
| 165 result.setY(result.y() - margins[topMargin] * zoomFactor); |
| 166 result.setHeight(result.height() - heightDelta); |
| 167 } |
| 168 return result; |
| 169 } |
| 170 |
| 171 // Checkboxes |
| 172 |
| 173 static const IntSize* checkboxSizes() |
| 174 { |
| 175 static const IntSize sizes[3] = { IntSize(14, 14), IntSize(12, 12), IntSize(
10, 10) }; |
| 176 return sizes; |
| 177 } |
| 178 |
| 179 static const int* checkboxMargins(NSControlSize controlSize) |
| 180 { |
| 181 static const int margins[3][4] = |
| 182 { |
| 183 { 3, 4, 4, 2 }, |
| 184 { 4, 3, 3, 3 }, |
| 185 { 4, 3, 3, 3 }, |
| 186 }; |
| 187 return margins[controlSize]; |
| 188 } |
| 189 |
| 190 static LengthSize checkboxSize(const Font& font, const LengthSize& zoomedSize, f
loat zoomFactor) |
| 191 { |
| 192 // If the width and height are both specified, then we have nothing to do. |
| 193 if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrin
sicOrAuto()) |
| 194 return zoomedSize; |
| 195 |
| 196 // Use the font size to determine the intrinsic width of the control. |
| 197 return sizeFromFont(font, zoomedSize, zoomFactor, checkboxSizes()); |
| 198 } |
| 199 |
| 200 static NSButtonCell* checkbox(ControlStates states, const IntRect& zoomedRect, f
loat zoomFactor) |
| 201 { |
| 202 static NSButtonCell* checkboxCell; |
| 203 if (!checkboxCell) { |
| 204 checkboxCell = [[NSButtonCell alloc] init]; |
| 205 [checkboxCell setButtonType:NSSwitchButton]; |
| 206 [checkboxCell setTitle:nil]; |
| 207 [checkboxCell setAllowsMixedState:YES]; |
| 208 [checkboxCell setFocusRingType:NSFocusRingTypeExterior]; |
| 209 } |
| 210 |
| 211 // Set the control size based off the rectangle we're painting into. |
| 212 setControlSize(checkboxCell, checkboxSizes(), zoomedRect.size(), zoomFactor)
; |
| 213 |
| 214 // Update the various states we respond to. |
| 215 updateStates(checkboxCell, states); |
| 216 |
| 217 return checkboxCell; |
| 218 } |
| 219 |
| 220 // FIXME: Share more code with radio buttons. |
| 221 static void paintCheckbox(ControlStates states, GraphicsContext* context, const
IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) |
| 222 { |
| 223 BEGIN_BLOCK_OBJC_EXCEPTIONS |
| 224 |
| 225 // Determine the width and height needed for the control and prepare the cel
l for painting. |
| 226 NSButtonCell* checkboxCell = checkbox(states, zoomedRect, zoomFactor); |
| 227 |
| 228 context->save(); |
| 229 |
| 230 NSControlSize controlSize = [checkboxCell controlSize]; |
| 231 IntSize zoomedSize = checkboxSizes()[controlSize]; |
| 232 zoomedSize.setWidth(zoomedSize.width() * zoomFactor); |
| 233 zoomedSize.setHeight(zoomedSize.height() * zoomFactor); |
| 234 IntRect inflatedRect = inflateRect(zoomedRect, zoomedSize, checkboxMargins(c
ontrolSize), zoomFactor); |
| 235 |
| 236 if (zoomFactor != 1.0f) { |
| 237 inflatedRect.setWidth(inflatedRect.width() / zoomFactor); |
| 238 inflatedRect.setHeight(inflatedRect.height() / zoomFactor); |
| 239 context->translate(inflatedRect.x(), inflatedRect.y()); |
| 240 context->scale(FloatSize(zoomFactor, zoomFactor)); |
| 241 context->translate(-inflatedRect.x(), -inflatedRect.y()); |
| 242 } |
| 243 |
| 244 [checkboxCell drawWithFrame:NSRect(inflatedRect) inView:FlippedView()]; |
| 245 [checkboxCell setControlView:nil]; |
| 246 |
| 247 context->restore(); |
| 248 |
| 249 END_BLOCK_OBJC_EXCEPTIONS |
| 250 } |
| 251 |
| 252 // Radio Buttons |
| 253 |
| 254 static const IntSize* radioSizes() |
| 255 { |
| 256 static const IntSize sizes[3] = { IntSize(14, 15), IntSize(12, 13), IntSize(
10, 10) }; |
| 257 return sizes; |
| 258 } |
| 259 |
| 260 static const int* radioMargins(NSControlSize controlSize) |
| 261 { |
| 262 static const int margins[3][4] = |
| 263 { |
| 264 { 2, 2, 4, 2 }, |
| 265 { 3, 2, 3, 2 }, |
| 266 { 1, 0, 2, 0 }, |
| 267 }; |
| 268 return margins[controlSize]; |
| 269 } |
| 270 |
| 271 static LengthSize radioSize(const Font& font, const LengthSize& zoomedSize, floa
t zoomFactor) |
| 272 { |
| 273 // If the width and height are both specified, then we have nothing to do. |
| 274 if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrin
sicOrAuto()) |
| 275 return zoomedSize; |
| 276 |
| 277 // Use the font size to determine the intrinsic width of the control. |
| 278 return sizeFromFont(font, zoomedSize, zoomFactor, radioSizes()); |
| 279 } |
| 280 |
| 281 static NSButtonCell* radio(ControlStates states, const IntRect& zoomedRect, floa
t zoomFactor) |
| 282 { |
| 283 static NSButtonCell* radioCell; |
| 284 if (!radioCell) { |
| 285 radioCell = [[NSButtonCell alloc] init]; |
| 286 [radioCell setButtonType:NSRadioButton]; |
| 287 [radioCell setTitle:nil]; |
| 288 [radioCell setFocusRingType:NSFocusRingTypeExterior]; |
| 289 } |
| 290 |
| 291 // Set the control size based off the rectangle we're painting into. |
| 292 setControlSize(radioCell, radioSizes(), zoomedRect.size(), zoomFactor); |
| 293 |
| 294 // Update the various states we respond to. |
| 295 updateStates(radioCell, states); |
| 296 |
| 297 return radioCell; |
| 298 } |
| 299 |
| 300 static void paintRadio(ControlStates states, GraphicsContext* context, const Int
Rect& zoomedRect, float zoomFactor, ScrollView* scrollView) |
| 301 { |
| 302 // Determine the width and height needed for the control and prepare the cel
l for painting. |
| 303 NSButtonCell* radioCell = radio(states, zoomedRect, zoomFactor); |
| 304 |
| 305 context->save(); |
| 306 |
| 307 NSControlSize controlSize = [radioCell controlSize]; |
| 308 IntSize zoomedSize = radioSizes()[controlSize]; |
| 309 zoomedSize.setWidth(zoomedSize.width() * zoomFactor); |
| 310 zoomedSize.setHeight(zoomedSize.height() * zoomFactor); |
| 311 IntRect inflatedRect = inflateRect(zoomedRect, zoomedSize, radioMargins(cont
rolSize), zoomFactor); |
| 312 |
| 313 if (zoomFactor != 1.0f) { |
| 314 inflatedRect.setWidth(inflatedRect.width() / zoomFactor); |
| 315 inflatedRect.setHeight(inflatedRect.height() / zoomFactor); |
| 316 context->translate(inflatedRect.x(), inflatedRect.y()); |
| 317 context->scale(FloatSize(zoomFactor, zoomFactor)); |
| 318 context->translate(-inflatedRect.x(), -inflatedRect.y()); |
| 319 } |
| 320 |
| 321 BEGIN_BLOCK_OBJC_EXCEPTIONS |
| 322 [radioCell drawWithFrame:NSRect(inflatedRect) inView:FlippedView()]; |
| 323 [radioCell setControlView:nil]; |
| 324 END_BLOCK_OBJC_EXCEPTIONS |
| 325 |
| 326 context->restore(); |
| 327 } |
| 328 |
| 329 // Buttons |
| 330 |
| 331 // Buttons really only constrain height. They respect width. |
| 332 static const IntSize* buttonSizes() |
| 333 { |
| 334 static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0,
15) }; |
| 335 return sizes; |
| 336 } |
| 337 |
| 338 static const int* buttonMargins(NSControlSize controlSize) |
| 339 { |
| 340 static const int margins[3][4] = |
| 341 { |
| 342 { 4, 6, 7, 6 }, |
| 343 { 4, 5, 6, 5 }, |
| 344 { 0, 1, 1, 1 }, |
| 345 }; |
| 346 return margins[controlSize]; |
| 347 } |
| 348 |
| 349 static NSButtonCell* button(ControlPart part, ControlStates states, const IntRec
t& zoomedRect, float zoomFactor) |
| 350 { |
| 351 static NSButtonCell *buttonCell; |
| 352 static bool defaultButton; |
| 353 if (!buttonCell) { |
| 354 buttonCell = [[NSButtonCell alloc] init]; |
| 355 [buttonCell setTitle:nil]; |
| 356 [buttonCell setButtonType:NSMomentaryPushInButton]; |
| 357 } |
| 358 |
| 359 // Set the control size based off the rectangle we're painting into. |
| 360 if (part == SquareButtonPart || zoomedRect.height() > buttonSizes()[NSRegula
rControlSize].height() * zoomFactor) { |
| 361 // Use the square button |
| 362 if ([buttonCell bezelStyle] != NSShadowlessSquareBezelStyle) |
| 363 [buttonCell setBezelStyle:NSShadowlessSquareBezelStyle]; |
| 364 } else if ([buttonCell bezelStyle] != NSRoundedBezelStyle) |
| 365 [buttonCell setBezelStyle:NSRoundedBezelStyle]; |
| 366 |
| 367 setControlSize(buttonCell, buttonSizes(), zoomedRect.size(), zoomFactor); |
| 368 |
| 369 if (defaultButton != (states & DefaultState)) { |
| 370 defaultButton = !defaultButton; |
| 371 [buttonCell setKeyEquivalent:(defaultButton ? @"\r" : @"")]; |
| 372 } |
| 373 |
| 374 // Update the various states we respond to. |
| 375 updateStates(buttonCell, states); |
| 376 |
| 377 return buttonCell; |
| 378 } |
| 379 |
| 380 static void paintButton(ControlPart part, ControlStates states, GraphicsContext*
context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) |
| 381 { |
| 382 BEGIN_BLOCK_OBJC_EXCEPTIONS |
| 383 |
| 384 // Determine the width and height needed for the control and prepare the cel
l for painting. |
| 385 NSButtonCell *buttonCell = button(part, states, zoomedRect, zoomFactor); |
| 386 LocalCurrentGraphicsContext localContext(context); |
| 387 |
| 388 NSControlSize controlSize = [buttonCell controlSize]; |
| 389 IntSize zoomedSize = buttonSizes()[controlSize]; |
| 390 zoomedSize.setWidth(zoomedRect.width()); // Buttons don't ever constrain wid
th, so the zoomed width can just be honored. |
| 391 zoomedSize.setHeight(zoomedSize.height() * zoomFactor); |
| 392 IntRect inflatedRect = zoomedRect; |
| 393 if ([buttonCell bezelStyle] == NSRoundedBezelStyle) { |
| 394 // Center the button within the available space. |
| 395 if (inflatedRect.height() > zoomedSize.height()) { |
| 396 inflatedRect.setY(inflatedRect.y() + (inflatedRect.height() - zoomed
Size.height()) / 2); |
| 397 inflatedRect.setHeight(zoomedSize.height()); |
| 398 } |
| 399 |
| 400 // Now inflate it to account for the shadow. |
| 401 inflatedRect = inflateRect(inflatedRect, zoomedSize, buttonMargins(contr
olSize), zoomFactor); |
| 402 |
| 403 if (zoomFactor != 1.0f) { |
| 404 inflatedRect.setWidth(inflatedRect.width() / zoomFactor); |
| 405 inflatedRect.setHeight(inflatedRect.height() / zoomFactor); |
| 406 context->translate(inflatedRect.x(), inflatedRect.y()); |
| 407 context->scale(FloatSize(zoomFactor, zoomFactor)); |
| 408 context->translate(-inflatedRect.x(), -inflatedRect.y()); |
| 409 } |
| 410 } |
| 411 |
| 412 [buttonCell drawWithFrame:NSRect(inflatedRect) inView:FlippedView()]; |
| 413 [buttonCell setControlView:nil]; |
| 414 |
| 415 END_BLOCK_OBJC_EXCEPTIONS |
| 416 } |
| 417 |
| 418 // Theme overrides |
| 419 |
| 420 int ThemeChromiumMac::baselinePositionAdjustment(ControlPart part) const |
| 421 { |
| 422 if (part == CheckboxPart || part == RadioPart) |
| 423 return -2; |
| 424 return Theme::baselinePositionAdjustment(part); |
| 425 } |
| 426 |
| 427 FontDescription ThemeChromiumMac::controlFont(ControlPart part, const Font& font
, float zoomFactor) const |
| 428 { |
| 429 switch (part) { |
| 430 case PushButtonPart: { |
| 431 FontDescription fontDescription; |
| 432 fontDescription.setIsAbsoluteSize(true); |
| 433 fontDescription.setGenericFamily(FontDescription::SerifFamily); |
| 434 |
| 435 NSFont* nsFont = [NSFont systemFontOfSize:[NSFont systemFontSizeForC
ontrolSize:controlSizeForFont(font)]]; |
| 436 fontDescription.firstFamily().setFamily([nsFont familyName]); |
| 437 fontDescription.setComputedSize([nsFont pointSize] * zoomFactor); |
| 438 fontDescription.setSpecifiedSize([nsFont pointSize] * zoomFactor); |
| 439 return fontDescription; |
| 440 } |
| 441 default: |
| 442 return Theme::controlFont(part, font, zoomFactor); |
| 443 } |
| 444 } |
| 445 |
| 446 LengthSize ThemeChromiumMac::controlSize(ControlPart part, const Font& font, con
st LengthSize& zoomedSize, float zoomFactor) const |
| 447 { |
| 448 switch (part) { |
| 449 case CheckboxPart: |
| 450 return checkboxSize(font, zoomedSize, zoomFactor); |
| 451 case RadioPart: |
| 452 return radioSize(font, zoomedSize, zoomFactor); |
| 453 case PushButtonPart: |
| 454 // Height is reset to auto so that specified heights can be ignored. |
| 455 return sizeFromFont(font, LengthSize(zoomedSize.width(), Length()),
zoomFactor, buttonSizes()); |
| 456 default: |
| 457 return zoomedSize; |
| 458 } |
| 459 } |
| 460 |
| 461 LengthSize ThemeChromiumMac::minimumControlSize(ControlPart part, const Font& fo
nt, float zoomFactor) const |
| 462 { |
| 463 switch (part) { |
| 464 case SquareButtonPart: |
| 465 case DefaultButtonPart: |
| 466 case ButtonPart: |
| 467 return LengthSize(Length(0, Fixed), Length(static_cast<int>(15 * zoo
mFactor), Fixed)); |
| 468 default: |
| 469 return Theme::minimumControlSize(part, font, zoomFactor); |
| 470 } |
| 471 } |
| 472 |
| 473 LengthBox ThemeChromiumMac::controlBorder(ControlPart part, const Font& font, co
nst LengthBox& zoomedBox, float zoomFactor) const |
| 474 { |
| 475 switch (part) { |
| 476 case SquareButtonPart: |
| 477 case DefaultButtonPart: |
| 478 case ButtonPart: |
| 479 return LengthBox(0, zoomedBox.right().value(), 0, zoomedBox.left().v
alue()); |
| 480 default: |
| 481 return Theme::controlBorder(part, font, zoomedBox, zoomFactor); |
| 482 } |
| 483 } |
| 484 |
| 485 LengthBox ThemeChromiumMac::controlPadding(ControlPart part, const Font& font, c
onst LengthBox& zoomedBox, float zoomFactor) const |
| 486 { |
| 487 switch (part) { |
| 488 case PushButtonPart: { |
| 489 // Just use 8px. AppKit wants to use 11px for mini buttons, but tha
t padding is just too large |
| 490 // for real-world Web sites (creating a huge necessary minimum width
for buttons whose space is |
| 491 // by definition constrained, since we select mini only for small cr
amped environments. |
| 492 // This also guarantees the HTML <button> will match our rendering b
y default, since we're using a consistent |
| 493 // padding. |
| 494 const int padding = 8 * zoomFactor; |
| 495 return LengthBox(0, padding, 0, padding); |
| 496 } |
| 497 default: |
| 498 return Theme::controlPadding(part, font, zoomedBox, zoomFactor); |
| 499 } |
| 500 } |
| 501 |
| 502 void ThemeChromiumMac::inflateControlPaintRect(ControlPart part, ControlStates s
tates, IntRect& zoomedRect, float zoomFactor) const |
| 503 { |
| 504 BEGIN_BLOCK_OBJC_EXCEPTIONS |
| 505 switch (part) { |
| 506 case CheckboxPart: { |
| 507 // We inflate the rect as needed to account for padding included in
the cell to accommodate the checkbox |
| 508 // shadow" and the check. We don't consider this part of the bounds
of the control in WebKit. |
| 509 NSCell *cell = checkbox(states, zoomedRect, zoomFactor); |
| 510 NSControlSize controlSize = [cell controlSize]; |
| 511 IntSize zoomedSize = checkboxSizes()[controlSize]; |
| 512 zoomedSize.setHeight(zoomedSize.height() * zoomFactor); |
| 513 zoomedSize.setWidth(zoomedSize.width() * zoomFactor); |
| 514 zoomedRect = inflateRect(zoomedRect, zoomedSize, checkboxMargins(con
trolSize), zoomFactor); |
| 515 break; |
| 516 } |
| 517 case RadioPart: { |
| 518 // We inflate the rect as needed to account for padding included in
the cell to accommodate the radio button |
| 519 // shadow". We don't consider this part of the bounds of the contro
l in WebKit. |
| 520 NSCell *cell = radio(states, zoomedRect, zoomFactor); |
| 521 NSControlSize controlSize = [cell controlSize]; |
| 522 IntSize zoomedSize = radioSizes()[controlSize]; |
| 523 zoomedSize.setHeight(zoomedSize.height() * zoomFactor); |
| 524 zoomedSize.setWidth(zoomedSize.width() * zoomFactor); |
| 525 zoomedRect = inflateRect(zoomedRect, zoomedSize, radioMargins(contro
lSize), zoomFactor); |
| 526 break; |
| 527 } |
| 528 case PushButtonPart: |
| 529 case DefaultButtonPart: |
| 530 case ButtonPart: { |
| 531 NSButtonCell *cell = button(part, states, zoomedRect, zoomFactor); |
| 532 NSControlSize controlSize = [cell controlSize]; |
| 533 |
| 534 // We inflate the rect as needed to account for the Aqua button's sh
adow. |
| 535 if ([cell bezelStyle] == NSRoundedBezelStyle) { |
| 536 IntSize zoomedSize = buttonSizes()[controlSize]; |
| 537 zoomedSize.setHeight(zoomedSize.height() * zoomFactor); |
| 538 zoomedSize.setWidth(zoomedRect.width()); // Buttons don't ever c
onstrain width, so the zoomed width can just be honored. |
| 539 zoomedRect = inflateRect(zoomedRect, zoomedSize, buttonMargins(c
ontrolSize), zoomFactor); |
| 540 } |
| 541 break; |
| 542 } |
| 543 default: |
| 544 break; |
| 545 } |
| 546 END_BLOCK_OBJC_EXCEPTIONS |
| 547 } |
| 548 |
| 549 void ThemeChromiumMac::paint(ControlPart part, ControlStates states, GraphicsCon
text* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollVi
ew) const |
| 550 { |
| 551 switch (part) { |
| 552 case CheckboxPart: |
| 553 paintCheckbox(states, context, zoomedRect, zoomFactor, scrollView); |
| 554 break; |
| 555 case RadioPart: |
| 556 paintRadio(states, context, zoomedRect, zoomFactor, scrollView); |
| 557 break; |
| 558 case PushButtonPart: |
| 559 case DefaultButtonPart: |
| 560 case ButtonPart: |
| 561 case SquareButtonPart: |
| 562 paintButton(part, states, context, zoomedRect, zoomFactor, scrollVie
w); |
| 563 break; |
| 564 default: |
| 565 break; |
| 566 } |
| 567 } |
| 568 |
| 569 } |
OLD | NEW |