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 "chrome/browser/ui/views/location_bar/icon_label_bubble_view.h"
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"
17 IconLabelBubbleView::IconLabelBubbleView(const int background_images
[],
18 const int hover_background_images
[],
20 const gfx::FontList
& font_list
,
22 SkColor parent_background_color
,
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),
31 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
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);
39 if (hover_background_images
) {
40 hover_background_painter_
.reset(
41 views::Painter::CreateImageGridPainter(hover_background_images
));
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
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
)));
67 label_
->SetElideBehavior(views::Label::ELIDE_IN_MIDDLE
);
71 IconLabelBubbleView::~IconLabelBubbleView() {
74 void IconLabelBubbleView::SetLabel(const base::string16
& label
) {
75 label_
->SetText(label
);
78 void IconLabelBubbleView::SetImage(const gfx::ImageSkia
& image_skia
) {
79 image_
->SetImage(image_skia
);
82 gfx::Size
IconLabelBubbleView::GetPreferredSize() const {
83 // Height will be ignored by the LocationBarView.
84 return GetSizeForLabelWidth(label_
->GetPreferredSize().width());
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),
96 gfx::Size
IconLabelBubbleView::GetSizeForLabelWidth(int width
) const {
97 gfx::Size
size(GetPreLabelWidth() + width
+ GetBubbleOuterPadding(false), 0);
98 size
.SetToMax(background_painter_
->GetMinimumSize());
102 void IconLabelBubbleView::OnMouseEntered(const ui::MouseEvent
& event
) {
104 if (hover_background_painter_
.get())
108 void IconLabelBubbleView::OnMouseExited(const ui::MouseEvent
& event
) {
110 if (hover_background_painter_
.get())
115 int IconLabelBubbleView::GetBubbleOuterPadding(bool by_icon
) {
116 return LocationBarView::kItemPadding
- LocationBarView::kBubblePadding
+
117 (by_icon
? 0 : LocationBarView::kIconInternalPadding
);
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());
126 int IconLabelBubbleView::GetPreLabelWidth() const {
127 const int image_width
= image_
->GetPreferredSize().width();
128 return GetBubbleOuterPadding(true) +
129 (image_width
? (image_width
+ LocationBarView::kItemPadding
) : 0);