1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/views/controls/menu/menu_image_util.h"
7 #include "base/i18n/rtl.h"
8 #include "base/logging.h"
9 #include "third_party/skia/include/effects/SkGradientShader.h"
10 #include "ui/base/resource/resource_bundle.h"
11 #include "ui/gfx/canvas.h"
12 #include "ui/gfx/geometry/point.h"
13 #include "ui/gfx/geometry/size.h"
14 #include "ui/gfx/image/canvas_image_source.h"
15 #include "ui/gfx/image/image.h"
16 #include "ui/gfx/image/image_skia.h"
17 #include "ui/gfx/image/image_skia_source.h"
18 #include "ui/resources/grit/ui_resources.h"
19 #include "ui/views/resources/grit/views_resources.h"
23 // Size of the radio button inciator.
24 const int kSelectedIndicatorSize
= 5;
25 const int kIndicatorSize
= 10;
27 // Used for the radio indicator. See theme_draw for details.
28 const double kGradientStop
= .5;
29 const SkColor kGradient0
= SkColorSetRGB(255, 255, 255);
30 const SkColor kGradient1
= SkColorSetRGB(255, 255, 255);
31 const SkColor kGradient2
= SkColorSetRGB(0xD8, 0xD8, 0xD8);
32 const SkColor kBaseStroke
= SkColorSetRGB(0x8F, 0x8F, 0x8F);
33 const SkColor kRadioButtonIndicatorGradient0
= SkColorSetRGB(0, 0, 0);
34 const SkColor kRadioButtonIndicatorGradient1
= SkColorSetRGB(0x83, 0x83, 0x83);
35 const SkColor kIndicatorStroke
= SkColorSetRGB(0, 0, 0);
37 class RadioButtonImageSource
: public gfx::CanvasImageSource
{
39 explicit RadioButtonImageSource(bool selected
)
40 : CanvasImageSource(gfx::Size(kIndicatorSize
+ 2, kIndicatorSize
+ 2),
44 ~RadioButtonImageSource() override
{}
46 void Draw(gfx::Canvas
* canvas
) override
{
47 canvas
->Translate(gfx::Vector2d(1, 1));
49 SkPoint gradient_points
[3];
50 gradient_points
[0].iset(0, 0);
51 gradient_points
[1].iset(0,
52 static_cast<int>(kIndicatorSize
* kGradientStop
));
53 gradient_points
[2].iset(0, kIndicatorSize
);
54 SkColor gradient_colors
[3] = { kGradient0
, kGradient1
, kGradient2
};
55 skia::RefPtr
<SkShader
> shader
= skia::AdoptRef(
56 SkGradientShader::CreateLinear(
57 gradient_points
, gradient_colors
, NULL
, arraysize(gradient_points
),
58 SkShader::kClamp_TileMode
));
60 paint
.setStyle(SkPaint::kFill_Style
);
61 paint
.setAntiAlias(true);
62 paint
.setShader(shader
.get());
63 int radius
= kIndicatorSize
/ 2;
64 canvas
->sk_canvas()->drawCircle(radius
, radius
, radius
, paint
);
65 paint
.setStrokeWidth(SkIntToScalar(0));
66 paint
.setShader(NULL
);
67 paint
.setStyle(SkPaint::kStroke_Style
);
68 paint
.setColor(kBaseStroke
);
69 canvas
->sk_canvas()->drawCircle(radius
, radius
, radius
, paint
);
72 SkPoint selected_gradient_points
[2];
73 selected_gradient_points
[0].iset(0, 0);
74 selected_gradient_points
[1].iset(0, kSelectedIndicatorSize
);
75 SkColor selected_gradient_colors
[2] = { kRadioButtonIndicatorGradient0
,
76 kRadioButtonIndicatorGradient1
};
77 shader
= skia::AdoptRef(
78 SkGradientShader::CreateLinear(
79 selected_gradient_points
, selected_gradient_colors
, NULL
,
80 arraysize(selected_gradient_points
), SkShader::kClamp_TileMode
));
81 paint
.setShader(shader
.get());
82 paint
.setStyle(SkPaint::kFill_Style
);
83 canvas
->sk_canvas()->drawCircle(radius
, radius
,
84 kSelectedIndicatorSize
/ 2, paint
);
86 paint
.setStrokeWidth(SkIntToScalar(0));
87 paint
.setShader(NULL
);
88 paint
.setStyle(SkPaint::kStroke_Style
);
89 paint
.setColor(kIndicatorStroke
);
90 canvas
->sk_canvas()->drawCircle(radius
, radius
,
91 kSelectedIndicatorSize
/ 2, paint
);
98 DISALLOW_COPY_AND_ASSIGN(RadioButtonImageSource
);
101 class SubmenuArrowImageSource
: public gfx::CanvasImageSource
{
103 SubmenuArrowImageSource(int image_id
)
104 : gfx::CanvasImageSource(ui::ResourceBundle::GetSharedInstance().
105 GetImageNamed(image_id
).ToImageSkia()->size(), false),
106 image_id_(image_id
) {}
107 ~SubmenuArrowImageSource() override
{}
109 void Draw(gfx::Canvas
* canvas
) override
{
110 ui::ResourceBundle
& rb
= ui::ResourceBundle::GetSharedInstance();
111 const gfx::ImageSkia
* r
= rb
.GetImageNamed(image_id_
).ToImageSkia();
112 canvas
->Scale(-1, 1);
113 canvas
->DrawImageInt(*r
, - r
->width(), 0);
117 static gfx::Size
GetSubmenuArrowSize() {
118 return ui::ResourceBundle::GetSharedInstance()
119 .GetImageNamed(IDR_MENU_HIERARCHY_ARROW
).ToImageSkia()->size();
124 DISALLOW_COPY_AND_ASSIGN(SubmenuArrowImageSource
);
127 gfx::ImageSkia
GetRtlSubmenuArrowImage(bool rtl
,
128 bool dark_background
) {
129 int image_id
= dark_background
? IDR_MENU_HIERARCHY_ARROW_DARK_BACKGROUND
:
130 IDR_MENU_HIERARCHY_ARROW
;
133 return ui::ResourceBundle::GetSharedInstance().GetImageNamed(image_id
).
137 static gfx::ImageSkia
* kRtlArrow
= NULL
;
138 static gfx::ImageSkia
* kRtlArrowDarkBg
= NULL
;
139 gfx::ImageSkia
** image
= dark_background
? &kRtlArrowDarkBg
: &kRtlArrow
;
142 SubmenuArrowImageSource
* source
= new SubmenuArrowImageSource(image_id
);
143 *image
= new gfx::ImageSkia(source
, source
->size());
153 gfx::ImageSkia
GetMenuCheckImage(bool dark_background
) {
154 int image_id
= dark_background
? IDR_MENU_CHECK_CHECKED_DARK_BACKGROUND
:
155 IDR_MENU_CHECK_CHECKED
;
156 return ui::ResourceBundle::GetSharedInstance().GetImageNamed(image_id
).
160 gfx::ImageSkia
GetRadioButtonImage(bool selected
) {
161 int image_id
= selected
? IDR_MENU_RADIO_SELECTED
: IDR_MENU_RADIO_EMPTY
;
162 return ui::ResourceBundle::GetSharedInstance().GetImageNamed(image_id
).
166 gfx::ImageSkia
GetSubmenuArrowImage(bool dark_background
) {
167 return GetRtlSubmenuArrowImage(base::i18n::IsRTL(), dark_background
);