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 internal {
     26 
     27 namespace {
     28 
     29 const int kButtonHoverAlpha = 150;
     30 
     31 const int kButtonCornerRadius = 2;
     32 
     33 const int kButtonHoverSize = 28;
     34 
     35 const int kBackgroundOffset = (48 - kButtonHoverSize) / 2;
     36 
     37 }  // namesapce
     38 
     39 OverflowButton::OverflowButton(views::ButtonListener* listener)
     40     : CustomButton(listener),
     41       bottom_image_(NULL) {
     42   ResourceBundle& rb = ResourceBundle::GetSharedInstance();
     43   bottom_image_ = rb.GetImageNamed(IDR_AURA_LAUNCHER_OVERFLOW).ToImageSkia();
     44 
     45 
     46   SetAccessibilityFocusable(true);
     47   SetAccessibleName(l10n_util::GetStringUTF16(IDS_ASH_SHELF_OVERFLOW_NAME));
     48 }
     49 
     50 OverflowButton::~OverflowButton() {}
     51 
     52 void OverflowButton::OnShelfAlignmentChanged() {
     53   SchedulePaint();
     54 }
     55 
     56 void OverflowButton::PaintBackground(gfx::Canvas* canvas, int alpha) {
     57   gfx::Rect bounds(GetContentsBounds());
     58   gfx::Rect rect(0, 0, kButtonHoverSize, kButtonHoverSize);
     59   ShelfLayoutManager* shelf =
     60       ShelfLayoutManager::ForLauncher(GetWidget()->GetNativeView());
     61 
     62   // Nudge the background a little to line up right.
     63   if (shelf->IsHorizontalAlignment()) {
     64     rect.set_origin(gfx::Point(
     65         bounds.x() + ((bounds.width() - kButtonHoverSize) / 2) - 1,
     66         bounds.y() + kBackgroundOffset - 1));
     67 
     68   } else {
     69     rect.set_origin(gfx::Point(
     70         bounds.x() + kBackgroundOffset - 1,
     71         bounds.y() + ((bounds.height() - kButtonHoverSize) / 2) - 1));
     72   }
     73 
     74   SkPaint paint;
     75   paint.setAntiAlias(true);
     76   paint.setStyle(SkPaint::kFill_Style);
     77   paint.setColor(SkColorSetARGB(
     78       kButtonHoverAlpha * hover_animation_->GetCurrentValue(),
     79       0, 0, 0));
     80 
     81   const SkScalar radius = SkIntToScalar(kButtonCornerRadius);
     82   SkPath path;
     83   path.addRoundRect(gfx::RectToSkRect(rect), radius, radius);
     84   canvas->DrawPath(path, paint);
     85 }
     86 
     87 void OverflowButton::OnPaint(gfx::Canvas* canvas) {
     88   ShelfLayoutManager* layout_manager = ShelfLayoutManager::ForLauncher(
     89       GetWidget()->GetNativeView());
     90   ShelfAlignment alignment = layout_manager->GetAlignment();
     91 
     92   gfx::Rect bounds(GetContentsBounds());
     93   if (ash::switches::UseAlternateShelfLayout()) {
     94     ResourceBundle& rb = ResourceBundle::GetSharedInstance();
     95     int background_image_id = 0;
     96     if (layout_manager->shelf_widget()->launcher()->IsShowingOverflowBubble())
     97       background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_PRESSED;
     98     else if(layout_manager->shelf_widget()->GetDimsShelf())
     99       background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_ON_BLACK;
    100     else
    101       background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_NORMAL;
    102 
    103     const gfx::ImageSkia* background =
    104         rb.GetImageNamed(background_image_id).ToImageSkia();
    105     if (alignment == SHELF_ALIGNMENT_LEFT) {
    106       bounds = gfx::Rect(
    107           bounds.right() - background->width() -
    108               ShelfLayoutManager::kShelfItemInset,
    109           bounds.y() + (bounds.height() - background->height()) / 2,
    110           background->width(), background->height());
    111     } else if (alignment == SHELF_ALIGNMENT_RIGHT) {
    112       bounds = gfx::Rect(
    113           bounds.x() + ShelfLayoutManager::kShelfItemInset,
    114           bounds.y() + (bounds.height() - background->height()) / 2,
    115           background->width(), background->height());
    116     } else {
    117       bounds = gfx::Rect(
    118           bounds.x() + (bounds.width() - background->width()) / 2,
    119           bounds.y() + ShelfLayoutManager::kShelfItemInset,
    120           background->width(), background->height());
    121     }
    122     canvas->DrawImageInt(*background, bounds.x(), bounds.y());
    123   } else {
    124     if (alignment == SHELF_ALIGNMENT_BOTTOM) {
    125       bounds = gfx::Rect(
    126           bounds.x() + ((bounds.width() - kButtonHoverSize) / 2) - 1,
    127           bounds.y() + kBackgroundOffset - 1,
    128           kButtonHoverSize, kButtonHoverSize);
    129     } else {
    130       bounds = gfx::Rect(
    131           bounds.x() + kBackgroundOffset -1,
    132           bounds.y() + ((bounds.height() - kButtonHoverSize) / 2) -1,
    133           kButtonHoverSize, kButtonHoverSize);
    134     }
    135     if (hover_animation_->is_animating()) {
    136       PaintBackground(
    137           canvas,
    138           kButtonHoverAlpha * hover_animation_->GetCurrentValue());
    139     } else if (state() == STATE_HOVERED || state() == STATE_PRESSED) {
    140       PaintBackground(canvas, kButtonHoverAlpha);
    141     }
    142   }
    143 
    144   if (height() < kButtonHoverSize)
    145     return;
    146 
    147   const gfx::ImageSkia* image = NULL;
    148 
    149   switch(alignment) {
    150     case SHELF_ALIGNMENT_LEFT:
    151       if (left_image_.isNull()) {
    152         left_image_ = gfx::ImageSkiaOperations::CreateRotatedImage(
    153             *bottom_image_, SkBitmapOperations::ROTATION_90_CW);
    154       }
    155       image = &left_image_;
    156       break;
    157     case SHELF_ALIGNMENT_RIGHT:
    158       if (right_image_.isNull()) {
    159         right_image_ = gfx::ImageSkiaOperations::CreateRotatedImage(
    160             *bottom_image_, SkBitmapOperations::ROTATION_270_CW);
    161       }
    162       image = &right_image_;
    163       break;
    164     default:
    165       image = bottom_image_;
    166       break;
    167   }
    168 
    169   canvas->DrawImageInt(*image,
    170                        bounds.x() + ((bounds.width() - image->width()) / 2),
    171                        bounds.y() + ((bounds.height() - image->height()) / 2));
    172 }
    173 
    174 }  // namespace internal
    175 }  // namespace ash
    176