1424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Copyright 2013 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/overflow_button.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ash/ash_switches.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ash/shelf/shelf_layout_manager.h"
9ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ash/shelf/shelf_widget.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_resources.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ash_strings.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkPaint.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkPath.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "ui/gfx/animation/throb_animation.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h"
18ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/gfx/image/image_skia_operations.h"
19ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "ui/gfx/skbitmap_operations.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/skia_util.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/transform.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/widget/widget.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ash {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kButtonHoverAlpha = 150;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kButtonCornerRadius = 2;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kButtonHoverSize = 28;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kBackgroundOffset = (48 - kButtonHoverSize) / 2;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namesapce
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)OverflowButton::OverflowButton(views::ButtonListener* listener)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : CustomButton(listener),
39ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      bottom_image_(NULL) {
40c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
41c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  bottom_image_ = rb.GetImageNamed(IDR_ASH_SHELF_OVERFLOW).ToImageSkia();
42ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetAccessibilityFocusable(true);
452385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen Murdoch  SetAccessibleName(l10n_util::GetStringUTF16(IDS_ASH_SHELF_OVERFLOW_NAME));
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
482385ea399aae016c0806a4f9ef3c9cfe3d2a39dfBen MurdochOverflowButton::~OverflowButton() {}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OverflowButton::OnShelfAlignmentChanged() {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SchedulePaint();
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OverflowButton::PaintBackground(gfx::Canvas* canvas, int alpha) {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect bounds(GetContentsBounds());
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect rect(0, 0, kButtonHoverSize, kButtonHoverSize);
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ShelfLayoutManager* shelf =
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ShelfLayoutManager::ForShelf(GetWidget()->GetNativeView());
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Nudge the background a little to line up right.
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shelf->IsHorizontalAlignment()) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rect.set_origin(gfx::Point(
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bounds.x() + ((bounds.width() - kButtonHoverSize) / 2) - 1,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bounds.y() + kBackgroundOffset - 1));
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rect.set_origin(gfx::Point(
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bounds.x() + kBackgroundOffset - 1,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        bounds.y() + ((bounds.height() - kButtonHoverSize) / 2) - 1));
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint paint;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setAntiAlias(true);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setStyle(SkPaint::kFill_Style);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  paint.setColor(SkColorSetARGB(
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kButtonHoverAlpha * hover_animation_->GetCurrentValue(),
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      0, 0, 0));
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const SkScalar radius = SkIntToScalar(kButtonCornerRadius);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPath path;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path.addRoundRect(gfx::RectToSkRect(rect), radius, radius);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->DrawPath(path, paint);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OverflowButton::OnPaint(gfx::Canvas* canvas) {
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ShelfLayoutManager* layout_manager =
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ShelfLayoutManager::ForShelf(GetWidget()->GetNativeView());
88ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ShelfAlignment alignment = layout_manager->GetAlignment();
89ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
90ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  gfx::Rect bounds(GetContentsBounds());
91a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  ResourceBundle& rb = ResourceBundle::GetSharedInstance();
92a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  int background_image_id = 0;
93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (layout_manager->shelf_widget()->shelf()->IsShowingOverflowBubble())
94a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_PRESSED;
95a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  else if(layout_manager->shelf_widget()->GetDimsShelf())
96a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_ON_BLACK;
97a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  else
98a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_NORMAL;
99a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch
100a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  const gfx::ImageSkia* background =
101a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      rb.GetImageNamed(background_image_id).ToImageSkia();
102a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (alignment == SHELF_ALIGNMENT_LEFT) {
103a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    bounds = gfx::Rect(
104a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        bounds.right() - background->width() -
105a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch            ShelfLayoutManager::kShelfItemInset,
106a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        bounds.y() + (bounds.height() - background->height()) / 2,
107a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        background->width(), background->height());
108a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  } else if (alignment == SHELF_ALIGNMENT_RIGHT) {
109a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    bounds = gfx::Rect(
110a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        bounds.x() + ShelfLayoutManager::kShelfItemInset,
111a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        bounds.y() + (bounds.height() - background->height()) / 2,
112a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        background->width(), background->height());
113ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  } else {
114a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    bounds = gfx::Rect(
115a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        bounds.x() + (bounds.width() - background->width()) / 2,
116a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        bounds.y() + ShelfLayoutManager::kShelfItemInset,
117a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch        background->width(), background->height());
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
119a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  canvas->DrawImageInt(*background, bounds.x(), bounds.y());
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (height() < kButtonHoverSize)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
124ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  const gfx::ImageSkia* image = NULL;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
126ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  switch(alignment) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SHELF_ALIGNMENT_LEFT:
128ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      if (left_image_.isNull()) {
129ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        left_image_ = gfx::ImageSkiaOperations::CreateRotatedImage(
130ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            *bottom_image_, SkBitmapOperations::ROTATION_90_CW);
131ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      }
132ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      image = &left_image_;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SHELF_ALIGNMENT_RIGHT:
135ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      if (right_image_.isNull()) {
136ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch        right_image_ = gfx::ImageSkiaOperations::CreateRotatedImage(
137ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            *bottom_image_, SkBitmapOperations::ROTATION_270_CW);
138ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      }
139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      image = &right_image_;
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      break;
141ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    default:
142ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      image = bottom_image_;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
146ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  canvas->DrawImageInt(*image,
147ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                       bounds.x() + ((bounds.width() - image->width()) / 2),
148ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch                       bounds.y() + ((bounds.height() - image->height()) / 2));
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ash
152