15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/native_theme/native_theme_base.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ui_resources.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/effects/SkGradientShader.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/layout.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/ui_base_switches.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/color_utils.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/skia_util.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These are the default dimensions of radio buttons and checkboxes.
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kCheckboxAndRadioWidth = 13;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kCheckboxAndRadioHeight = 13;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// These sizes match the sizes in Chromium Win.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kSliderThumbWidth = 11;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kSliderThumbHeight = 21;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kSliderTrackBackgroundColor =
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xe3, 0xdd, 0xd8);
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kSliderThumbLightGrey = SkColorSetRGB(0xf4, 0xf2, 0xef);
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kSliderThumbDarkGrey = SkColorSetRGB(0xea, 0xe5, 0xe0);
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kSliderThumbBorderDarkGrey =
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0x9d, 0x96, 0x8e);
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kMenuPopupBackgroundColor = SkColorSetRGB(210, 225, 246);
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const unsigned int kDefaultScrollbarWidth = 15;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const unsigned int kDefaultScrollbarButtonLength = 14;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxTinyColor = SK_ColorGRAY;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxShadowColor = SkColorSetARGB(0x15, 0, 0, 0);
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxShadowHoveredColor = SkColorSetARGB(0x1F, 0, 0, 0);
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxShadowDisabledColor = SkColorSetARGB(0, 0, 0, 0);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxGradientColors[] = {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xed, 0xed, 0xed),
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xde, 0xde, 0xde) };
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxGradientPressedColors[] = {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xe7, 0xe7, 0xe7),
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xd7, 0xd7, 0xd7) };
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxGradientHoveredColors[] = {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xf0, 0xf0, 0xf0),
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetRGB(0xe0, 0xe0, 0xe0) };
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxGradientDisabledColors[] = {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetARGB(0x80, 0xed, 0xed, 0xed),
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorSetARGB(0x80, 0xde, 0xde, 0xde) };
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxBorderColor = SkColorSetARGB(0x40, 0, 0, 0);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxBorderHoveredColor = SkColorSetARGB(0x4D, 0, 0, 0);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxBorderDisabledColor = SkColorSetARGB(0x20, 0, 0, 0);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxStrokeColor = SkColorSetARGB(0xB3, 0, 0, 0);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kCheckboxStrokeDisabledColor = SkColorSetARGB(0x59, 0, 0, 0);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kRadioDotColor = SkColorSetRGB(0x66, 0x66, 0x66);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kRadioDotDisabledColor = SkColorSetARGB(0x80, 0x66, 0x66, 0x66);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const SkColor kInputInvalidColor = SkColorSetRGB(0xde, 0x49, 0x32);
71b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Get lightness adjusted color.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColor BrightenColor(const color_utils::HSL& hsl, SkAlpha alpha,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    double lightness_amount) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color_utils::HSL adjusted = hsl;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  adjusted.l += lightness_amount;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (adjusted.l > 1.0)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    adjusted.l = 1.0;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (adjusted.l < 0.0)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    adjusted.l = 0.0;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return color_utils::HSLToSkColor(adjusted, alpha);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size NativeThemeBase::GetPartSize(Part part,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       State state,
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const ExtraParams& extra) const {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (part) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Please keep these in the order of NativeTheme::Part.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCheckbox:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(kCheckboxAndRadioWidth, kCheckboxAndRadioHeight);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kInnerSpinButton:
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(scrollbar_width_, 0);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuList:
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size();  // No default size.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuCheck:
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuCheckBackground:
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupArrow:
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupBackground:
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size();  // No default size.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupGutter:
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupSeparator:
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuItemBackground:
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kProgressBar:
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kPushButton:
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size();  // No default size.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kRadio:
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(kCheckboxAndRadioWidth, kCheckboxAndRadioHeight);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarDownArrow:
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarUpArrow:
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(scrollbar_width_, scrollbar_button_length_);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarLeftArrow:
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarRightArrow:
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(scrollbar_button_length_, scrollbar_width_);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarHorizontalThumb:
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This matches Firefox on Linux.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(2 * scrollbar_width_, scrollbar_width_);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarVerticalThumb:
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // This matches Firefox on Linux.
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(scrollbar_width_, 2 * scrollbar_width_);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarHorizontalTrack:
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(0, scrollbar_width_);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarVerticalTrack:
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(scrollbar_width_, 0);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarHorizontalGripper:
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarVerticalGripper:
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kSliderTrack:
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size();  // No default size.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kSliderThumb:
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // These sizes match the sizes in Chromium Win.
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size(kSliderThumbWidth, kSliderThumbHeight);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTabPanelBackground:
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTextField:
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return gfx::Size();  // No default size.
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTrackbarThumb:
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTrackbarTrack:
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kWindowResizeGripper:
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "Unknown theme part: " << part;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::Paint(SkCanvas* canvas,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            Part part,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            State state,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const gfx::Rect& rect,
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const ExtraParams& extra) const {
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (rect.IsEmpty())
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (part) {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Please keep these in the order of NativeTheme::Part.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kCheckbox:
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintCheckbox(canvas, state, rect, extra.button);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kInnerSpinButton:
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintInnerSpinButton(canvas, state, rect, extra.inner_spin);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuList:
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintMenuList(canvas, state, rect, extra.menu_list);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuCheck:
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuCheckBackground:
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupArrow:
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupBackground:
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      PaintMenuPopupBackground(canvas, rect.size(), extra.menu_background);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupGutter:
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuPopupSeparator:
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kMenuItemBackground:
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintMenuItemBackground(canvas, state, rect, extra.menu_list);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kProgressBar:
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintProgressBar(canvas, state, rect, extra.progress_bar);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kPushButton:
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintButton(canvas, state, rect, extra.button);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kRadio:
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintRadio(canvas, state, rect, extra.button);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarDownArrow:
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarUpArrow:
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarLeftArrow:
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarRightArrow:
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintArrowButton(canvas, rect, part, state);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarHorizontalThumb:
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarVerticalThumb:
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintScrollbarThumb(canvas, part, state, rect);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarHorizontalTrack:
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarVerticalTrack:
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintScrollbarTrack(canvas, part, state, extra.scrollbar_track, rect);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarHorizontalGripper:
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarVerticalGripper:
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Invoked by views scrollbar code, don't care about for non-win
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // implementations, so no NOTIMPLEMENTED.
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kSliderTrack:
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintSliderTrack(canvas, state, rect, extra.slider);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kSliderThumb:
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintSliderThumb(canvas, state, rect, extra.slider);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTabPanelBackground:
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTextField:
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      PaintTextField(canvas, state, rect, extra.text_field);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTrackbarThumb:
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kTrackbarTrack:
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kWindowResizeGripper:
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTIMPLEMENTED();
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED() << "Unknown theme part: " << part;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeThemeBase::NativeThemeBase()
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : scrollbar_width_(kDefaultScrollbarWidth),
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scrollbar_button_length_(kDefaultScrollbarButtonLength) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)NativeThemeBase::~NativeThemeBase() {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintArrowButton(
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkCanvas* canvas,
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect, Part direction, State state) const {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int widthMiddle, lengthMiddle;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (direction == kScrollbarUpArrow || direction == kScrollbarDownArrow) {
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widthMiddle = rect.width() / 2 + 1;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    lengthMiddle = rect.height() / 2 + 1;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    lengthMiddle = rect.width() / 2 + 1;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    widthMiddle = rect.height() / 2 + 1;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Calculate button color.
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar trackHSV[3];
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(track_color_, trackHSV);
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor buttonColor = SaturateAndBrighten(trackHSV, 0, 0.2f);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor backgroundColor = buttonColor;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state == kPressed) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkScalar buttonHSV[3];
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorToHSV(buttonColor, buttonHSV);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buttonColor = SaturateAndBrighten(buttonHSV, 0, -0.1f);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (state == kHovered) {
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkScalar buttonHSV[3];
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColorToHSV(buttonColor, buttonHSV);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buttonColor = SaturateAndBrighten(buttonHSV, 0, 0.05f);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect skrect;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y()
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      + rect.height());
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Paint the background (the area visible behind the rounded corners).
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(backgroundColor);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Paint the button's outline and fill the middle
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPath outline;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (direction) {
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarUpArrow:
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.moveTo(rect.x() + 0.5, rect.y() + rect.height() + 0.5);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(0, -(rect.height() - 2));
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(2, -2);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(rect.width() - 5, 0);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(2, 2);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(0, rect.height() - 2);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarDownArrow:
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.moveTo(rect.x() + 0.5, rect.y() - 0.5);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(0, rect.height() - 2);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(2, 2);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(rect.width() - 5, 0);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(2, -2);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(0, -(rect.height() - 2));
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarRightArrow:
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.moveTo(rect.x() - 0.5, rect.y() + 0.5);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(rect.width() - 2, 0);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(2, 2);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(0, rect.height() - 5);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(-2, 2);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(-(rect.width() - 2), 0);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarLeftArrow:
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.moveTo(rect.x() + rect.width() + 0.5, rect.y() + 0.5);
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(-(rect.width() - 2), 0);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(-2, 2);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(0, rect.height() - 5);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(2, 2);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      outline.rLineTo(rect.width() - 2, 0);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  outline.close();
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kFill_Style);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(buttonColor);
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawPath(outline, paint);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setAntiAlias(true);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kStroke_Style);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar thumbHSV[3];
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(thumb_inactive_color_, thumbHSV);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(OutlineColor(trackHSV, thumbHSV));
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawPath(outline, paint);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the button is disabled or read-only, the arrow is drawn with the
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // outline color.
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state != kDisabled)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(SK_ColorBLACK);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setAntiAlias(false);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kFill_Style);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPath path;
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The constants in this block of code are hand-tailored to produce good
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // looking arrows without anti-aliasing.
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (direction) {
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarUpArrow:
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.moveTo(rect.x() + widthMiddle - 4, rect.y() + lengthMiddle + 2);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(7, 0);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(-4, -4);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarDownArrow:
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.moveTo(rect.x() + widthMiddle - 4, rect.y() + lengthMiddle - 3);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(7, 0);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(-4, 4);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarRightArrow:
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.moveTo(rect.x() + lengthMiddle - 3, rect.y() + widthMiddle - 4);
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(0, 7);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(4, -4);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kScrollbarLeftArrow:
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.moveTo(rect.x() + lengthMiddle + 1, rect.y() + widthMiddle - 5);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(0, 9);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      path.rLineTo(-4, -4);
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.close();
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawPath(path, paint);
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintScrollbarTrack(SkCanvas* canvas,
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Part part,
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state,
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ScrollbarTrackExtraParams& extra_params,
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect) const {
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect skrect;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skrect.set(rect.x(), rect.y(), rect.right(), rect.bottom());
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar track_hsv[3];
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(track_color_, track_hsv);
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(SaturateAndBrighten(track_hsv, 0, 0));
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar thumb_hsv[3];
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(thumb_inactive_color_, thumb_hsv);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(OutlineColor(track_hsv, thumb_hsv));
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawBox(canvas, rect, paint);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintScrollbarThumb(SkCanvas* canvas,
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           Part part,
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           State state,
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const gfx::Rect& rect) const {
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool hovered = state == kHovered;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int midx = rect.x() + rect.width() / 2;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int midy = rect.y() + rect.height() / 2;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool vertical = part == kScrollbarVerticalThumb;
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar thumb[3];
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(hovered ? thumb_active_color_ : thumb_inactive_color_, thumb);
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(SaturateAndBrighten(thumb, 0, 0.02f));
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect skrect;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (vertical)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(rect.x(), rect.y(), midx + 1, rect.y() + rect.height());
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), midy + 1);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(SaturateAndBrighten(thumb, 0, -0.02f));
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (vertical) {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        midx + 1, rect.y(), rect.x() + rect.width(), rect.y() + rect.height());
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rect.x(), midy + 1, rect.x() + rect.width(), rect.y() + rect.height());
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar track[3];
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColorToHSV(track_color_, track);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(OutlineColor(track, thumb));
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawBox(canvas, rect, paint);
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rect.height() > 10 && rect.width() > 10) {
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int grippy_half_width = 2;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int inter_grippy_offset = 3;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (vertical) {
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawHorizLine(canvas,
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midx - grippy_half_width,
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midx + grippy_half_width,
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midy - inter_grippy_offset,
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    paint);
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawHorizLine(canvas,
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midx - grippy_half_width,
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midx + grippy_half_width,
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midy,
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    paint);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawHorizLine(canvas,
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midx - grippy_half_width,
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midx + grippy_half_width,
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    midy + inter_grippy_offset,
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    paint);
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawVertLine(canvas,
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midx - inter_grippy_offset,
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midy - grippy_half_width,
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midy + grippy_half_width,
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   paint);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawVertLine(canvas,
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midx,
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midy - grippy_half_width,
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midy + grippy_half_width,
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   paint);
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DrawVertLine(canvas,
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midx + inter_grippy_offset,
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midy - grippy_half_width,
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   midy + grippy_half_width,
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   paint);
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintCheckbox(SkCanvas* canvas,
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    State state,
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const gfx::Rect& rect,
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const ButtonExtraParams& button) const {
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkRect skrect = PaintCheckboxRadioCommon(canvas, state, rect,
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           SkIntToScalar(2));
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!skrect.isEmpty()) {
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Draw the checkmark / dash.
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkPaint paint;
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    paint.setAntiAlias(true);
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    paint.setStyle(SkPaint::kStroke_Style);
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (state == kDisabled)
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      paint.setColor(kCheckboxStrokeDisabledColor);
4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    else
4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      paint.setColor(kCheckboxStrokeColor);
4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (button.indeterminate) {
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SkPath dash;
4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dash.moveTo(skrect.x() + skrect.width() * 0.16,
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  (skrect.y() + skrect.bottom()) / 2);
4972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dash.rLineTo(skrect.width() * 0.68, 0);
4982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      paint.setStrokeWidth(SkFloatToScalar(skrect.height() * 0.2));
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      canvas->drawPath(dash, paint);
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (button.checked) {
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SkPath check;
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      check.moveTo(skrect.x() + skrect.width() * 0.2,
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   skrect.y() + skrect.height() * 0.5);
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      check.rLineTo(skrect.width() * 0.2, skrect.height() * 0.2);
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      paint.setStrokeWidth(SkFloatToScalar(skrect.height() * 0.23));
5062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      check.lineTo(skrect.right() - skrect.width() * 0.2,
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   skrect.y() + skrect.height() * 0.2);
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      canvas->drawPath(check, paint);
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Draws the common elements of checkboxes and radio buttons.
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Returns the rectangle within which any additional decorations should be
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// drawn, or empty if none.
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SkRect NativeThemeBase::PaintCheckboxRadioCommon(
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkCanvas* canvas,
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state,
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect,
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SkScalar borderRadius) const {
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect skrect = gfx::RectToSkRect(rect);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use the largest square that fits inside the provided rectangle.
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No other browser seems to support non-square widget, so accidentally
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // having non-square sizes is common (eg. amazon and webkit dev tools).
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (skrect.width() != skrect.height()) {
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkScalar size = SkMinScalar(skrect.width(), skrect.height());
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.inset((skrect.width() - size) / 2, (skrect.height() - size) / 2);
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the rectangle is too small then paint only a rectangle.  We don't want
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to have to worry about '- 1' and '+ 1' calculations below having overflow
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // or underflow.
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (skrect.width() <= 2) {
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(kCheckboxTinyColor);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kFill_Style);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawRect(skrect, paint);
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Too small to draw anything more.
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return SkRect::MakeEmpty();
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make room for the drop shadow.
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skrect.iset(skrect.x(), skrect.y(), skrect.right() - 1, skrect.bottom() - 1);
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Draw the drop shadow below the widget.
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state != kPressed) {
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setAntiAlias(true);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkRect shadowRect = skrect;
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shadowRect.offset(0, 1);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state == kDisabled)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     paint.setColor(kCheckboxShadowDisabledColor);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (state == kHovered)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setColor(kCheckboxShadowHoveredColor);
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setColor(kCheckboxShadowColor);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kFill_Style);
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawRoundRect(shadowRect, borderRadius, borderRadius, paint);
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Draw the gradient-filled rectangle
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPoint gradient_bounds[3];
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gradient_bounds[0].set(skrect.x(), skrect.y());
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gradient_bounds[1].set(skrect.x(), skrect.y() + skrect.height() * 0.38);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gradient_bounds[2].set(skrect.x(), skrect.bottom());
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const SkColor* startEndColors;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state == kPressed)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    startEndColors = kCheckboxGradientPressedColors;
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (state == kHovered)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    startEndColors = kCheckboxGradientHoveredColors;
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (state == kDisabled)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    startEndColors = kCheckboxGradientDisabledColors;
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else /* kNormal */
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    startEndColors = kCheckboxGradientColors;
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor colors[3] = {startEndColors[0], startEndColors[0], startEndColors[1]};
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  skia::RefPtr<SkShader> shader = skia::AdoptRef(
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SkGradientShader::CreateLinear(
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gradient_bounds, colors, NULL, 3, SkShader::kClamp_TileMode, NULL));
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setAntiAlias(true);
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  paint.setShader(shader.get());
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kFill_Style);
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawRoundRect(skrect, borderRadius, borderRadius, paint);
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setShader(NULL);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Draw the border.
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (state == kHovered)
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(kCheckboxBorderHoveredColor);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else if (state == kDisabled)
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(kCheckboxBorderDisabledColor);
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(kCheckboxBorderColor);
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kStroke_Style);
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStrokeWidth(SkIntToScalar(1));
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skrect.inset(SkFloatToScalar(.5f), SkFloatToScalar(.5f));
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawRoundRect(skrect, borderRadius, borderRadius, paint);
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return the rectangle excluding the drop shadow for drawing any additional
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // decorations.
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return skrect;
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintRadio(SkCanvas* canvas,
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  State state,
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const gfx::Rect& rect,
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const ButtonExtraParams& button) const {
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Most of a radio button is the same as a checkbox, except the the rounded
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // square is a circle (i.e. border radius >= 100%).
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const SkScalar radius = SkFloatToScalar(
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<float>(std::max(rect.width(), rect.height())) / 2);
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkRect skrect = PaintCheckboxRadioCommon(canvas, state, rect, radius);
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!skrect.isEmpty() && button.checked) {
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Draw the dot.
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setAntiAlias(true);
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kFill_Style);
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (state == kDisabled)
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setColor(kRadioDotDisabledColor);
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setColor(kRadioDotColor);
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.inset(skrect.width() * 0.25, skrect.height() * 0.25);
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Use drawRoundedRect instead of drawOval to be completely consistent
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // with the border in PaintCheckboxRadioNewCommon.
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawRoundRect(skrect, radius, radius, paint);
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintButton(SkCanvas* canvas,
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  State state,
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const gfx::Rect& rect,
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const ButtonExtraParams& button) const {
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kRight = rect.right();
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kBottom = rect.bottom();
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect skrect = SkRect::MakeLTRB(rect.x(), rect.y(), kRight, kBottom);
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor base_color = button.background_color;
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color_utils::HSL base_hsl;
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color_utils::SkColorToHSL(base_color, &base_hsl);
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Our standard gradient is from 0xdd to 0xf8. This is the amount of
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // increased luminance between those values.
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor light_color(BrightenColor(base_hsl, SkColorGetA(base_color), 0.105));
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the button is too small, fallback to drawing a single, solid color
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rect.width() < 5 || rect.height() < 5) {
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(base_color);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawRect(skrect, paint);
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(SK_ColorBLACK);
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kLightEnd = state == kPressed ? 1 : 0;
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kDarkEnd = !kLightEnd;
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPoint gradient_bounds[2];
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gradient_bounds[kLightEnd].iset(rect.x(), rect.y());
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gradient_bounds[kDarkEnd].iset(rect.x(), kBottom - 1);
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkColor colors[2];
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  colors[0] = light_color;
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  colors[1] = base_color;
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  skia::RefPtr<SkShader> shader = skia::AdoptRef(
6662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SkGradientShader::CreateLinear(
6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          gradient_bounds, colors, NULL, 2, SkShader::kClamp_TileMode, NULL));
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kFill_Style);
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setAntiAlias(true);
6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  paint.setShader(shader.get());
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawRoundRect(skrect, SkIntToScalar(1), SkIntToScalar(1), paint);
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setShader(NULL);
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (button.has_border) {
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int border_alpha = state == kHovered ? 0x80 : 0x55;
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (button.is_focused) {
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      border_alpha = 0xff;
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setColor(GetSystemColor(kColorId_FocusedBorderColor));
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kStroke_Style);
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStrokeWidth(SkIntToScalar(1));
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setAlpha(border_alpha);
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.inset(SkFloatToScalar(.5f), SkFloatToScalar(.5f));
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawRoundRect(skrect, SkIntToScalar(1), SkIntToScalar(1), paint);
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintTextField(SkCanvas* canvas,
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     State state,
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const gfx::Rect& rect,
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     const TextFieldExtraParams& text) const {
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The following drawing code simulates the user-agent css border for
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // text area and text input so that we do not break layout tests. Once we
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // have decided the desired looks, we should update the code here and
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the layout test expectations.
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect bounds;
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bounds.set(rect.x(), rect.y(), rect.right() - 1, rect.bottom() - 1);
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint fill_paint;
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fill_paint.setStyle(SkPaint::kFill_Style);
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fill_paint.setColor(text.background_color);
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawRect(bounds, fill_paint);
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (text.is_text_area) {
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Draw text area border: 1px solid black
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint stroke_paint;
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fill_paint.setStyle(SkPaint::kStroke_Style);
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fill_paint.setColor(SK_ColorBLACK);
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawRect(bounds, fill_paint);
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Draw text input and listbox inset border
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   Text Input: 2px inset #eee
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    //   Listbox: 1px inset #808080
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SkColor kLightColor = text.is_listbox ?
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SkColorSetRGB(0x80, 0x80, 0x80) : SkColorSetRGB(0xee, 0xee, 0xee);
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SkColor kDarkColor = text.is_listbox ?
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SkColorSetRGB(0x2c, 0x2c, 0x2c) : SkColorSetRGB(0x9a, 0x9a, 0x9a);
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const int kBorderWidth = text.is_listbox ? 1 : 2;
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint dark_paint;
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dark_paint.setAntiAlias(true);
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dark_paint.setStyle(SkPaint::kFill_Style);
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    dark_paint.setColor(kDarkColor);
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint light_paint;
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    light_paint.setAntiAlias(true);
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    light_paint.setStyle(SkPaint::kFill_Style);
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    light_paint.setColor(kLightColor);
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int left = rect.x();
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int top = rect.y();
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int right = rect.right();
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int bottom = rect.bottom();
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPath path;
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.incReserve(4);
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Top
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.moveTo(SkIntToScalar(left), SkIntToScalar(top));
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(left + kBorderWidth),
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                SkIntToScalar(top + kBorderWidth));
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(right - kBorderWidth),
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                SkIntToScalar(top + kBorderWidth));
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(right), SkIntToScalar(top));
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawPath(path, dark_paint);
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Bottom
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.reset();
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.moveTo(SkIntToScalar(left + kBorderWidth),
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                SkIntToScalar(bottom - kBorderWidth));
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(left), SkIntToScalar(bottom));
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(right), SkIntToScalar(bottom));
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(right - kBorderWidth),
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                SkIntToScalar(bottom - kBorderWidth));
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawPath(path, light_paint);
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Left
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.reset();
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.moveTo(SkIntToScalar(left), SkIntToScalar(top));
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(left), SkIntToScalar(bottom));
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(left + kBorderWidth),
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                SkIntToScalar(bottom - kBorderWidth));
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(left + kBorderWidth),
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                SkIntToScalar(top + kBorderWidth));
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawPath(path, dark_paint);
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Right
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.reset();
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.moveTo(SkIntToScalar(right - kBorderWidth),
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                SkIntToScalar(top + kBorderWidth));
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(right - kBorderWidth), SkIntToScalar(bottom));
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(right), SkIntToScalar(bottom));
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.lineTo(SkIntToScalar(right), SkIntToScalar(top));
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->drawPath(path, light_paint);
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintMenuList(
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkCanvas* canvas,
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state,
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect,
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MenuListExtraParams& menu_list) const {
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If a border radius is specified, we let the WebCore paint the background
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and the border of the control.
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!menu_list.has_border_radius) {
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ButtonExtraParams button = { 0 };
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    button.background_color = menu_list.background_color;
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    button.has_border = menu_list.has_border;
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PaintButton(canvas, state, rect, button);
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(SK_ColorBLACK);
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setAntiAlias(true);
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kFill_Style);
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPath path;
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.moveTo(menu_list.arrow_x, menu_list.arrow_y - 3);
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.rLineTo(6, 0);
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.rLineTo(-3, 6);
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.close();
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawPath(path, paint);
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void NativeThemeBase::PaintMenuPopupBackground(
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkCanvas* canvas,
8082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const gfx::Size& size,
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const MenuBackgroundExtraParams& menu_background) const {
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawColor(kMenuPopupBackgroundColor, SkXfermode::kSrc_Mode);
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintMenuItemBackground(
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkCanvas* canvas,
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state,
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect,
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const MenuListExtraParams& menu_list) const {
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // By default don't draw anything over the normal background.
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintSliderTrack(SkCanvas* canvas,
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       State state,
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const gfx::Rect& rect,
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const SliderExtraParams& slider) const {
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMidX = rect.x() + rect.width() / 2;
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMidY = rect.y() + rect.height() / 2;
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(kSliderTrackBackgroundColor);
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect skrect;
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (slider.vertical) {
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(std::max(rect.x(), kMidX - 2),
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               rect.y(),
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               std::min(rect.right(), kMidX + 2),
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               rect.bottom());
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(rect.x(),
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               std::max(rect.y(), kMidY - 2),
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               rect.right(),
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               std::min(rect.bottom(), kMidY + 2));
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawRect(skrect, paint);
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintSliderThumb(SkCanvas* canvas,
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       State state,
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const gfx::Rect& rect,
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       const SliderExtraParams& slider) const {
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const bool hovered = (state == kHovered) || slider.in_drag;
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMidX = rect.x() + rect.width() / 2;
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMidY = rect.y() + rect.height() / 2;
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(hovered ? SK_ColorWHITE : kSliderThumbLightGrey);
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect skrect;
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (slider.vertical)
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(rect.x(), rect.y(), kMidX + 1, rect.bottom());
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(rect.x(), rect.y(), rect.right(), kMidY + 1);
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(hovered ? kSliderThumbLightGrey : kSliderThumbDarkGrey);
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (slider.vertical)
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(kMidX + 1, rect.y(), rect.right(), rect.bottom());
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    skrect.set(rect.x(), kMidY + 1, rect.right(), rect.bottom());
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(kSliderThumbBorderDarkGrey);
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawBox(canvas, rect, paint);
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rect.height() > 10 && rect.width() > 10) {
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY, paint);
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY - 3, paint);
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DrawHorizLine(canvas, kMidX - 2, kMidX + 2, kMidY + 3, paint);
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintInnerSpinButton(SkCanvas* canvas,
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state,
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect,
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const InnerSpinButtonExtraParams& spin_button) const {
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (spin_button.read_only)
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    state = kDisabled;
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  State north_state = state;
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  State south_state = state;
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (spin_button.spin_up)
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    south_state = south_state != kDisabled ? kNormal : kDisabled;
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  else
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    north_state = north_state != kDisabled ? kNormal : kDisabled;
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect half = rect;
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  half.set_height(rect.height() / 2);
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PaintArrowButton(canvas, half, kScrollbarUpArrow, north_state);
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  half.set_y(rect.y() + rect.height() / 2);
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PaintArrowButton(canvas, half, kScrollbarDownArrow, south_state);
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::PaintProgressBar(SkCanvas* canvas,
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    State state,
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Rect& rect,
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ProgressBarExtraParams& progress_bar) const {
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia* bar_image = rb.GetImageSkiaNamed(IDR_PROGRESS_BAR);
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia* left_border_image = rb.GetImageSkiaNamed(
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDR_PROGRESS_BORDER_LEFT);
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::ImageSkia* right_border_image = rb.GetImageSkiaNamed(
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDR_PROGRESS_BORDER_RIGHT);
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
917ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  DCHECK(bar_image->width() > 0);
918ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  DCHECK(rect.width() > 0);
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
920ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  float tile_scale_y = static_cast<float>(rect.height()) / bar_image->height();
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
922ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  int dest_left_border_width = left_border_image->width();
923ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  int dest_right_border_width = right_border_image->width();
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Since an implicit float -> int conversion will truncate, we want to make
926ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // sure that if a border is desired, it gets at least one pixel.
927ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (dest_left_border_width > 0) {
928ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    dest_left_border_width = dest_left_border_width * tile_scale_y;
929ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    dest_left_border_width = std::max(dest_left_border_width, 1);
930ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
931ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (dest_right_border_width > 0) {
932ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    dest_right_border_width = dest_right_border_width * tile_scale_y;
933ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    dest_right_border_width = std::max(dest_right_border_width, 1);
934ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
935ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
936ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // Since the width of the progress bar may not be evenly divisible by the
937ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // tile size, in order to make it look right we may need to draw some of the
938ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  // with a width of 1 pixel smaller than the rest of the tiles.
939ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  int new_tile_width = static_cast<int>(bar_image->width() * tile_scale_y);
940ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  new_tile_width = std::max(new_tile_width, 1);
941ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
942ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  float tile_scale_x = static_cast<float>(new_tile_width) / bar_image->width();
943ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  if (rect.width() % new_tile_width == 0) {
944ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    DrawTiledImage(canvas, *bar_image, 0, 0, tile_scale_x, tile_scale_y,
945ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        rect.x(), rect.y(),
946ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        rect.width(), rect.height());
947ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  } else {
948ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    int num_tiles = 1 + rect.width() / new_tile_width;
949ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    int overshoot = num_tiles * new_tile_width - rect.width();
950ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // Since |overshoot| represents the number of tiles that were too big, draw
951ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    // |overshoot| tiles with their width reduced by 1.
952ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    int num_big_tiles = num_tiles - overshoot;
953ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    int num_small_tiles = overshoot;
954ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    int small_width = new_tile_width - 1;
955ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    float small_scale_x = static_cast<float>(small_width) / bar_image->width();
956ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    float big_scale_x = tile_scale_x;
957ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
958ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    gfx::Rect big_rect = rect;
959ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    gfx::Rect small_rect = rect;
960ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    big_rect.Inset(0, 0, num_small_tiles*small_width, 0);
961ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    small_rect.Inset(num_big_tiles*new_tile_width, 0, 0, 0);
962ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
963ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    DrawTiledImage(canvas, *bar_image, 0, 0, big_scale_x, tile_scale_y,
964ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      big_rect.x(), big_rect.y(), big_rect.width(), big_rect.height());
965ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    DrawTiledImage(canvas, *bar_image, 0, 0, small_scale_x, tile_scale_y,
966ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch      small_rect.x(), small_rect.y(), small_rect.width(), small_rect.height());
967ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  }
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (progress_bar.value_rect_width) {
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::ImageSkia* value_image = rb.GetImageSkiaNamed(IDR_PROGRESS_VALUE);
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
971ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    new_tile_width = static_cast<int>(value_image->width() * tile_scale_y);
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tile_scale_x = static_cast<float>(new_tile_width) /
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        value_image->width();
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    DrawTiledImage(canvas, *value_image, 0, 0, tile_scale_x, tile_scale_y,
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        progress_bar.value_rect_x,
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        progress_bar.value_rect_y,
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        progress_bar.value_rect_width,
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        progress_bar.value_rect_height);
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawImageInt(canvas, *left_border_image, 0, 0, left_border_image->width(),
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      left_border_image->height(), rect.x(), rect.y(), dest_left_border_width,
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      rect.height());
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int dest_x = rect.right() - dest_right_border_width;
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawImageInt(canvas, *right_border_image, 0, 0, right_border_image->width(),
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               right_border_image->height(), dest_x, rect.y(),
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               dest_right_border_width, rect.height());
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool NativeThemeBase::IntersectsClipRectInt(SkCanvas* canvas,
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            int x, int y, int w, int h) const {
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect clip;
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return canvas->getClipBounds(&clip) &&
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      clip.intersect(SkIntToScalar(x), SkIntToScalar(y), SkIntToScalar(x + w),
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     SkIntToScalar(y + h));
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::DrawImageInt(
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkCanvas* sk_canvas, const gfx::ImageSkia& image,
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int src_x, int src_y, int src_w, int src_h,
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int dest_x, int dest_y, int dest_w, int dest_h) const {
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(pkotwicz): Do something better and don't infer device
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // scale factor from canvas scale.
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkMatrix m = sk_canvas->getTotalMatrix();
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::ScaleFactor device_scale_factor = ui::GetScaleFactorFromScale(
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkScalarAbs(m.getScaleX()));
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling(
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sk_canvas, device_scale_factor));
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->DrawImageInt(image, src_x, src_y, src_w, src_h,
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dest_x, dest_y, dest_w, dest_h, true);
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::DrawTiledImage(SkCanvas* sk_canvas,
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::ImageSkia& image,
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int src_x, int src_y, float tile_scale_x, float tile_scale_y,
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int dest_x, int dest_y, int w, int h) const {
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(pkotwicz): Do something better and don't infer device
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // scale factor from canvas scale.
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkMatrix m = sk_canvas->getTotalMatrix();
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::ScaleFactor device_scale_factor = ui::GetScaleFactorFromScale(
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkScalarAbs(m.getScaleX()));
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<gfx::Canvas> canvas(gfx::Canvas::CreateCanvasWithoutScaling(
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      sk_canvas, device_scale_factor));
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->TileImageInt(image, src_x, src_y, tile_scale_x,
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tile_scale_y, dest_x, dest_y, w, h);
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColor NativeThemeBase::SaturateAndBrighten(SkScalar* hsv,
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             SkScalar saturate_amount,
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                             SkScalar brighten_amount) const {
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar color[3];
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color[0] = hsv[0];
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color[1] = Clamp(hsv[1] + saturate_amount, 0.0, 1.0);
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  color[2] = Clamp(hsv[2] + brighten_amount, 0.0, 1.0);
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SkHSVToColor(color);
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::DrawVertLine(SkCanvas* canvas,
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   int x,
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   int y1,
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   int y2,
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const SkPaint& paint) const {
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect skrect;
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skrect.set(x, y1, x + 1, y2 + 1);
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::DrawHorizLine(SkCanvas* canvas,
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int x1,
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int x2,
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    int y,
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    const SkPaint& paint) const {
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect skrect;
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  skrect.set(x1, y, x2 + 1, y + 1);
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->drawIRect(skrect, paint);
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NativeThemeBase::DrawBox(SkCanvas* canvas,
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const gfx::Rect& rect,
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const SkPaint& paint) const {
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int right = rect.x() + rect.width() - 1;
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int bottom = rect.y() + rect.height() - 1;
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawHorizLine(canvas, rect.x(), right, rect.y(), paint);
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawVertLine(canvas, right, rect.y(), bottom, paint);
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawHorizLine(canvas, rect.x(), right, bottom, paint);
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DrawVertLine(canvas, rect.x(), rect.y(), bottom, paint);
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkScalar NativeThemeBase::Clamp(SkScalar value,
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                SkScalar min,
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                SkScalar max) const {
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::min(std::max(value, min), max);
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SkColor NativeThemeBase::OutlineColor(SkScalar* hsv1, SkScalar* hsv2) const {
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GTK Theme engines have way too much control over the layout of
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the scrollbar. We might be able to more closely approximate its
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // look-and-feel, if we sent whole images instead of just colors
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the browser to the renderer. But even then, some themes
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // would just break.
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // So, instead, we don't even try to 100% replicate the look of
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the native scrollbar. We render our own version, but we make
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sure to pick colors that blend in nicely with the system GTK
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // theme. In most cases, we can just sample a couple of pixels
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // from the system scrollbar and use those colors to draw our
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // scrollbar.
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This works fine for the track color and the overall thumb
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // color. But it fails spectacularly for the outline color used
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // around the thumb piece.  Not all themes have a clearly defined
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // outline. For some of them it is partially transparent, and for
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // others the thickness is very unpredictable.
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // So, instead of trying to approximate the system theme, we
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // instead try to compute a reasonable looking choice based on the
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // known color of the track and the thumb piece. This is difficult
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when trying to deal both with high- and low-contrast themes,
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and both with positive and inverted themes.
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The following code has been tested to look OK with all of the
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // default GTK themes.
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar min_diff = Clamp((hsv1[1] + hsv2[1]) * 1.2f, 0.28f, 0.5f);
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkScalar diff = Clamp(fabs(hsv1[2] - hsv2[2]) / 2, min_diff, 0.5f);
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (hsv1[2] + hsv2[2] > 1.0)
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    diff = -diff;
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SaturateAndBrighten(hsv2, -0.2f, diff);
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
1115