| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ash/common/shelf/app_list_button.h" | 5 #include "ash/common/shelf/app_list_button.h" |
| 6 | 6 |
| 7 #include "ash/common/ash_constants.h" | |
| 8 #include "ash/common/material_design/material_design_controller.h" | |
| 9 #include "ash/common/shelf/ink_drop_button_listener.h" | 7 #include "ash/common/shelf/ink_drop_button_listener.h" |
| 10 #include "ash/common/shelf/shelf_constants.h" | 8 #include "ash/common/shelf/shelf_constants.h" |
| 11 #include "ash/common/shelf/shelf_item_types.h" | |
| 12 #include "ash/common/shelf/shelf_view.h" | 9 #include "ash/common/shelf/shelf_view.h" |
| 13 #include "ash/common/shelf/wm_shelf.h" | 10 #include "ash/common/shelf/wm_shelf.h" |
| 14 #include "ash/common/shelf/wm_shelf_util.h" | |
| 15 #include "ash/common/strings/grit/ash_strings.h" | 11 #include "ash/common/strings/grit/ash_strings.h" |
| 16 #include "ash/common/system/tray/tray_popup_utils.h" | 12 #include "ash/common/system/tray/tray_popup_utils.h" |
| 17 #include "ash/common/wm_shell.h" | 13 #include "ash/common/wm_shell.h" |
| 18 #include "ash/public/cpp/shelf_types.h" | 14 #include "ash/public/cpp/shelf_types.h" |
| 19 #include "ash/resources/grit/ash_resources.h" | |
| 20 #include "base/command_line.h" | |
| 21 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
| 22 #include "ui/accessibility/ax_node_data.h" | 16 #include "ui/accessibility/ax_node_data.h" |
| 23 #include "ui/app_list/app_list_switches.h" | |
| 24 #include "ui/base/l10n/l10n_util.h" | 17 #include "ui/base/l10n/l10n_util.h" |
| 25 #include "ui/base/resource/resource_bundle.h" | |
| 26 #include "ui/gfx/canvas.h" | 18 #include "ui/gfx/canvas.h" |
| 27 #include "ui/gfx/scoped_canvas.h" | 19 #include "ui/gfx/scoped_canvas.h" |
| 28 #include "ui/views/animation/flood_fill_ink_drop_ripple.h" | 20 #include "ui/views/animation/flood_fill_ink_drop_ripple.h" |
| 29 #include "ui/views/animation/ink_drop_impl.h" | 21 #include "ui/views/animation/ink_drop_impl.h" |
| 30 #include "ui/views/animation/ink_drop_mask.h" | 22 #include "ui/views/animation/ink_drop_mask.h" |
| 31 #include "ui/views/painter.h" | 23 #include "ui/views/painter.h" |
| 32 | 24 |
| 33 namespace ash { | 25 namespace ash { |
| 34 | 26 |
| 35 AppListButton::AppListButton(InkDropButtonListener* listener, | 27 AppListButton::AppListButton(InkDropButtonListener* listener, |
| 36 ShelfView* shelf_view, | 28 ShelfView* shelf_view, |
| 37 WmShelf* wm_shelf) | 29 WmShelf* wm_shelf) |
| 38 : views::ImageButton(nullptr), | 30 : views::ImageButton(nullptr), |
| 39 is_showing_app_list_(false), | 31 is_showing_app_list_(false), |
| 40 draw_background_as_active_(false), | |
| 41 background_color_(kShelfDefaultBaseColor), | 32 background_color_(kShelfDefaultBaseColor), |
| 42 listener_(listener), | 33 listener_(listener), |
| 43 shelf_view_(shelf_view), | 34 shelf_view_(shelf_view), |
| 44 wm_shelf_(wm_shelf) { | 35 wm_shelf_(wm_shelf) { |
| 45 DCHECK(listener_); | 36 DCHECK(listener_); |
| 46 DCHECK(shelf_view_); | 37 DCHECK(shelf_view_); |
| 47 DCHECK(wm_shelf_); | 38 DCHECK(wm_shelf_); |
| 48 if (ash::MaterialDesignController::IsShelfMaterial()) { | 39 |
| 49 SetInkDropMode(InkDropMode::ON_NO_GESTURE_HANDLER); | 40 SetInkDropMode(InkDropMode::ON_NO_GESTURE_HANDLER); |
| 50 set_ink_drop_base_color(kShelfInkDropBaseColor); | 41 set_ink_drop_base_color(kShelfInkDropBaseColor); |
| 51 set_ink_drop_visible_opacity(kShelfInkDropVisibleOpacity); | 42 set_ink_drop_visible_opacity(kShelfInkDropVisibleOpacity); |
| 52 } | |
| 53 SetAccessibleName( | 43 SetAccessibleName( |
| 54 l10n_util::GetStringUTF16(IDS_ASH_SHELF_APP_LIST_LAUNCHER_TITLE)); | 44 l10n_util::GetStringUTF16(IDS_ASH_SHELF_APP_LIST_LAUNCHER_TITLE)); |
| 55 SetSize( | 45 SetSize( |
| 56 gfx::Size(GetShelfConstant(SHELF_SIZE), GetShelfConstant(SHELF_SIZE))); | 46 gfx::Size(GetShelfConstant(SHELF_SIZE), GetShelfConstant(SHELF_SIZE))); |
| 57 SetFocusPainter(TrayPopupUtils::CreateFocusPainter()); | 47 SetFocusPainter(TrayPopupUtils::CreateFocusPainter()); |
| 58 set_notify_action(CustomButton::NOTIFY_ON_PRESS); | 48 set_notify_action(CustomButton::NOTIFY_ON_PRESS); |
| 59 } | 49 } |
| 60 | 50 |
| 61 AppListButton::~AppListButton() {} | 51 AppListButton::~AppListButton() {} |
| 62 | 52 |
| 63 void AppListButton::OnAppListShown() { | 53 void AppListButton::OnAppListShown() { |
| 64 if (ash::MaterialDesignController::IsShelfMaterial()) | 54 AnimateInkDrop(views::InkDropState::ACTIVATED, nullptr); |
| 65 AnimateInkDrop(views::InkDropState::ACTIVATED, nullptr); | |
| 66 else | |
| 67 SchedulePaint(); | |
| 68 is_showing_app_list_ = true; | 55 is_showing_app_list_ = true; |
| 69 wm_shelf_->UpdateAutoHideState(); | 56 wm_shelf_->UpdateAutoHideState(); |
| 70 } | 57 } |
| 71 | 58 |
| 72 void AppListButton::OnAppListDismissed() { | 59 void AppListButton::OnAppListDismissed() { |
| 73 if (ash::MaterialDesignController::IsShelfMaterial()) | 60 AnimateInkDrop(views::InkDropState::DEACTIVATED, nullptr); |
| 74 AnimateInkDrop(views::InkDropState::DEACTIVATED, nullptr); | |
| 75 else | |
| 76 SchedulePaint(); | |
| 77 is_showing_app_list_ = false; | 61 is_showing_app_list_ = false; |
| 78 wm_shelf_->UpdateAutoHideState(); | 62 wm_shelf_->UpdateAutoHideState(); |
| 79 } | 63 } |
| 80 | 64 |
| 81 void AppListButton::UpdateShelfItemBackground(SkColor color) { | 65 void AppListButton::UpdateShelfItemBackground(SkColor color) { |
| 82 background_color_ = color; | 66 background_color_ = color; |
| 83 SchedulePaint(); | 67 SchedulePaint(); |
| 84 } | 68 } |
| 85 | 69 |
| 86 bool AppListButton::OnMousePressed(const ui::MouseEvent& event) { | 70 bool AppListButton::OnMousePressed(const ui::MouseEvent& event) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 99 ImageButton::OnMouseCaptureLost(); | 83 ImageButton::OnMouseCaptureLost(); |
| 100 } | 84 } |
| 101 | 85 |
| 102 bool AppListButton::OnMouseDragged(const ui::MouseEvent& event) { | 86 bool AppListButton::OnMouseDragged(const ui::MouseEvent& event) { |
| 103 ImageButton::OnMouseDragged(event); | 87 ImageButton::OnMouseDragged(event); |
| 104 shelf_view_->PointerDraggedOnButton(this, ShelfView::MOUSE, event); | 88 shelf_view_->PointerDraggedOnButton(this, ShelfView::MOUSE, event); |
| 105 return true; | 89 return true; |
| 106 } | 90 } |
| 107 | 91 |
| 108 void AppListButton::OnGestureEvent(ui::GestureEvent* event) { | 92 void AppListButton::OnGestureEvent(ui::GestureEvent* event) { |
| 109 const bool is_material = ash::MaterialDesignController::IsShelfMaterial(); | |
| 110 switch (event->type()) { | 93 switch (event->type()) { |
| 111 case ui::ET_GESTURE_SCROLL_BEGIN: | 94 case ui::ET_GESTURE_SCROLL_BEGIN: |
| 112 if (is_material) | 95 AnimateInkDrop(views::InkDropState::HIDDEN, event); |
| 113 AnimateInkDrop(views::InkDropState::HIDDEN, event); | |
| 114 else | |
| 115 SetDrawBackgroundAsActive(false); | |
| 116 shelf_view_->PointerPressedOnButton(this, ShelfView::TOUCH, *event); | 96 shelf_view_->PointerPressedOnButton(this, ShelfView::TOUCH, *event); |
| 117 event->SetHandled(); | 97 event->SetHandled(); |
| 118 return; | 98 return; |
| 119 case ui::ET_GESTURE_SCROLL_UPDATE: | 99 case ui::ET_GESTURE_SCROLL_UPDATE: |
| 120 shelf_view_->PointerDraggedOnButton(this, ShelfView::TOUCH, *event); | 100 shelf_view_->PointerDraggedOnButton(this, ShelfView::TOUCH, *event); |
| 121 event->SetHandled(); | 101 event->SetHandled(); |
| 122 return; | 102 return; |
| 123 case ui::ET_GESTURE_SCROLL_END: | 103 case ui::ET_GESTURE_SCROLL_END: |
| 124 case ui::ET_SCROLL_FLING_START: | 104 case ui::ET_SCROLL_FLING_START: |
| 125 shelf_view_->PointerReleasedOnButton(this, ShelfView::TOUCH, false); | 105 shelf_view_->PointerReleasedOnButton(this, ShelfView::TOUCH, false); |
| 126 event->SetHandled(); | 106 event->SetHandled(); |
| 127 return; | 107 return; |
| 128 case ui::ET_GESTURE_TAP_DOWN: | 108 case ui::ET_GESTURE_TAP_DOWN: |
| 129 if (!is_material) | 109 if (!WmShell::Get()->IsApplistVisible()) |
| 130 SetDrawBackgroundAsActive(true); | |
| 131 else if (!WmShell::Get()->IsApplistVisible()) | |
| 132 AnimateInkDrop(views::InkDropState::ACTION_PENDING, event); | 110 AnimateInkDrop(views::InkDropState::ACTION_PENDING, event); |
| 133 ImageButton::OnGestureEvent(event); | 111 ImageButton::OnGestureEvent(event); |
| 134 break; | 112 break; |
| 135 case ui::ET_GESTURE_TAP_CANCEL: | |
| 136 case ui::ET_GESTURE_TAP: | |
| 137 if (!is_material) | |
| 138 SetDrawBackgroundAsActive(false); | |
| 139 ImageButton::OnGestureEvent(event); | |
| 140 break; | |
| 141 default: | 113 default: |
| 142 ImageButton::OnGestureEvent(event); | 114 ImageButton::OnGestureEvent(event); |
| 143 return; | 115 return; |
| 144 } | 116 } |
| 145 } | 117 } |
| 146 | 118 |
| 147 void AppListButton::OnPaint(gfx::Canvas* canvas) { | 119 void AppListButton::OnPaint(gfx::Canvas* canvas) { |
| 148 // Call the base class first to paint any background/borders. | 120 // Call the base class first to paint any background/borders. |
| 149 View::OnPaint(canvas); | 121 View::OnPaint(canvas); |
| 150 | 122 |
| 151 if (ash::MaterialDesignController::IsShelfMaterial()) { | |
| 152 PaintMd(canvas); | |
| 153 } else { | |
| 154 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | |
| 155 const gfx::ImageSkia& foreground_image = | |
| 156 *rb.GetImageNamed(IDR_ASH_SHELF_ICON_APPLIST).ToImageSkia(); | |
| 157 PaintAppListButton(canvas, foreground_image); | |
| 158 } | |
| 159 | |
| 160 views::Painter::PaintFocusPainter(this, canvas, focus_painter()); | |
| 161 } | |
| 162 | |
| 163 void AppListButton::PaintMd(gfx::Canvas* canvas) { | |
| 164 gfx::PointF circle_center(GetCenterPoint()); | 123 gfx::PointF circle_center(GetCenterPoint()); |
| 165 | 124 |
| 166 // Paint the circular background. | 125 // Paint the circular background. |
| 167 cc::PaintFlags bg_flags; | 126 cc::PaintFlags bg_flags; |
| 168 bg_flags.setColor(background_color_); | 127 bg_flags.setColor(background_color_); |
| 169 bg_flags.setFlags(cc::PaintFlags::kAntiAlias_Flag); | 128 bg_flags.setFlags(cc::PaintFlags::kAntiAlias_Flag); |
| 170 bg_flags.setStyle(cc::PaintFlags::kFill_Style); | 129 bg_flags.setStyle(cc::PaintFlags::kFill_Style); |
| 171 canvas->DrawCircle(circle_center, kAppListButtonRadius, bg_flags); | 130 canvas->DrawCircle(circle_center, kAppListButtonRadius, bg_flags); |
| 172 | 131 |
| 173 // Paint a white ring as the foreground. The ceil/dsf math assures that the | 132 // Paint a white ring as the foreground. The ceil/dsf math assures that the |
| 174 // ring draws sharply and is centered at all scale factors. | 133 // ring draws sharply and is centered at all scale factors. |
| 175 const float kRingOuterRadiusDp = 7.f; | 134 const float kRingOuterRadiusDp = 7.f; |
| 176 const float kRingThicknessDp = 1.5f; | 135 const float kRingThicknessDp = 1.5f; |
| 177 gfx::ScopedCanvas scoped_canvas(canvas); | 136 gfx::ScopedCanvas scoped_canvas(canvas); |
| 178 const float dsf = canvas->UndoDeviceScaleFactor(); | 137 const float dsf = canvas->UndoDeviceScaleFactor(); |
| 179 circle_center.Scale(dsf); | 138 circle_center.Scale(dsf); |
| 180 | 139 |
| 181 cc::PaintFlags fg_flags; | 140 cc::PaintFlags fg_flags; |
| 182 fg_flags.setFlags(cc::PaintFlags::kAntiAlias_Flag); | 141 fg_flags.setFlags(cc::PaintFlags::kAntiAlias_Flag); |
| 183 fg_flags.setStyle(cc::PaintFlags::kStroke_Style); | 142 fg_flags.setStyle(cc::PaintFlags::kStroke_Style); |
| 184 fg_flags.setColor(kShelfIconColor); | 143 fg_flags.setColor(kShelfIconColor); |
| 185 const float thickness = std::ceil(kRingThicknessDp * dsf); | 144 const float thickness = std::ceil(kRingThicknessDp * dsf); |
| 186 const float radius = std::ceil(kRingOuterRadiusDp * dsf) - thickness / 2; | 145 const float radius = std::ceil(kRingOuterRadiusDp * dsf) - thickness / 2; |
| 187 fg_flags.setStrokeWidth(thickness); | 146 fg_flags.setStrokeWidth(thickness); |
| 188 // Make sure the center of the circle lands on pixel centers. | 147 // Make sure the center of the circle lands on pixel centers. |
| 189 canvas->DrawCircle(circle_center, radius, fg_flags); | 148 canvas->DrawCircle(circle_center, radius, fg_flags); |
| 190 } | |
| 191 | 149 |
| 192 void AppListButton::PaintAppListButton(gfx::Canvas* canvas, | 150 views::Painter::PaintFocusPainter(this, canvas, focus_painter()); |
| 193 const gfx::ImageSkia& foreground_image) { | |
| 194 int background_image_id = 0; | |
| 195 | |
| 196 if (WmShell::Get()->GetAppListTargetVisibility() || | |
| 197 draw_background_as_active_) { | |
| 198 background_image_id = IDR_AURA_LAUNCHER_BACKGROUND_PRESSED; | |
| 199 } else { | |
| 200 background_image_id = IDR_AURA_LAUNCHER_BACKGROUND_NORMAL; | |
| 201 } | |
| 202 | |
| 203 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); | |
| 204 gfx::ImageSkia background_image = | |
| 205 *rb.GetImageNamed(background_image_id).ToImageSkia(); | |
| 206 gfx::Rect background_bounds(background_image.size()); | |
| 207 ShelfAlignment alignment = wm_shelf_->GetAlignment(); | |
| 208 gfx::Rect contents_bounds = GetContentsBounds(); | |
| 209 | |
| 210 if (alignment == SHELF_ALIGNMENT_LEFT) { | |
| 211 background_bounds.set_x(contents_bounds.width() - kShelfItemInset - | |
| 212 background_image.width()); | |
| 213 background_bounds.set_y( | |
| 214 contents_bounds.y() + | |
| 215 (contents_bounds.height() - background_image.height()) / 2); | |
| 216 } else if (alignment == SHELF_ALIGNMENT_RIGHT) { | |
| 217 background_bounds.set_x(kShelfItemInset); | |
| 218 background_bounds.set_y( | |
| 219 contents_bounds.y() + | |
| 220 (contents_bounds.height() - background_image.height()) / 2); | |
| 221 } else { | |
| 222 background_bounds.set_y(kShelfItemInset); | |
| 223 background_bounds.set_x( | |
| 224 contents_bounds.x() + | |
| 225 (contents_bounds.width() - background_image.width()) / 2); | |
| 226 } | |
| 227 | |
| 228 canvas->DrawImageInt(background_image, background_bounds.x(), | |
| 229 background_bounds.y()); | |
| 230 gfx::Rect foreground_bounds(foreground_image.size()); | |
| 231 foreground_bounds.set_x( | |
| 232 background_bounds.x() + | |
| 233 std::max(0, (background_bounds.width() - foreground_bounds.width()) / 2)); | |
| 234 foreground_bounds.set_y( | |
| 235 background_bounds.y() + | |
| 236 std::max(0, | |
| 237 (background_bounds.height() - foreground_bounds.height()) / 2)); | |
| 238 canvas->DrawImageInt(foreground_image, foreground_bounds.x(), | |
| 239 foreground_bounds.y()); | |
| 240 } | 151 } |
| 241 | 152 |
| 242 void AppListButton::GetAccessibleNodeData(ui::AXNodeData* node_data) { | 153 void AppListButton::GetAccessibleNodeData(ui::AXNodeData* node_data) { |
| 243 node_data->role = ui::AX_ROLE_BUTTON; | 154 node_data->role = ui::AX_ROLE_BUTTON; |
| 244 node_data->SetName(shelf_view_->GetTitleForView(this)); | 155 node_data->SetName(shelf_view_->GetTitleForView(this)); |
| 245 } | 156 } |
| 246 | 157 |
| 247 std::unique_ptr<views::InkDropRipple> AppListButton::CreateInkDropRipple() | 158 std::unique_ptr<views::InkDropRipple> AppListButton::CreateInkDropRipple() |
| 248 const { | 159 const { |
| 249 gfx::Point center = GetCenterPoint(); | 160 gfx::Point center = GetCenterPoint(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 275 CustomButton::CreateDefaultInkDropImpl(); | 186 CustomButton::CreateDefaultInkDropImpl(); |
| 276 ink_drop->SetShowHighlightOnHover(false); | 187 ink_drop->SetShowHighlightOnHover(false); |
| 277 return std::move(ink_drop); | 188 return std::move(ink_drop); |
| 278 } | 189 } |
| 279 | 190 |
| 280 std::unique_ptr<views::InkDropMask> AppListButton::CreateInkDropMask() const { | 191 std::unique_ptr<views::InkDropMask> AppListButton::CreateInkDropMask() const { |
| 281 return base::MakeUnique<views::CircleInkDropMask>(size(), GetCenterPoint(), | 192 return base::MakeUnique<views::CircleInkDropMask>(size(), GetCenterPoint(), |
| 282 kAppListButtonRadius); | 193 kAppListButtonRadius); |
| 283 } | 194 } |
| 284 | 195 |
| 285 void AppListButton::SetDrawBackgroundAsActive(bool draw_background_as_active) { | |
| 286 if (draw_background_as_active_ == draw_background_as_active) | |
| 287 return; | |
| 288 draw_background_as_active_ = draw_background_as_active; | |
| 289 SchedulePaint(); | |
| 290 } | |
| 291 | |
| 292 gfx::Point AppListButton::GetCenterPoint() const { | 196 gfx::Point AppListButton::GetCenterPoint() const { |
| 293 // For a bottom-aligned shelf, the button bounds could have a larger height | 197 // For a bottom-aligned shelf, the button bounds could have a larger height |
| 294 // than width (in the case of touch-dragging the shelf updwards) or a larger | 198 // than width (in the case of touch-dragging the shelf updwards) or a larger |
| 295 // width than height (in the case of a shelf hide/show animation), so adjust | 199 // width than height (in the case of a shelf hide/show animation), so adjust |
| 296 // the y-position of the circle's center to ensure correct layout. Similarly | 200 // the y-position of the circle's center to ensure correct layout. Similarly |
| 297 // adjust the x-position for a left- or right-aligned shelf. | 201 // adjust the x-position for a left- or right-aligned shelf. |
| 298 const int x_mid = width() / 2.f; | 202 const int x_mid = width() / 2.f; |
| 299 const int y_mid = height() / 2.f; | 203 const int y_mid = height() / 2.f; |
| 300 ShelfAlignment alignment = wm_shelf_->GetAlignment(); | 204 ShelfAlignment alignment = wm_shelf_->GetAlignment(); |
| 301 if (alignment == SHELF_ALIGNMENT_BOTTOM || | 205 if (alignment == SHELF_ALIGNMENT_BOTTOM || |
| 302 alignment == SHELF_ALIGNMENT_BOTTOM_LOCKED) { | 206 alignment == SHELF_ALIGNMENT_BOTTOM_LOCKED) { |
| 303 return gfx::Point(x_mid, x_mid); | 207 return gfx::Point(x_mid, x_mid); |
| 304 } else if (alignment == SHELF_ALIGNMENT_RIGHT) { | 208 } else if (alignment == SHELF_ALIGNMENT_RIGHT) { |
| 305 return gfx::Point(y_mid, y_mid); | 209 return gfx::Point(y_mid, y_mid); |
| 306 } else { | 210 } else { |
| 307 DCHECK_EQ(alignment, SHELF_ALIGNMENT_LEFT); | 211 DCHECK_EQ(alignment, SHELF_ALIGNMENT_LEFT); |
| 308 return gfx::Point(width() - y_mid, y_mid); | 212 return gfx::Point(width() - y_mid, y_mid); |
| 309 } | 213 } |
| 310 } | 214 } |
| 311 | 215 |
| 312 } // namespace ash | 216 } // namespace ash |
| OLD | NEW |