• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
OverflowButton(views::ButtonListener * listener)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 
~OverflowButton()48 OverflowButton::~OverflowButton() {}
49 
OnShelfAlignmentChanged()50 void OverflowButton::OnShelfAlignmentChanged() {
51   SchedulePaint();
52 }
53 
PaintBackground(gfx::Canvas * canvas,int alpha)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 
OnPaint(gfx::Canvas * canvas)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