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