- add sources.
[platform/framework/web/crosswalk.git] / src / ash / shelf / overflow_button.cc
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   set_accessibility_focusable(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