OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gfx/native_theme_linux.h" | 5 #include "gfx/native_theme_linux.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "gfx/codec/png_codec.h" | |
9 #include "gfx/color_utils.h" | |
10 #include "gfx/gfx_module.h" | |
8 #include "gfx/size.h" | 11 #include "gfx/size.h" |
9 #include "gfx/rect.h" | 12 #include "gfx/rect.h" |
13 #include "grit/gfx_resources.h" | |
14 #include "third_party/skia/include/effects/SkGradientShader.h" | |
10 | 15 |
11 namespace gfx { | 16 namespace gfx { |
12 | 17 |
13 unsigned int NativeThemeLinux::button_length_ = 14; | 18 unsigned int NativeThemeLinux::button_length_ = 14; |
14 unsigned int NativeThemeLinux::scrollbar_width_ = 15; | 19 unsigned int NativeThemeLinux::scrollbar_width_ = 15; |
15 unsigned int NativeThemeLinux::thumb_inactive_color_ = 0xeaeaea; | 20 unsigned int NativeThemeLinux::thumb_inactive_color_ = 0xeaeaea; |
16 unsigned int NativeThemeLinux::thumb_active_color_ = 0xf4f4f4; | 21 unsigned int NativeThemeLinux::thumb_active_color_ = 0xf4f4f4; |
17 unsigned int NativeThemeLinux::track_color_ = 0xd3d3d3; | 22 unsigned int NativeThemeLinux::track_color_ = 0xd3d3d3; |
18 | 23 |
24 // These are the default dimensions of radio buttons and checkboxes. | |
25 static const int kCheckboxAndRadioWidth = 13; | |
26 static const int kCheckboxAndRadioHeight = 13; | |
27 | |
28 // These sizes match the sizes in Chromium Win. | |
29 static const int kSliderThumbWidth = 11; | |
30 static const int kSliderThumbHeight = 21; | |
31 | |
32 static const SkColor kSliderTrackBackgroundColor = | |
33 SkColorSetRGB(0xe3, 0xdd, 0xd8); | |
34 static const SkColor kSliderThumbLightGrey = SkColorSetRGB(0xf4, 0xf2, 0xef); | |
35 static const SkColor kSliderThumbDarkGrey = SkColorSetRGB(0xea, 0xe5, 0xe0); | |
36 static const SkColor kSliderThumbBorderDarkGrey = | |
37 SkColorSetRGB(0x9d, 0x96, 0x8e); | |
38 | |
19 #if !defined(OS_CHROMEOS) | 39 #if !defined(OS_CHROMEOS) |
20 // Chromeos has a different look. | 40 // Chromeos has a different look. |
21 // static | 41 // static |
22 NativeThemeLinux* NativeThemeLinux::instance() { | 42 NativeThemeLinux* NativeThemeLinux::instance() { |
23 // The global NativeThemeLinux instance. | 43 // The global NativeThemeLinux instance. |
24 static NativeThemeLinux s_native_theme; | 44 static NativeThemeLinux s_native_theme; |
25 return &s_native_theme; | 45 return &s_native_theme; |
26 } | 46 } |
27 #endif | 47 #endif |
28 | 48 |
49 // Get lightness adjusted color. | |
50 static SkColor BrightenColor(const color_utils::HSL& hsl, SkAlpha alpha, | |
51 double lightness_amount) { | |
52 color_utils::HSL adjusted = hsl; | |
53 adjusted.l += lightness_amount; | |
54 if (adjusted.l > 1.0) | |
55 adjusted.l = 1.0; | |
56 if (adjusted.l < 0.0) | |
57 adjusted.l = 0.0; | |
58 | |
59 return color_utils::HSLToSkColor(adjusted, alpha); | |
60 } | |
61 | |
62 static SkBitmap* GfxGetBitmapNamed(int key) { | |
63 base::StringPiece data = GfxModule::GetResource(key); | |
64 if (!data.size()) { | |
65 NOTREACHED() << "Unable to load image resource " << key; | |
66 return NULL; | |
67 } | |
68 | |
69 SkBitmap bitmap; | |
70 if (!gfx::PNGCodec::Decode( | |
71 reinterpret_cast<const unsigned char*>(data.data()), | |
72 data.size(), &bitmap)) { | |
73 NOTREACHED() << "Unable to decode image resource " << key; | |
74 return NULL; | |
75 } | |
76 | |
77 return new SkBitmap(bitmap); | |
78 } | |
79 | |
29 NativeThemeLinux::NativeThemeLinux() { | 80 NativeThemeLinux::NativeThemeLinux() { |
30 } | 81 } |
31 | 82 |
32 NativeThemeLinux::~NativeThemeLinux() { | 83 NativeThemeLinux::~NativeThemeLinux() { |
33 } | 84 } |
34 | 85 |
35 gfx::Size NativeThemeLinux::GetSize(Part part) const { | 86 gfx::Size NativeThemeLinux::GetSize(Part part) const { |
36 switch (part) { | 87 switch (part) { |
37 case kScrollbarDownArrow: | 88 case kScrollbarDownArrow: |
38 case kScrollbarUpArrow: | 89 case kScrollbarUpArrow: |
39 return gfx::Size(scrollbar_width_, button_length_); | 90 return gfx::Size(scrollbar_width_, button_length_); |
40 case kScrollbarLeftArrow: | 91 case kScrollbarLeftArrow: |
41 case kScrollbarRightArrow: | 92 case kScrollbarRightArrow: |
42 return gfx::Size(button_length_, scrollbar_width_); | 93 return gfx::Size(button_length_, scrollbar_width_); |
43 case kScrollbarHorizontalThumb: | 94 case kScrollbarHorizontalThumb: |
44 // This matches Firefox on Linux. | 95 // This matches Firefox on Linux. |
45 return gfx::Size(2 * scrollbar_width_, scrollbar_width_); | 96 return gfx::Size(2 * scrollbar_width_, scrollbar_width_); |
46 case kScrollbarVerticalThumb: | 97 case kScrollbarVerticalThumb: |
47 // This matches Firefox on Linux. | 98 // This matches Firefox on Linux. |
48 return gfx::Size(scrollbar_width_, 2 * scrollbar_width_); | 99 return gfx::Size(scrollbar_width_, 2 * scrollbar_width_); |
49 break; | 100 break; |
50 case kScrollbarHorizontalTrack: | 101 case kScrollbarHorizontalTrack: |
51 return gfx::Size(0, scrollbar_width_); | 102 return gfx::Size(0, scrollbar_width_); |
52 case kScrollbarVerticalTrack: | 103 case kScrollbarVerticalTrack: |
53 return gfx::Size(scrollbar_width_, 0); | 104 return gfx::Size(scrollbar_width_, 0); |
105 case kCheckbox: | |
106 case kRadio: | |
107 return gfx::Size(kCheckboxAndRadioWidth, kCheckboxAndRadioHeight); | |
108 case kSliderThumb: | |
109 // These sizes match the sizes in Chromium Win. | |
110 return gfx::Size(kSliderThumbWidth, kSliderThumbHeight); | |
111 case kInnerSpinButton: | |
112 return gfx::Size(scrollbar_width_, 0); | |
113 case kPushButton: | |
114 case kTextField: | |
115 case kMenuList: | |
116 case kSliderTrack: | |
117 case kProgressBar: | |
118 return gfx::Size(); // No default size. | |
54 } | 119 } |
55 return gfx::Size(); | 120 return gfx::Size(); |
56 } | 121 } |
57 | 122 |
58 void NativeThemeLinux::PaintArrowButton( | 123 void NativeThemeLinux::PaintArrowButton( |
59 skia::PlatformCanvas* canvas, | 124 skia::PlatformCanvas* canvas, |
60 const gfx::Rect& rect, Part direction, State state) { | 125 const gfx::Rect& rect, Part direction, State state) { |
61 int widthMiddle, lengthMiddle; | 126 int widthMiddle, lengthMiddle; |
62 SkPaint paint; | 127 SkPaint paint; |
63 if (direction == kScrollbarUpArrow || direction == kScrollbarDownArrow) { | 128 if (direction == kScrollbarUpArrow || direction == kScrollbarDownArrow) { |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
194 PaintArrowButton(canvas, rect, part, state); | 259 PaintArrowButton(canvas, rect, part, state); |
195 break; | 260 break; |
196 case kScrollbarHorizontalThumb: | 261 case kScrollbarHorizontalThumb: |
197 case kScrollbarVerticalThumb: | 262 case kScrollbarVerticalThumb: |
198 PaintThumb(canvas, part, state, rect); | 263 PaintThumb(canvas, part, state, rect); |
199 break; | 264 break; |
200 case kScrollbarHorizontalTrack: | 265 case kScrollbarHorizontalTrack: |
201 case kScrollbarVerticalTrack: | 266 case kScrollbarVerticalTrack: |
202 PaintTrack(canvas, part, state, extra.scrollbar_track, rect); | 267 PaintTrack(canvas, part, state, extra.scrollbar_track, rect); |
203 break; | 268 break; |
269 case kCheckbox: | |
270 PaintCheckbox(canvas, state, rect, extra.button); | |
271 break; | |
272 case kRadio: | |
273 PaintRadio(canvas, state, rect, extra.button); | |
274 break; | |
275 case kPushButton: | |
276 PaintButton(canvas, state, rect, extra.button); | |
277 break; | |
278 case kTextField: | |
279 PaintTextField(canvas, state, rect, extra.text_field); | |
280 break; | |
281 case kMenuList: | |
282 PaintMenuList(canvas, state, rect, extra.menu_list); | |
283 break; | |
284 case kSliderTrack: | |
285 PaintSliderTrack(canvas, state, rect, extra.slider); | |
286 break; | |
287 case kSliderThumb: | |
288 PaintSliderThumb(canvas, state, rect, extra.slider); | |
289 break; | |
290 case kInnerSpinButton: | |
291 PaintInnerSpinButton(canvas, state, rect, extra.inner_spin); | |
292 break; | |
293 case kProgressBar: | |
294 PaintProgressBar(canvas, state, rect, extra.progress_bar); | |
295 break; | |
204 } | 296 } |
205 } | 297 } |
206 | 298 |
207 void NativeThemeLinux::PaintTrack(skia::PlatformCanvas* canvas, | 299 void NativeThemeLinux::PaintTrack(skia::PlatformCanvas* canvas, |
208 Part part, | 300 Part part, |
209 State state, | 301 State state, |
210 const ScrollbarTrackExtraParams& extra_params, | 302 const ScrollbarTrackExtraParams& extra_params, |
211 const gfx::Rect& rect) { | 303 const gfx::Rect& rect) { |
212 SkPaint paint; | 304 SkPaint paint; |
213 SkIRect skrect; | 305 SkIRect skrect; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
297 paint); | 389 paint); |
298 DrawVertLine(canvas, | 390 DrawVertLine(canvas, |
299 midx + inter_grippy_offset, | 391 midx + inter_grippy_offset, |
300 midy - grippy_half_width, | 392 midy - grippy_half_width, |
301 midy + grippy_half_width, | 393 midy + grippy_half_width, |
302 paint); | 394 paint); |
303 } | 395 } |
304 } | 396 } |
305 } | 397 } |
306 | 398 |
399 void NativeThemeLinux::PaintCheckbox(skia::PlatformCanvas* canvas, | |
400 State state, | |
401 const gfx::Rect& rect, | |
402 const ButtonExtraParams& button) { | |
403 static SkBitmap* image_disabled_indeterminate = GfxGetBitmapNamed( | |
404 IDR_LINUX_CHECKBOX_DISABLED_INDETERMINATE); | |
405 static SkBitmap* image_indeterminate = GfxGetBitmapNamed( | |
406 IDR_LINUX_CHECKBOX_INDETERMINATE); | |
407 static SkBitmap* image_disabled_on = GfxGetBitmapNamed( | |
408 IDR_LINUX_CHECKBOX_DISABLED_ON); | |
409 static SkBitmap* image_on = GfxGetBitmapNamed(IDR_LINUX_CHECKBOX_ON); | |
410 static SkBitmap* image_disabled_off = GfxGetBitmapNamed( | |
411 IDR_LINUX_CHECKBOX_DISABLED_OFF); | |
412 static SkBitmap* image_off = GfxGetBitmapNamed(IDR_LINUX_CHECKBOX_OFF); | |
413 | |
414 SkBitmap* image = NULL; | |
415 if (button.indeterminate) { | |
416 image = state == kDisabled ? image_disabled_indeterminate | |
417 : image_indeterminate; | |
418 } else if (button.checked) { | |
419 image = state == kDisabled ? image_disabled_on : image_on; | |
420 } else { | |
421 image = state == kDisabled ? image_disabled_off : image_off; | |
422 } | |
423 | |
424 gfx::Rect bounds = rect.Center(gfx::Size(image->width(), image->height())); | |
425 canvas->drawBitmap(*image, SkIntToScalar(bounds.x()), | |
426 SkIntToScalar(bounds.y())); | |
427 } | |
428 | |
429 void NativeThemeLinux::PaintRadio(skia::PlatformCanvas* canvas, | |
430 State state, | |
431 const gfx::Rect& rect, | |
432 const ButtonExtraParams& button) { | |
433 static SkBitmap* image_disabled_on = GfxGetBitmapNamed( | |
434 IDR_LINUX_RADIO_DISABLED_ON); | |
435 static SkBitmap* image_on = GfxGetBitmapNamed(IDR_LINUX_RADIO_ON); | |
436 static SkBitmap* image_disabled_off = GfxGetBitmapNamed( | |
437 IDR_LINUX_RADIO_DISABLED_OFF); | |
438 static SkBitmap* image_off = GfxGetBitmapNamed(IDR_LINUX_RADIO_OFF); | |
439 | |
440 SkBitmap* image = NULL; | |
441 if (state == kDisabled) { | |
442 image = button.checked ? image_disabled_on : image_disabled_off; | |
DaveMoore
2011/01/19 17:04:13
Nit: No braces around the single line if / else
xiyuan
2011/01/19 19:06:42
Done.
| |
443 } else { | |
444 image = button.checked ? image_on : image_off; | |
445 } | |
446 | |
447 gfx::Rect bounds = rect.Center(gfx::Size(image->width(), image->height())); | |
448 canvas->drawBitmap(*image, SkIntToScalar(bounds.x()), | |
449 SkIntToScalar(bounds.y())); | |
450 } | |
451 | |
452 void NativeThemeLinux::PaintButton(skia::PlatformCanvas* canvas, | |
453 State state, | |
454 const gfx::Rect& rect, | |
455 const ButtonExtraParams& button) { | |
456 SkPaint paint; | |
457 SkRect skrect; | |
458 const int kRight = rect.right(); | |
459 const int kBottom = rect.bottom(); | |
460 SkColor base_color = button.background_color; | |
461 | |
462 color_utils::HSL base_hsl; | |
463 color_utils::SkColorToHSL(base_color, &base_hsl); | |
464 | |
465 // Our standard gradient is from 0xdd to 0xf8. This is the amount of | |
466 // increased luminance between those values. | |
467 SkColor light_color(BrightenColor(base_hsl, SkColorGetA(base_color), 0.105)); | |
468 | |
469 // If the button is too small, fallback to drawing a single, solid color | |
470 if (rect.width() < 5 || rect.height() < 5) { | |
471 paint.setColor(base_color); | |
472 skrect.set(rect.x(), rect.y(), kRight, kBottom); | |
473 canvas->drawRect(skrect, paint); | |
474 return; | |
475 } | |
476 | |
477 const int kBorderAlpha = state == kHover ? 0x80 : 0x55; | |
478 paint.setARGB(kBorderAlpha, 0, 0, 0); | |
479 canvas->drawLine(rect.x() + 1, rect.y(), kRight - 1, rect.y(), paint); | |
480 canvas->drawLine(kRight - 1, rect.y() + 1, kRight - 1, kBottom - 1, paint); | |
481 canvas->drawLine(rect.x() + 1, kBottom - 1, kRight - 1, kBottom - 1, paint); | |
482 canvas->drawLine(rect.x(), rect.y() + 1, rect.x(), kBottom - 1, paint); | |
483 | |
484 paint.setColor(SK_ColorBLACK); | |
485 const int kLightEnd = state == kPressed ? 1 : 0; | |
486 const int kDarkEnd = !kLightEnd; | |
487 SkPoint gradient_bounds[2]; | |
488 gradient_bounds[kLightEnd].set(SkIntToScalar(rect.x()), | |
489 SkIntToScalar(rect.y())); | |
490 gradient_bounds[kDarkEnd].set(SkIntToScalar(rect.x()), | |
491 SkIntToScalar(kBottom - 1)); | |
492 SkColor colors[2]; | |
493 colors[0] = light_color; | |
494 colors[1] = base_color; | |
495 | |
496 SkShader* shader = SkGradientShader::CreateLinear( | |
497 gradient_bounds, colors, NULL, 2, SkShader::kClamp_TileMode, NULL); | |
498 paint.setStyle(SkPaint::kFill_Style); | |
499 paint.setShader(shader); | |
500 shader->unref(); | |
501 | |
502 skrect.set(rect.x() + 1, rect.y() + 1, kRight - 1, kBottom - 1); | |
503 canvas->drawRect(skrect, paint); | |
504 | |
505 paint.setShader(NULL); | |
506 paint.setColor(BrightenColor(base_hsl, SkColorGetA(base_color), -0.0588)); | |
507 canvas->drawPoint(rect.x() + 1, rect.y() + 1, paint); | |
508 canvas->drawPoint(kRight - 2, rect.y() + 1, paint); | |
509 canvas->drawPoint(rect.x() + 1, kBottom - 2, paint); | |
510 canvas->drawPoint(kRight - 2, kBottom - 2, paint); | |
511 } | |
512 | |
513 void NativeThemeLinux::PaintTextField(skia::PlatformCanvas* canvas, | |
514 State state, | |
515 const gfx::Rect& rect, | |
516 const TextFieldExtraParams& text) { | |
517 // The following drawing code simulates the user-agent css border for | |
518 // text area and text input so that we do not break layout tests. Once we | |
519 // have decided the desired looks, we should update the code here and | |
520 // the layout test expectations. | |
521 SkRect bounds; | |
522 bounds.set(rect.x(), rect.y(), rect.right() - 1, rect.bottom() - 1); | |
523 | |
524 SkPaint fill_paint; | |
525 fill_paint.setStyle(SkPaint::kFill_Style); | |
526 fill_paint.setColor(text.background_color); | |
527 canvas->drawRect(bounds, fill_paint); | |
528 | |
529 if (text.is_text_area) { | |
530 // Draw text area border: 1px solid black | |
531 SkPaint stroke_paint; | |
532 fill_paint.setStyle(SkPaint::kStroke_Style); | |
533 fill_paint.setColor(SK_ColorBLACK); | |
534 canvas->drawRect(bounds, fill_paint); | |
535 } else { | |
536 // Draw text input and listbox inset border | |
537 // Text Input: 2px inset #eee | |
538 // Listbox: 1px inset #808080 | |
539 const SkColor kLightColor = text.is_listbox ? | |
540 SkColorSetRGB(0x80, 0x80, 0x80) : SkColorSetRGB(0xee, 0xee, 0xee); | |
541 const SkColor kDarkColor = text.is_listbox ? | |
542 SkColorSetRGB(0x2c, 0x2c, 0x2c) : SkColorSetRGB(0x9a, 0x9a, 0x9a); | |
543 const int kBorderWidth = text.is_listbox ? 1 : 2; | |
544 | |
545 SkPaint dark_paint; | |
546 dark_paint.setAntiAlias(true); | |
547 dark_paint.setStyle(SkPaint::kFill_Style); | |
548 dark_paint.setColor(kDarkColor); | |
549 | |
550 SkPaint light_paint; | |
551 light_paint.setAntiAlias(true); | |
552 light_paint.setStyle(SkPaint::kFill_Style); | |
553 light_paint.setColor(kLightColor); | |
554 | |
555 int left = rect.x(); | |
556 int top = rect.y(); | |
557 int right = rect.right(); | |
558 int bottom = rect.bottom(); | |
559 | |
560 SkPath path; | |
561 path.incReserve(4); | |
562 | |
563 // Top | |
564 path.moveTo(SkIntToScalar(left), SkIntToScalar(top)); | |
565 path.lineTo(SkIntToScalar(left + kBorderWidth), | |
566 SkIntToScalar(top + kBorderWidth)); | |
567 path.lineTo(SkIntToScalar(right - kBorderWidth), | |
568 SkIntToScalar(top + kBorderWidth)); | |
569 path.lineTo(SkIntToScalar(right), SkIntToScalar(top)); | |
570 canvas->drawPath(path, dark_paint); | |
571 | |
572 // Bottom | |
573 path.reset(); | |
574 path.moveTo(SkIntToScalar(left + kBorderWidth), | |
575 SkIntToScalar(bottom - kBorderWidth)); | |
576 path.lineTo(SkIntToScalar(left), SkIntToScalar(bottom)); | |
577 path.lineTo(SkIntToScalar(right), SkIntToScalar(bottom)); | |
578 path.lineTo(SkIntToScalar(right - kBorderWidth), | |
579 SkIntToScalar(bottom - kBorderWidth)); | |
580 canvas->drawPath(path, light_paint); | |
581 | |
582 // Left | |
583 path.reset(); | |
584 path.moveTo(SkIntToScalar(left), SkIntToScalar(top)); | |
585 path.lineTo(SkIntToScalar(left), SkIntToScalar(bottom)); | |
586 path.lineTo(SkIntToScalar(left + kBorderWidth), | |
587 SkIntToScalar(bottom - kBorderWidth)); | |
588 path.lineTo(SkIntToScalar(left + kBorderWidth), | |
589 SkIntToScalar(top + kBorderWidth)); | |
590 canvas->drawPath(path, dark_paint); | |
591 | |
592 // Right | |
593 path.reset(); | |
594 path.moveTo(SkIntToScalar(right - kBorderWidth), | |
595 SkIntToScalar(top + kBorderWidth)); | |
596 path.lineTo(SkIntToScalar(right - kBorderWidth), SkIntToScalar(bottom)); | |
597 path.lineTo(SkIntToScalar(right), SkIntToScalar(bottom)); | |
598 path.lineTo(SkIntToScalar(right), SkIntToScalar(top)); | |
599 canvas->drawPath(path, light_paint); | |
600 } | |
601 } | |
602 | |
603 void NativeThemeLinux::PaintMenuList(skia::PlatformCanvas* canvas, | |
604 State state, | |
605 const gfx::Rect& rect, | |
606 const MenuListExtraParams& menu_list) { | |
607 ButtonExtraParams button = { 0 }; | |
608 button.background_color = menu_list.background_color; | |
609 PaintButton(canvas, state, rect, button); | |
610 | |
611 SkPaint paint; | |
612 paint.setColor(SK_ColorBLACK); | |
613 paint.setAntiAlias(true); | |
614 paint.setStyle(SkPaint::kFill_Style); | |
615 | |
616 SkPath path; | |
617 path.moveTo(menu_list.arrow_x, menu_list.arrow_y - 3); | |
618 path.rLineTo(6, 0); | |
619 path.rLineTo(-3, 6); | |
620 path.close(); | |
621 canvas->drawPath(path, paint); | |
622 } | |
623 | |
624 void NativeThemeLinux::PaintSliderTrack(skia::PlatformCanvas* canvas, | |
625 State state, | |
626 const gfx::Rect& rect, | |
627 const SliderExtraParams& slider) { | |
628 const int kMidX = rect.x() + rect.width() / 2; | |
629 const int kMidY = rect.y() + rect.height() / 2; | |
630 | |
631 SkPaint paint; | |
632 paint.setColor(kSliderTrackBackgroundColor); | |
633 | |
634 SkRect skrect; | |
635 if (slider.vertical) { | |
636 skrect.set(std::max(rect.x(), kMidX - 2), | |
637 rect.y(), | |
638 std::min(rect.right(), kMidX + 2), | |
639 rect.bottom()); | |
640 } else { | |
641 skrect.set(rect.x(), | |
642 std::max(rect.y(), kMidY - 2), | |
643 rect.right(), | |
644 std::min(rect.bottom(), kMidY + 2)); | |
645 } | |
646 canvas->drawRect(skrect, paint); | |
647 } | |
648 | |
649 void NativeThemeLinux::PaintSliderThumb(skia::PlatformCanvas* canvas, | |
650 State state, | |
651 const gfx::Rect& rect, | |
652 const SliderExtraParams& slider) { | |
653 const bool hovered = state == kHover || slider.in_drag; | |
tony
2011/01/18 22:39:19
Nit: Can you put () around the ==? Also, it shoul
xiyuan
2011/01/19 19:06:42
Done.
| |
654 const int kMidX = rect.x() + rect.width() / 2; | |
655 const int kMidY = rect.y() + rect.height() / 2; | |
656 | |
657 SkPaint paint; | |
658 paint.setColor(hovered ? SK_ColorWHITE : kSliderThumbLightGrey); | |
659 | |
660 SkIRect skrect; | |
661 if (slider.vertical) | |
662 skrect.set(rect.x(), rect.y(), kMidX + 1, rect.bottom()); | |
663 else | |
664 skrect.set(rect.x(), rect.y(), rect.right(), kMidY + 1); | |
665 | |
666 canvas->drawIRect(skrect, paint); | |
667 | |
668 paint.setColor(hovered ? kSliderThumbLightGrey : kSliderThumbDarkGrey); | |
669 | |
670 if (slider.vertical) | |
671 skrect.set(kMidX + 1, rect.y(), rect.right(), rect.bottom()); | |
672 else | |
673 skrect.set(rect.x(), kMidY + 1, rect.right(), rect.bottom()); | |
674 | |
675 canvas->drawIRect(skrect, paint); | |
676 | |
677 paint.setColor(kSliderThumbBorderDarkGrey); | |
678 DrawBox(canvas, rect, paint); | |
679 | |
680 if (rect.height() > 10 && rect.width() > 10) { | |
681 DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY, paint); | |
682 DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY - 3, paint); | |
683 DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY + 3, paint); | |
684 } | |
685 } | |
686 | |
687 void NativeThemeLinux::PaintInnerSpinButton(skia::PlatformCanvas* canvas, | |
688 State state, | |
689 const gfx::Rect& rect, | |
690 const InnerSpinButtonExtraParams& spin_button) { | |
691 if (spin_button.read_only) | |
692 state = kDisabled; | |
693 | |
694 State north_state = state; | |
695 State south_state = state; | |
696 if (spin_button.spin_up) | |
697 south_state = south_state != kDisabled ? kNormal : kDisabled; | |
698 else | |
699 north_state = north_state != kDisabled ? kNormal : kDisabled; | |
700 | |
701 gfx::Rect half = rect; | |
702 half.set_height(rect.height() / 2); | |
703 PaintArrowButton(canvas, half, kScrollbarUpArrow, north_state); | |
704 | |
705 half.set_y(rect.y() + rect.height() / 2); | |
706 PaintArrowButton(canvas, half, kScrollbarDownArrow, south_state); | |
707 } | |
708 | |
709 void NativeThemeLinux::PaintProgressBar(skia::PlatformCanvas* canvas, | |
710 State state, | |
711 const gfx::Rect& rect, | |
712 const ProgressBarExtraParams& progress_bar) { | |
713 static SkBitmap* bar_image = GfxGetBitmapNamed(IDR_PROGRESS_BAR); | |
714 static SkBitmap* value_image = GfxGetBitmapNamed(IDR_PROGRESS_VALUE); | |
715 static SkBitmap* left_border_image = GfxGetBitmapNamed( | |
716 IDR_PROGRESS_BORDER_LEFT); | |
717 static SkBitmap* right_border_image = GfxGetBitmapNamed( | |
718 IDR_PROGRESS_BORDER_RIGHT); | |
719 | |
720 double tile_scale = static_cast<double>(rect.height()) / | |
721 bar_image->height(); | |
722 | |
723 int new_tile_width = static_cast<int>(bar_image->width() * tile_scale); | |
724 double tile_scale_x = static_cast<double>(new_tile_width) / | |
725 bar_image->width(); | |
726 | |
727 DrawTiledImage(canvas, *bar_image, 0, 0, tile_scale_x, tile_scale, | |
728 rect.x(), rect.y(), rect.width(), rect.height()); | |
729 | |
730 if (progress_bar.value_rect_width) { | |
731 | |
732 new_tile_width = static_cast<int>(value_image->width() * tile_scale); | |
733 tile_scale_x = static_cast<double>(new_tile_width) / | |
734 value_image->width(); | |
735 | |
736 DrawTiledImage(canvas, *value_image, 0, 0, tile_scale_x, tile_scale, | |
737 progress_bar.value_rect_x, | |
738 progress_bar.value_rect_y, | |
739 progress_bar.value_rect_width, | |
740 progress_bar.value_rect_height); | |
741 } | |
742 | |
743 int dest_left_border_width = static_cast<int>(left_border_image->width() * | |
744 tile_scale); | |
745 SkRect dest_rect = { | |
746 SkIntToScalar(rect.x()), | |
747 SkIntToScalar(rect.y()), | |
748 SkIntToScalar(rect.x() + dest_left_border_width), | |
749 SkIntToScalar(rect.bottom()) | |
750 }; | |
751 canvas->drawBitmapRect(*left_border_image, NULL, dest_rect); | |
752 | |
753 int dest_right_border_width = static_cast<int>(right_border_image->width() * | |
754 tile_scale); | |
755 dest_rect.set(SkIntToScalar(rect.right() - dest_right_border_width), | |
756 SkIntToScalar(rect.y()), | |
757 SkIntToScalar(rect.right()), | |
758 SkIntToScalar(rect.bottom())); | |
759 canvas->drawBitmapRect(*right_border_image, NULL, dest_rect); | |
760 } | |
761 | |
307 void NativeThemeLinux::DrawVertLine(SkCanvas* canvas, | 762 void NativeThemeLinux::DrawVertLine(SkCanvas* canvas, |
308 int x, | 763 int x, |
309 int y1, | 764 int y1, |
310 int y2, | 765 int y2, |
311 const SkPaint& paint) const { | 766 const SkPaint& paint) const { |
312 SkIRect skrect; | 767 SkIRect skrect; |
313 skrect.set(x, y1, x + 1, y2 + 1); | 768 skrect.set(x, y1, x + 1, y2 + 1); |
314 canvas->drawIRect(skrect, paint); | 769 canvas->drawIRect(skrect, paint); |
315 } | 770 } |
316 | 771 |
(...skipping 11 matching lines...) Expand all Loading... | |
328 const gfx::Rect& rect, | 783 const gfx::Rect& rect, |
329 const SkPaint& paint) const { | 784 const SkPaint& paint) const { |
330 const int right = rect.x() + rect.width() - 1; | 785 const int right = rect.x() + rect.width() - 1; |
331 const int bottom = rect.y() + rect.height() - 1; | 786 const int bottom = rect.y() + rect.height() - 1; |
332 DrawHorizLine(canvas, rect.x(), right, rect.y(), paint); | 787 DrawHorizLine(canvas, rect.x(), right, rect.y(), paint); |
333 DrawVertLine(canvas, right, rect.y(), bottom, paint); | 788 DrawVertLine(canvas, right, rect.y(), bottom, paint); |
334 DrawHorizLine(canvas, rect.x(), right, bottom, paint); | 789 DrawHorizLine(canvas, rect.x(), right, bottom, paint); |
335 DrawVertLine(canvas, rect.x(), rect.y(), bottom, paint); | 790 DrawVertLine(canvas, rect.x(), rect.y(), bottom, paint); |
336 } | 791 } |
337 | 792 |
793 void NativeThemeLinux::DrawTiledImage(SkCanvas* canvas, | |
794 const SkBitmap& bitmap, | |
795 int src_x, int src_y, double tile_scale_x, double tile_scale_y, | |
796 int dest_x, int dest_y, int w, int h) const { | |
797 SkShader* shader = SkShader::CreateBitmapShader(bitmap, | |
798 SkShader::kRepeat_TileMode, | |
799 SkShader::kRepeat_TileMode); | |
800 if (tile_scale_x != 1.0 || tile_scale_y != 1.0) { | |
801 SkMatrix shader_scale; | |
802 shader_scale.setScale(SkDoubleToScalar(tile_scale_x), | |
803 SkDoubleToScalar(tile_scale_y)); | |
804 shader->setLocalMatrix(shader_scale); | |
805 } | |
806 | |
807 SkPaint paint; | |
808 paint.setShader(shader); | |
809 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); | |
810 | |
811 // CreateBitmapShader returns a Shader with a reference count of one, we | |
812 // need to unref after paint takes ownership of the shader. | |
813 shader->unref(); | |
814 canvas->save(); | |
815 canvas->translate(SkIntToScalar(dest_x - src_x), | |
816 SkIntToScalar(dest_y - src_y)); | |
817 canvas->clipRect(SkRect::MakeXYWH(src_x, src_y, w, h)); | |
818 canvas->drawPaint(paint); | |
819 canvas->restore(); | |
820 } | |
821 | |
338 SkScalar NativeThemeLinux::Clamp(SkScalar value, | 822 SkScalar NativeThemeLinux::Clamp(SkScalar value, |
339 SkScalar min, | 823 SkScalar min, |
340 SkScalar max) const { | 824 SkScalar max) const { |
341 return std::min(std::max(value, min), max); | 825 return std::min(std::max(value, min), max); |
342 } | 826 } |
343 | 827 |
344 SkColor NativeThemeLinux::SaturateAndBrighten(SkScalar* hsv, | 828 SkColor NativeThemeLinux::SaturateAndBrighten(SkScalar* hsv, |
345 SkScalar saturate_amount, | 829 SkScalar saturate_amount, |
346 SkScalar brighten_amount) const { | 830 SkScalar brighten_amount) const { |
347 SkScalar color[3]; | 831 SkScalar color[3]; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
390 | 874 |
391 void NativeThemeLinux::SetScrollbarColors(unsigned inactive_color, | 875 void NativeThemeLinux::SetScrollbarColors(unsigned inactive_color, |
392 unsigned active_color, | 876 unsigned active_color, |
393 unsigned track_color) const { | 877 unsigned track_color) const { |
394 thumb_inactive_color_ = inactive_color; | 878 thumb_inactive_color_ = inactive_color; |
395 thumb_active_color_ = active_color; | 879 thumb_active_color_ = active_color; |
396 track_color_ = track_color; | 880 track_color_ = track_color; |
397 } | 881 } |
398 | 882 |
399 } // namespace gfx | 883 } // namespace gfx |
OLD | NEW |