OLD | NEW |
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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 if (zoomedSize.height().isIntrinsicOrAuto() && controlSize.height() > 0) | 88 if (zoomedSize.height().isIntrinsicOrAuto() && controlSize.height() > 0) |
89 result.setHeight(Length(controlSize.height(), Fixed)); | 89 result.setHeight(Length(controlSize.height(), Fixed)); |
90 return result; | 90 return result; |
91 } | 91 } |
92 | 92 |
93 static LengthSize sizeFromFont(const FontDescription& fontDescription, const Len
gthSize& zoomedSize, float zoomFactor, const IntSize* sizes) | 93 static LengthSize sizeFromFont(const FontDescription& fontDescription, const Len
gthSize& zoomedSize, float zoomFactor, const IntSize* sizes) |
94 { | 94 { |
95 return sizeFromNSControlSize(controlSizeForFont(fontDescription), zoomedSize
, zoomFactor, sizes); | 95 return sizeFromNSControlSize(controlSizeForFont(fontDescription), zoomedSize
, zoomFactor, sizes); |
96 } | 96 } |
97 | 97 |
98 static ControlSize controlSizeFromPixelSize(const IntSize* sizes, const IntSize&
minZoomedSize, float zoomFactor) | 98 NSControlSize ThemeMac::controlSizeFromPixelSize(const IntSize* sizes, const Int
Size& minZoomedSize, float zoomFactor) |
99 { | 99 { |
100 if (minZoomedSize.width() >= static_cast<int>(sizes[NSRegularControlSize].wi
dth() * zoomFactor) && | 100 if (minZoomedSize.width() >= static_cast<int>(sizes[NSRegularControlSize].wi
dth() * zoomFactor) && |
101 minZoomedSize.height() >= static_cast<int>(sizes[NSRegularControlSize].h
eight() * zoomFactor)) | 101 minZoomedSize.height() >= static_cast<int>(sizes[NSRegularControlSize].h
eight() * zoomFactor)) |
102 return NSRegularControlSize; | 102 return NSRegularControlSize; |
103 if (minZoomedSize.width() >= static_cast<int>(sizes[NSSmallControlSize].widt
h() * zoomFactor) && | 103 if (minZoomedSize.width() >= static_cast<int>(sizes[NSSmallControlSize].widt
h() * zoomFactor) && |
104 minZoomedSize.height() >= static_cast<int>(sizes[NSSmallControlSize].hei
ght() * zoomFactor)) | 104 minZoomedSize.height() >= static_cast<int>(sizes[NSSmallControlSize].hei
ght() * zoomFactor)) |
105 return NSSmallControlSize; | 105 return NSSmallControlSize; |
106 return NSMiniControlSize; | 106 return NSMiniControlSize; |
107 } | 107 } |
108 | 108 |
109 static void setControlSize(NSCell* cell, const IntSize* sizes, const IntSize& mi
nZoomedSize, float zoomFactor) | 109 static void setControlSize(NSCell* cell, const IntSize* sizes, const IntSize& mi
nZoomedSize, float zoomFactor) |
110 { | 110 { |
111 ControlSize size = controlSizeFromPixelSize(sizes, minZoomedSize, zoomFactor
); | 111 ControlSize size = ThemeMac::controlSizeFromPixelSize(sizes, minZoomedSize,
zoomFactor); |
112 if (size != [cell controlSize]) // Only update if we have to, since AppKit d
oes work even if the size is the same. | 112 if (size != [cell controlSize]) // Only update if we have to, since AppKit d
oes work even if the size is the same. |
113 [cell setControlSize:(NSControlSize)size]; | 113 [cell setControlSize:(NSControlSize)size]; |
114 } | 114 } |
115 | 115 |
116 static void updateStates(NSCell* cell, ControlStates states) | 116 static void updateStates(NSCell* cell, ControlStates states) |
117 { | 117 { |
118 // Hover state is not supported by Aqua. | 118 // Hover state is not supported by Aqua. |
119 | 119 |
120 // Pressed state | 120 // Pressed state |
121 bool oldPressed = [cell isHighlighted]; | 121 bool oldPressed = [cell isHighlighted]; |
(...skipping 12 matching lines...) Expand all Loading... |
134 bool indeterminate = (states & IndeterminateControlState); | 134 bool indeterminate = (states & IndeterminateControlState); |
135 bool checked = states & CheckedControlState; | 135 bool checked = states & CheckedControlState; |
136 bool oldChecked = [cell state] == NSOnState; | 136 bool oldChecked = [cell state] == NSOnState; |
137 if (oldIndeterminate != indeterminate || checked != oldChecked) | 137 if (oldIndeterminate != indeterminate || checked != oldChecked) |
138 [cell setState:indeterminate ? NSMixedState : (checked ? NSOnState : NSO
ffState)]; | 138 [cell setState:indeterminate ? NSMixedState : (checked ? NSOnState : NSO
ffState)]; |
139 | 139 |
140 // Window inactive state does not need to be checked explicitly, since we pa
int parented to | 140 // Window inactive state does not need to be checked explicitly, since we pa
int parented to |
141 // a view in a window whose key state can be detected. | 141 // a view in a window whose key state can be detected. |
142 } | 142 } |
143 | 143 |
144 static ThemeDrawState convertControlStatesToThemeDrawState(ThemeButtonKind kind,
ControlStates states) | |
145 { | |
146 if (states & ReadOnlyControlState) | |
147 return kThemeStateUnavailableInactive; | |
148 if (!(states & EnabledControlState)) | |
149 return kThemeStateUnavailableInactive; | |
150 | |
151 // Do not process PressedState if !EnabledControlState or ReadOnlyControlSta
te. | |
152 if (states & PressedControlState) { | |
153 if (kind == kThemeIncDecButton || kind == kThemeIncDecButtonSmall || kin
d == kThemeIncDecButtonMini) | |
154 return states & SpinUpControlState ? kThemeStatePressedUp : kThemeSt
atePressedDown; | |
155 return kThemeStatePressed; | |
156 } | |
157 return kThemeStateActive; | |
158 } | |
159 | |
160 // Return a fake NSView whose sole purpose is to tell AppKit that it's flipped. | 144 // Return a fake NSView whose sole purpose is to tell AppKit that it's flipped. |
161 static NSView* ensuredView(ScrollableArea* scrollableArea) | 145 NSView* ThemeMac::ensuredView(ScrollableArea* scrollableArea) |
162 { | 146 { |
163 // Use a fake flipped view. | 147 // Use a fake flipped view. |
164 static NSView *flippedView = [[BlinkFlippedControl alloc] init]; | 148 static NSView *flippedView = [[BlinkFlippedControl alloc] init]; |
165 [flippedView setFrameSize:NSSizeFromCGSize(scrollableArea->contentsSize())]; | 149 [flippedView setFrameSize:NSSizeFromCGSize(scrollableArea->contentsSize())]; |
166 | 150 |
167 return flippedView; | 151 return flippedView; |
168 } | 152 } |
169 | 153 |
170 // static | 154 // static |
171 IntRect ThemeMac::inflateRect(const IntRect& zoomedRect, const IntSize& zoomedSi
ze, const int* margins, float zoomFactor) | 155 IntRect ThemeMac::inflateRect(const IntRect& zoomedRect, const IntSize& zoomedSi
ze, const int* margins, float zoomFactor) |
(...skipping 29 matching lines...) Expand all Loading... |
201 IntRect result; | 185 IntRect result; |
202 result.setX(rect.x() - margin); | 186 result.setX(rect.x() - margin); |
203 result.setY(rect.y() - margin); | 187 result.setY(rect.y() - margin); |
204 result.setWidth(rect.width() + 2 * margin); | 188 result.setWidth(rect.width() + 2 * margin); |
205 result.setHeight(rect.height() + 2 * margin); | 189 result.setHeight(rect.height() + 2 * margin); |
206 return result; | 190 return result; |
207 } | 191 } |
208 | 192 |
209 // Checkboxes | 193 // Checkboxes |
210 | 194 |
211 static const IntSize* checkboxSizes() | 195 const IntSize* ThemeMac::checkboxSizes() |
212 { | 196 { |
213 static const IntSize sizes[3] = { IntSize(14, 14), IntSize(12, 12), IntSize(
10, 10) }; | 197 static const IntSize sizes[3] = { IntSize(14, 14), IntSize(12, 12), IntSize(
10, 10) }; |
214 return sizes; | 198 return sizes; |
215 } | 199 } |
216 | 200 |
217 static const int* checkboxMargins(NSControlSize controlSize) | 201 const int* ThemeMac::checkboxMargins(NSControlSize controlSize) |
218 { | 202 { |
219 static const int margins[3][4] = | 203 static const int margins[3][4] = |
220 { | 204 { |
221 { 3, 4, 4, 2 }, | 205 { 3, 4, 4, 2 }, |
222 { 4, 3, 3, 3 }, | 206 { 4, 3, 3, 3 }, |
223 { 4, 3, 3, 3 }, | 207 { 4, 3, 3, 3 }, |
224 }; | 208 }; |
225 return margins[controlSize]; | 209 return margins[controlSize]; |
226 } | 210 } |
227 | 211 |
228 static LengthSize checkboxSize(const FontDescription& fontDescription, const Len
gthSize& zoomedSize, float zoomFactor) | 212 LengthSize ThemeMac::checkboxSize(const FontDescription& fontDescription, const
LengthSize& zoomedSize, float zoomFactor) |
229 { | 213 { |
230 // If the width and height are both specified, then we have nothing to do. | 214 // If the width and height are both specified, then we have nothing to do. |
231 if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrin
sicOrAuto()) | 215 if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrin
sicOrAuto()) |
232 return zoomedSize; | 216 return zoomedSize; |
233 | 217 |
234 // Use the font size to determine the intrinsic width of the control. | 218 // Use the font size to determine the intrinsic width of the control. |
235 return sizeFromFont(fontDescription, zoomedSize, zoomFactor, checkboxSizes()
); | 219 return sizeFromFont(fontDescription, zoomedSize, zoomFactor, checkboxSizes()
); |
236 } | 220 } |
237 | 221 |
238 static NSButtonCell *checkbox(ControlStates states, const IntRect& zoomedRect, f
loat zoomFactor) | 222 NSButtonCell *ThemeMac::checkbox(ControlStates states, const IntRect& zoomedRect
, float zoomFactor) |
239 { | 223 { |
240 static NSButtonCell *checkboxCell; | 224 static NSButtonCell *checkboxCell; |
241 if (!checkboxCell) { | 225 if (!checkboxCell) { |
242 checkboxCell = [[NSButtonCell alloc] init]; | 226 checkboxCell = [[NSButtonCell alloc] init]; |
243 [checkboxCell setButtonType:NSSwitchButton]; | 227 [checkboxCell setButtonType:NSSwitchButton]; |
244 [checkboxCell setTitle:nil]; | 228 [checkboxCell setTitle:nil]; |
245 [checkboxCell setAllowsMixedState:YES]; | 229 [checkboxCell setAllowsMixedState:YES]; |
246 [checkboxCell setFocusRingType:NSFocusRingTypeExterior]; | 230 [checkboxCell setFocusRingType:NSFocusRingTypeExterior]; |
247 } | 231 } |
248 | 232 |
249 // Set the control size based off the rectangle we're painting into. | 233 // Set the control size based off the rectangle we're painting into. |
250 setControlSize(checkboxCell, checkboxSizes(), zoomedRect.size(), zoomFactor)
; | 234 setControlSize(checkboxCell, checkboxSizes(), zoomedRect.size(), zoomFactor)
; |
251 | 235 |
252 // Update the various states we respond to. | 236 // Update the various states we respond to. |
253 updateStates(checkboxCell, states); | 237 updateStates(checkboxCell, states); |
254 | 238 |
255 return checkboxCell; | 239 return checkboxCell; |
256 } | 240 } |
257 | 241 |
258 // FIXME: Share more code with radio buttons. | 242 const IntSize* ThemeMac::radioSizes() |
259 static void paintCheckbox(ControlStates states, GraphicsContext& context, const
IntRect& zoomedRect, float zoomFactor, ScrollableArea* scrollableArea) | |
260 { | |
261 BEGIN_BLOCK_OBJC_EXCEPTIONS | |
262 | |
263 // Determine the width and height needed for the control and prepare the cel
l for painting. | |
264 NSButtonCell *checkboxCell = checkbox(states, zoomedRect, zoomFactor); | |
265 GraphicsContextStateSaver stateSaver(context); | |
266 | |
267 NSControlSize controlSize = [checkboxCell controlSize]; | |
268 IntSize zoomedSize = checkboxSizes()[controlSize]; | |
269 zoomedSize.setWidth(zoomedSize.width() * zoomFactor); | |
270 zoomedSize.setHeight(zoomedSize.height() * zoomFactor); | |
271 IntRect inflatedRect = ThemeMac::inflateRect(zoomedRect, zoomedSize, checkbo
xMargins(controlSize), zoomFactor); | |
272 | |
273 if (zoomFactor != 1.0f) { | |
274 inflatedRect.setWidth(inflatedRect.width() / zoomFactor); | |
275 inflatedRect.setHeight(inflatedRect.height() / zoomFactor); | |
276 context.translate(inflatedRect.x(), inflatedRect.y()); | |
277 context.scale(zoomFactor, zoomFactor); | |
278 context.translate(-inflatedRect.x(), -inflatedRect.y()); | |
279 } | |
280 | |
281 LocalCurrentGraphicsContext localContext(context, ThemeMac::inflateRectForFo
cusRing(inflatedRect)); | |
282 NSView* view = ensuredView(scrollableArea); | |
283 [checkboxCell drawWithFrame:NSRect(inflatedRect) inView:view]; | |
284 if (states & FocusControlState) | |
285 [checkboxCell cr_drawFocusRingWithFrame:NSRect(inflatedRect) inView:view
]; | |
286 [checkboxCell setControlView:nil]; | |
287 | |
288 END_BLOCK_OBJC_EXCEPTIONS | |
289 } | |
290 | |
291 // Radio Buttons | |
292 | |
293 static const IntSize* radioSizes() | |
294 { | 243 { |
295 static const IntSize sizes[3] = { IntSize(14, 15), IntSize(12, 13), IntSize(
10, 10) }; | 244 static const IntSize sizes[3] = { IntSize(14, 15), IntSize(12, 13), IntSize(
10, 10) }; |
296 return sizes; | 245 return sizes; |
297 } | 246 } |
298 | 247 |
299 static const int* radioMargins(NSControlSize controlSize) | 248 const int* ThemeMac::radioMargins(NSControlSize controlSize) |
300 { | 249 { |
301 static const int margins[3][4] = | 250 static const int margins[3][4] = |
302 { | 251 { |
303 { 2, 2, 4, 2 }, | 252 { 2, 2, 4, 2 }, |
304 { 3, 2, 3, 2 }, | 253 { 3, 2, 3, 2 }, |
305 { 1, 0, 2, 0 }, | 254 { 1, 0, 2, 0 }, |
306 }; | 255 }; |
307 return margins[controlSize]; | 256 return margins[controlSize]; |
308 } | 257 } |
309 | 258 |
310 static LengthSize radioSize(const FontDescription& fontDescription, const Length
Size& zoomedSize, float zoomFactor) | 259 LengthSize ThemeMac::radioSize(const FontDescription& fontDescription, const Len
gthSize& zoomedSize, float zoomFactor) |
311 { | 260 { |
312 // If the width and height are both specified, then we have nothing to do. | 261 // If the width and height are both specified, then we have nothing to do. |
313 if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrin
sicOrAuto()) | 262 if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrin
sicOrAuto()) |
314 return zoomedSize; | 263 return zoomedSize; |
315 | 264 |
316 // Use the font size to determine the intrinsic width of the control. | 265 // Use the font size to determine the intrinsic width of the control. |
317 return sizeFromFont(fontDescription, zoomedSize, zoomFactor, radioSizes()); | 266 return sizeFromFont(fontDescription, zoomedSize, zoomFactor, radioSizes()); |
318 } | 267 } |
319 | 268 |
320 static NSButtonCell *radio(ControlStates states, const IntRect& zoomedRect, floa
t zoomFactor) | 269 NSButtonCell *ThemeMac::radio(ControlStates states, const IntRect& zoomedRect, f
loat zoomFactor) |
321 { | 270 { |
322 static NSButtonCell *radioCell; | 271 static NSButtonCell *radioCell; |
323 if (!radioCell) { | 272 if (!radioCell) { |
324 radioCell = [[NSButtonCell alloc] init]; | 273 radioCell = [[NSButtonCell alloc] init]; |
325 [radioCell setButtonType:NSRadioButton]; | 274 [radioCell setButtonType:NSRadioButton]; |
326 [radioCell setTitle:nil]; | 275 [radioCell setTitle:nil]; |
327 [radioCell setFocusRingType:NSFocusRingTypeExterior]; | 276 [radioCell setFocusRingType:NSFocusRingTypeExterior]; |
328 } | 277 } |
329 | 278 |
330 // Set the control size based off the rectangle we're painting into. | 279 // Set the control size based off the rectangle we're painting into. |
331 setControlSize(radioCell, radioSizes(), zoomedRect.size(), zoomFactor); | 280 setControlSize(radioCell, radioSizes(), zoomedRect.size(), zoomFactor); |
332 | 281 |
333 // Update the various states we respond to. | 282 // Update the various states we respond to. |
334 // Cocoa draws NSMixedState NSRadioButton as NSOnState so we don't want that
. | 283 // Cocoa draws NSMixedState NSRadioButton as NSOnState so we don't want that
. |
335 states &= ~IndeterminateControlState; | 284 states &= ~IndeterminateControlState; |
336 updateStates(radioCell, states); | 285 updateStates(radioCell, states); |
337 | 286 |
338 return radioCell; | 287 return radioCell; |
339 } | 288 } |
340 | 289 |
341 static void paintRadio(ControlStates states, GraphicsContext& context, const Int
Rect& zoomedRect, float zoomFactor, ScrollableArea* scrollableArea) | |
342 { | |
343 // Determine the width and height needed for the control and prepare the cel
l for painting. | |
344 NSButtonCell *radioCell = radio(states, zoomedRect, zoomFactor); | |
345 GraphicsContextStateSaver stateSaver(context); | |
346 | |
347 NSControlSize controlSize = [radioCell controlSize]; | |
348 IntSize zoomedSize = radioSizes()[controlSize]; | |
349 zoomedSize.setWidth(zoomedSize.width() * zoomFactor); | |
350 zoomedSize.setHeight(zoomedSize.height() * zoomFactor); | |
351 IntRect inflatedRect = ThemeMac::inflateRect(zoomedRect, zoomedSize, radioMa
rgins(controlSize), zoomFactor); | |
352 | |
353 if (zoomFactor != 1.0f) { | |
354 inflatedRect.setWidth(inflatedRect.width() / zoomFactor); | |
355 inflatedRect.setHeight(inflatedRect.height() / zoomFactor); | |
356 context.translate(inflatedRect.x(), inflatedRect.y()); | |
357 context.scale(zoomFactor, zoomFactor); | |
358 context.translate(-inflatedRect.x(), -inflatedRect.y()); | |
359 } | |
360 | |
361 LocalCurrentGraphicsContext localContext(context, ThemeMac::inflateRectForFo
cusRing(inflatedRect)); | |
362 BEGIN_BLOCK_OBJC_EXCEPTIONS | |
363 NSView* view = ensuredView(scrollableArea); | |
364 [radioCell drawWithFrame:NSRect(inflatedRect) inView:view]; | |
365 if (states & FocusControlState) | |
366 [radioCell cr_drawFocusRingWithFrame:NSRect(inflatedRect) inView:view]; | |
367 [radioCell setControlView:nil]; | |
368 END_BLOCK_OBJC_EXCEPTIONS | |
369 } | |
370 | |
371 // Buttons | |
372 | |
373 // Buttons really only constrain height. They respect width. | 290 // Buttons really only constrain height. They respect width. |
374 static const IntSize* buttonSizes() | 291 const IntSize* ThemeMac::buttonSizes() |
375 { | 292 { |
376 static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0,
15) }; | 293 static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0,
15) }; |
377 return sizes; | 294 return sizes; |
378 } | 295 } |
379 | 296 |
380 static const int* buttonMargins(NSControlSize controlSize) | 297 const int* ThemeMac::buttonMargins(NSControlSize controlSize) |
381 { | 298 { |
382 static const int margins[3][4] = | 299 static const int margins[3][4] = |
383 { | 300 { |
384 { 4, 6, 7, 6 }, | 301 { 4, 6, 7, 6 }, |
385 { 4, 5, 6, 5 }, | 302 { 4, 5, 6, 5 }, |
386 { 0, 1, 1, 1 }, | 303 { 0, 1, 1, 1 }, |
387 }; | 304 }; |
388 return margins[controlSize]; | 305 return margins[controlSize]; |
389 } | 306 } |
390 | 307 |
391 static void setUpButtonCell(NSButtonCell *cell, ControlPart part, ControlStates
states, const IntRect& zoomedRect, float zoomFactor) | 308 static void setUpButtonCell(NSButtonCell *cell, ControlPart part, ControlStates
states, const IntRect& zoomedRect, float zoomFactor) |
392 { | 309 { |
393 // Set the control size based off the rectangle we're painting into. | 310 // Set the control size based off the rectangle we're painting into. |
394 const IntSize* sizes = buttonSizes(); | 311 const IntSize* sizes = ThemeMac::buttonSizes(); |
395 if (part == SquareButtonPart || zoomedRect.height() > buttonSizes()[NSRegula
rControlSize].height() * zoomFactor) { | 312 if (part == SquareButtonPart || zoomedRect.height() > ThemeMac::buttonSizes(
)[NSRegularControlSize].height() * zoomFactor) { |
396 // Use the square button | 313 // Use the square button |
397 if ([cell bezelStyle] != NSShadowlessSquareBezelStyle) | 314 if ([cell bezelStyle] != NSShadowlessSquareBezelStyle) |
398 [cell setBezelStyle:NSShadowlessSquareBezelStyle]; | 315 [cell setBezelStyle:NSShadowlessSquareBezelStyle]; |
399 } else if ([cell bezelStyle] != NSRoundedBezelStyle) | 316 } else if ([cell bezelStyle] != NSRoundedBezelStyle) |
400 [cell setBezelStyle:NSRoundedBezelStyle]; | 317 [cell setBezelStyle:NSRoundedBezelStyle]; |
401 | 318 |
402 setControlSize(cell, sizes, zoomedRect.size(), zoomFactor); | 319 setControlSize(cell, sizes, zoomedRect.size(), zoomFactor); |
403 | 320 |
404 // Update the various states we respond to. | 321 // Update the various states we respond to. |
405 updateStates(cell, states); | 322 updateStates(cell, states); |
406 } | 323 } |
407 | 324 |
408 static NSButtonCell *button(ControlPart part, ControlStates states, const IntRec
t& zoomedRect, float zoomFactor) | 325 NSButtonCell *ThemeMac::button(ControlPart part, ControlStates states, const Int
Rect& zoomedRect, float zoomFactor) |
409 { | 326 { |
410 static NSButtonCell *cell = nil; | 327 static NSButtonCell *cell = nil; |
411 if (!cell) { | 328 if (!cell) { |
412 cell = [[NSButtonCell alloc] init]; | 329 cell = [[NSButtonCell alloc] init]; |
413 [cell setTitle:nil]; | 330 [cell setTitle:nil]; |
414 [cell setButtonType:NSMomentaryPushInButton]; | 331 [cell setButtonType:NSMomentaryPushInButton]; |
415 } | 332 } |
416 setUpButtonCell(cell, part, states, zoomedRect, zoomFactor); | 333 setUpButtonCell(cell, part, states, zoomedRect, zoomFactor); |
417 return cell; | 334 return cell; |
418 } | 335 } |
419 | 336 |
420 static void paintButton(ControlPart part, ControlStates states, GraphicsContext&
context, const IntRect& zoomedRect, float zoomFactor, ScrollableArea* scrollabl
eArea) | 337 const IntSize* ThemeMac::stepperSizes() |
421 { | |
422 BEGIN_BLOCK_OBJC_EXCEPTIONS | |
423 | |
424 // Determine the width and height needed for the control and prepare the cel
l for painting. | |
425 NSButtonCell *buttonCell = button(part, states, zoomedRect, zoomFactor); | |
426 GraphicsContextStateSaver stateSaver(context); | |
427 | |
428 NSControlSize controlSize = [buttonCell controlSize]; | |
429 IntSize zoomedSize = buttonSizes()[controlSize]; | |
430 zoomedSize.setWidth(zoomedRect.width()); // Buttons don't ever constrain wid
th, so the zoomed width can just be honored. | |
431 zoomedSize.setHeight(zoomedSize.height() * zoomFactor); | |
432 IntRect inflatedRect = zoomedRect; | |
433 if ([buttonCell bezelStyle] == NSRoundedBezelStyle) { | |
434 // Center the button within the available space. | |
435 if (inflatedRect.height() > zoomedSize.height()) { | |
436 inflatedRect.setY(inflatedRect.y() + (inflatedRect.height() - zoomed
Size.height()) / 2); | |
437 inflatedRect.setHeight(zoomedSize.height()); | |
438 } | |
439 | |
440 // Now inflate it to account for the shadow. | |
441 inflatedRect = ThemeMac::inflateRect(inflatedRect, zoomedSize, buttonMar
gins(controlSize), zoomFactor); | |
442 | |
443 if (zoomFactor != 1.0f) { | |
444 inflatedRect.setWidth(inflatedRect.width() / zoomFactor); | |
445 inflatedRect.setHeight(inflatedRect.height() / zoomFactor); | |
446 context.translate(inflatedRect.x(), inflatedRect.y()); | |
447 context.scale(zoomFactor, zoomFactor); | |
448 context.translate(-inflatedRect.x(), -inflatedRect.y()); | |
449 } | |
450 } | |
451 | |
452 LocalCurrentGraphicsContext localContext(context, ThemeMac::inflateRectForFo
cusRing(inflatedRect)); | |
453 NSView* view = ensuredView(scrollableArea); | |
454 | |
455 [buttonCell drawWithFrame:NSRect(inflatedRect) inView:view]; | |
456 if (states & FocusControlState) | |
457 [buttonCell cr_drawFocusRingWithFrame:NSRect(inflatedRect) inView:view]; | |
458 [buttonCell setControlView:nil]; | |
459 | |
460 END_BLOCK_OBJC_EXCEPTIONS | |
461 } | |
462 | |
463 // Stepper | |
464 | |
465 static const IntSize* stepperSizes() | |
466 { | 338 { |
467 static const IntSize sizes[3] = { IntSize(19, 27), IntSize(15, 22), IntSize(
13, 15) }; | 339 static const IntSize sizes[3] = { IntSize(19, 27), IntSize(15, 22), IntSize(
13, 15) }; |
468 return sizes; | 340 return sizes; |
469 } | 341 } |
470 | 342 |
471 // We don't use controlSizeForFont() for steppers because the stepper height | 343 // We don't use controlSizeForFont() for steppers because the stepper height |
472 // should be equal to or less than the corresponding text field height, | 344 // should be equal to or less than the corresponding text field height, |
473 static NSControlSize stepperControlSizeForFont(const FontDescription& fontDescri
ption) | 345 static NSControlSize stepperControlSizeForFont(const FontDescription& fontDescri
ption) |
474 { | 346 { |
475 int fontSize = fontDescription.computedPixelSize(); | 347 int fontSize = fontDescription.computedPixelSize(); |
476 if (fontSize >= 27) | 348 if (fontSize >= 27) |
477 return NSRegularControlSize; | 349 return NSRegularControlSize; |
478 if (fontSize >= 22) | 350 if (fontSize >= 22) |
479 return NSSmallControlSize; | 351 return NSSmallControlSize; |
480 return NSMiniControlSize; | 352 return NSMiniControlSize; |
481 } | 353 } |
482 | 354 |
483 static void paintStepper(ControlStates states, GraphicsContext& context, const I
ntRect& zoomedRect, float zoomFactor, ScrollableArea*) | |
484 { | |
485 // We don't use NSStepperCell because there are no ways to draw an | |
486 // NSStepperCell with the up button highlighted. | |
487 | |
488 HIThemeButtonDrawInfo drawInfo; | |
489 drawInfo.version = 0; | |
490 drawInfo.state = convertControlStatesToThemeDrawState(kThemeIncDecButton, st
ates); | |
491 drawInfo.adornment = kThemeAdornmentDefault; | |
492 ControlSize controlSize = controlSizeFromPixelSize(stepperSizes(), zoomedRec
t.size(), zoomFactor); | |
493 if (controlSize == NSSmallControlSize) | |
494 drawInfo.kind = kThemeIncDecButtonSmall; | |
495 else if (controlSize == NSMiniControlSize) | |
496 drawInfo.kind = kThemeIncDecButtonMini; | |
497 else | |
498 drawInfo.kind = kThemeIncDecButton; | |
499 | |
500 IntRect rect(zoomedRect); | |
501 GraphicsContextStateSaver stateSaver(context); | |
502 if (zoomFactor != 1.0f) { | |
503 rect.setWidth(rect.width() / zoomFactor); | |
504 rect.setHeight(rect.height() / zoomFactor); | |
505 context.translate(rect.x(), rect.y()); | |
506 context.scale(zoomFactor, zoomFactor); | |
507 context.translate(-rect.x(), -rect.y()); | |
508 } | |
509 CGRect bounds(rect); | |
510 CGRect backgroundBounds; | |
511 HIThemeGetButtonBackgroundBounds(&bounds, &drawInfo, &backgroundBounds); | |
512 // Center the stepper rectangle in the specified area. | |
513 backgroundBounds.origin.x = bounds.origin.x + (bounds.size.width - backgroun
dBounds.size.width) / 2; | |
514 if (backgroundBounds.size.height < bounds.size.height) { | |
515 int heightDiff = clampTo<int>(bounds.size.height - backgroundBounds.size
.height); | |
516 backgroundBounds.origin.y = bounds.origin.y + (heightDiff / 2) + 1; | |
517 } | |
518 | |
519 LocalCurrentGraphicsContext localContext(context, rect); | |
520 HIThemeDrawButton(&backgroundBounds, &drawInfo, localContext.cgContext(), kH
IThemeOrientationNormal, 0); | |
521 } | |
522 | |
523 // Theme overrides | 355 // Theme overrides |
524 | 356 |
525 int ThemeMac::baselinePositionAdjustment(ControlPart part) const | 357 int ThemeMac::baselinePositionAdjustment(ControlPart part) const |
526 { | 358 { |
527 if (part == CheckboxPart || part == RadioPart) | 359 if (part == CheckboxPart || part == RadioPart) |
528 return -2; | 360 return -2; |
529 return Theme::baselinePositionAdjustment(part); | 361 return Theme::baselinePositionAdjustment(part); |
530 } | 362 } |
531 | 363 |
532 FontDescription ThemeMac::controlFont(ControlPart part, const FontDescription& f
ontDescription, float zoomFactor) const | 364 FontDescription ThemeMac::controlFont(ControlPart part, const FontDescription& f
ontDescription, float zoomFactor) const |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 zoomedSize.setWidth(zoomedSize.width() * zoomFactor); | 491 zoomedSize.setWidth(zoomedSize.width() * zoomFactor); |
660 zoomedRect = inflateRect(zoomedRect, zoomedSize, stepperMargin, zoom
Factor); | 492 zoomedRect = inflateRect(zoomedRect, zoomedSize, stepperMargin, zoom
Factor); |
661 break; | 493 break; |
662 } | 494 } |
663 default: | 495 default: |
664 break; | 496 break; |
665 } | 497 } |
666 END_BLOCK_OBJC_EXCEPTIONS | 498 END_BLOCK_OBJC_EXCEPTIONS |
667 } | 499 } |
668 | 500 |
669 void ThemeMac::paint(ControlPart part, ControlStates states, GraphicsContext& co
ntext, const IntRect& zoomedRect, float zoomFactor, ScrollableArea* scrollableAr
ea) const | |
670 { | |
671 switch (part) { | |
672 case CheckboxPart: | |
673 paintCheckbox(states, context, zoomedRect, zoomFactor, scrollableAre
a); | |
674 break; | |
675 case RadioPart: | |
676 paintRadio(states, context, zoomedRect, zoomFactor, scrollableArea); | |
677 break; | |
678 case PushButtonPart: | |
679 case ButtonPart: | |
680 case SquareButtonPart: | |
681 paintButton(part, states, context, zoomedRect, zoomFactor, scrollabl
eArea); | |
682 break; | |
683 case InnerSpinButtonPart: | |
684 paintStepper(states, context, zoomedRect, zoomFactor, scrollableArea
); | |
685 break; | |
686 default: | |
687 break; | |
688 } | |
689 } | 501 } |
690 | |
691 } | |
OLD | NEW |