diff options
Diffstat (limited to 'chromium/ash/launcher/overflow_button.cc')
-rw-r--r-- | chromium/ash/launcher/overflow_button.cc | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/chromium/ash/launcher/overflow_button.cc b/chromium/ash/launcher/overflow_button.cc new file mode 100644 index 00000000000..c3d5a6891d0 --- /dev/null +++ b/chromium/ash/launcher/overflow_button.cc @@ -0,0 +1,178 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/launcher/overflow_button.h" + +#include "ash/ash_switches.h" +#include "ash/shelf/shelf_layout_manager.h" +#include "ash/shelf/shelf_widget.h" +#include "grit/ash_resources.h" +#include "grit/ash_strings.h" +#include "third_party/skia/include/core/SkPaint.h" +#include "third_party/skia/include/core/SkPath.h" +#include "ui/base/animation/throb_animation.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/image/image_skia_operations.h" +#include "ui/gfx/skbitmap_operations.h" +#include "ui/gfx/skia_util.h" +#include "ui/gfx/transform.h" +#include "ui/views/widget/widget.h" + +namespace ash { +namespace internal { + +namespace { + +const int kButtonHoverAlpha = 150; + +const int kButtonCornerRadius = 2; + +const int kButtonHoverSize = 28; + +const int kBackgroundOffset = (48 - kButtonHoverSize) / 2; + +// Padding from the inner edge of the shelf (towards center of display) to +// the edge of the background image of the overflow button. +const int kImagePaddingFromShelf = 5; + +} // namesapce + +OverflowButton::OverflowButton(views::ButtonListener* listener) + : CustomButton(listener), + bottom_image_(NULL) { + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + bottom_image_ = rb.GetImageNamed(IDR_AURA_LAUNCHER_OVERFLOW).ToImageSkia(); + + + set_accessibility_focusable(true); + SetAccessibleName(l10n_util::GetStringUTF16(IDS_ASH_SHELF_OVERFLOW_NAME)); +} + +OverflowButton::~OverflowButton() {} + +void OverflowButton::OnShelfAlignmentChanged() { + SchedulePaint(); +} + +void OverflowButton::PaintBackground(gfx::Canvas* canvas, int alpha) { + gfx::Rect bounds(GetContentsBounds()); + gfx::Rect rect(0, 0, kButtonHoverSize, kButtonHoverSize); + ShelfLayoutManager* shelf = + ShelfLayoutManager::ForLauncher(GetWidget()->GetNativeView()); + + // Nudge the background a little to line up right. + if (shelf->IsHorizontalAlignment()) { + rect.set_origin(gfx::Point( + bounds.x() + ((bounds.width() - kButtonHoverSize) / 2) - 1, + bounds.y() + kBackgroundOffset - 1)); + + } else { + rect.set_origin(gfx::Point( + bounds.x() + kBackgroundOffset - 1, + bounds.y() + ((bounds.height() - kButtonHoverSize) / 2) - 1)); + } + + SkPaint paint; + paint.setAntiAlias(true); + paint.setStyle(SkPaint::kFill_Style); + paint.setColor(SkColorSetARGB( + kButtonHoverAlpha * hover_animation_->GetCurrentValue(), + 0, 0, 0)); + + const SkScalar radius = SkIntToScalar(kButtonCornerRadius); + SkPath path; + path.addRoundRect(gfx::RectToSkRect(rect), radius, radius); + canvas->DrawPath(path, paint); +} + +void OverflowButton::OnPaint(gfx::Canvas* canvas) { + ShelfLayoutManager* layout_manager = ShelfLayoutManager::ForLauncher( + GetWidget()->GetNativeView()); + ShelfAlignment alignment = layout_manager->GetAlignment(); + + gfx::Rect bounds(GetContentsBounds()); + if (ash::switches::UseAlternateShelfLayout()) { + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + int background_image_id = 0; + if (layout_manager->shelf_widget()->launcher()->IsShowingOverflowBubble()) + background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_PRESSED; + else if(layout_manager->shelf_widget()->GetDimsShelf()) + background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_ON_BLACK; + else + background_image_id = IDR_AURA_NOTIFICATION_BACKGROUND_NORMAL; + + const gfx::ImageSkia* background = + rb.GetImageNamed(background_image_id).ToImageSkia(); + if (alignment == SHELF_ALIGNMENT_LEFT) { + bounds = gfx::Rect( + bounds.right() - background->width() - kImagePaddingFromShelf, + bounds.y() + (bounds.height() - background->height()) / 2, + background->width(), background->height()); + } else if (alignment == SHELF_ALIGNMENT_RIGHT) { + bounds = gfx::Rect( + bounds.x() + kImagePaddingFromShelf, + bounds.y() + (bounds.height() - background->height()) / 2, + background->width(), background->height()); + } else { + bounds = gfx::Rect( + bounds.x() + (bounds.width() - background->width()) / 2, + bounds.y() + kImagePaddingFromShelf, + background->width(), background->height()); + } + canvas->DrawImageInt(*background, bounds.x(), bounds.y()); + } else { + if (alignment == SHELF_ALIGNMENT_BOTTOM) { + bounds = gfx::Rect( + bounds.x() + ((bounds.width() - kButtonHoverSize) / 2) - 1, + bounds.y() + kBackgroundOffset - 1, + kButtonHoverSize, kButtonHoverSize); + } else { + bounds = gfx::Rect( + bounds.x() + kBackgroundOffset -1, + bounds.y() + ((bounds.height() - kButtonHoverSize) / 2) -1, + kButtonHoverSize, kButtonHoverSize); + } + if (hover_animation_->is_animating()) { + PaintBackground( + canvas, + kButtonHoverAlpha * hover_animation_->GetCurrentValue()); + } else if (state() == STATE_HOVERED || state() == STATE_PRESSED) { + PaintBackground(canvas, kButtonHoverAlpha); + } + } + + if (height() < kButtonHoverSize) + return; + + const gfx::ImageSkia* image = NULL; + + switch(alignment) { + case SHELF_ALIGNMENT_LEFT: + if (left_image_.isNull()) { + left_image_ = gfx::ImageSkiaOperations::CreateRotatedImage( + *bottom_image_, SkBitmapOperations::ROTATION_90_CW); + } + image = &left_image_; + break; + case SHELF_ALIGNMENT_RIGHT: + if (right_image_.isNull()) { + right_image_ = gfx::ImageSkiaOperations::CreateRotatedImage( + *bottom_image_, SkBitmapOperations::ROTATION_270_CW); + } + image = &right_image_; + break; + default: + image = bottom_image_; + break; + } + + canvas->DrawImageInt(*image, + bounds.x() + ((bounds.width() - image->width()) / 2), + bounds.y() + ((bounds.height() - image->height()) / 2)); +} + +} // namespace internal +} // namespace ash |