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)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/menu/menu_image_util.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/i18n/rtl.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/effects/SkGradientShader.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/canvas_image_source.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image_skia_source.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/point.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h"
1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "ui/resources/grit/ui_resources.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Size of the radio button inciator.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kSelectedIndicatorSize = 5;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kIndicatorSize = 10;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Used for the radio indicator. See theme_draw for details.
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const double kGradientStop = .5;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kGradient0 = SkColorSetRGB(255, 255, 255);
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kGradient1 = SkColorSetRGB(255, 255, 255);
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kGradient2 = SkColorSetRGB(0xD8, 0xD8, 0xD8);
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kBaseStroke = SkColorSetRGB(0x8F, 0x8F, 0x8F);
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kRadioButtonIndicatorGradient0 = SkColorSetRGB(0, 0, 0);
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kRadioButtonIndicatorGradient1 = SkColorSetRGB(0x83, 0x83, 0x83);
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const SkColor kIndicatorStroke = SkColorSetRGB(0, 0, 0);
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RadioButtonImageSource : public gfx::CanvasImageSource {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit RadioButtonImageSource(bool selected)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : CanvasImageSource(gfx::Size(kIndicatorSize + 2, kIndicatorSize + 2),
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          false),
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        selected_(selected) {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~RadioButtonImageSource() {}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Draw(gfx::Canvas* canvas) OVERRIDE {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->Translate(gfx::Vector2d(1, 1));
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPoint gradient_points[3];
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gradient_points[0].iset(0, 0);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gradient_points[1].iset(0,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            static_cast<int>(kIndicatorSize * kGradientStop));
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gradient_points[2].iset(0, kIndicatorSize);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkColor gradient_colors[3] = { kGradient0, kGradient1, kGradient2 };
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    skia::RefPtr<SkShader> shader = skia::AdoptRef(
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SkGradientShader::CreateLinear(
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            gradient_points, gradient_colors, NULL, arraysize(gradient_points),
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            SkShader::kClamp_TileMode));
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkPaint paint;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kFill_Style);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setAntiAlias(true);
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    paint.setShader(shader.get());
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int radius = kIndicatorSize / 2;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->sk_canvas()->drawCircle(radius, radius, radius, paint);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStrokeWidth(SkIntToScalar(0));
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setShader(NULL);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setStyle(SkPaint::kStroke_Style);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    paint.setColor(kBaseStroke);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->sk_canvas()->drawCircle(radius, radius, radius, paint);
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (selected_) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkPoint selected_gradient_points[2];
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      selected_gradient_points[0].iset(0, 0);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      selected_gradient_points[1].iset(0, kSelectedIndicatorSize);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkColor selected_gradient_colors[2] = { kRadioButtonIndicatorGradient0,
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              kRadioButtonIndicatorGradient1 };
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shader = skia::AdoptRef(
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          SkGradientShader::CreateLinear(
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              selected_gradient_points, selected_gradient_colors, NULL,
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)              arraysize(selected_gradient_points), SkShader::kClamp_TileMode));
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      paint.setShader(shader.get());
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setStyle(SkPaint::kFill_Style);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      canvas->sk_canvas()->drawCircle(radius, radius,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      kSelectedIndicatorSize / 2, paint);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setStrokeWidth(SkIntToScalar(0));
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setShader(NULL);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setStyle(SkPaint::kStroke_Style);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      paint.setColor(kIndicatorStroke);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      canvas->sk_canvas()->drawCircle(radius, radius,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      kSelectedIndicatorSize / 2, paint);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool selected_;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RadioButtonImageSource);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SubmenuArrowImageSource : public gfx::CanvasImageSource {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1024e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  SubmenuArrowImageSource(int image_id)
1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      : gfx::CanvasImageSource(ui::ResourceBundle::GetSharedInstance().
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)            GetImageNamed(image_id).ToImageSkia()->size(), false),
1054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        image_id_(image_id) {}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SubmenuArrowImageSource() {}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Draw(gfx::Canvas* canvas) OVERRIDE {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    const gfx::ImageSkia* r = rb.GetImageNamed(image_id_).ToImageSkia();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->Scale(-1, 1);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    canvas->DrawImageInt(*r, - r->width(), 0);
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static gfx::Size GetSubmenuArrowSize() {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ui::ResourceBundle::GetSharedInstance()
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        .GetImageNamed(IDR_MENU_HIERARCHY_ARROW).ToImageSkia()->size();
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int image_id_;
1224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SubmenuArrowImageSource);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)gfx::ImageSkia GetRtlSubmenuArrowImage(bool rtl,
1274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                       bool dark_background) {
1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int image_id = dark_background ? IDR_MENU_HIERARCHY_ARROW_DARK_BACKGROUND :
1294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   IDR_MENU_HIERARCHY_ARROW;
1304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!rtl) {
1324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return ui::ResourceBundle::GetSharedInstance().GetImageNamed(image_id).
1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        AsImageSkia();
1344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
1354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static gfx::ImageSkia* kRtlArrow = NULL;
1374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  static gfx::ImageSkia* kRtlArrowDarkBg = NULL;
1384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  gfx::ImageSkia** image = dark_background ? &kRtlArrowDarkBg : &kRtlArrow;
1394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!*image) {
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    SubmenuArrowImageSource* source = new SubmenuArrowImageSource(image_id);
1424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    *image = new gfx::ImageSkia(source, source->size());
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return **image;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace views {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)gfx::ImageSkia GetMenuCheckImage(bool dark_background) {
1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int image_id = dark_background ? IDR_MENU_CHECK_CHECKED_DARK_BACKGROUND :
1544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)                                   IDR_MENU_CHECK_CHECKED;
1554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return ui::ResourceBundle::GetSharedInstance().GetImageNamed(image_id).
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      AsImageSkia();
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)gfx::ImageSkia GetRadioButtonImage(bool selected) {
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int image_id = selected ? IDR_MENU_RADIO_SELECTED : IDR_MENU_RADIO_EMPTY;
1614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return ui::ResourceBundle::GetSharedInstance().GetImageNamed(image_id).
1624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      AsImageSkia();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)gfx::ImageSkia GetSubmenuArrowImage(bool dark_background) {
1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  return GetRtlSubmenuArrowImage(base::i18n::IsRTL(), dark_background);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace views
170