icon_label_bubble_view.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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 17IconLabelBubbleView::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(views::Label::ELIDE_IN_MIDDLE); 68 AddChildView(label_); 69} 70 71IconLabelBubbleView::~IconLabelBubbleView() { 72} 73 74void IconLabelBubbleView::SetLabel(const base::string16& label) { 75 label_->SetText(label); 76} 77 78void IconLabelBubbleView::SetImage(const gfx::ImageSkia& image_skia) { 79 image_->SetImage(image_skia); 80} 81 82gfx::Size IconLabelBubbleView::GetPreferredSize() const { 83 // Height will be ignored by the LocationBarView. 84 return GetSizeForLabelWidth(label_->GetPreferredSize().width()); 85} 86 87void 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 96gfx::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 102void IconLabelBubbleView::OnMouseEntered(const ui::MouseEvent& event) { 103 in_hover_ = true; 104 if (hover_background_painter_.get()) 105 SchedulePaint(); 106} 107 108void IconLabelBubbleView::OnMouseExited(const ui::MouseEvent& event) { 109 in_hover_ = false; 110 if (hover_background_painter_.get()) 111 SchedulePaint(); 112} 113 114// static 115int IconLabelBubbleView::GetBubbleOuterPadding(bool by_icon) { 116 return LocationBarView::kItemPadding - LocationBarView::kBubblePadding + 117 (by_icon ? 0 : LocationBarView::kIconInternalPadding); 118} 119 120void 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 126int 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