Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / ui / views / location_bar / icon_label_bubble_view.cc
blobed09f59f1616ebb12ab6dd6e5a0d9b8c75f9f557
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/layout_constants.h"
9 #include "ui/base/resource/resource_bundle.h"
10 #include "ui/gfx/canvas.h"
11 #include "ui/gfx/color_utils.h"
12 #include "ui/views/controls/image_view.h"
13 #include "ui/views/painter.h"
15 namespace {
17 SkColor CalculateImageColor(gfx::ImageSkia* image) {
18 // We grab the color of the middle pixel of the image, which we treat as
19 // the representative color of the entire image (reasonable, given the current
20 // appearance of these assets).
21 const SkBitmap& bitmap(image->GetRepresentation(1.0f).sk_bitmap());
22 SkAutoLockPixels pixel_lock(bitmap);
23 return bitmap.getColor(bitmap.width() / 2, bitmap.height() / 2);
26 } // namespace
28 IconLabelBubbleView::IconLabelBubbleView(int contained_image,
29 const gfx::FontList& font_list,
30 SkColor text_color,
31 SkColor parent_background_color,
32 bool elide_in_middle)
33 : background_painter_(nullptr),
34 image_(new views::ImageView()),
35 label_(new views::Label(base::string16(), font_list)),
36 is_extension_icon_(false),
37 parent_background_color_(parent_background_color) {
38 if (contained_image) {
39 image_->SetImage(
40 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
41 contained_image));
44 // Disable separate hit testing for |image_|. This prevents views treating
45 // |image_| as a separate mouse hover region from |this|.
46 image_->set_interactive(false);
47 AddChildView(image_);
49 label_->SetEnabledColor(text_color);
51 if (elide_in_middle)
52 label_->SetElideBehavior(gfx::ELIDE_MIDDLE);
53 AddChildView(label_);
56 IconLabelBubbleView::~IconLabelBubbleView() {
59 void IconLabelBubbleView::SetBackgroundImageGrid(
60 const int background_images[]) {
61 background_painter_.reset(
62 views::Painter::CreateImageGridPainter(background_images));
63 // Use the middle image of the background to represent the color of the entire
64 // background.
65 gfx::ImageSkia* background_image =
66 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
67 background_images[4]);
68 SetLabelBackgroundColor(CalculateImageColor(background_image));
71 void IconLabelBubbleView::SetBackgroundImageWithInsets(int background_image_id,
72 gfx::Insets& insets) {
73 gfx::ImageSkia* background_image =
74 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
75 background_image_id);
76 background_painter_.reset(
77 views::Painter::CreateImagePainter(*background_image, insets));
78 SetLabelBackgroundColor(CalculateImageColor(background_image));
81 void IconLabelBubbleView::SetLabel(const base::string16& label) {
82 label_->SetText(label);
85 void IconLabelBubbleView::SetImage(const gfx::ImageSkia& image_skia) {
86 image_->SetImage(image_skia);
89 bool IconLabelBubbleView::ShouldShowBackground() const {
90 return true;
93 double IconLabelBubbleView::WidthMultiplier() const {
94 return 1.0;
97 gfx::Size IconLabelBubbleView::GetPreferredSize() const {
98 // Height will be ignored by the LocationBarView.
99 return GetSizeForLabelWidth(label_->GetPreferredSize().width());
102 void IconLabelBubbleView::Layout() {
103 const int image_width = image()->GetPreferredSize().width();
104 image_->SetBounds(std::min((width() - image_width) / 2,
105 GetBubbleOuterPadding(!is_extension_icon_)),
106 0, image_->GetPreferredSize().width(), height());
108 const int padding = GetLayoutConstant(LOCATION_BAR_HORIZONTAL_PADDING);
109 int pre_label_width =
110 GetBubbleOuterPadding(true) + (image_width ? (image_width + padding) : 0);
111 label_->SetBounds(pre_label_width, 0,
112 width() - pre_label_width - GetBubbleOuterPadding(false),
113 height());
116 gfx::Size IconLabelBubbleView::GetSizeForLabelWidth(int width) const {
117 gfx::Size size(image_->GetPreferredSize());
118 if (ShouldShowBackground()) {
119 const int image_width = image_->GetPreferredSize().width();
120 const int padding = GetLayoutConstant(LOCATION_BAR_HORIZONTAL_PADDING);
121 const int non_label_width =
122 GetBubbleOuterPadding(true) +
123 (image_width ? (image_width + padding) : 0) +
124 GetBubbleOuterPadding(false);
125 size = gfx::Size(WidthMultiplier() * (width + non_label_width), 0);
126 size.SetToMax(background_painter_->GetMinimumSize());
129 return size;
132 int IconLabelBubbleView::GetBubbleOuterPadding(bool by_icon) const {
133 return GetLayoutConstant(LOCATION_BAR_HORIZONTAL_PADDING) -
134 GetLayoutConstant(LOCATION_BAR_BUBBLE_HORIZONTAL_PADDING) +
135 (by_icon ? 0 : GetLayoutConstant(ICON_LABEL_VIEW_TRAILING_PADDING));
138 void IconLabelBubbleView::SetLabelBackgroundColor(
139 SkColor background_image_color) {
140 // The background images are painted atop |parent_background_color_|.
141 // Alpha-blend |background_image_color| with |parent_background_color_| to
142 // determine the actual color the label text will sit atop.
143 // Tricky bit: We alpha blend an opaque version of |background_image_color|
144 // against |parent_background_color_| using the original image grid color's
145 // alpha. This is because AlphaBlend(a, b, 255) always returns |a| unchanged
146 // even if |a| is a color with non-255 alpha.
147 label_->SetBackgroundColor(color_utils::AlphaBlend(
148 SkColorSetA(background_image_color, 255), parent_background_color_,
149 SkColorGetA(background_image_color)));
152 const char* IconLabelBubbleView::GetClassName() const {
153 return "IconLabelBubbleView";
156 void IconLabelBubbleView::OnPaint(gfx::Canvas* canvas) {
157 if (!ShouldShowBackground())
158 return;
159 if (background_painter_)
160 background_painter_->Paint(canvas, size());