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