Home | History | Annotate | Download | only in views
      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/dropdown_bar_view.h"
      6 
      7 #include "chrome/browser/themes/theme_service.h"
      8 #include "chrome/browser/ui/view_ids.h"
      9 #include "chrome/browser/ui/views/frame/browser_view.h"
     10 #include "grit/generated_resources.h"
     11 #include "grit/theme_resources.h"
     12 #include "third_party/skia/include/core/SkCanvas.h"
     13 #include "third_party/skia/include/core/SkRect.h"
     14 #include "ui/base/resource/resource_bundle.h"
     15 #include "ui/gfx/canvas.h"
     16 #include "ui/gfx/image/image_skia.h"
     17 #include "ui/views/background.h"
     18 #include "ui/views/border.h"
     19 #include "ui/views/painter.h"
     20 #include "ui/views/widget/widget.h"
     21 
     22 namespace {
     23 
     24 // When we are animating, we draw only the top part of the left and right
     25 // edges to give the illusion that the find dialog is attached to the
     26 // window during this animation; this is the height of the items we draw.
     27 const int kAnimatingEdgeHeight = 5;
     28 
     29 // Background to paint toolbar background with rounded corners.
     30 class DropdownBackground : public views::Background {
     31  public:
     32   explicit DropdownBackground(BrowserView* browser,
     33                               const gfx::ImageSkia* left_alpha_mask,
     34                               const gfx::ImageSkia* right_alpha_mask);
     35   virtual ~DropdownBackground() {}
     36 
     37   // Overridden from views::Background.
     38   virtual void Paint(gfx::Canvas* canvas, views::View* view) const OVERRIDE;
     39 
     40  private:
     41   BrowserView* browser_view_;
     42   const gfx::ImageSkia* left_alpha_mask_;
     43   const gfx::ImageSkia* right_alpha_mask_;
     44 
     45   DISALLOW_COPY_AND_ASSIGN(DropdownBackground);
     46 };
     47 
     48 DropdownBackground::DropdownBackground(BrowserView* browser_view,
     49                                      const gfx::ImageSkia* left_alpha_mask,
     50                                      const gfx::ImageSkia* right_alpha_mask)
     51     : browser_view_(browser_view),
     52       left_alpha_mask_(left_alpha_mask),
     53       right_alpha_mask_(right_alpha_mask) {
     54 }
     55 
     56 void DropdownBackground::Paint(gfx::Canvas* canvas, views::View* view) const {
     57   // Find the offset from which to tile the toolbar background image.
     58   // First, get the origin with respect to the screen.
     59   gfx::Point origin = view->GetWidget()->GetWindowBoundsInScreen().origin();
     60   // Now convert from screen to parent coordinates.
     61   views::View::ConvertPointToTarget(NULL, browser_view_, &origin);
     62   // Finally, calculate the background image tiling offset.
     63   origin = browser_view_->OffsetPointForToolbarBackgroundImage(origin);
     64 
     65   ui::ThemeProvider* tp = view->GetThemeProvider();
     66   gfx::ImageSkia background = *tp->GetImageSkiaNamed(IDR_THEME_TOOLBAR);
     67 
     68   int left_edge_width = left_alpha_mask_->width();
     69   int right_edge_width = right_alpha_mask_->width();
     70   int mask_height = left_alpha_mask_->height();
     71   int height = view->bounds().height();
     72 
     73   // Stretch the middle background to cover the entire area.
     74   canvas->TileImageInt(background, origin.x(), origin.y(),
     75       0, 0, view->bounds().width(), height);
     76 
     77   SkPaint paint;
     78   paint.setXfermodeMode(SkXfermode::kDstIn_Mode);
     79   // Draw left edge.
     80   canvas->DrawImageInt(*left_alpha_mask_, 0, 0, left_edge_width, mask_height,
     81       0, 0, left_edge_width, height, false, paint);
     82 
     83   // Draw right edge.
     84   int x_right_edge = view->bounds().width() - right_edge_width;
     85   canvas->DrawImageInt(*right_alpha_mask_, 0, 0, right_edge_width,
     86       mask_height, x_right_edge, 0, right_edge_width, height, false, paint);
     87 }
     88 
     89 }  // namespace
     90 
     91 DropdownBarView::DropdownBarView(DropdownBarHost* host)
     92     : host_(host),
     93       animation_offset_(0) {
     94 }
     95 
     96 DropdownBarView::~DropdownBarView() {
     97 }
     98 
     99 ////////////////////////////////////////////////////////////////////////////////
    100 // DropDownBarView, public:
    101 
    102 void DropdownBarView::SetAnimationOffset(int offset) {
    103   animation_offset_ = offset;
    104   set_clip_insets(gfx::Insets(animation_offset_, 0, 0, 0));
    105 }
    106 
    107 // DropDownBarView, views::View overrides:
    108 void DropdownBarView::OnPaint(gfx::Canvas* canvas) {
    109   OnPaintBackground(canvas);
    110   OnPaintBorder(canvas);
    111 
    112   if (animation_offset() > 0) {
    113      gfx::Canvas animating_edges(
    114          gfx::Size(bounds().width(), kAnimatingEdgeHeight),
    115          canvas->scale_factor(),
    116          false);
    117      canvas->Translate(bounds().OffsetFromOrigin());
    118      OnPaintBackground(&animating_edges);
    119      OnPaintBorder(&animating_edges);
    120      canvas->DrawImageInt(gfx::ImageSkia(animating_edges.ExtractImageRep()),
    121          bounds().x(), animation_offset());
    122   }
    123 }
    124 
    125 ////////////////////////////////////////////////////////////////////////////////
    126 // DropDownBarView, protected:
    127 
    128 void DropdownBarView::SetBackground(const gfx::ImageSkia* left_alpha_mask,
    129                                     const gfx::ImageSkia* right_alpha_mask) {
    130   set_background(new DropdownBackground(host()->browser_view(), left_alpha_mask,
    131       right_alpha_mask));
    132 }
    133 
    134 void DropdownBarView::SetBorder(int left_border_image_id,
    135                                 int middle_border_image_id,
    136                                 int right_border_image_id) {
    137   int border_image_ids[3] = {left_border_image_id, middle_border_image_id,
    138       right_border_image_id};
    139   set_border(views::Border::CreateBorderPainter(
    140       new views::HorizontalPainter(border_image_ids), gfx::Insets()));
    141 }
    142