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