• 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 "chrome/browser/ui/views/location_bar/icon_label_bubble_view.h"
6 
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
9 #include "grit/theme_resources.h"
10 #include "ui/base/resource/resource_bundle.h"
11 #include "ui/gfx/canvas.h"
12 #include "ui/gfx/color_utils.h"
13 #include "ui/views/controls/image_view.h"
14 #include "ui/views/painter.h"
15 
16 
IconLabelBubbleView(const int background_images[],const int hover_background_images[],int contained_image,const gfx::FontList & font_list,SkColor text_color,SkColor parent_background_color,bool elide_in_middle)17 IconLabelBubbleView::IconLabelBubbleView(const int background_images[],
18                                          const int hover_background_images[],
19                                          int contained_image,
20                                          const gfx::FontList& font_list,
21                                          SkColor text_color,
22                                          SkColor parent_background_color,
23                                          bool elide_in_middle)
24     : background_painter_(
25           views::Painter::CreateImageGridPainter(background_images)),
26       image_(new views::ImageView()),
27       label_(new views::Label(base::string16(), font_list)),
28       is_extension_icon_(false),
29       in_hover_(false) {
30   image_->SetImage(
31       ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
32           contained_image));
33 
34   // Disable separate hit testing for |image_|.  This prevents views treating
35   // |image_| as a separate mouse hover region from |this|.
36   image_->set_interactive(false);
37   AddChildView(image_);
38 
39   if (hover_background_images) {
40     hover_background_painter_.reset(
41         views::Painter::CreateImageGridPainter(hover_background_images));
42   }
43 
44   label_->SetEnabledColor(text_color);
45   // Calculate the actual background color for the label.  The background images
46   // are painted atop |parent_background_color|.  We grab the color of the
47   // middle pixel of the middle image of the background, which we treat as the
48   // representative color of the entire background (reasonable, given the
49   // current appearance of these images).  Then we alpha-blend it over the
50   // parent background color to determine the actual color the label text will
51   // sit atop.
52   const SkBitmap& bitmap(
53       ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
54           background_images[4])->GetRepresentation(1.0f).sk_bitmap());
55   SkAutoLockPixels pixel_lock(bitmap);
56   SkColor background_image_color =
57       bitmap.getColor(bitmap.width() / 2, bitmap.height() / 2);
58   // Tricky bit: We alpha blend an opaque version of |background_image_color|
59   // against |parent_background_color| using the original image grid color's
60   // alpha. This is because AlphaBlend(a, b, 255) always returns |a| unchanged
61   // even if |a| is a color with non-255 alpha.
62   label_->SetBackgroundColor(
63       color_utils::AlphaBlend(SkColorSetA(background_image_color, 255),
64                               parent_background_color,
65                               SkColorGetA(background_image_color)));
66   if (elide_in_middle)
67     label_->SetElideBehavior(gfx::ELIDE_MIDDLE);
68   AddChildView(label_);
69 }
70 
~IconLabelBubbleView()71 IconLabelBubbleView::~IconLabelBubbleView() {
72 }
73 
SetLabel(const base::string16 & label)74 void IconLabelBubbleView::SetLabel(const base::string16& label) {
75   label_->SetText(label);
76 }
77 
SetImage(const gfx::ImageSkia & image_skia)78 void IconLabelBubbleView::SetImage(const gfx::ImageSkia& image_skia) {
79   image_->SetImage(image_skia);
80 }
81 
GetPreferredSize() const82 gfx::Size IconLabelBubbleView::GetPreferredSize() const {
83   // Height will be ignored by the LocationBarView.
84   return GetSizeForLabelWidth(label_->GetPreferredSize().width());
85 }
86 
Layout()87 void IconLabelBubbleView::Layout() {
88   image_->SetBounds(GetBubbleOuterPadding(!is_extension_icon_), 0,
89                     image_->GetPreferredSize().width(), height());
90   const int pre_label_width = GetPreLabelWidth();
91   label_->SetBounds(pre_label_width, 0,
92                     width() - pre_label_width - GetBubbleOuterPadding(false),
93                     height());
94 }
95 
GetSizeForLabelWidth(int width) const96 gfx::Size IconLabelBubbleView::GetSizeForLabelWidth(int width) const {
97   gfx::Size size(GetPreLabelWidth() + width + GetBubbleOuterPadding(false), 0);
98   size.SetToMax(background_painter_->GetMinimumSize());
99   return size;
100 }
101 
OnMouseEntered(const ui::MouseEvent & event)102 void IconLabelBubbleView::OnMouseEntered(const ui::MouseEvent& event) {
103   in_hover_ = true;
104   if (hover_background_painter_.get())
105     SchedulePaint();
106 }
107 
OnMouseExited(const ui::MouseEvent & event)108 void IconLabelBubbleView::OnMouseExited(const ui::MouseEvent& event) {
109   in_hover_ = false;
110   if (hover_background_painter_.get())
111     SchedulePaint();
112 }
113 
114 // static
GetBubbleOuterPadding(bool by_icon)115 int IconLabelBubbleView::GetBubbleOuterPadding(bool by_icon) {
116   return LocationBarView::kItemPadding - LocationBarView::kBubblePadding +
117       (by_icon ? 0 : LocationBarView::kIconInternalPadding);
118 }
119 
OnPaint(gfx::Canvas * canvas)120 void IconLabelBubbleView::OnPaint(gfx::Canvas* canvas) {
121   views::Painter* painter = (in_hover_ && hover_background_painter_) ?
122       hover_background_painter_.get() : background_painter_.get();
123   painter->Paint(canvas, size());
124 }
125 
GetPreLabelWidth() const126 int IconLabelBubbleView::GetPreLabelWidth() const {
127   const int image_width = image_->GetPreferredSize().width();
128   return GetBubbleOuterPadding(true) +
129       (image_width ? (image_width + LocationBarView::kItemPadding) : 0);
130 }
131