1// Copyright 2013 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/overflow_button.h" 6 7#include "ash/ash_switches.h" 8#include "ash/shelf/shelf_layout_manager.h" 9#include "ash/shelf/shelf_widget.h" 10#include "grit/ash_resources.h" 11#include "grit/ash_strings.h" 12#include "third_party/skia/include/core/SkPaint.h" 13#include "third_party/skia/include/core/SkPath.h" 14#include "ui/base/l10n/l10n_util.h" 15#include "ui/base/resource/resource_bundle.h" 16#include "ui/gfx/animation/throb_animation.h" 17#include "ui/gfx/canvas.h" 18#include "ui/gfx/image/image_skia_operations.h" 19#include "ui/gfx/skbitmap_operations.h" 20#include "ui/gfx/skia_util.h" 21#include "ui/gfx/transform.h" 22#include "ui/views/widget/widget.h" 23 24namespace ash { 25namespace { 26 27const int kButtonHoverAlpha = 150; 28 29const int kButtonCornerRadius = 2; 30 31const int kButtonHoverSize = 28; 32 33const int kBackgroundOffset = (48 - kButtonHoverSize) / 2; 34 35} // namesapce 36 37OverflowButton::OverflowButton(views::ButtonListener* listener) 38 : CustomButton(listener), 39 bottom_image_(NULL) { 40 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 41 bottom_image_ = rb.GetImageNamed(IDR_ASH_SHELF_OVERFLOW).ToImageSkia(); 42 43 44 SetAccessibilityFocusable(true); 45 SetAccessibleName(l10n_util::GetStringUTF16(IDS_ASH_SHELF_OVERFLOW_NAME)); 46} 47 48OverflowButton::~OverflowButton() {} 49 50void OverflowButton::OnShelfAlignmentChanged() { 51 SchedulePaint(); 52} 53 54void OverflowButton::PaintBackground(gfx::Canvas* canvas, int alpha) { 55 gfx::Rect bounds(GetContentsBounds()); 56 gfx::Rect rect(0, 0, kButtonHoverSize, kButtonHoverSize); 57 ShelfLayoutManager* shelf = 58 ShelfLayoutManager::ForShelf(GetWidget()->GetNativeView()); 59 60 // Nudge the background a little to line up right. 61 if (shelf->IsHorizontalAlignment()) { 62 rect.set_origin(gfx::Point( 63 bounds.x() + ((bounds.width() - kButtonHoverSize) / 2) - 1, 64 bounds.y() + kBackgroundOffset - 1)); 65 66 } else { 67 rect.set_origin(gfx::Point( 68 bounds.x() + kBackgroundOffset - 1, 69 bounds.y() + ((bounds.height() - kButtonHoverSize) / 2) - 1)); 70 } 71 72 SkPaint paint; 73 paint.setAntiAlias(true); 74 paint.setStyle(SkPaint::kFill_Style); 75 paint.setColor(SkColorSetARGB( 76 kButtonHoverAlpha * hover_animation_->GetCurrentValue(), 77 0, 0, 0)); 78 79 const SkScalar radius = SkIntToScalar(kButtonCornerRadius); 80 SkPath path; 81 path.addRoundRect(gfx::RectToSkRect(rect), radius, radius); 82 canvas->DrawPath(path, paint); 83} 84 85void OverflowButton::OnPaint(gfx::Canvas* canvas) { 86 ShelfLayoutManager* layout_manager = 87 ShelfLayoutManager::ForShelf(GetWidget()->GetNativeView()); 88 ShelfAlignment alignment = layout_manager->GetAlignment(); 89 90 gfx::Rect bounds(GetContentsBounds()); 91 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 92 int background_image_id = 0; 93 if (layout_manager->shelf_widget()->shelf()->IsShowingOverflowBubble()) 94 background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_PRESSED; 95 else if(layout_manager->shelf_widget()->GetDimsShelf()) 96 background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_ON_BLACK; 97 else 98 background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_NORMAL; 99 100 const gfx::ImageSkia* background = 101 rb.GetImageNamed(background_image_id).ToImageSkia(); 102 if (alignment == SHELF_ALIGNMENT_LEFT) { 103 bounds = gfx::Rect( 104 bounds.right() - background->width() - 105 ShelfLayoutManager::kShelfItemInset, 106 bounds.y() + (bounds.height() - background->height()) / 2, 107 background->width(), background->height()); 108 } else if (alignment == SHELF_ALIGNMENT_RIGHT) { 109 bounds = gfx::Rect( 110 bounds.x() + ShelfLayoutManager::kShelfItemInset, 111 bounds.y() + (bounds.height() - background->height()) / 2, 112 background->width(), background->height()); 113 } else { 114 bounds = gfx::Rect( 115 bounds.x() + (bounds.width() - background->width()) / 2, 116 bounds.y() + ShelfLayoutManager::kShelfItemInset, 117 background->width(), background->height()); 118 } 119 canvas->DrawImageInt(*background, bounds.x(), bounds.y()); 120 121 if (height() < kButtonHoverSize) 122 return; 123 124 const gfx::ImageSkia* image = NULL; 125 126 switch(alignment) { 127 case SHELF_ALIGNMENT_LEFT: 128 if (left_image_.isNull()) { 129 left_image_ = gfx::ImageSkiaOperations::CreateRotatedImage( 130 *bottom_image_, SkBitmapOperations::ROTATION_90_CW); 131 } 132 image = &left_image_; 133 break; 134 case SHELF_ALIGNMENT_RIGHT: 135 if (right_image_.isNull()) { 136 right_image_ = gfx::ImageSkiaOperations::CreateRotatedImage( 137 *bottom_image_, SkBitmapOperations::ROTATION_270_CW); 138 } 139 image = &right_image_; 140 break; 141 default: 142 image = bottom_image_; 143 break; 144 } 145 146 canvas->DrawImageInt(*image, 147 bounds.x() + ((bounds.width() - image->width()) / 2), 148 bounds.y() + ((bounds.height() - image->height()) / 2)); 149} 150 151} // namespace ash 152