OLD | NEW |
---|---|
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/point.h" | |
26 #include "ui/views/border.h" | 28 #include "ui/views/border.h" |
27 #include "ui/views/view_model_utils.h" | 29 #include "ui/views/view_model_utils.h" |
28 #include "ui/views/widget/widget.h" | 30 #include "ui/views/widget/widget.h" |
29 | 31 |
30 #if defined(USE_AURA) | 32 #if defined(USE_AURA) |
31 #include "ui/aura/window.h" | 33 #include "ui/aura/window.h" |
32 #include "ui/aura/window_event_dispatcher.h" | 34 #include "ui/aura/window_event_dispatcher.h" |
33 #if defined(OS_WIN) | 35 #if defined(OS_WIN) |
34 #include "ui/views/win/hwnd_util.h" | 36 #include "ui/views/win/hwnd_util.h" |
35 #endif // defined(OS_WIN) | 37 #endif // defined(OS_WIN) |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
85 // Delays in milliseconds to show re-order preview. | 87 // Delays in milliseconds to show re-order preview. |
86 const int kReorderDelay = 120; | 88 const int kReorderDelay = 120; |
87 | 89 |
88 // Delays in milliseconds to show folder item reparent UI. | 90 // Delays in milliseconds to show folder item reparent UI. |
89 const int kFolderItemReparentDelay = 50; | 91 const int kFolderItemReparentDelay = 50; |
90 | 92 |
91 // Radius of the circle, in which if entered, show folder dropping preview | 93 // Radius of the circle, in which if entered, show folder dropping preview |
92 // UI. | 94 // UI. |
93 const int kFolderDroppingCircleRadius = 15; | 95 const int kFolderDroppingCircleRadius = 15; |
94 | 96 |
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. | 97 // 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 | 98 // 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 | 99 // 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 | 100 // 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. | 101 // the layer and fades it out while fading in the item at the same time. |
107 class RowMoveAnimationDelegate : public gfx::AnimationDelegate { | 102 class RowMoveAnimationDelegate : public gfx::AnimationDelegate { |
108 public: | 103 public: |
109 RowMoveAnimationDelegate(views::View* view, | 104 RowMoveAnimationDelegate(views::View* view, |
110 ui::Layer* layer, | 105 ui::Layer* layer, |
111 const gfx::Rect& layer_target) | 106 const gfx::Rect& layer_target) |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
362 SetPaintToLayer(true); | 357 SetPaintToLayer(true); |
363 // Clip any icons that are outside the grid view's bounds. These icons would | 358 // 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. | 359 // otherwise be visible to the user when the grid view is off screen. |
365 layer()->SetMasksToBounds(true); | 360 layer()->SetMasksToBounds(true); |
366 SetFillsBoundsOpaquely(false); | 361 SetFillsBoundsOpaquely(false); |
367 | 362 |
368 pagination_model_.SetTransitionDurations(kPageTransitionDurationInMs, | 363 pagination_model_.SetTransitionDurations(kPageTransitionDurationInMs, |
369 kOverscrollPageTransitionDurationMs); | 364 kOverscrollPageTransitionDurationMs); |
370 | 365 |
371 pagination_model_.AddObserver(this); | 366 pagination_model_.AddObserver(this); |
367 // The experimental app list transitions vertically. | |
368 PaginationController::ScrollAxis scroll_axis = | |
369 app_list::switches::IsExperimentalAppListEnabled() | |
370 ? PaginationController::SCROLL_AXIS_VERTICAL | |
371 : PaginationController::SCROLL_AXIS_HORIZONTAL; | |
372 pagination_controller_.reset( | |
373 new PaginationController(&pagination_model_, scroll_axis)); | |
372 page_switcher_view_ = new PageSwitcher(&pagination_model_); | 374 page_switcher_view_ = new PageSwitcher(&pagination_model_); |
373 AddChildView(page_switcher_view_); | 375 AddChildView(page_switcher_view_); |
374 } | 376 } |
375 | 377 |
376 AppsGridView::~AppsGridView() { | 378 AppsGridView::~AppsGridView() { |
377 // Coming here |drag_view_| should already be canceled since otherwise the | 379 // Coming here |drag_view_| should already be canceled since otherwise the |
378 // drag would disappear after the app list got animated away and closed, | 380 // drag would disappear after the app list got animated away and closed, |
379 // which would look odd. | 381 // which would look odd. |
380 DCHECK(!drag_view_); | 382 DCHECK(!drag_view_); |
381 if (drag_view_) | 383 if (drag_view_) |
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
954 | 956 |
955 bool AppsGridView::OnKeyReleased(const ui::KeyEvent& event) { | 957 bool AppsGridView::OnKeyReleased(const ui::KeyEvent& event) { |
956 bool handled = false; | 958 bool handled = false; |
957 if (selected_view_) | 959 if (selected_view_) |
958 handled = selected_view_->OnKeyReleased(event); | 960 handled = selected_view_->OnKeyReleased(event); |
959 | 961 |
960 return handled; | 962 return handled; |
961 } | 963 } |
962 | 964 |
963 bool AppsGridView::OnMouseWheel(const ui::MouseWheelEvent& event) { | 965 bool AppsGridView::OnMouseWheel(const ui::MouseWheelEvent& event) { |
964 int offset; | 966 return pagination_controller_->OnScroll( |
965 if (GetScrollAxis() == SCROLL_AXIS_HORIZONTAL) { | 967 gfx::Point(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 } | 968 } |
986 | 969 |
987 void AppsGridView::ViewHierarchyChanged( | 970 void AppsGridView::ViewHierarchyChanged( |
988 const ViewHierarchyChangedDetails& details) { | 971 const ViewHierarchyChangedDetails& details) { |
989 if (!details.is_add && details.parent == this) { | 972 if (!details.is_add && details.parent == this) { |
990 // The view being delete should not have reference in |view_model_|. | 973 // The view being delete should not have reference in |view_model_|. |
991 CHECK_EQ(-1, view_model_.GetIndexOfView(details.child)); | 974 CHECK_EQ(-1, view_model_.GetIndexOfView(details.child)); |
992 | 975 |
993 if (selected_view_ == details.child) | 976 if (selected_view_ == details.child) |
994 selected_view_ = NULL; | 977 selected_view_ = NULL; |
995 if (activated_folder_item_view_ == details.child) | 978 if (activated_folder_item_view_ == details.child) |
996 activated_folder_item_view_ = NULL; | 979 activated_folder_item_view_ = NULL; |
997 | 980 |
998 if (drag_view_ == details.child) | 981 if (drag_view_ == details.child) |
999 EndDrag(true); | 982 EndDrag(true); |
1000 | 983 |
1001 bounds_animator_.StopAnimatingView(details.child); | 984 bounds_animator_.StopAnimatingView(details.child); |
1002 } | 985 } |
1003 } | 986 } |
1004 | 987 |
1005 void AppsGridView::OnGestureEvent(ui::GestureEvent* event) { | 988 void AppsGridView::OnGestureEvent(ui::GestureEvent* event) { |
1006 const ui::GestureEventDetails& details = event->details(); | 989 pagination_controller_->OnGestureEvent(event, GetContentsBounds()); |
1007 switch (event->type()) { | |
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 } | 990 } |
1044 | 991 |
1045 void AppsGridView::OnScrollEvent(ui::ScrollEvent* event) { | 992 void AppsGridView::OnScrollEvent(ui::ScrollEvent* event) { |
1046 if (event->type() == ui::ET_SCROLL_FLING_CANCEL) | 993 if (event->type() == ui::ET_SCROLL_FLING_CANCEL) |
1047 return; | 994 return; |
1048 | 995 |
1049 float offset; | 996 if (pagination_controller_->OnScroll( |
1050 if (GetScrollAxis() == SCROLL_AXIS_HORIZONTAL) { | 997 gfx::Point(static_cast<int>(event->x_offset()), |
1051 // If the view scrolls horizontally, both horizontal and vertical scroll | 998 static_cast<int>(event->y_offset())))) { |
calamity
2014/09/01 01:49:30
Maybe gfx::ToFlooredPoint(gfx::PointF(event->x_off
Matt Giuca
2014/09/01 03:02:26
Done.
| |
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(); | 999 event->SetHandled(); |
1067 event->StopPropagation(); | 1000 event->StopPropagation(); |
1068 } | 1001 } |
1069 } | 1002 } |
1070 | 1003 |
1071 void AppsGridView::Update() { | 1004 void AppsGridView::Update() { |
1072 DCHECK(!selected_view_ && !drag_view_); | 1005 DCHECK(!selected_view_ && !drag_view_); |
1073 view_model_.Clear(); | 1006 view_model_.Clear(); |
1074 if (!item_list_ || !item_list_->item_count()) | 1007 if (!item_list_ || !item_list_->item_count()) |
1075 return; | 1008 return; |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1263 drop_attempt_ == DROP_FOR_REORDER) { | 1196 drop_attempt_ == DROP_FOR_REORDER) { |
1264 ++slot_index; | 1197 ++slot_index; |
1265 view_index = GetIndexFromModelIndex(slot_index); | 1198 view_index = GetIndexFromModelIndex(slot_index); |
1266 } | 1199 } |
1267 } | 1200 } |
1268 | 1201 |
1269 // Decide the x or y offset for current item. | 1202 // Decide the x or y offset for current item. |
1270 int x_offset = 0; | 1203 int x_offset = 0; |
1271 int y_offset = 0; | 1204 int y_offset = 0; |
1272 | 1205 |
1273 if (GetScrollAxis() == SCROLL_AXIS_HORIZONTAL) { | 1206 if (pagination_controller_->scroll_axis() == |
1207 PaginationController::SCROLL_AXIS_HORIZONTAL) { | |
1274 if (view_index.page < current_page) | 1208 if (view_index.page < current_page) |
1275 x_offset = -page_width; | 1209 x_offset = -page_width; |
1276 else if (view_index.page > current_page) | 1210 else if (view_index.page > current_page) |
1277 x_offset = page_width; | 1211 x_offset = page_width; |
1278 | 1212 |
1279 if (is_valid) { | 1213 if (is_valid) { |
1280 if (view_index.page == current_page || | 1214 if (view_index.page == current_page || |
1281 view_index.page == transition.target_page) { | 1215 view_index.page == transition.target_page) { |
1282 x_offset += transition.progress * page_width * dir; | 1216 x_offset += transition.progress * page_width * dir; |
1283 } | 1217 } |
(...skipping 998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2282 | 2216 |
2283 void AppsGridView::SetAsFolderDroppingTarget(const Index& target_index, | 2217 void AppsGridView::SetAsFolderDroppingTarget(const Index& target_index, |
2284 bool is_target_folder) { | 2218 bool is_target_folder) { |
2285 AppListItemView* target_view = | 2219 AppListItemView* target_view = |
2286 static_cast<AppListItemView*>( | 2220 static_cast<AppListItemView*>( |
2287 GetViewAtSlotOnCurrentPage(target_index.slot)); | 2221 GetViewAtSlotOnCurrentPage(target_index.slot)); |
2288 if (target_view) | 2222 if (target_view) |
2289 target_view->SetAsAttemptedFolderTarget(is_target_folder); | 2223 target_view->SetAsAttemptedFolderTarget(is_target_folder); |
2290 } | 2224 } |
2291 | 2225 |
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 | 2226 } // namespace app_list |
OLD | NEW |