icon_label_bubble_view.cc revision 868fa2fe829687343ffae624259930155e16dbd8
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/controls/label.h"
15#include "ui/views/painter.h"
16
17
18IconLabelBubbleView::IconLabelBubbleView(const int background_images[],
19                                         int contained_image,
20                                         const gfx::Font& font,
21                                         int font_y_offset,
22                                         SkColor text_color,
23                                         SkColor parent_background_color,
24                                         bool elide_in_middle)
25    : background_painter_(
26          views::Painter::CreateImageGridPainter(background_images)),
27      image_(new views::ImageView()),
28      label_(new views::Label()),
29      is_extension_icon_(false) {
30  image_->SetImage(
31      ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
32          contained_image));
33  AddChildView(image_);
34
35  label_->set_border(views::Border::CreateEmptyBorder(font_y_offset, 0, 0, 0));
36  label_->SetFont(font);
37  label_->SetEnabledColor(text_color);
38  // Calculate the actual background color for the label.  The background images
39  // are painted atop |parent_background_color|.  We grab the color of the
40  // middle pixel of the middle image of the background, which we treat as the
41  // representative color of the entire background (reasonable, given the
42  // current appearance of these images).  Then we alpha-blend it over the
43  // parent background color to determine the actual color the label text will
44  // sit atop.
45  const SkBitmap& bitmap(
46      ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
47          background_images[4])->GetRepresentation(
48          ui::SCALE_FACTOR_100P).sk_bitmap());
49  SkAutoLockPixels pixel_lock(bitmap);
50  SkColor background_image_color =
51      bitmap.getColor(bitmap.width() / 2, bitmap.height() / 2);
52  // Tricky bit: We alpha blend an opaque version of |background_image_color|
53  // against |parent_background_color| using the original image grid color's
54  // alpha. This is because AlphaBlend(a, b, 255) always returns |a| unchanged
55  // even if |a| is a color with non-255 alpha.
56  label_->SetBackgroundColor(
57      color_utils::AlphaBlend(SkColorSetA(background_image_color, 255),
58                              parent_background_color,
59                              SkColorGetA(background_image_color)));
60  if (elide_in_middle)
61    label_->SetElideBehavior(views::Label::ELIDE_IN_MIDDLE);
62  AddChildView(label_);
63}
64
65IconLabelBubbleView::~IconLabelBubbleView() {
66}
67
68void IconLabelBubbleView::SetLabel(const string16& label) {
69  label_->SetText(label);
70}
71
72void IconLabelBubbleView::SetImage(const gfx::ImageSkia& image_skia) {
73  image_->SetImage(image_skia);
74}
75
76gfx::Size IconLabelBubbleView::GetPreferredSize() {
77  // Height will be ignored by the LocationBarView.
78  return GetSizeForLabelWidth(label_->GetPreferredSize().width());
79}
80
81void IconLabelBubbleView::Layout() {
82  image_->SetBounds(GetBubbleOuterPadding(!is_extension_icon_), 0,
83                    image_->GetPreferredSize().width(), height());
84  const int pre_label_width = GetPreLabelWidth();
85  label_->SetBounds(pre_label_width, 0,
86                    width() - pre_label_width - GetBubbleOuterPadding(false),
87                    label_->GetPreferredSize().height());
88}
89
90gfx::Size IconLabelBubbleView::GetSizeForLabelWidth(int width) const {
91  gfx::Size size(GetPreLabelWidth() + width + GetBubbleOuterPadding(false), 0);
92  size.SetToMax(background_painter_->GetMinimumSize());
93  return size;
94}
95
96// static
97int IconLabelBubbleView::GetBubbleOuterPadding(bool by_icon) {
98  return LocationBarView::GetItemPadding() - LocationBarView::kBubblePadding +
99      (by_icon ? 0 : LocationBarView::kIconInternalPadding);
100}
101
102void IconLabelBubbleView::OnPaint(gfx::Canvas* canvas) {
103  background_painter_->Paint(canvas, size());
104}
105
106int IconLabelBubbleView::GetPreLabelWidth() const {
107  const int image_width = image_->GetPreferredSize().width();
108  return GetBubbleOuterPadding(true) +
109      (image_width ? (image_width + LocationBarView::GetItemPadding()) : 0);
110}
111