Home | History | Annotate | Download | only in shelf
      1 // Copyright 2013 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 "ash/shelf/overflow_button.h"
      6 
      7 #include "ash/ash_switches.h"
      8 #include "ash/shelf/shelf_layout_manager.h"
      9 #include "ash/shelf/shelf_widget.h"
     10 #include "grit/ash_resources.h"
     11 #include "grit/ash_strings.h"
     12 #include "third_party/skia/include/core/SkPaint.h"
     13 #include "third_party/skia/include/core/SkPath.h"
     14 #include "ui/base/l10n/l10n_util.h"
     15 #include "ui/base/resource/resource_bundle.h"
     16 #include "ui/gfx/animation/throb_animation.h"
     17 #include "ui/gfx/canvas.h"
     18 #include "ui/gfx/image/image_skia_operations.h"
     19 #include "ui/gfx/skbitmap_operations.h"
     20 #include "ui/gfx/skia_util.h"
     21 #include "ui/gfx/transform.h"
     22 #include "ui/views/widget/widget.h"
     23 
     24 namespace ash {
     25 namespace {
     26 
     27 const int kButtonHoverAlpha = 150;
     28 
     29 const int kButtonCornerRadius = 2;
     30 
     31 const int kButtonHoverSize = 28;
     32 
     33 const int kBackgroundOffset = (48 - kButtonHoverSize) / 2;
     34 
     35 }  // namesapce
     36 
     37 OverflowButton::OverflowButton(views::ButtonListener* listener)
     38     : CustomButton(listener),
     39       bottom_image_(NULL) {
     40   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
     41   bottom_image_ = rb.GetImageNamed(IDR_ASH_SHELF_OVERFLOW).ToImageSkia();
     42 
     43 
     44   SetAccessibilityFocusable(true);
     45   SetAccessibleName(l10n_util::GetStringUTF16(IDS_ASH_SHELF_OVERFLOW_NAME));
     46 }
     47 
     48 OverflowButton::~OverflowButton() {}
     49 
     50 void OverflowButton::OnShelfAlignmentChanged() {
     51   SchedulePaint();
     52 }
     53 
     54 void OverflowButton::PaintBackground(gfx::Canvas* canvas, int alpha) {
     55   gfx::Rect bounds(GetContentsBounds());
     56   gfx::Rect rect(0, 0, kButtonHoverSize, kButtonHoverSize);
     57   ShelfLayoutManager* shelf =
     58       ShelfLayoutManager::ForShelf(GetWidget()->GetNativeView());
     59 
     60   // Nudge the background a little to line up right.
     61   if (shelf->IsHorizontalAlignment()) {
     62     rect.set_origin(gfx::Point(
     63         bounds.x() + ((bounds.width() - kButtonHoverSize) / 2) - 1,
     64         bounds.y() + kBackgroundOffset - 1));
     65 
     66   } else {
     67     rect.set_origin(gfx::Point(
     68         bounds.x() + kBackgroundOffset - 1,
     69         bounds.y() + ((bounds.height() - kButtonHoverSize) / 2) - 1));
     70   }
     71 
     72   SkPaint paint;
     73   paint.setAntiAlias(true);
     74   paint.setStyle(SkPaint::kFill_Style);
     75   paint.setColor(SkColorSetARGB(
     76       kButtonHoverAlpha * hover_animation_->GetCurrentValue(),
     77       0, 0, 0));
     78 
     79   const SkScalar radius = SkIntToScalar(kButtonCornerRadius);
     80   SkPath path;
     81   path.addRoundRect(gfx::RectToSkRect(rect), radius, radius);
     82   canvas->DrawPath(path, paint);
     83 }
     84 
     85 void OverflowButton::OnPaint(gfx::Canvas* canvas) {
     86   ShelfLayoutManager* layout_manager =
     87       ShelfLayoutManager::ForShelf(GetWidget()->GetNativeView());
     88   ShelfAlignment alignment = layout_manager->GetAlignment();
     89 
     90   gfx::Rect bounds(GetContentsBounds());
     91   ResourceBundle& rb = ResourceBundle::GetSharedInstance();
     92   int background_image_id = 0;
     93   if (layout_manager->shelf_widget()->shelf()->IsShowingOverflowBubble())
     94     background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_PRESSED;
     95   else if(layout_manager->shelf_widget()->GetDimsShelf())
     96     background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_ON_BLACK;
     97   else
     98     background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_NORMAL;
     99 
    100   const gfx::ImageSkia* background =
    101       rb.GetImageNamed(background_image_id).ToImageSkia();
    102   if (alignment == SHELF_ALIGNMENT_LEFT) {
    103     bounds = gfx::Rect(
    104         bounds.right() - background->width() -
    105             ShelfLayoutManager::kShelfItemInset,
    106         bounds.y() + (bounds.height() - background->height()) / 2,
    107         background->width(), background->height());
    108   } else if (alignment == SHELF_ALIGNMENT_RIGHT) {
    109     bounds = gfx::Rect(
    110         bounds.x() + ShelfLayoutManager::kShelfItemInset,
    111         bounds.y() + (bounds.height() - background->height()) / 2,
    112         background->width(), background->height());
    113   } else {
    114     bounds = gfx::Rect(
    115         bounds.x() + (bounds.width() - background->width()) / 2,
    116         bounds.y() + ShelfLayoutManager::kShelfItemInset,
    117         background->width(), background->height());
    118   }
    119   canvas->DrawImageInt(*background, bounds.x(), bounds.y());
    120 
    121   if (height() < kButtonHoverSize)
    122     return;
    123 
    124   const gfx::ImageSkia* image = NULL;
    125 
    126   switch(alignment) {
    127     case SHELF_ALIGNMENT_LEFT:
    128       if (left_image_.isNull()) {
    129         left_image_ = gfx::ImageSkiaOperations::CreateRotatedImage(
    130             *bottom_image_, SkBitmapOperations::ROTATION_90_CW);
    131       }
    132       image = &left_image_;
    133       break;
    134     case SHELF_ALIGNMENT_RIGHT:
    135       if (right_image_.isNull()) {
    136         right_image_ = gfx::ImageSkiaOperations::CreateRotatedImage(
    137             *bottom_image_, SkBitmapOperations::ROTATION_270_CW);
    138       }
    139       image = &right_image_;
    140       break;
    141     default:
    142       image = bottom_image_;
    143       break;
    144   }
    145 
    146   canvas->DrawImageInt(*image,
    147                        bounds.x() + ((bounds.width() - image->width()) / 2),
    148                        bounds.y() + ((bounds.height() - image->height()) / 2));
    149 }
    150 
    151 }  // namespace ash
    152