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.
5 #include "ash/launcher/overflow_button.h"
7 #include "ash/wm/shelf_layout_manager.h"
8 #include "grit/ash_resources.h"
9 #include "grit/ash_strings.h"
10 #include "third_party/skia/include/core/SkPaint.h"
11 #include "third_party/skia/include/core/SkPath.h"
12 #include "ui/base/animation/throb_animation.h"
13 #include "ui/base/l10n/l10n_util.h"
14 #include "ui/base/resource/resource_bundle.h"
15 #include "ui/gfx/canvas.h"
16 #include "ui/gfx/skia_util.h"
17 #include "ui/gfx/transform.h"
18 #include "ui/views/widget/widget.h"
25 const int kButtonHoverAlpha
= 150;
27 const int kButtonCornerRadius
= 2;
29 const int kButtonHoverSize
= 28;
31 const int kBackgroundOffset
= (48 - kButtonHoverSize
) / 2;
33 void RotateCounterclockwise(gfx::Transform
* transform
) {
35 rotation
.set3x3(0, -1, 0,
38 transform
->matrix().preConcat(rotation
);
41 void RotateClockwise(gfx::Transform
* transform
) {
43 rotation
.set3x3( 0, 1, 0,
46 transform
->matrix().preConcat(rotation
);
51 OverflowButton::OverflowButton(views::ButtonListener
* listener
)
52 : CustomButton(listener
),
54 ResourceBundle
& rb
= ResourceBundle::GetSharedInstance();
55 image_
= rb
.GetImageNamed(IDR_AURA_LAUNCHER_OVERFLOW
).ToImageSkia();
57 set_accessibility_focusable(true);
59 l10n_util::GetStringUTF16(IDS_AURA_LAUNCHER_OVERFLOW_NAME
));
63 OverflowButton::~OverflowButton() {
66 void OverflowButton::OnShelfAlignmentChanged() {
70 void OverflowButton::PaintBackground(gfx::Canvas
* canvas
, int alpha
) {
71 gfx::Rect
bounds(GetContentsBounds());
72 gfx::Rect
rect(0, 0, kButtonHoverSize
, kButtonHoverSize
);
73 ShelfLayoutManager
* shelf
=
74 ShelfLayoutManager::ForLauncher(GetWidget()->GetNativeView());
76 // Nudge the background a little to line up right.
77 if (shelf
->GetAlignment() == SHELF_ALIGNMENT_BOTTOM
) {
78 rect
.set_origin(gfx::Point(
79 bounds
.x() + ((bounds
.width() - kButtonHoverSize
) / 2) - 1,
80 bounds
.y() + kBackgroundOffset
- 1));
83 rect
.set_origin(gfx::Point(
84 bounds
.x() + kBackgroundOffset
- 1,
85 bounds
.y() + ((bounds
.height() - kButtonHoverSize
) / 2) - 1));
89 paint
.setAntiAlias(true);
90 paint
.setStyle(SkPaint::kFill_Style
);
91 paint
.setColor(SkColorSetARGB(
92 kButtonHoverAlpha
* hover_animation_
->GetCurrentValue(),
95 const SkScalar radius
= SkIntToScalar(kButtonCornerRadius
);
97 path
.addRoundRect(gfx::RectToSkRect(rect
), radius
, radius
);
98 canvas
->DrawPath(path
, paint
);
101 void OverflowButton::OnPaint(gfx::Canvas
* canvas
) {
102 ShelfAlignment alignment
= ShelfLayoutManager::ForLauncher(
103 GetWidget()->GetNativeView())->GetAlignment();
105 if (hover_animation_
->is_animating()) {
108 kButtonHoverAlpha
* hover_animation_
->GetCurrentValue());
109 } else if (state() == STATE_HOVERED
|| state() == STATE_PRESSED
) {
110 PaintBackground(canvas
, kButtonHoverAlpha
);
113 if (height() < kButtonHoverSize
)
116 gfx::Transform transform
;
119 case SHELF_ALIGNMENT_BOTTOM
:
120 // Shift 1 pixel left to align with overflow bubble tip.
121 transform
.Translate(-1, kBackgroundOffset
);
123 case SHELF_ALIGNMENT_LEFT
:
124 transform
.Translate(kBackgroundOffset
, -1);
125 RotateClockwise(&transform
);
127 case SHELF_ALIGNMENT_RIGHT
:
128 transform
.Translate(kBackgroundOffset
, height());
129 RotateCounterclockwise(&transform
);
134 canvas
->Transform(transform
);
136 gfx::Rect
rect(GetContentsBounds());
137 if (alignment
== SHELF_ALIGNMENT_BOTTOM
) {
138 canvas
->DrawImageInt(*image_
,
139 rect
.x() + (rect
.width() - image_
->width()) / 2,
140 kButtonHoverSize
- image_
->height());
142 canvas
->DrawImageInt(*image_
,
143 kButtonHoverSize
- image_
->width(),
144 rect
.y() + (rect
.height() - image_
->height()) / 2);
149 } // namespace internal