1a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "ash/shelf/app_list_button.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ash/ash_constants.h"
8a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/ash_switches.h"
9a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/shelf/shelf_button.h"
10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ash/shelf/shelf_button_host.h"
11a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/shelf/shelf_item_types.h"
12a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/shelf/shelf_layout_manager.h"
13a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/shelf/shelf_widget.h"
14a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ash/shell.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/command_line.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_resources.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_strings.h"
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/accessibility/ax_view_state.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer_animation_element.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/layer_animation_sequence.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/scoped_layer_animation_settings.h"
25a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/gfx/canvas.h"
26a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/gfx/image/image_skia_operations.h"
27a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "ui/views/controls/button/image_button.h"
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/views/painter.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash {
31a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch// static
32a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochconst int AppListButton::kImageBoundsSize = 7;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppListButton::AppListButton(views::ButtonListener* listener,
36a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                             ShelfButtonHost* host,
37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                             ShelfWidget* shelf_widget)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : views::ImageButton(listener),
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      draw_background_as_active_(false),
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      touch_feedback_enabled_(CommandLine::ForCurrentProcess()->
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          HasSwitch(switches::kAshEnableTouchViewTouchFeedback)),
42a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      host_(host),
43a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      shelf_widget_(shelf_widget) {
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  SetAccessibleName(l10n_util::GetStringUTF16(IDS_ASH_SHELF_APP_LIST_TITLE));
45a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  SetSize(gfx::Size(kShelfSize, kShelfSize));
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SetFocusPainter(views::Painter::CreateSolidFocusPainter(
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      kFocusBorderColor, gfx::Insets(1, 1, 1, 1)));
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppListButton::~AppListButton() {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AppListButton::OnMousePressed(const ui::MouseEvent& event) {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageButton::OnMousePressed(event);
55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_->PointerPressedOnButton(this, ShelfButtonHost::MOUSE, event);
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListButton::OnMouseReleased(const ui::MouseEvent& event) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageButton::OnMouseReleased(event);
61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_->PointerReleasedOnButton(this, ShelfButtonHost::MOUSE, false);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListButton::OnMouseCaptureLost() {
65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_->PointerReleasedOnButton(this, ShelfButtonHost::MOUSE, true);
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageButton::OnMouseCaptureLost();
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AppListButton::OnMouseDragged(const ui::MouseEvent& event) {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageButton::OnMouseDragged(event);
71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  host_->PointerDraggedOnButton(this, ShelfButtonHost::MOUSE, event);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListButton::OnMouseMoved(const ui::MouseEvent& event) {
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageButton::OnMouseMoved(event);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_->MouseMovedOverButton(this);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListButton::OnMouseEntered(const ui::MouseEvent& event) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageButton::OnMouseEntered(event);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_->MouseEnteredButton(this);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListButton::OnMouseExited(const ui::MouseEvent& event) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ImageButton::OnMouseExited(event);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  host_->MouseExitedButton(this);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid AppListButton::OnGestureEvent(ui::GestureEvent* event) {
91a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  switch (event->type()) {
92a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch   case ui::ET_GESTURE_SCROLL_BEGIN:
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     if (touch_feedback_enabled_)
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       SetDrawBackgroundAsActive(false);
95a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch     host_->PointerPressedOnButton(this, ShelfButtonHost::TOUCH, *event);
96a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch     event->SetHandled();
97a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch     return;
98a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch   case ui::ET_GESTURE_SCROLL_UPDATE:
99a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch     host_->PointerDraggedOnButton(this, ShelfButtonHost::TOUCH, *event);
100a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch     event->SetHandled();
101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch     return;
102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch   case ui::ET_GESTURE_SCROLL_END:
103a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch   case ui::ET_SCROLL_FLING_START:
104a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch     host_->PointerReleasedOnButton(this, ShelfButtonHost::TOUCH, false);
105a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch     event->SetHandled();
106a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch     return;
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   case ui::ET_GESTURE_TAP_DOWN:
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     if (touch_feedback_enabled_)
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       SetDrawBackgroundAsActive(true);
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     ImageButton::OnGestureEvent(event);
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     break;
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   case ui::ET_GESTURE_TAP_CANCEL:
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci   case ui::ET_GESTURE_TAP:
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     if (touch_feedback_enabled_)
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       SetDrawBackgroundAsActive(false);
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     ImageButton::OnGestureEvent(event);
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci     break;
118a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch   default:
119a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch     ImageButton::OnGestureEvent(event);
120a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch     return;
121a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
122a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
123a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
124a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid AppListButton::OnPaint(gfx::Canvas* canvas) {
125a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  // Call the base class first to paint any background/borders.
126a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  View::OnPaint(canvas);
127a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
128a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  int background_image_id = 0;
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (Shell::GetInstance()->GetAppListTargetVisibility() ||
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      draw_background_as_active_) {
131a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_PRESSED;
132a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  } else {
133a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    if (shelf_widget_->GetDimsShelf())
134a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_ON_BLACK;
135a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    else
136a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_NORMAL;
137a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
138a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
139a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const gfx::ImageSkia* background_image =
140a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      rb.GetImageNamed(background_image_id).ToImageSkia();
141a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const gfx::ImageSkia* forground_image =
142a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      rb.GetImageNamed(IDR_ASH_SHELF_ICON_APPLIST).ToImageSkia();
143a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
144a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gfx::Rect contents_bounds = GetContentsBounds();
145a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gfx::Rect background_bounds, forground_bounds;
146a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
147a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ShelfAlignment alignment = shelf_widget_->GetAlignment();
148a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  background_bounds.set_size(background_image->size());
149a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (alignment == SHELF_ALIGNMENT_LEFT) {
150a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    background_bounds.set_x(contents_bounds.width() -
151a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        ShelfLayoutManager::kShelfItemInset - background_image->width());
152a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    background_bounds.set_y(contents_bounds.y() +
153a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        (contents_bounds.height() - background_image->height()) / 2);
154a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  } else if(alignment == SHELF_ALIGNMENT_RIGHT) {
155a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    background_bounds.set_x(ShelfLayoutManager::kShelfItemInset);
156a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    background_bounds.set_y(contents_bounds.y() +
157a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        (contents_bounds.height() - background_image->height()) / 2);
158a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  } else {
159a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    background_bounds.set_y(ShelfLayoutManager::kShelfItemInset);
160a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    background_bounds.set_x(contents_bounds.x() +
161a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        (contents_bounds.width() - background_image->width()) / 2);
162a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  }
163a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
164a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  forground_bounds.set_size(forground_image->size());
165a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  forground_bounds.set_x(background_bounds.x() +
166a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      std::max(0,
167a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          (background_bounds.width() - forground_bounds.width()) / 2));
168a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  forground_bounds.set_y(background_bounds.y() +
169a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      std::max(0,
170a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          (background_bounds.height() - forground_bounds.height()) / 2));
171a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
172a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  canvas->DrawImageInt(*background_image,
173a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                       background_bounds.x(),
174a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                       background_bounds.y());
175a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  canvas->DrawImageInt(*forground_image,
176a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                       forground_bounds.x(),
177a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                       forground_bounds.y());
178a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
179a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  views::Painter::PaintFocusPainter(this, canvas, focus_painter());
180a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch}
181a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void AppListButton::GetAccessibleState(ui::AXViewState* state) {
183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  state->role = ui::AX_ROLE_BUTTON;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  state->name = host_->GetAccessibleName(this);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AppListButton::SetDrawBackgroundAsActive(
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    bool draw_background_as_active) {
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (draw_background_as_active_ == draw_background_as_active)
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  draw_background_as_active_ = draw_background_as_active;
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SchedulePaint();
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
196