[email protected] | dfd64f0 | 2013-08-30 02:17:32 | [diff] [blame] | 1 | // Copyright 2013 The Chromium Authors. All rights reserved. |
[email protected] | 7e84644 | 2012-08-07 04:22:34 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
jamescook | 775aa607 | 2017-03-05 06:11:58 | [diff] [blame] | 5 | #include "ash/shelf/overflow_button.h" |
[email protected] | 7e84644 | 2012-08-07 04:22:34 | [diff] [blame] | 6 | |
estade | 1b92771b | 2017-01-10 04:51:20 | [diff] [blame] | 7 | #include "ash/resources/vector_icons/vector_icons.h" |
jamescook | 775aa607 | 2017-03-05 06:11:58 | [diff] [blame] | 8 | #include "ash/shelf/shelf_constants.h" |
| 9 | #include "ash/shelf/shelf_view.h" |
| 10 | #include "ash/shelf/wm_shelf.h" |
jamescook | e45f811 | 2017-03-02 16:45:42 | [diff] [blame] | 11 | #include "ash/strings/grit/ash_strings.h" |
mohsen | 623c7e4 | 2016-09-16 18:45:38 | [diff] [blame] | 12 | #include "base/memory/ptr_util.h" |
[email protected] | 7e84644 | 2012-08-07 04:22:34 | [diff] [blame] | 13 | #include "ui/base/l10n/l10n_util.h" |
[email protected] | 7e84644 | 2012-08-07 04:22:34 | [diff] [blame] | 14 | #include "ui/gfx/canvas.h" |
[email protected] | e9edd00 | 2013-08-10 15:19:24 | [diff] [blame] | 15 | #include "ui/gfx/image/image_skia_operations.h" |
tdanderson | 4f0032c | 2016-06-10 04:33:15 | [diff] [blame] | 16 | #include "ui/gfx/paint_vector_icon.h" |
[email protected] | e9edd00 | 2013-08-10 15:19:24 | [diff] [blame] | 17 | #include "ui/gfx/skbitmap_operations.h" |
mohsen | 623c7e4 | 2016-09-16 18:45:38 | [diff] [blame] | 18 | #include "ui/views/animation/flood_fill_ink_drop_ripple.h" |
bruthig | ca8b19cd | 2016-11-08 02:53:55 | [diff] [blame] | 19 | #include "ui/views/animation/ink_drop_impl.h" |
mohsen | 6cc1f1f | 2016-11-24 05:15:09 | [diff] [blame] | 20 | #include "ui/views/animation/ink_drop_mask.h" |
[email protected] | 7e84644 | 2012-08-07 04:22:34 | [diff] [blame] | 21 | |
| 22 | namespace ash { |
[email protected] | 7e84644 | 2012-08-07 04:22:34 | [diff] [blame] | 23 | |
jamescook | 65ae2bb | 2016-08-11 22:44:36 | [diff] [blame] | 24 | OverflowButton::OverflowButton(ShelfView* shelf_view, WmShelf* wm_shelf) |
mohsen | 497110a | 2016-06-16 19:29:31 | [diff] [blame] | 25 | : CustomButton(nullptr), |
jamescook | 65ae2bb | 2016-08-11 22:44:36 | [diff] [blame] | 26 | shelf_view_(shelf_view), |
bruthig | a2239af | 2016-08-02 17:07:29 | [diff] [blame] | 27 | wm_shelf_(wm_shelf), |
bruthig | 33189d2 | 2017-02-25 18:54:21 | [diff] [blame] | 28 | background_color_(kShelfDefaultBaseColor) { |
jamescook | 65ae2bb | 2016-08-11 22:44:36 | [diff] [blame] | 29 | DCHECK(shelf_view_); |
mohsen | 4116d239 | 2017-02-28 19:06:29 | [diff] [blame] | 30 | |
| 31 | SetInkDropMode(InkDropMode::ON); |
| 32 | set_ink_drop_base_color(kShelfInkDropBaseColor); |
| 33 | set_ink_drop_visible_opacity(kShelfInkDropVisibleOpacity); |
| 34 | set_hide_ink_drop_when_showing_context_menu(false); |
| 35 | bottom_image_ = gfx::CreateVectorIcon(kShelfOverflowIcon, kShelfIconColor); |
[email protected] | 7e84644 | 2012-08-07 04:22:34 | [diff] [blame] | 36 | |
karandeepb | e7ad02a | 2016-04-27 23:57:22 | [diff] [blame] | 37 | SetFocusBehavior(FocusBehavior::ACCESSIBLE_ONLY); |
[email protected] | 81dd43d | 2013-08-06 05:58:27 | [diff] [blame] | 38 | SetAccessibleName(l10n_util::GetStringUTF16(IDS_ASH_SHELF_OVERFLOW_NAME)); |
[email protected] | 7e84644 | 2012-08-07 04:22:34 | [diff] [blame] | 39 | } |
| 40 | |
[email protected] | 81dd43d | 2013-08-06 05:58:27 | [diff] [blame] | 41 | OverflowButton::~OverflowButton() {} |
[email protected] | 7e84644 | 2012-08-07 04:22:34 | [diff] [blame] | 42 | |
[email protected] | 1fcfb99 | 2012-12-05 01:47:23 | [diff] [blame] | 43 | void OverflowButton::OnShelfAlignmentChanged() { |
[email protected] | 7e84644 | 2012-08-07 04:22:34 | [diff] [blame] | 44 | SchedulePaint(); |
| 45 | } |
| 46 | |
mohsen | 623c7e4 | 2016-09-16 18:45:38 | [diff] [blame] | 47 | void OverflowButton::OnOverflowBubbleShown() { |
| 48 | AnimateInkDrop(views::InkDropState::ACTIVATED, nullptr); |
mohsen | 623c7e4 | 2016-09-16 18:45:38 | [diff] [blame] | 49 | } |
| 50 | |
| 51 | void OverflowButton::OnOverflowBubbleHidden() { |
| 52 | AnimateInkDrop(views::InkDropState::DEACTIVATED, nullptr); |
mohsen | 623c7e4 | 2016-09-16 18:45:38 | [diff] [blame] | 53 | } |
| 54 | |
bruthig | 33189d2 | 2017-02-25 18:54:21 | [diff] [blame] | 55 | void OverflowButton::UpdateShelfItemBackground(SkColor color) { |
| 56 | background_color_ = color; |
bruthig | a2239af | 2016-08-02 17:07:29 | [diff] [blame] | 57 | SchedulePaint(); |
| 58 | } |
| 59 | |
tdanderson | 992a565 | 2016-06-08 23:10:32 | [diff] [blame] | 60 | void OverflowButton::OnPaint(gfx::Canvas* canvas) { |
| 61 | gfx::Rect bounds = CalculateButtonBounds(); |
| 62 | PaintBackground(canvas, bounds); |
| 63 | PaintForeground(canvas, bounds); |
[email protected] | 7e84644 | 2012-08-07 04:22:34 | [diff] [blame] | 64 | } |
| 65 | |
bruthig | ca8b19cd | 2016-11-08 02:53:55 | [diff] [blame] | 66 | std::unique_ptr<views::InkDrop> OverflowButton::CreateInkDrop() { |
mohsen | eb659d9 | 2016-11-15 01:04:15 | [diff] [blame] | 67 | std::unique_ptr<views::InkDropImpl> ink_drop = |
| 68 | CreateDefaultFloodFillInkDropImpl(); |
| 69 | ink_drop->SetShowHighlightOnHover(false); |
| 70 | ink_drop->SetAutoHighlightMode(views::InkDropImpl::AutoHighlightMode::NONE); |
| 71 | return std::move(ink_drop); |
bruthig | ca8b19cd | 2016-11-08 02:53:55 | [diff] [blame] | 72 | } |
| 73 | |
mohsen | 623c7e4 | 2016-09-16 18:45:38 | [diff] [blame] | 74 | std::unique_ptr<views::InkDropRipple> OverflowButton::CreateInkDropRipple() |
| 75 | const { |
mohsen | 7dfd81cc | 2016-11-29 16:08:00 | [diff] [blame] | 76 | gfx::Insets insets = GetLocalBounds().InsetsFrom(CalculateButtonBounds()); |
mohsen | 623c7e4 | 2016-09-16 18:45:38 | [diff] [blame] | 77 | return base::MakeUnique<views::FloodFillInkDropRipple>( |
mohsen | 7dfd81cc | 2016-11-29 16:08:00 | [diff] [blame] | 78 | size(), insets, GetInkDropCenterBasedOnLastEvent(), GetInkDropBaseColor(), |
| 79 | ink_drop_visible_opacity()); |
mohsen | 623c7e4 | 2016-09-16 18:45:38 | [diff] [blame] | 80 | } |
| 81 | |
| 82 | bool OverflowButton::ShouldEnterPushedState(const ui::Event& event) { |
| 83 | if (shelf_view_->IsShowingOverflowBubble()) |
| 84 | return false; |
| 85 | |
| 86 | return CustomButton::ShouldEnterPushedState(event); |
| 87 | } |
| 88 | |
mohsen | 497110a | 2016-06-16 19:29:31 | [diff] [blame] | 89 | void OverflowButton::NotifyClick(const ui::Event& event) { |
| 90 | CustomButton::NotifyClick(event); |
bruthig | 25b329d | 2016-11-04 19:43:51 | [diff] [blame] | 91 | shelf_view_->ButtonPressed(this, event, GetInkDrop()); |
mohsen | 497110a | 2016-06-16 19:29:31 | [diff] [blame] | 92 | } |
| 93 | |
mohsen | 6cc1f1f | 2016-11-24 05:15:09 | [diff] [blame] | 94 | std::unique_ptr<views::InkDropMask> OverflowButton::CreateInkDropMask() const { |
| 95 | gfx::Insets insets = GetLocalBounds().InsetsFrom(CalculateButtonBounds()); |
| 96 | return base::MakeUnique<views::RoundRectInkDropMask>( |
| 97 | size(), insets, kOverflowButtonCornerRadius); |
| 98 | } |
| 99 | |
tdanderson | 992a565 | 2016-06-08 23:10:32 | [diff] [blame] | 100 | void OverflowButton::PaintBackground(gfx::Canvas* canvas, |
| 101 | const gfx::Rect& bounds) { |
mohsen | 4116d239 | 2017-02-28 19:06:29 | [diff] [blame] | 102 | cc::PaintFlags flags; |
| 103 | flags.setFlags(cc::PaintFlags::kAntiAlias_Flag); |
| 104 | flags.setColor(background_color_); |
| 105 | canvas->DrawRoundRect(bounds, kOverflowButtonCornerRadius, flags); |
tdanderson | 992a565 | 2016-06-08 23:10:32 | [diff] [blame] | 106 | } |
[email protected] | 7e84644 | 2012-08-07 04:22:34 | [diff] [blame] | 107 | |
tdanderson | 992a565 | 2016-06-08 23:10:32 | [diff] [blame] | 108 | void OverflowButton::PaintForeground(gfx::Canvas* canvas, |
| 109 | const gfx::Rect& bounds) { |
| 110 | const gfx::ImageSkia* image = nullptr; |
[email protected] | b4b45aa | 2012-09-24 16:10:57 | [diff] [blame] | 111 | |
jamescook | 8a5416dc | 2016-07-19 20:04:24 | [diff] [blame] | 112 | switch (wm_shelf_->GetAlignment()) { |
jamescook | 1b474d6a | 2016-06-04 05:56:00 | [diff] [blame] | 113 | case SHELF_ALIGNMENT_LEFT: |
[email protected] | e9edd00 | 2013-08-10 15:19:24 | [diff] [blame] | 114 | if (left_image_.isNull()) { |
| 115 | left_image_ = gfx::ImageSkiaOperations::CreateRotatedImage( |
mohsen | 4116d239 | 2017-02-28 19:06:29 | [diff] [blame] | 116 | bottom_image_, SkBitmapOperations::ROTATION_90_CW); |
[email protected] | e9edd00 | 2013-08-10 15:19:24 | [diff] [blame] | 117 | } |
| 118 | image = &left_image_; |
[email protected] | 7e84644 | 2012-08-07 04:22:34 | [diff] [blame] | 119 | break; |
jamescook | 1b474d6a | 2016-06-04 05:56:00 | [diff] [blame] | 120 | case SHELF_ALIGNMENT_RIGHT: |
[email protected] | e9edd00 | 2013-08-10 15:19:24 | [diff] [blame] | 121 | if (right_image_.isNull()) { |
| 122 | right_image_ = gfx::ImageSkiaOperations::CreateRotatedImage( |
mohsen | 4116d239 | 2017-02-28 19:06:29 | [diff] [blame] | 123 | bottom_image_, SkBitmapOperations::ROTATION_270_CW); |
[email protected] | e9edd00 | 2013-08-10 15:19:24 | [diff] [blame] | 124 | } |
| 125 | image = &right_image_; |
[email protected] | 7e84644 | 2012-08-07 04:22:34 | [diff] [blame] | 126 | break; |
[email protected] | e9edd00 | 2013-08-10 15:19:24 | [diff] [blame] | 127 | default: |
mohsen | 4116d239 | 2017-02-28 19:06:29 | [diff] [blame] | 128 | image = &bottom_image_; |
[email protected] | 8572c487 | 2013-01-12 17:16:07 | [diff] [blame] | 129 | break; |
[email protected] | 7e84644 | 2012-08-07 04:22:34 | [diff] [blame] | 130 | } |
| 131 | |
[email protected] | e9edd00 | 2013-08-10 15:19:24 | [diff] [blame] | 132 | canvas->DrawImageInt(*image, |
| 133 | bounds.x() + ((bounds.width() - image->width()) / 2), |
| 134 | bounds.y() + ((bounds.height() - image->height()) / 2)); |
[email protected] | 7e84644 | 2012-08-07 04:22:34 | [diff] [blame] | 135 | } |
| 136 | |
mohsen | 623c7e4 | 2016-09-16 18:45:38 | [diff] [blame] | 137 | gfx::Rect OverflowButton::CalculateButtonBounds() const { |
jamescook | 8a5416dc | 2016-07-19 20:04:24 | [diff] [blame] | 138 | ShelfAlignment alignment = wm_shelf_->GetAlignment(); |
mohsen | 4116d239 | 2017-02-28 19:06:29 | [diff] [blame] | 139 | gfx::Rect content_bounds = GetContentsBounds(); |
| 140 | // Align the button to the top of a bottom-aligned shelf, to the right edge |
| 141 | // a left-aligned shelf, and to the left edge of a right-aligned shelf. |
| 142 | const int inset = (GetShelfConstant(SHELF_SIZE) - kOverflowButtonSize) / 2; |
| 143 | const int x = alignment == SHELF_ALIGNMENT_LEFT |
| 144 | ? content_bounds.right() - inset - kOverflowButtonSize |
| 145 | : content_bounds.x() + inset; |
| 146 | return gfx::Rect(x, content_bounds.y() + inset, kOverflowButtonSize, |
| 147 | kOverflowButtonSize); |
tdanderson | 992a565 | 2016-06-08 23:10:32 | [diff] [blame] | 148 | } |
| 149 | |
[email protected] | 7e84644 | 2012-08-07 04:22:34 | [diff] [blame] | 150 | } // namespace ash |