Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(208)

Side by Side Diff: ui/app_list/views/apps_grid_view.cc

Issue 524503003: Refactor app list scrolling: introduce the PaginationController class. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ares-appgrid-vertical-scroll
Patch Set: Fix GN and Gyp. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/app_list/views/apps_grid_view.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "ui/app_list/views/apps_grid_view.h" 5 #include "ui/app_list/views/apps_grid_view.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <set> 8 #include <set>
9 #include <string> 9 #include <string>
10 10
11 #include "base/guid.h" 11 #include "base/guid.h"
12 #include "ui/app_list/app_list_constants.h" 12 #include "ui/app_list/app_list_constants.h"
13 #include "ui/app_list/app_list_folder_item.h" 13 #include "ui/app_list/app_list_folder_item.h"
14 #include "ui/app_list/app_list_item.h" 14 #include "ui/app_list/app_list_item.h"
15 #include "ui/app_list/app_list_switches.h" 15 #include "ui/app_list/app_list_switches.h"
16 #include "ui/app_list/pagination_controller.h"
16 #include "ui/app_list/views/app_list_drag_and_drop_host.h" 17 #include "ui/app_list/views/app_list_drag_and_drop_host.h"
17 #include "ui/app_list/views/app_list_folder_view.h" 18 #include "ui/app_list/views/app_list_folder_view.h"
18 #include "ui/app_list/views/app_list_item_view.h" 19 #include "ui/app_list/views/app_list_item_view.h"
19 #include "ui/app_list/views/apps_grid_view_delegate.h" 20 #include "ui/app_list/views/apps_grid_view_delegate.h"
20 #include "ui/app_list/views/page_switcher.h" 21 #include "ui/app_list/views/page_switcher.h"
21 #include "ui/app_list/views/pulsing_block_view.h" 22 #include "ui/app_list/views/pulsing_block_view.h"
22 #include "ui/app_list/views/top_icon_animation_view.h" 23 #include "ui/app_list/views/top_icon_animation_view.h"
23 #include "ui/compositor/scoped_layer_animation_settings.h" 24 #include "ui/compositor/scoped_layer_animation_settings.h"
24 #include "ui/events/event.h" 25 #include "ui/events/event.h"
25 #include "ui/gfx/animation/animation.h" 26 #include "ui/gfx/animation/animation.h"
27 #include "ui/gfx/geometry/vector2d.h"
28 #include "ui/gfx/geometry/vector2d_conversions.h"
26 #include "ui/views/border.h" 29 #include "ui/views/border.h"
27 #include "ui/views/view_model_utils.h" 30 #include "ui/views/view_model_utils.h"
28 #include "ui/views/widget/widget.h" 31 #include "ui/views/widget/widget.h"
29 32
30 #if defined(USE_AURA) 33 #if defined(USE_AURA)
31 #include "ui/aura/window.h" 34 #include "ui/aura/window.h"
32 #include "ui/aura/window_event_dispatcher.h" 35 #include "ui/aura/window_event_dispatcher.h"
33 #if defined(OS_WIN) 36 #if defined(OS_WIN)
34 #include "ui/views/win/hwnd_util.h" 37 #include "ui/views/win/hwnd_util.h"
35 #endif // defined(OS_WIN) 38 #endif // defined(OS_WIN)
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 // Delays in milliseconds to show re-order preview. 88 // Delays in milliseconds to show re-order preview.
86 const int kReorderDelay = 120; 89 const int kReorderDelay = 120;
87 90
88 // Delays in milliseconds to show folder item reparent UI. 91 // Delays in milliseconds to show folder item reparent UI.
89 const int kFolderItemReparentDelay = 50; 92 const int kFolderItemReparentDelay = 50;
90 93
91 // Radius of the circle, in which if entered, show folder dropping preview 94 // Radius of the circle, in which if entered, show folder dropping preview
92 // UI. 95 // UI.
93 const int kFolderDroppingCircleRadius = 15; 96 const int kFolderDroppingCircleRadius = 15;
94 97
95 // Constants for dealing with scroll events.
96 const int kMinMouseWheelToSwitchPage = 20;
97 const int kMinScrollToSwitchPage = 20;
98 const int kMinHorizVelocityToSwitchPage = 800;
99
100 const double kFinishTransitionThreshold = 0.33;
101
102 // RowMoveAnimationDelegate is used when moving an item into a different row. 98 // RowMoveAnimationDelegate is used when moving an item into a different row.
103 // Before running the animation, the item's layer is re-created and kept in 99 // Before running the animation, the item's layer is re-created and kept in
104 // the original position, then the item is moved to just before its target 100 // the original position, then the item is moved to just before its target
105 // position and opacity set to 0. When the animation runs, this delegate moves 101 // position and opacity set to 0. When the animation runs, this delegate moves
106 // the layer and fades it out while fading in the item at the same time. 102 // the layer and fades it out while fading in the item at the same time.
107 class RowMoveAnimationDelegate : public gfx::AnimationDelegate { 103 class RowMoveAnimationDelegate : public gfx::AnimationDelegate {
108 public: 104 public:
109 RowMoveAnimationDelegate(views::View* view, 105 RowMoveAnimationDelegate(views::View* view,
110 ui::Layer* layer, 106 ui::Layer* layer,
111 const gfx::Rect& layer_target) 107 const gfx::Rect& layer_target)
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 SetPaintToLayer(true); 358 SetPaintToLayer(true);
363 // Clip any icons that are outside the grid view's bounds. These icons would 359 // Clip any icons that are outside the grid view's bounds. These icons would
364 // otherwise be visible to the user when the grid view is off screen. 360 // otherwise be visible to the user when the grid view is off screen.
365 layer()->SetMasksToBounds(true); 361 layer()->SetMasksToBounds(true);
366 SetFillsBoundsOpaquely(false); 362 SetFillsBoundsOpaquely(false);
367 363
368 pagination_model_.SetTransitionDurations(kPageTransitionDurationInMs, 364 pagination_model_.SetTransitionDurations(kPageTransitionDurationInMs,
369 kOverscrollPageTransitionDurationMs); 365 kOverscrollPageTransitionDurationMs);
370 366
371 pagination_model_.AddObserver(this); 367 pagination_model_.AddObserver(this);
368 // The experimental app list transitions vertically.
369 PaginationController::ScrollAxis scroll_axis =
370 app_list::switches::IsExperimentalAppListEnabled()
371 ? PaginationController::SCROLL_AXIS_VERTICAL
372 : PaginationController::SCROLL_AXIS_HORIZONTAL;
373 pagination_controller_.reset(
374 new PaginationController(&pagination_model_, scroll_axis));
372 page_switcher_view_ = new PageSwitcher(&pagination_model_); 375 page_switcher_view_ = new PageSwitcher(&pagination_model_);
373 AddChildView(page_switcher_view_); 376 AddChildView(page_switcher_view_);
374 } 377 }
375 378
376 AppsGridView::~AppsGridView() { 379 AppsGridView::~AppsGridView() {
377 // Coming here |drag_view_| should already be canceled since otherwise the 380 // Coming here |drag_view_| should already be canceled since otherwise the
378 // drag would disappear after the app list got animated away and closed, 381 // drag would disappear after the app list got animated away and closed,
379 // which would look odd. 382 // which would look odd.
380 DCHECK(!drag_view_); 383 DCHECK(!drag_view_);
381 if (drag_view_) 384 if (drag_view_)
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after
954 957
955 bool AppsGridView::OnKeyReleased(const ui::KeyEvent& event) { 958 bool AppsGridView::OnKeyReleased(const ui::KeyEvent& event) {
956 bool handled = false; 959 bool handled = false;
957 if (selected_view_) 960 if (selected_view_)
958 handled = selected_view_->OnKeyReleased(event); 961 handled = selected_view_->OnKeyReleased(event);
959 962
960 return handled; 963 return handled;
961 } 964 }
962 965
963 bool AppsGridView::OnMouseWheel(const ui::MouseWheelEvent& event) { 966 bool AppsGridView::OnMouseWheel(const ui::MouseWheelEvent& event) {
964 int offset; 967 return pagination_controller_->OnScroll(
965 if (GetScrollAxis() == SCROLL_AXIS_HORIZONTAL) { 968 gfx::Vector2d(event.x_offset(), event.y_offset()));
966 // If the view scrolls horizontally, both horizontal and vertical scroll
967 // events are valid (since most mouse wheels only have vertical scrolling).
968 if (abs(event.x_offset()) > abs(event.y_offset()))
969 offset = event.x_offset();
970 else
971 offset = event.y_offset();
972 } else {
973 // If the view scrolls vertically, only vertical scroll events are valid.
974 offset = event.y_offset();
975 }
976
977 if (abs(offset) > kMinMouseWheelToSwitchPage) {
978 if (!pagination_model_.has_transition()) {
979 pagination_model_.SelectPageRelative(offset > 0 ? -1 : 1, true);
980 }
981 return true;
982 }
983
984 return false;
985 } 969 }
986 970
987 void AppsGridView::ViewHierarchyChanged( 971 void AppsGridView::ViewHierarchyChanged(
988 const ViewHierarchyChangedDetails& details) { 972 const ViewHierarchyChangedDetails& details) {
989 if (!details.is_add && details.parent == this) { 973 if (!details.is_add && details.parent == this) {
990 // The view being delete should not have reference in |view_model_|. 974 // The view being delete should not have reference in |view_model_|.
991 CHECK_EQ(-1, view_model_.GetIndexOfView(details.child)); 975 CHECK_EQ(-1, view_model_.GetIndexOfView(details.child));
992 976
993 if (selected_view_ == details.child) 977 if (selected_view_ == details.child)
994 selected_view_ = NULL; 978 selected_view_ = NULL;
995 if (activated_folder_item_view_ == details.child) 979 if (activated_folder_item_view_ == details.child)
996 activated_folder_item_view_ = NULL; 980 activated_folder_item_view_ = NULL;
997 981
998 if (drag_view_ == details.child) 982 if (drag_view_ == details.child)
999 EndDrag(true); 983 EndDrag(true);
1000 984
1001 bounds_animator_.StopAnimatingView(details.child); 985 bounds_animator_.StopAnimatingView(details.child);
1002 } 986 }
1003 } 987 }
1004 988
1005 void AppsGridView::OnGestureEvent(ui::GestureEvent* event) { 989 void AppsGridView::OnGestureEvent(ui::GestureEvent* event) {
1006 const ui::GestureEventDetails& details = event->details(); 990 if (pagination_controller_->OnGestureEvent(*event, GetContentsBounds()))
1007 switch (event->type()) { 991 event->SetHandled();
1008 case ui::ET_GESTURE_SCROLL_BEGIN:
1009 pagination_model_.StartScroll();
1010 event->SetHandled();
1011 return;
1012 case ui::ET_GESTURE_SCROLL_UPDATE: {
1013 float scroll = GetScrollAxis() == SCROLL_AXIS_HORIZONTAL
1014 ? details.scroll_x()
1015 : details.scroll_y();
1016 gfx::Rect bounds(GetContentsBounds());
1017 int size = GetScrollAxis() == SCROLL_AXIS_HORIZONTAL ? bounds.width()
1018 : bounds.height();
1019 // scroll > 0 means moving contents right or down. That is, transitioning
1020 // to the previous page.
1021 pagination_model_.UpdateScroll(scroll / size);
1022 event->SetHandled();
1023 return;
1024 }
1025 case ui::ET_GESTURE_SCROLL_END:
1026 pagination_model_.EndScroll(pagination_model_.transition().progress <
1027 kFinishTransitionThreshold);
1028 event->SetHandled();
1029 return;
1030 case ui::ET_SCROLL_FLING_START: {
1031 float velocity = GetScrollAxis() == SCROLL_AXIS_HORIZONTAL
1032 ? details.velocity_x()
1033 : details.velocity_y();
1034 pagination_model_.EndScroll(true);
1035 if (fabs(velocity) > kMinHorizVelocityToSwitchPage)
1036 pagination_model_.SelectPageRelative(velocity < 0 ? 1 : -1, true);
1037 event->SetHandled();
1038 return;
1039 }
1040 default:
1041 break;
1042 }
1043 } 992 }
1044 993
1045 void AppsGridView::OnScrollEvent(ui::ScrollEvent* event) { 994 void AppsGridView::OnScrollEvent(ui::ScrollEvent* event) {
1046 if (event->type() == ui::ET_SCROLL_FLING_CANCEL) 995 if (event->type() == ui::ET_SCROLL_FLING_CANCEL)
1047 return; 996 return;
1048 997
1049 float offset; 998 gfx::Vector2dF offset(event->x_offset(), event->y_offset());
1050 if (GetScrollAxis() == SCROLL_AXIS_HORIZONTAL) { 999 if (pagination_controller_->OnScroll(gfx::ToFlooredVector2d(offset))) {
1051 // If the view scrolls horizontally, both horizontal and vertical scroll
1052 // events are valid (vertical scroll events simulate mouse wheel).
1053 if (std::abs(event->x_offset()) > std::abs(event->y_offset()))
1054 offset = event->x_offset();
1055 else
1056 offset = event->y_offset();
1057 } else {
1058 // If the view scrolls vertically, only vertical scroll events are valid.
1059 offset = event->y_offset();
1060 }
1061
1062 if (std::abs(offset) > kMinScrollToSwitchPage) {
1063 if (!pagination_model_.has_transition()) {
1064 pagination_model_.SelectPageRelative(offset > 0 ? -1 : 1, true);
1065 }
1066 event->SetHandled(); 1000 event->SetHandled();
1067 event->StopPropagation(); 1001 event->StopPropagation();
1068 } 1002 }
1069 } 1003 }
1070 1004
1071 void AppsGridView::Update() { 1005 void AppsGridView::Update() {
1072 DCHECK(!selected_view_ && !drag_view_); 1006 DCHECK(!selected_view_ && !drag_view_);
1073 view_model_.Clear(); 1007 view_model_.Clear();
1074 if (!item_list_ || !item_list_->item_count()) 1008 if (!item_list_ || !item_list_->item_count())
1075 return; 1009 return;
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1263 drop_attempt_ == DROP_FOR_REORDER) { 1197 drop_attempt_ == DROP_FOR_REORDER) {
1264 ++slot_index; 1198 ++slot_index;
1265 view_index = GetIndexFromModelIndex(slot_index); 1199 view_index = GetIndexFromModelIndex(slot_index);
1266 } 1200 }
1267 } 1201 }
1268 1202
1269 // Decide the x or y offset for current item. 1203 // Decide the x or y offset for current item.
1270 int x_offset = 0; 1204 int x_offset = 0;
1271 int y_offset = 0; 1205 int y_offset = 0;
1272 1206
1273 if (GetScrollAxis() == SCROLL_AXIS_HORIZONTAL) { 1207 if (pagination_controller_->scroll_axis() ==
1208 PaginationController::SCROLL_AXIS_HORIZONTAL) {
1274 if (view_index.page < current_page) 1209 if (view_index.page < current_page)
1275 x_offset = -page_width; 1210 x_offset = -page_width;
1276 else if (view_index.page > current_page) 1211 else if (view_index.page > current_page)
1277 x_offset = page_width; 1212 x_offset = page_width;
1278 1213
1279 if (is_valid) { 1214 if (is_valid) {
1280 if (view_index.page == current_page || 1215 if (view_index.page == current_page ||
1281 view_index.page == transition.target_page) { 1216 view_index.page == transition.target_page) {
1282 x_offset += transition.progress * page_width * dir; 1217 x_offset += transition.progress * page_width * dir;
1283 } 1218 }
(...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after
2282 2217
2283 void AppsGridView::SetAsFolderDroppingTarget(const Index& target_index, 2218 void AppsGridView::SetAsFolderDroppingTarget(const Index& target_index,
2284 bool is_target_folder) { 2219 bool is_target_folder) {
2285 AppListItemView* target_view = 2220 AppListItemView* target_view =
2286 static_cast<AppListItemView*>( 2221 static_cast<AppListItemView*>(
2287 GetViewAtSlotOnCurrentPage(target_index.slot)); 2222 GetViewAtSlotOnCurrentPage(target_index.slot));
2288 if (target_view) 2223 if (target_view)
2289 target_view->SetAsAttemptedFolderTarget(is_target_folder); 2224 target_view->SetAsAttemptedFolderTarget(is_target_folder);
2290 } 2225 }
2291 2226
2292 // static
2293 AppsGridView::ScrollAxis AppsGridView::GetScrollAxis() {
2294 // The experimental app list transitions vertically.
2295 return app_list::switches::IsExperimentalAppListEnabled()
2296 ? SCROLL_AXIS_VERTICAL
2297 : SCROLL_AXIS_HORIZONTAL;
2298 }
2299
2300 } // namespace app_list 2227 } // namespace app_list
OLDNEW
« no previous file with comments | « ui/app_list/views/apps_grid_view.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698