• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "ui/views/controls/menu/menu_image_util.h"
6 
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/image/canvas_image_source.h"
13 #include "ui/gfx/image/image.h"
14 #include "ui/gfx/image/image_skia.h"
15 #include "ui/gfx/image/image_skia_source.h"
16 #include "ui/gfx/point.h"
17 #include "ui/gfx/size.h"
18 #include "ui/resources/grit/ui_resources.h"
19 
20 namespace {
21 
22 // Size of the radio button inciator.
23 const int kSelectedIndicatorSize = 5;
24 const int kIndicatorSize = 10;
25 
26 // Used for the radio indicator. See theme_draw for details.
27 const double kGradientStop = .5;
28 const SkColor kGradient0 = SkColorSetRGB(255, 255, 255);
29 const SkColor kGradient1 = SkColorSetRGB(255, 255, 255);
30 const SkColor kGradient2 = SkColorSetRGB(0xD8, 0xD8, 0xD8);
31 const SkColor kBaseStroke = SkColorSetRGB(0x8F, 0x8F, 0x8F);
32 const SkColor kRadioButtonIndicatorGradient0 = SkColorSetRGB(0, 0, 0);
33 const SkColor kRadioButtonIndicatorGradient1 = SkColorSetRGB(0x83, 0x83, 0x83);
34 const SkColor kIndicatorStroke = SkColorSetRGB(0, 0, 0);
35 
36 class RadioButtonImageSource : public gfx::CanvasImageSource {
37  public:
RadioButtonImageSource(bool selected)38   explicit RadioButtonImageSource(bool selected)
39       : CanvasImageSource(gfx::Size(kIndicatorSize + 2, kIndicatorSize + 2),
40                           false),
41         selected_(selected) {
42   }
~RadioButtonImageSource()43   virtual ~RadioButtonImageSource() {}
44 
Draw(gfx::Canvas * canvas)45   virtual void Draw(gfx::Canvas* canvas) OVERRIDE {
46     canvas->Translate(gfx::Vector2d(1, 1));
47 
48     SkPoint gradient_points[3];
49     gradient_points[0].iset(0, 0);
50     gradient_points[1].iset(0,
51                             static_cast<int>(kIndicatorSize * kGradientStop));
52     gradient_points[2].iset(0, kIndicatorSize);
53     SkColor gradient_colors[3] = { kGradient0, kGradient1, kGradient2 };
54     skia::RefPtr<SkShader> shader = skia::AdoptRef(
55         SkGradientShader::CreateLinear(
56             gradient_points, gradient_colors, NULL, arraysize(gradient_points),
57             SkShader::kClamp_TileMode));
58     SkPaint paint;
59     paint.setStyle(SkPaint::kFill_Style);
60     paint.setAntiAlias(true);
61     paint.setShader(shader.get());
62     int radius = kIndicatorSize / 2;
63     canvas->sk_canvas()->drawCircle(radius, radius, radius, paint);
64     paint.setStrokeWidth(SkIntToScalar(0));
65     paint.setShader(NULL);
66     paint.setStyle(SkPaint::kStroke_Style);
67     paint.setColor(kBaseStroke);
68     canvas->sk_canvas()->drawCircle(radius, radius, radius, paint);
69 
70     if (selected_) {
71       SkPoint selected_gradient_points[2];
72       selected_gradient_points[0].iset(0, 0);
73       selected_gradient_points[1].iset(0, kSelectedIndicatorSize);
74       SkColor selected_gradient_colors[2] = { kRadioButtonIndicatorGradient0,
75                                               kRadioButtonIndicatorGradient1 };
76       shader = skia::AdoptRef(
77           SkGradientShader::CreateLinear(
78               selected_gradient_points, selected_gradient_colors, NULL,
79               arraysize(selected_gradient_points), SkShader::kClamp_TileMode));
80       paint.setShader(shader.get());
81       paint.setStyle(SkPaint::kFill_Style);
82       canvas->sk_canvas()->drawCircle(radius, radius,
83                                       kSelectedIndicatorSize / 2, paint);
84 
85       paint.setStrokeWidth(SkIntToScalar(0));
86       paint.setShader(NULL);
87       paint.setStyle(SkPaint::kStroke_Style);
88       paint.setColor(kIndicatorStroke);
89       canvas->sk_canvas()->drawCircle(radius, radius,
90                                       kSelectedIndicatorSize / 2, paint);
91     }
92   }
93 
94  private:
95   bool selected_;
96 
97   DISALLOW_COPY_AND_ASSIGN(RadioButtonImageSource);
98 };
99 
100 class SubmenuArrowImageSource : public gfx::CanvasImageSource {
101  public:
SubmenuArrowImageSource(int image_id)102   SubmenuArrowImageSource(int image_id)
103       : gfx::CanvasImageSource(ui::ResourceBundle::GetSharedInstance().
104             GetImageNamed(image_id).ToImageSkia()->size(), false),
105         image_id_(image_id) {}
~SubmenuArrowImageSource()106   virtual ~SubmenuArrowImageSource() {}
107 
Draw(gfx::Canvas * canvas)108   virtual void Draw(gfx::Canvas* canvas) OVERRIDE {
109     ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
110     const gfx::ImageSkia* r = rb.GetImageNamed(image_id_).ToImageSkia();
111     canvas->Scale(-1, 1);
112     canvas->DrawImageInt(*r, - r->width(), 0);
113   }
114 
115  private:
GetSubmenuArrowSize()116   static gfx::Size GetSubmenuArrowSize() {
117     return ui::ResourceBundle::GetSharedInstance()
118         .GetImageNamed(IDR_MENU_HIERARCHY_ARROW).ToImageSkia()->size();
119   }
120 
121   int image_id_;
122 
123   DISALLOW_COPY_AND_ASSIGN(SubmenuArrowImageSource);
124 };
125 
GetRtlSubmenuArrowImage(bool rtl,bool dark_background)126 gfx::ImageSkia GetRtlSubmenuArrowImage(bool rtl,
127                                        bool dark_background) {
128   int image_id = dark_background ? IDR_MENU_HIERARCHY_ARROW_DARK_BACKGROUND :
129                                    IDR_MENU_HIERARCHY_ARROW;
130 
131   if (!rtl) {
132     return ui::ResourceBundle::GetSharedInstance().GetImageNamed(image_id).
133         AsImageSkia();
134   }
135 
136   static gfx::ImageSkia* kRtlArrow = NULL;
137   static gfx::ImageSkia* kRtlArrowDarkBg = NULL;
138   gfx::ImageSkia** image = dark_background ? &kRtlArrowDarkBg : &kRtlArrow;
139 
140   if (!*image) {
141     SubmenuArrowImageSource* source = new SubmenuArrowImageSource(image_id);
142     *image = new gfx::ImageSkia(source, source->size());
143   }
144 
145   return **image;
146 }
147 
148 }  // namespace
149 
150 namespace views {
151 
GetMenuCheckImage(bool dark_background)152 gfx::ImageSkia GetMenuCheckImage(bool dark_background) {
153   int image_id = dark_background ? IDR_MENU_CHECK_CHECKED_DARK_BACKGROUND :
154                                    IDR_MENU_CHECK_CHECKED;
155   return ui::ResourceBundle::GetSharedInstance().GetImageNamed(image_id).
156       AsImageSkia();
157 }
158 
GetRadioButtonImage(bool selected)159 gfx::ImageSkia GetRadioButtonImage(bool selected) {
160   int image_id = selected ? IDR_MENU_RADIO_SELECTED : IDR_MENU_RADIO_EMPTY;
161   return ui::ResourceBundle::GetSharedInstance().GetImageNamed(image_id).
162       AsImageSkia();
163 }
164 
GetSubmenuArrowImage(bool dark_background)165 gfx::ImageSkia GetSubmenuArrowImage(bool dark_background) {
166   return GetRtlSubmenuArrowImage(base::i18n::IsRTL(), dark_background);
167 }
168 
169 }  // namespace views
170