1// Copyright 2014 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/alternate_app_list_button.h"
6
7#include "ash/ash_constants.h"
8#include "ash/ash_switches.h"
9#include "ash/shelf/shelf_button.h"
10#include "ash/shelf/shelf_button_host.h"
11#include "ash/shelf/shelf_item_types.h"
12#include "ash/shelf/shelf_layout_manager.h"
13#include "ash/shelf/shelf_widget.h"
14#include "ash/shell.h"
15#include "grit/ash_resources.h"
16#include "grit/ash_strings.h"
17#include "ui/accessibility/ax_view_state.h"
18#include "ui/base/l10n/l10n_util.h"
19#include "ui/base/resource/resource_bundle.h"
20#include "ui/compositor/layer.h"
21#include "ui/compositor/layer_animation_element.h"
22#include "ui/compositor/layer_animation_sequence.h"
23#include "ui/compositor/scoped_layer_animation_settings.h"
24#include "ui/gfx/canvas.h"
25#include "ui/gfx/image/image_skia_operations.h"
26#include "ui/views/controls/button/image_button.h"
27#include "ui/views/painter.h"
28
29namespace ash {
30// static
31const int AlternateAppListButton::kImageBoundsSize = 7;
32
33
34AlternateAppListButton::AlternateAppListButton(views::ButtonListener* listener,
35                                               ShelfButtonHost* host,
36                                               ShelfWidget* shelf_widget)
37    : views::ImageButton(listener),
38      host_(host),
39      shelf_widget_(shelf_widget) {
40  SetAccessibleName(l10n_util::GetStringUTF16(IDS_ASH_SHELF_APP_LIST_TITLE));
41  SetSize(gfx::Size(ShelfLayoutManager::kShelfSize,
42                    ShelfLayoutManager::kShelfSize));
43  SetFocusPainter(views::Painter::CreateSolidFocusPainter(
44                      kFocusBorderColor, gfx::Insets(1, 1, 1, 1)));
45}
46
47AlternateAppListButton::~AlternateAppListButton() {
48}
49
50bool AlternateAppListButton::OnMousePressed(const ui::MouseEvent& event) {
51  ImageButton::OnMousePressed(event);
52  host_->PointerPressedOnButton(this, ShelfButtonHost::MOUSE, event);
53  return true;
54}
55
56void AlternateAppListButton::OnMouseReleased(const ui::MouseEvent& event) {
57  ImageButton::OnMouseReleased(event);
58  host_->PointerReleasedOnButton(this, ShelfButtonHost::MOUSE, false);
59}
60
61void AlternateAppListButton::OnMouseCaptureLost() {
62  host_->PointerReleasedOnButton(this, ShelfButtonHost::MOUSE, true);
63  ImageButton::OnMouseCaptureLost();
64}
65
66bool AlternateAppListButton::OnMouseDragged(const ui::MouseEvent& event) {
67  ImageButton::OnMouseDragged(event);
68  host_->PointerDraggedOnButton(this, ShelfButtonHost::MOUSE, event);
69  return true;
70}
71
72void AlternateAppListButton::OnMouseMoved(const ui::MouseEvent& event) {
73  ImageButton::OnMouseMoved(event);
74  host_->MouseMovedOverButton(this);
75}
76
77void AlternateAppListButton::OnMouseEntered(const ui::MouseEvent& event) {
78  ImageButton::OnMouseEntered(event);
79  host_->MouseEnteredButton(this);
80}
81
82void AlternateAppListButton::OnMouseExited(const ui::MouseEvent& event) {
83  ImageButton::OnMouseExited(event);
84  host_->MouseExitedButton(this);
85}
86
87void AlternateAppListButton::OnGestureEvent(ui::GestureEvent* event) {
88  switch (event->type()) {
89   case ui::ET_GESTURE_SCROLL_BEGIN:
90     host_->PointerPressedOnButton(this, ShelfButtonHost::TOUCH, *event);
91     event->SetHandled();
92     return;
93   case ui::ET_GESTURE_SCROLL_UPDATE:
94     host_->PointerDraggedOnButton(this, ShelfButtonHost::TOUCH, *event);
95     event->SetHandled();
96     return;
97   case ui::ET_GESTURE_SCROLL_END:
98   case ui::ET_SCROLL_FLING_START:
99     host_->PointerReleasedOnButton(this, ShelfButtonHost::TOUCH, false);
100     event->SetHandled();
101     return;
102   default:
103     ImageButton::OnGestureEvent(event);
104     return;
105  }
106}
107
108void AlternateAppListButton::OnPaint(gfx::Canvas* canvas) {
109  // Call the base class first to paint any background/borders.
110  View::OnPaint(canvas);
111
112  int background_image_id = 0;
113  if (Shell::GetInstance()->GetAppListTargetVisibility()) {
114    background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_PRESSED;
115  } else {
116    if (shelf_widget_->GetDimsShelf())
117      background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_ON_BLACK;
118    else
119      background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_NORMAL;
120  }
121  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
122  const gfx::ImageSkia* background_image =
123      rb.GetImageNamed(background_image_id).ToImageSkia();
124  const gfx::ImageSkia* forground_image =
125      rb.GetImageNamed(IDR_ASH_SHELF_ICON_APPLIST_ALTERNATE).ToImageSkia();
126
127  gfx::Rect contents_bounds = GetContentsBounds();
128  gfx::Rect background_bounds, forground_bounds;
129
130  ShelfAlignment alignment = shelf_widget_->GetAlignment();
131  background_bounds.set_size(background_image->size());
132  if (alignment == SHELF_ALIGNMENT_LEFT) {
133    background_bounds.set_x(contents_bounds.width() -
134        ShelfLayoutManager::kShelfItemInset - background_image->width());
135    background_bounds.set_y(contents_bounds.y() +
136        (contents_bounds.height() - background_image->height()) / 2);
137  } else if(alignment == SHELF_ALIGNMENT_RIGHT) {
138    background_bounds.set_x(ShelfLayoutManager::kShelfItemInset);
139    background_bounds.set_y(contents_bounds.y() +
140        (contents_bounds.height() - background_image->height()) / 2);
141  } else {
142    background_bounds.set_y(ShelfLayoutManager::kShelfItemInset);
143    background_bounds.set_x(contents_bounds.x() +
144        (contents_bounds.width() - background_image->width()) / 2);
145  }
146
147  forground_bounds.set_size(forground_image->size());
148  forground_bounds.set_x(background_bounds.x() +
149      std::max(0,
150          (background_bounds.width() - forground_bounds.width()) / 2));
151  forground_bounds.set_y(background_bounds.y() +
152      std::max(0,
153          (background_bounds.height() - forground_bounds.height()) / 2));
154
155  canvas->DrawImageInt(*background_image,
156                       background_bounds.x(),
157                       background_bounds.y());
158  canvas->DrawImageInt(*forground_image,
159                       forground_bounds.x(),
160                       forground_bounds.y());
161
162  views::Painter::PaintFocusPainter(this, canvas, focus_painter());
163}
164
165void AlternateAppListButton::GetAccessibleState(
166    ui::AXViewState* state) {
167  state->role = ui::AX_ROLE_BUTTON;
168  state->name = host_->GetAccessibleName(this);
169}
170
171}  // namespace ash
172