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

Side by Side Diff: gfx/native_theme_linux.cc

Issue 6254004: Move more web widgets painting from webkit to chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 11 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 | Annotate | Revision Log
OLDNEW
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 const int NativeThemeLinux::kCheckboxAndRadioWidth = 13;
26 const int NativeThemeLinux::kCheckboxAndRadioHeight = 13;
27
28 static const SkColor kSliderTrackBackgroundColor =
29 SkColorSetRGB(0xe3, 0xdd, 0xd8);
30 static const SkColor kSliderThumbLightGrey = SkColorSetRGB(0xf4, 0xf2, 0xef);
31 static const SkColor kSliderThumbDarkGrey = SkColorSetRGB(0xea, 0xe5, 0xe0);
32 static const SkColor kSliderThumbBorderDarkGrey =
33 SkColorSetRGB(0x9d, 0x96, 0x8e);
34
19 #if !defined(OS_CHROMEOS) 35 #if !defined(OS_CHROMEOS)
20 // Chromeos has a different look. 36 // Chromeos has a different look.
21 // static 37 // static
22 NativeThemeLinux* NativeThemeLinux::instance() { 38 NativeThemeLinux* NativeThemeLinux::instance() {
23 // The global NativeThemeLinux instance. 39 // The global NativeThemeLinux instance.
24 static NativeThemeLinux s_native_theme; 40 static NativeThemeLinux s_native_theme;
25 return &s_native_theme; 41 return &s_native_theme;
26 } 42 }
27 #endif 43 #endif
28 44
45 static SkBitmap* GfxGetBitmapNamed(int key) {
46 base::StringPiece data = GfxModule::GetResource(key);
47
48 SkBitmap bitmap;
49 gfx::PNGCodec::Decode(reinterpret_cast<const unsigned char*>(data.data()),
50 data.size(), &bitmap);
tony 2011/01/14 22:06:04 Should we DCHECK the return value of Decode? Mayb
xiyuan 2011/01/18 21:30:49 Done.
51 return new SkBitmap(bitmap);
52 }
53
29 NativeThemeLinux::NativeThemeLinux() { 54 NativeThemeLinux::NativeThemeLinux() {
30 } 55 }
31 56
32 NativeThemeLinux::~NativeThemeLinux() { 57 NativeThemeLinux::~NativeThemeLinux() {
33 } 58 }
34 59
35 gfx::Size NativeThemeLinux::GetSize(Part part) const { 60 gfx::Size NativeThemeLinux::GetSize(Part part) const {
36 switch (part) { 61 switch (part) {
37 case kScrollbarDownArrow: 62 case kScrollbarDownArrow:
38 case kScrollbarUpArrow: 63 case kScrollbarUpArrow:
39 return gfx::Size(scrollbar_width_, button_length_); 64 return gfx::Size(scrollbar_width_, button_length_);
40 case kScrollbarLeftArrow: 65 case kScrollbarLeftArrow:
41 case kScrollbarRightArrow: 66 case kScrollbarRightArrow:
42 return gfx::Size(button_length_, scrollbar_width_); 67 return gfx::Size(button_length_, scrollbar_width_);
43 case kScrollbarHorizontalThumb: 68 case kScrollbarHorizontalThumb:
44 // This matches Firefox on Linux. 69 // This matches Firefox on Linux.
45 return gfx::Size(2 * scrollbar_width_, scrollbar_width_); 70 return gfx::Size(2 * scrollbar_width_, scrollbar_width_);
46 case kScrollbarVerticalThumb: 71 case kScrollbarVerticalThumb:
47 // This matches Firefox on Linux. 72 // This matches Firefox on Linux.
48 return gfx::Size(scrollbar_width_, 2 * scrollbar_width_); 73 return gfx::Size(scrollbar_width_, 2 * scrollbar_width_);
49 break; 74 break;
50 case kScrollbarHorizontalTrack: 75 case kScrollbarHorizontalTrack:
51 return gfx::Size(0, scrollbar_width_); 76 return gfx::Size(0, scrollbar_width_);
52 case kScrollbarVerticalTrack: 77 case kScrollbarVerticalTrack:
53 return gfx::Size(scrollbar_width_, 0); 78 return gfx::Size(scrollbar_width_, 0);
79 case kCheckbox:
80 case kRadio:
81 return gfx::Size(kCheckboxAndRadioWidth, kCheckboxAndRadioHeight);
82 case kSliderThumb:
83 // These sizes match the sizes in Chromium Win.
84 return gfx::Size(11, 21);
tony 2011/01/14 22:06:04 Can we convert 11 and 21 into constants?
xiyuan 2011/01/18 21:30:49 Done.
85 case kInnerSpinButton:
86 return gfx::Size(scrollbar_width_, 0);
87 case kPushButton:
88 case kTextField:
89 case kMenuList:
90 case kSliderTrack:
91 case kProgressBar:
92 return gfx::Size(); // No default size.
54 } 93 }
55 return gfx::Size(); 94 return gfx::Size();
56 } 95 }
57 96
58 void NativeThemeLinux::PaintArrowButton( 97 void NativeThemeLinux::PaintArrowButton(
59 skia::PlatformCanvas* canvas, 98 skia::PlatformCanvas* canvas,
60 const gfx::Rect& rect, Part direction, State state) { 99 const gfx::Rect& rect, Part direction, State state) {
61 int widthMiddle, lengthMiddle; 100 int widthMiddle, lengthMiddle;
62 SkPaint paint; 101 SkPaint paint;
63 if (direction == kScrollbarUpArrow || direction == kScrollbarDownArrow) { 102 if (direction == kScrollbarUpArrow || direction == kScrollbarDownArrow) {
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 PaintArrowButton(canvas, rect, part, state); 233 PaintArrowButton(canvas, rect, part, state);
195 break; 234 break;
196 case kScrollbarHorizontalThumb: 235 case kScrollbarHorizontalThumb:
197 case kScrollbarVerticalThumb: 236 case kScrollbarVerticalThumb:
198 PaintThumb(canvas, part, state, rect); 237 PaintThumb(canvas, part, state, rect);
199 break; 238 break;
200 case kScrollbarHorizontalTrack: 239 case kScrollbarHorizontalTrack:
201 case kScrollbarVerticalTrack: 240 case kScrollbarVerticalTrack:
202 PaintTrack(canvas, part, state, extra.scrollbar_track, rect); 241 PaintTrack(canvas, part, state, extra.scrollbar_track, rect);
203 break; 242 break;
243 case kCheckbox:
244 PaintCheckbox(canvas, state, rect, extra.button);
245 break;
246 case kRadio:
247 PaintRadio(canvas, state, rect, extra.button);
248 break;
249 case kPushButton:
250 PaintButton(canvas, state, rect, extra.button);
251 break;
252 case kTextField:
253 PaintTextField(canvas, state, rect, extra.text_field);
254 break;
255 case kMenuList:
256 PaintMenuList(canvas, state, rect, extra.menu_list);
257 break;
258 case kSliderTrack:
259 PaintSliderTrack(canvas, state, rect, extra.slider);
260 break;
261 case kSliderThumb:
262 PaintSliderThumb(canvas, state, rect, extra.slider);
263 break;
264 case kInnerSpinButton:
265 PaintInnerSpinButton(canvas, state, rect, extra.inner_spin);
266 break;
267 case kProgressBar:
268 PaintProgressBar(canvas, state, rect, extra.progress_bar);
269 break;
204 } 270 }
205 } 271 }
206 272
207 void NativeThemeLinux::PaintTrack(skia::PlatformCanvas* canvas, 273 void NativeThemeLinux::PaintTrack(skia::PlatformCanvas* canvas,
208 Part part, 274 Part part,
209 State state, 275 State state,
210 const ScrollbarTrackExtraParams& extra_params, 276 const ScrollbarTrackExtraParams& extra_params,
211 const gfx::Rect& rect) { 277 const gfx::Rect& rect) {
212 SkPaint paint; 278 SkPaint paint;
213 SkIRect skrect; 279 SkIRect skrect;
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 paint); 363 paint);
298 DrawVertLine(canvas, 364 DrawVertLine(canvas,
299 midx + inter_grippy_offset, 365 midx + inter_grippy_offset,
300 midy - grippy_half_width, 366 midy - grippy_half_width,
301 midy + grippy_half_width, 367 midy + grippy_half_width,
302 paint); 368 paint);
303 } 369 }
304 } 370 }
305 } 371 }
306 372
373 void NativeThemeLinux::PaintCheckbox(skia::PlatformCanvas* canvas,
374 State state,
375 const gfx::Rect& rect,
376 const ButtonExtraParams& button) {
377 static SkBitmap* image_disabled_indeterminate = GfxGetBitmapNamed(
378 IDR_LINUX_CHECKBOX_DISABLED_INDETERMINATE);
379 static SkBitmap* image_indeterminate = GfxGetBitmapNamed(
380 IDR_LINUX_CHECKBOX_INDETERMINATE);
381 static SkBitmap* image_disabled_on = GfxGetBitmapNamed(
382 IDR_LINUX_CHECKBOX_DISABLED_ON);
383 static SkBitmap* image_on = GfxGetBitmapNamed(IDR_LINUX_CHECKBOX_ON);
384 static SkBitmap* image_disabled_off = GfxGetBitmapNamed(
385 IDR_LINUX_CHECKBOX_DISABLED_OFF);
386 static SkBitmap* image_off = GfxGetBitmapNamed(IDR_LINUX_CHECKBOX_OFF);
387
388 SkBitmap* image = NULL;
389 if (button.indeterminate) {
390 image = state == kDisabled ? image_disabled_indeterminate :
tony 2011/01/14 22:06:04 Nit: I normally line up the : below the ?
xiyuan 2011/01/18 21:30:49 Done.
391 image_indeterminate;
392 } else if (button.checked) {
393 image = state == kDisabled ? image_disabled_on : image_on;
394 } else {
395 image = state == kDisabled ? image_disabled_off : image_off;
396 }
397
398 gfx::Rect bounds = rect.Center(gfx::Size(image->width(), image->height()));
399 canvas->drawBitmap(*image, SkIntToScalar(bounds.x()),
400 SkIntToScalar(bounds.y()));
401 }
402
403 void NativeThemeLinux::PaintRadio(skia::PlatformCanvas* canvas,
404 State state,
405 const gfx::Rect& rect,
406 const ButtonExtraParams& button) {
407 static SkBitmap* image_disabled_on = GfxGetBitmapNamed(
408 IDR_LINUX_RADIO_DISABLED_ON);
409 static SkBitmap* image_on = GfxGetBitmapNamed(IDR_LINUX_RADIO_ON);
410 static SkBitmap* image_disabled_off = GfxGetBitmapNamed(
411 IDR_LINUX_RADIO_DISABLED_OFF);
412 static SkBitmap* image_off = GfxGetBitmapNamed(IDR_LINUX_RADIO_OFF);
413
414 SkBitmap* image = NULL;
415 if (state == kDisabled) {
416 image = button.checked ? image_disabled_on : image_disabled_off;
417 } else {
418 image = button.checked ? image_on : image_off;
419 }
420
421 gfx::Rect bounds = rect.Center(gfx::Size(image->width(), image->height()));
422 canvas->drawBitmap(*image, SkIntToScalar(bounds.x()),
423 SkIntToScalar(bounds.y()));
424 }
425
426 void NativeThemeLinux::PaintButton(skia::PlatformCanvas* canvas,
427 State state,
428 const gfx::Rect& rect,
429 const ButtonExtraParams& button) {
430 SkPaint paint;
431 SkRect skrect;
432 const int right = rect.right();
tony 2011/01/14 22:06:04 Local consts should still be of the form kRight. h
xiyuan 2011/01/18 21:30:49 Done.
433 const int bottom = rect.bottom();
434 SkColor base_color = button.background_color;
435
436 color_utils::HSL base_hsl;
437 color_utils::SkColorToHSL(base_color, &base_hsl);
438
439 // Our standard gradient is from 0xdd to 0xf8. This is the amount of
440 // increased luminance between those values.
441 SkColor light_color(BrightenColor(base_hsl, SkColorGetA(base_color), 0.105));
442
443 // If the button is too small, fallback to drawing a single, solid color
444 if (rect.width() < 5 || rect.height() < 5) {
445 paint.setColor(base_color);
446 skrect.set(rect.x(), rect.y(), right, bottom);
447 canvas->drawRect(skrect, paint);
448 return;
449 }
450
451 const int border_alpha = state == kHover ? 0x80 : 0x55;
tony 2011/01/14 22:06:04 const naming
xiyuan 2011/01/18 21:30:49 Done.
452 paint.setARGB(border_alpha, 0, 0, 0);
453 canvas->drawLine(rect.x() + 1, rect.y(), right - 1, rect.y(), paint);
454 canvas->drawLine(right - 1, rect.y() + 1, right - 1, bottom - 1, paint);
455 canvas->drawLine(rect.x() + 1, bottom - 1, right - 1, bottom - 1, paint);
456 canvas->drawLine(rect.x(), rect.y() + 1, rect.x(), bottom - 1, paint);
457
458 paint.setColor(SK_ColorBLACK);
459 SkPoint p[2];
tony 2011/01/14 22:06:04 Please use a variable name other than p. Maybe gr
xiyuan 2011/01/18 21:30:49 Done.
460 const int light_end = state == kPressed ? 1 : 0;
461 const int dark_end = !light_end;
tony 2011/01/14 22:06:04 const naming
xiyuan 2011/01/18 21:30:49 Done.
462 p[light_end].set(SkIntToScalar(rect.x()), SkIntToScalar(rect.y()));
463 p[dark_end].set(SkIntToScalar(rect.x()), SkIntToScalar(bottom - 1));
464 SkColor colors[2];
465 colors[0] = light_color;
466 colors[1] = base_color;
467
468 SkShader* shader = SkGradientShader::CreateLinear(
469 p, colors, NULL, 2, SkShader::kClamp_TileMode, NULL);
470 paint.setStyle(SkPaint::kFill_Style);
471 paint.setShader(shader);
472 shader->unref();
473
474 skrect.set(rect.x() + 1, rect.y() + 1, right - 1, bottom - 1);
475 canvas->drawRect(skrect, paint);
476
477 paint.setShader(NULL);
478 paint.setColor(BrightenColor(base_hsl, SkColorGetA(base_color), -0.0588));
479 canvas->drawPoint(rect.x() + 1, rect.y() + 1, paint);
480 canvas->drawPoint(right - 2, rect.y() + 1, paint);
481 canvas->drawPoint(rect.x() + 1, bottom - 2, paint);
482 canvas->drawPoint(right - 2, bottom - 2, paint);
483 }
484
485 void NativeThemeLinux::PaintTextField(skia::PlatformCanvas* canvas,
486 State state,
487 const gfx::Rect& rect,
488 const TextFieldExtraParams& text) {
489 // The following drawing code simulates the user-agent css border for
490 // text area and text input so that we do not break layout tests. Once we
491 // have decided the desired looks, we should update the code here and
492 // the layout test expectations.
493 SkRect bounds;
494 bounds.set(rect.x(), rect.y(), rect.right() - 1, rect.bottom() - 1);
495
496 SkPaint fill_paint;
497 fill_paint.setStyle(SkPaint::kFill_Style);
498 fill_paint.setColor(text.background_color);
499 canvas->drawRect(bounds, fill_paint);
500
501 if (text.is_text_area) {
502 // Draw text area border: 1px solid black
503 SkPaint stroke_paint;
504 fill_paint.setStyle(SkPaint::kStroke_Style);
505 fill_paint.setColor(SK_ColorBLACK);
506 canvas->drawRect(bounds, fill_paint);
507 } else {
508 // Draw text input and listbox inset border
509 // Text Input: 2px inset #eee
510 // Listbox: 1px inset #808080
511 const SkColor kLightColor = text.is_listbox ?
tony 2011/01/14 22:06:04 const naming
xiyuan 2011/01/18 21:30:49 Done. border_width -> kBorderWidth
512 SkColorSetRGB(0x80, 0x80, 0x80) : SkColorSetRGB(0xee, 0xee, 0xee);
513 const SkColor kDarkColor = text.is_listbox ?
514 SkColorSetRGB(0x2c, 0x2c, 0x2c) : SkColorSetRGB(0x9a, 0x9a, 0x9a);
515 const int border_width = text.is_listbox ? 1 : 2;
516
517 SkPaint dark_paint;
518 dark_paint.setAntiAlias(true);
519 dark_paint.setStyle(SkPaint::kFill_Style);
520 dark_paint.setColor(kDarkColor);
521
522 SkPaint light_paint;
523 light_paint.setAntiAlias(true);
524 light_paint.setStyle(SkPaint::kFill_Style);
525 light_paint.setColor(kLightColor);
526
527 int left = rect.x();
528 int top = rect.y();
529 int right = rect.right();
530 int bottom = rect.bottom();
531
532 SkPath path;
533 path.incReserve(4);
534
535 // Top
536 path.moveTo(SkIntToScalar(left), SkIntToScalar(top));
537 path.lineTo(SkIntToScalar(left + border_width),
538 SkIntToScalar(top + border_width));
539 path.lineTo(SkIntToScalar(right - border_width),
540 SkIntToScalar(top + border_width));
541 path.lineTo(SkIntToScalar(right), SkIntToScalar(top));
542 canvas->drawPath(path, dark_paint);
543
544 // Bottom
545 path.reset();
546 path.moveTo(SkIntToScalar(left + border_width),
547 SkIntToScalar(bottom - border_width));
548 path.lineTo(SkIntToScalar(left), SkIntToScalar(bottom));
549 path.lineTo(SkIntToScalar(right), SkIntToScalar(bottom));
550 path.lineTo(SkIntToScalar(right - border_width),
551 SkIntToScalar(bottom - border_width));
552 canvas->drawPath(path, light_paint);
553
554 // Left
555 path.reset();
556 path.moveTo(SkIntToScalar(left), SkIntToScalar(top));
557 path.lineTo(SkIntToScalar(left), SkIntToScalar(bottom));
558 path.lineTo(SkIntToScalar(left + border_width),
559 SkIntToScalar(bottom - border_width));
560 path.lineTo(SkIntToScalar(left + border_width),
561 SkIntToScalar(top + border_width));
562 canvas->drawPath(path, dark_paint);
563
564 // Right
565 path.reset();
566 path.moveTo(SkIntToScalar(right - border_width),
567 SkIntToScalar(top + border_width));
568 path.lineTo(SkIntToScalar(right - border_width), SkIntToScalar(bottom));
569 path.lineTo(SkIntToScalar(right), SkIntToScalar(bottom));
570 path.lineTo(SkIntToScalar(right), SkIntToScalar(top));
571 canvas->drawPath(path, light_paint);
572 }
573 }
574
575 void NativeThemeLinux::PaintMenuList(skia::PlatformCanvas* canvas,
576 State state,
577 const gfx::Rect& rect,
578 const MenuListExtraParams& menu_list) {
579 ButtonExtraParams button = { 0 };
580 button.background_color = menu_list.background_color;
581 PaintButton(canvas, state, rect, button);
582
583 SkPaint paint;
584 paint.setColor(SK_ColorBLACK);
585 paint.setAntiAlias(true);
586 paint.setStyle(SkPaint::kFill_Style);
587
588 SkPath path;
589 path.moveTo(menu_list.arrow_x, menu_list.arrow_y - 3);
590 path.rLineTo(6, 0);
591 path.rLineTo(-3, 6);
592 path.close();
593 canvas->drawPath(path, paint);
594 }
595
596 void NativeThemeLinux::PaintSliderTrack(skia::PlatformCanvas* canvas,
597 State state,
598 const gfx::Rect& rect,
599 const SliderExtraParams& slider) {
600 const int midx = rect.x() + rect.width() / 2;
601 const int midy = rect.y() + rect.height() / 2;
tony 2011/01/14 22:06:04 const naming
xiyuan 2011/01/18 21:30:49 Done.
602
603 SkPaint paint;
604 paint.setColor(kSliderTrackBackgroundColor);
605
606 SkRect skrect;
607 if (slider.vertical) {
608 skrect.set(std::max(rect.x(), midx - 2),
609 rect.y(),
610 std::min(rect.right(), midx + 2),
611 rect.bottom());
612 } else {
613 skrect.set(rect.x(),
614 std::max(rect.y(), midy - 2),
615 rect.right(),
616 std::min(rect.bottom(), midy + 2));
617 }
618 canvas->drawRect(skrect, paint);
619 }
620
621 void NativeThemeLinux::PaintSliderThumb(skia::PlatformCanvas* canvas,
622 State state,
623 const gfx::Rect& rect,
624 const SliderExtraParams& slider) {
625 const bool hovered = state == kHover || slider.in_drag;
626 const int midx = rect.x() + rect.width() / 2;
627 const int midy = rect.y() + rect.height() / 2;
tony 2011/01/14 22:06:04 const naming
xiyuan 2011/01/18 21:30:49 Done.
628
629 SkPaint paint;
630 paint.setColor(hovered ? SK_ColorWHITE : kSliderThumbLightGrey);
631
632 SkIRect skrect;
633 if (slider.vertical)
634 skrect.set(rect.x(), rect.y(), midx + 1, rect.bottom());
635 else
636 skrect.set(rect.x(), rect.y(), rect.right(), midy + 1);
637
638 canvas->drawIRect(skrect, paint);
639
640 paint.setColor(hovered ? kSliderThumbLightGrey : kSliderThumbDarkGrey);
641
642 if (slider.vertical)
643 skrect.set(midx + 1, rect.y(), rect.right(), rect.bottom());
644 else
645 skrect.set(rect.x(), midy + 1, rect.right(), rect.bottom());
646
647 canvas->drawIRect(skrect, paint);
648
649 paint.setColor(kSliderThumbBorderDarkGrey);
650 DrawBox(canvas, rect, paint);
651
652 if (rect.height() > 10 && rect.width() > 10) {
653 DrawHorizLine(canvas, midx - 2, midx + 2, midy, paint);
654 DrawHorizLine(canvas, midx - 2, midx + 2, midy - 3, paint);
655 DrawHorizLine(canvas, midx - 2, midx + 2, midy + 3, paint);
656 }
657 }
658
659 void NativeThemeLinux::PaintInnerSpinButton(skia::PlatformCanvas* canvas,
660 State state,
tony 2011/01/14 22:06:04 Nit: I think we often put multiple params on the s
xiyuan 2011/01/18 21:30:49 The third param is long and could in. That's why I
tony 2011/01/18 22:39:19 *shrug* this is fine. I don't have a strong feeli
661 const gfx::Rect& rect,
662 const InnerSpinButtonExtraParams& spin_button) {
663 if (spin_button.read_only)
664 state = kDisabled;
665
666 State north_state = state;
667 State south_state = state;
668 if (spin_button.spin_up)
669 south_state = south_state != kDisabled ? kNormal : kDisabled;
670 else
671 north_state = north_state != kDisabled ? kNormal : kDisabled;
672
673 gfx::Rect half = rect;
674 half.set_height(rect.height() / 2);
675 PaintArrowButton(canvas, half, kScrollbarUpArrow, north_state);
676
677 half.set_y(rect.y() + rect.height() / 2);
678 PaintArrowButton(canvas, half, kScrollbarDownArrow, south_state);
679 }
680
681 void NativeThemeLinux::PaintProgressBar(skia::PlatformCanvas* canvas,
682 State state,
683 const gfx::Rect& rect,
684 const ProgressBarExtraParams& progress_bar) {
685 static SkBitmap* bar_image = GfxGetBitmapNamed(IDR_PROGRESS_BAR);
686 static SkBitmap* value_image = GfxGetBitmapNamed(IDR_PROGRESS_VALUE);
687 static SkBitmap* left_border_image = GfxGetBitmapNamed(
688 IDR_PROGRESS_BORDER_LEFT);
689 static SkBitmap* right_border_image = GfxGetBitmapNamed(
690 IDR_PROGRESS_BORDER_RIGHT);
691
692 double tile_scale = static_cast<double>(rect.height()) /
693 bar_image->height();
694
695 int new_tile_width = static_cast<int>(bar_image->width() * tile_scale);
696 double tile_scale_x = static_cast<double>(new_tile_width) /
697 bar_image->width();
698
699 DrawTiledImage(canvas, *bar_image, 0, 0, tile_scale_x, tile_scale,
700 rect.x(), rect.y(), rect.width(), rect.height());
701
702 if (progress_bar.value_rect_width) {
703
704 new_tile_width = static_cast<int>(value_image->width() * tile_scale);
705 tile_scale_x = static_cast<double>(new_tile_width) /
706 value_image->width();
707
708 DrawTiledImage(canvas, *value_image, 0, 0, tile_scale_x, tile_scale,
709 progress_bar.value_rect_x,
710 progress_bar.value_rect_y,
711 progress_bar.value_rect_width,
712 progress_bar.value_rect_height);
713 }
714
715 int dest_left_border_width = static_cast<int>(left_border_image->width() *
716 tile_scale);
717 SkRect dest_rect = {
718 SkIntToScalar(rect.x()),
719 SkIntToScalar(rect.y()),
720 SkIntToScalar(rect.x() + dest_left_border_width),
721 SkIntToScalar(rect.bottom())
tony 2011/01/14 22:06:04 indent 2 spaces more
xiyuan 2011/01/18 21:30:49 Done.
722 };
723 canvas->drawBitmapRect(*left_border_image, NULL, dest_rect);
724
725 int dest_right_border_width = static_cast<int>(right_border_image->width() *
726 tile_scale);
727 dest_rect.set(SkIntToScalar(rect.right() - dest_right_border_width),
728 SkIntToScalar(rect.y()),
729 SkIntToScalar(rect.right()),
730 SkIntToScalar(rect.bottom()));
731 canvas->drawBitmapRect(*right_border_image, NULL, dest_rect);
732 }
733
307 void NativeThemeLinux::DrawVertLine(SkCanvas* canvas, 734 void NativeThemeLinux::DrawVertLine(SkCanvas* canvas,
308 int x, 735 int x,
309 int y1, 736 int y1,
310 int y2, 737 int y2,
311 const SkPaint& paint) const { 738 const SkPaint& paint) const {
312 SkIRect skrect; 739 SkIRect skrect;
313 skrect.set(x, y1, x + 1, y2 + 1); 740 skrect.set(x, y1, x + 1, y2 + 1);
314 canvas->drawIRect(skrect, paint); 741 canvas->drawIRect(skrect, paint);
315 } 742 }
316 743
(...skipping 11 matching lines...) Expand all
328 const gfx::Rect& rect, 755 const gfx::Rect& rect,
329 const SkPaint& paint) const { 756 const SkPaint& paint) const {
330 const int right = rect.x() + rect.width() - 1; 757 const int right = rect.x() + rect.width() - 1;
331 const int bottom = rect.y() + rect.height() - 1; 758 const int bottom = rect.y() + rect.height() - 1;
332 DrawHorizLine(canvas, rect.x(), right, rect.y(), paint); 759 DrawHorizLine(canvas, rect.x(), right, rect.y(), paint);
333 DrawVertLine(canvas, right, rect.y(), bottom, paint); 760 DrawVertLine(canvas, right, rect.y(), bottom, paint);
334 DrawHorizLine(canvas, rect.x(), right, bottom, paint); 761 DrawHorizLine(canvas, rect.x(), right, bottom, paint);
335 DrawVertLine(canvas, rect.x(), rect.y(), bottom, paint); 762 DrawVertLine(canvas, rect.x(), rect.y(), bottom, paint);
336 } 763 }
337 764
765 void NativeThemeLinux::DrawTiledImage(SkCanvas* canvas,
766 const SkBitmap& bitmap,
767 int src_x, int src_y, double tile_scale_x, double tile_scale_y,
768 int dest_x, int dest_y, int w, int h) const {
769 SkShader* shader = SkShader::CreateBitmapShader(bitmap,
tony 2011/01/14 22:06:04 Is there a smart pointer we can use to auto-unref
xiyuan 2011/01/18 21:30:49 I poked around in skia code and here are some find
tony 2011/01/18 22:39:19 Ok, this seems fine. I wasn't sure if there was a
770 SkShader::kRepeat_TileMode,
771 SkShader::kRepeat_TileMode);
772 if (tile_scale_x != 1.0 || tile_scale_y != 1.0) {
773 SkMatrix shader_scale;
774 shader_scale.setScale(SkDoubleToScalar(tile_scale_x),
775 SkDoubleToScalar(tile_scale_y));
776 shader->setLocalMatrix(shader_scale);
777 }
778
779 SkPaint paint;
780 paint.setShader(shader);
781 paint.setXfermodeMode(SkXfermode::kSrcOver_Mode);
782
783 // CreateBitmapShader returns a Shader with a reference count of one, we
784 // need to unref after paint takes ownership of the shader.
785 shader->unref();
786 canvas->save();
787 canvas->translate(SkIntToScalar(dest_x - src_x),
788 SkIntToScalar(dest_y - src_y));
789 canvas->clipRect(SkRect::MakeXYWH(src_x, src_y, w, h));
790 canvas->drawPaint(paint);
791 canvas->restore();
792 }
793
338 SkScalar NativeThemeLinux::Clamp(SkScalar value, 794 SkScalar NativeThemeLinux::Clamp(SkScalar value,
339 SkScalar min, 795 SkScalar min,
340 SkScalar max) const { 796 SkScalar max) const {
341 return std::min(std::max(value, min), max); 797 return std::min(std::max(value, min), max);
342 } 798 }
343 799
344 SkColor NativeThemeLinux::SaturateAndBrighten(SkScalar* hsv, 800 SkColor NativeThemeLinux::SaturateAndBrighten(SkScalar* hsv,
345 SkScalar saturate_amount, 801 SkScalar saturate_amount,
346 SkScalar brighten_amount) const { 802 SkScalar brighten_amount) const {
347 SkScalar color[3]; 803 SkScalar color[3];
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 846
391 void NativeThemeLinux::SetScrollbarColors(unsigned inactive_color, 847 void NativeThemeLinux::SetScrollbarColors(unsigned inactive_color,
392 unsigned active_color, 848 unsigned active_color,
393 unsigned track_color) const { 849 unsigned track_color) const {
394 thumb_inactive_color_ = inactive_color; 850 thumb_inactive_color_ = inactive_color;
395 thumb_active_color_ = active_color; 851 thumb_active_color_ = active_color;
396 track_color_ = track_color; 852 track_color_ = track_color;
397 } 853 }
398 854
399 } // namespace gfx 855 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698