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 | 8 |
9 #include "ui/app_list/app_list_item_model.h" | 9 #include "ui/app_list/app_list_item_model.h" |
10 #include "ui/app_list/apps_grid_view_delegate.h" | 10 #include "ui/app_list/apps_grid_view_delegate.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 #include "base/files/file_path.h" | 29 #include "base/files/file_path.h" |
30 #include "base/win/shortcut.h" | 30 #include "base/win/shortcut.h" |
31 #include "ui/base/dragdrop/drag_utils.h" | 31 #include "ui/base/dragdrop/drag_utils.h" |
32 #include "ui/base/dragdrop/drop_target_win.h" | 32 #include "ui/base/dragdrop/drop_target_win.h" |
33 #include "ui/base/dragdrop/os_exchange_data.h" | 33 #include "ui/base/dragdrop/os_exchange_data.h" |
34 #include "ui/base/dragdrop/os_exchange_data_provider_win.h" | 34 #include "ui/base/dragdrop/os_exchange_data_provider_win.h" |
35 #endif | 35 #endif |
36 | 36 |
37 namespace { | 37 namespace { |
38 | 38 |
| 39 // Distance a drag needs to be from the app grid to be considered 'outside', at |
| 40 // which point we rearrange the apps to their pre-drag configuration, as a drop |
| 41 // then would be canceled. We have a buffer to make it easier to drag apps to |
| 42 // other pages. |
| 43 const int kDragBufferPx = 20; |
| 44 |
39 // Padding space in pixels for fixed layout. | 45 // Padding space in pixels for fixed layout. |
40 const int kLeftRightPadding = 20; | 46 const int kLeftRightPadding = 20; |
41 const int kTopPadding = 1; | 47 const int kTopPadding = 1; |
42 | 48 |
43 // Padding space in pixels between pages. | 49 // Padding space in pixels between pages. |
44 const int kPagePadding = 40; | 50 const int kPagePadding = 40; |
45 | 51 |
46 // Preferred tile size when showing in fixed layout. | 52 // Preferred tile size when showing in fixed layout. |
47 const int kPreferredTileWidth = 88; | 53 const int kPreferredTileWidth = 88; |
48 const int kPreferredTileHeight = 98; | 54 const int kPreferredTileHeight = 98; |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 virtual void OnDragSourceCancel() OVERRIDE { | 182 virtual void OnDragSourceCancel() OVERRIDE { |
177 canceled_ = true; | 183 canceled_ = true; |
178 } | 184 } |
179 | 185 |
180 virtual void OnDragSourceDrop() OVERRIDE { | 186 virtual void OnDragSourceDrop() OVERRIDE { |
181 } | 187 } |
182 | 188 |
183 virtual void OnDragSourceMove() OVERRIDE { | 189 virtual void OnDragSourceMove() OVERRIDE { |
184 grid_view_->UpdateDrag(app_list::AppsGridView::MOUSE, | 190 grid_view_->UpdateDrag(app_list::AppsGridView::MOUSE, |
185 GetCursorInGridViewCoords()); | 191 GetCursorInGridViewCoords()); |
186 | |
187 // Don't turn pages if the cursor is dragged outside the view. | |
188 if (!IsCursorWithinGridView()) | |
189 grid_view_->StopPageFlipTimer(); | |
190 } | 192 } |
191 | 193 |
192 void SetupExchangeData(ui::OSExchangeData* data) { | 194 void SetupExchangeData(ui::OSExchangeData* data) { |
193 data->SetFilename(shortcut_path_); | 195 data->SetFilename(shortcut_path_); |
194 gfx::ImageSkia image(drag_view_->GetDragImage()); | 196 gfx::ImageSkia image(drag_view_->GetDragImage()); |
195 gfx::Size image_size(image.size()); | 197 gfx::Size image_size(image.size()); |
196 drag_utils::SetDragImageOnDataObject( | 198 drag_utils::SetDragImageOnDataObject( |
197 image, | 199 image, |
198 image.size(), | 200 image.size(), |
199 gfx::Vector2d(drag_view_offset_.x(), drag_view_offset_.y()), | 201 gfx::Vector2d(drag_view_offset_.x(), drag_view_offset_.y()), |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 AppsGridView::AppsGridView(AppsGridViewDelegate* delegate, | 236 AppsGridView::AppsGridView(AppsGridViewDelegate* delegate, |
235 PaginationModel* pagination_model) | 237 PaginationModel* pagination_model) |
236 : model_(NULL), | 238 : model_(NULL), |
237 delegate_(delegate), | 239 delegate_(delegate), |
238 pagination_model_(pagination_model), | 240 pagination_model_(pagination_model), |
239 page_switcher_view_(new PageSwitcher(pagination_model)), | 241 page_switcher_view_(new PageSwitcher(pagination_model)), |
240 cols_(0), | 242 cols_(0), |
241 rows_per_page_(0), | 243 rows_per_page_(0), |
242 selected_view_(NULL), | 244 selected_view_(NULL), |
243 drag_view_(NULL), | 245 drag_view_(NULL), |
| 246 drag_start_page_(-1), |
244 drag_pointer_(NONE), | 247 drag_pointer_(NONE), |
245 drag_and_drop_host_(NULL), | 248 drag_and_drop_host_(NULL), |
246 forward_events_to_drag_and_drop_host_(false), | 249 forward_events_to_drag_and_drop_host_(false), |
247 page_flip_target_(-1), | 250 page_flip_target_(-1), |
248 page_flip_delay_in_ms_(kPageFlipDelayInMs), | 251 page_flip_delay_in_ms_(kPageFlipDelayInMs), |
249 bounds_animator_(this) { | 252 bounds_animator_(this) { |
250 last_created_grid_view_for_test = this; | 253 last_created_grid_view_for_test = this; |
251 pagination_model_->AddObserver(this); | 254 pagination_model_->AddObserver(this); |
252 AddChildView(page_switcher_view_); | 255 AddChildView(page_switcher_view_); |
253 } | 256 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 | 319 |
317 void AppsGridView::InitiateDrag(AppListItemView* view, | 320 void AppsGridView::InitiateDrag(AppListItemView* view, |
318 Pointer pointer, | 321 Pointer pointer, |
319 const ui::LocatedEvent& event) { | 322 const ui::LocatedEvent& event) { |
320 DCHECK(view); | 323 DCHECK(view); |
321 if (drag_view_ || pulsing_blocks_model_.view_size()) | 324 if (drag_view_ || pulsing_blocks_model_.view_size()) |
322 return; | 325 return; |
323 | 326 |
324 drag_view_ = view; | 327 drag_view_ = view; |
325 drag_view_offset_ = event.location(); | 328 drag_view_offset_ = event.location(); |
| 329 drag_start_page_ = pagination_model_->selected_page(); |
326 ExtractDragLocation(event, &drag_start_grid_view_); | 330 ExtractDragLocation(event, &drag_start_grid_view_); |
327 drag_view_start_ = gfx::Point(drag_view_->x(), drag_view_->y()); | 331 drag_view_start_ = gfx::Point(drag_view_->x(), drag_view_->y()); |
328 } | 332 } |
329 | 333 |
330 void AppsGridView::OnGotShortcutPath(const base::FilePath& path) { | 334 void AppsGridView::OnGotShortcutPath(const base::FilePath& path) { |
331 #if defined(OS_WIN) && !defined(USE_AURA) | 335 #if defined(OS_WIN) && !defined(USE_AURA) |
332 // Drag may have ended before we get the shortcut path. | 336 // Drag may have ended before we get the shortcut path. |
333 if (!synchronous_drag_) | 337 if (!synchronous_drag_) |
334 return; | 338 return; |
335 // Setting the shortcut path here means the next time we hit UpdateDrag() | 339 // Setting the shortcut path here means the next time we hit UpdateDrag() |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
400 StartDragAndDropHostDrag(point); | 404 StartDragAndDropHostDrag(point); |
401 } | 405 } |
402 | 406 |
403 if (drag_pointer_ != pointer) | 407 if (drag_pointer_ != pointer) |
404 return; | 408 return; |
405 | 409 |
406 last_drag_point_ = point; | 410 last_drag_point_ = point; |
407 const Index last_drop_target = drop_target_; | 411 const Index last_drop_target = drop_target_; |
408 CalculateDropTarget(last_drag_point_, false); | 412 CalculateDropTarget(last_drag_point_, false); |
409 | 413 |
410 MaybeStartPageFlipTimer(last_drag_point_); | 414 if (IsPointWithinDragBuffer(last_drag_point_)) |
| 415 MaybeStartPageFlipTimer(last_drag_point_); |
| 416 else |
| 417 StopPageFlipTimer(); |
411 | 418 |
412 gfx::Point page_switcher_point(last_drag_point_); | 419 gfx::Point page_switcher_point(last_drag_point_); |
413 views::View::ConvertPointToTarget(this, page_switcher_view_, | 420 views::View::ConvertPointToTarget(this, page_switcher_view_, |
414 &page_switcher_point); | 421 &page_switcher_point); |
415 page_switcher_view_->UpdateUIForDragPoint(page_switcher_point); | 422 page_switcher_view_->UpdateUIForDragPoint(page_switcher_point); |
416 | 423 |
417 if (last_drop_target != drop_target_) | 424 if (last_drop_target != drop_target_) |
418 AnimateToIdealBounds(); | 425 AnimateToIdealBounds(); |
419 | 426 |
420 drag_view_->SetPosition(drag_view_start_ + drag_vector); | 427 drag_view_->SetPosition(drag_view_start_ + drag_vector); |
(...skipping 20 matching lines...) Expand all Loading... |
441 HideView(drag_view_, false); | 448 HideView(drag_view_, false); |
442 } | 449 } |
443 | 450 |
444 // The drag can be ended after the synchronous drag is created but before it | 451 // The drag can be ended after the synchronous drag is created but before it |
445 // is Run(). | 452 // is Run(). |
446 CleanUpSynchronousDrag(); | 453 CleanUpSynchronousDrag(); |
447 | 454 |
448 drag_pointer_ = NONE; | 455 drag_pointer_ = NONE; |
449 drop_target_ = Index(); | 456 drop_target_ = Index(); |
450 drag_view_ = NULL; | 457 drag_view_ = NULL; |
| 458 drag_start_grid_view_ = gfx::Point(); |
| 459 drag_start_page_ = -1; |
| 460 drag_view_offset_ = gfx::Point(); |
451 AnimateToIdealBounds(); | 461 AnimateToIdealBounds(); |
452 | 462 |
453 StopPageFlipTimer(); | 463 StopPageFlipTimer(); |
454 } | 464 } |
455 | 465 |
456 void AppsGridView::StopPageFlipTimer() { | 466 void AppsGridView::StopPageFlipTimer() { |
457 page_flip_timer_.Stop(); | 467 page_flip_timer_.Stop(); |
458 page_flip_target_ = -1; | 468 page_flip_target_ = -1; |
459 } | 469 } |
460 | 470 |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
891 // For non-aura, root location is not clearly defined but |drag_view_| does | 901 // For non-aura, root location is not clearly defined but |drag_view_| does |
892 // not have the scale transform. So no round error would be introduced and | 902 // not have the scale transform. So no round error would be introduced and |
893 // it's okay to use View::ConvertPointToTarget. | 903 // it's okay to use View::ConvertPointToTarget. |
894 *drag_point = event.location(); | 904 *drag_point = event.location(); |
895 views::View::ConvertPointToTarget(drag_view_, this, drag_point); | 905 views::View::ConvertPointToTarget(drag_view_, this, drag_point); |
896 #endif | 906 #endif |
897 } | 907 } |
898 | 908 |
899 void AppsGridView::CalculateDropTarget(const gfx::Point& drag_point, | 909 void AppsGridView::CalculateDropTarget(const gfx::Point& drag_point, |
900 bool use_page_button_hovering) { | 910 bool use_page_button_hovering) { |
901 const int current_page = pagination_model_->selected_page(); | 911 int current_page = pagination_model_->selected_page(); |
| 912 gfx::Point point(drag_point); |
| 913 if (!IsPointWithinDragBuffer(drag_point)) { |
| 914 point = drag_start_grid_view_; |
| 915 current_page = drag_start_page_; |
| 916 } |
902 | 917 |
903 if (use_page_button_hovering && | 918 if (use_page_button_hovering && |
904 page_switcher_view_->bounds().Contains(drag_point)) { | 919 page_switcher_view_->bounds().Contains(point)) { |
905 gfx::Point page_switcher_point(drag_point); | 920 gfx::Point page_switcher_point(point); |
906 views::View::ConvertPointToTarget(this, page_switcher_view_, | 921 views::View::ConvertPointToTarget(this, page_switcher_view_, |
907 &page_switcher_point); | 922 &page_switcher_point); |
908 int page = page_switcher_view_->GetPageForPoint(page_switcher_point); | 923 int page = page_switcher_view_->GetPageForPoint(page_switcher_point); |
909 if (pagination_model_->is_valid_page(page)) { | 924 if (pagination_model_->is_valid_page(page)) { |
910 drop_target_.page = page; | 925 drop_target_.page = page; |
911 drop_target_.slot = tiles_per_page() - 1; | 926 drop_target_.slot = tiles_per_page() - 1; |
912 } | 927 } |
913 } else { | 928 } else { |
914 const int drop_row = drag_point.y() / kPreferredTileHeight; | 929 const int drop_row = point.y() / kPreferredTileHeight; |
915 const int drop_col = std::min(cols_ - 1, | 930 const int drop_col = std::min(cols_ - 1, |
916 drag_point.x() / kPreferredTileWidth); | 931 point.x() / kPreferredTileWidth); |
917 | 932 |
918 drop_target_.page = current_page; | 933 drop_target_.page = current_page; |
919 drop_target_.slot = std::max(0, std::min( | 934 drop_target_.slot = std::max(0, std::min( |
920 tiles_per_page() - 1, | 935 tiles_per_page() - 1, |
921 drop_row * cols_ + drop_col)); | 936 drop_row * cols_ + drop_col)); |
922 } | 937 } |
923 | 938 |
924 // Limits to the last possible slot on last page. | 939 // Limits to the last possible slot on last page. |
925 if (drop_target_.page == pagination_model_->total_pages() - 1) { | 940 if (drop_target_.page == pagination_model_->total_pages() - 1) { |
926 drop_target_.slot = std::min( | 941 drop_target_.slot = std::min( |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
983 // From now on we forward the drag events. | 998 // From now on we forward the drag events. |
984 forward_events_to_drag_and_drop_host_ = true; | 999 forward_events_to_drag_and_drop_host_ = true; |
985 // Any flip operations are stopped. | 1000 // Any flip operations are stopped. |
986 StopPageFlipTimer(); | 1001 StopPageFlipTimer(); |
987 } | 1002 } |
988 } | 1003 } |
989 } | 1004 } |
990 } | 1005 } |
991 | 1006 |
992 void AppsGridView::MaybeStartPageFlipTimer(const gfx::Point& drag_point) { | 1007 void AppsGridView::MaybeStartPageFlipTimer(const gfx::Point& drag_point) { |
| 1008 if (!IsPointWithinDragBuffer(drag_point)) |
| 1009 StopPageFlipTimer(); |
993 int new_page_flip_target = -1; | 1010 int new_page_flip_target = -1; |
994 | 1011 |
995 if (page_switcher_view_->bounds().Contains(drag_point)) { | 1012 if (page_switcher_view_->bounds().Contains(drag_point)) { |
996 gfx::Point page_switcher_point(drag_point); | 1013 gfx::Point page_switcher_point(drag_point); |
997 views::View::ConvertPointToTarget(this, page_switcher_view_, | 1014 views::View::ConvertPointToTarget(this, page_switcher_view_, |
998 &page_switcher_point); | 1015 &page_switcher_point); |
999 new_page_flip_target = | 1016 new_page_flip_target = |
1000 page_switcher_view_->GetPageForPoint(page_switcher_point); | 1017 page_switcher_view_->GetPageForPoint(page_switcher_point); |
1001 } | 1018 } |
1002 | 1019 |
1003 // TODO(xiyuan): Fix this for RTL. | 1020 // TODO(xiyuan): Fix this for RTL. |
1004 if (new_page_flip_target == -1 && drag_point.x() < kPageFlipZoneSize) | 1021 if (new_page_flip_target == -1 && drag_point.x() < kPageFlipZoneSize) |
1005 new_page_flip_target = pagination_model_->selected_page() - 1; | 1022 new_page_flip_target = pagination_model_->selected_page() - 1; |
1006 | 1023 |
1007 if (new_page_flip_target == -1 && | 1024 if (new_page_flip_target == -1 && |
1008 drag_point.x() > width() - kPageFlipZoneSize) { | 1025 drag_point.x() > width() - kPageFlipZoneSize) { |
1009 new_page_flip_target = pagination_model_->selected_page() + 1; | 1026 new_page_flip_target = pagination_model_->selected_page() + 1; |
1010 } | 1027 } |
1011 | 1028 |
1012 if (new_page_flip_target == page_flip_target_) | 1029 if (new_page_flip_target == page_flip_target_) |
1013 return; | 1030 return; |
1014 | 1031 |
| 1032 StopPageFlipTimer(); |
1015 if (pagination_model_->is_valid_page(new_page_flip_target)) { | 1033 if (pagination_model_->is_valid_page(new_page_flip_target)) { |
1016 page_flip_target_ = new_page_flip_target; | 1034 page_flip_target_ = new_page_flip_target; |
1017 page_flip_timer_.Stop(); | |
1018 | 1035 |
1019 if (page_flip_target_ != pagination_model_->selected_page()) { | 1036 if (page_flip_target_ != pagination_model_->selected_page()) { |
1020 page_flip_timer_.Start(FROM_HERE, | 1037 page_flip_timer_.Start(FROM_HERE, |
1021 base::TimeDelta::FromMilliseconds(page_flip_delay_in_ms_), | 1038 base::TimeDelta::FromMilliseconds(page_flip_delay_in_ms_), |
1022 this, &AppsGridView::OnPageFlipTimer); | 1039 this, &AppsGridView::OnPageFlipTimer); |
1023 } | 1040 } |
1024 } else { | |
1025 page_flip_target_ = -1; | |
1026 page_flip_timer_.Stop(); | |
1027 } | 1041 } |
1028 } | 1042 } |
1029 | 1043 |
1030 void AppsGridView::OnPageFlipTimer() { | 1044 void AppsGridView::OnPageFlipTimer() { |
1031 DCHECK(pagination_model_->is_valid_page(page_flip_target_)); | 1045 DCHECK(pagination_model_->is_valid_page(page_flip_target_)); |
1032 pagination_model_->SelectPage(page_flip_target_, true); | 1046 pagination_model_->SelectPage(page_flip_target_, true); |
1033 } | 1047 } |
1034 | 1048 |
1035 void AppsGridView::MoveItemInModel(views::View* item_view, | 1049 void AppsGridView::MoveItemInModel(views::View* item_view, |
1036 const Index& target) { | 1050 const Index& target) { |
(...skipping 16 matching lines...) Expand all Loading... |
1053 void AppsGridView::CancelContextMenusOnCurrentPage() { | 1067 void AppsGridView::CancelContextMenusOnCurrentPage() { |
1054 int start = pagination_model_->selected_page() * tiles_per_page(); | 1068 int start = pagination_model_->selected_page() * tiles_per_page(); |
1055 int end = std::min(view_model_.view_size(), start + tiles_per_page()); | 1069 int end = std::min(view_model_.view_size(), start + tiles_per_page()); |
1056 for (int i = start; i < end; ++i) { | 1070 for (int i = start; i < end; ++i) { |
1057 AppListItemView* view = | 1071 AppListItemView* view = |
1058 static_cast<AppListItemView*>(view_model_.view_at(i)); | 1072 static_cast<AppListItemView*>(view_model_.view_at(i)); |
1059 view->CancelContextMenu(); | 1073 view->CancelContextMenu(); |
1060 } | 1074 } |
1061 } | 1075 } |
1062 | 1076 |
| 1077 bool AppsGridView::IsPointWithinDragBuffer(const gfx::Point& point) const { |
| 1078 gfx::Rect rect(GetLocalBounds()); |
| 1079 rect.Inset(-kDragBufferPx, -kDragBufferPx, -kDragBufferPx, -kDragBufferPx); |
| 1080 return rect.Contains(point); |
| 1081 } |
| 1082 |
1063 void AppsGridView::ButtonPressed(views::Button* sender, | 1083 void AppsGridView::ButtonPressed(views::Button* sender, |
1064 const ui::Event& event) { | 1084 const ui::Event& event) { |
1065 if (dragging()) | 1085 if (dragging()) |
1066 return; | 1086 return; |
1067 | 1087 |
1068 if (strcmp(sender->GetClassName(), AppListItemView::kViewClassName)) | 1088 if (strcmp(sender->GetClassName(), AppListItemView::kViewClassName)) |
1069 return; | 1089 return; |
1070 | 1090 |
1071 if (delegate_) { | 1091 if (delegate_) { |
1072 delegate_->ActivateApp(static_cast<AppListItemView*>(sender)->model(), | 1092 delegate_->ActivateApp(static_cast<AppListItemView*>(sender)->model(), |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1151 | 1171 |
1152 void AppsGridView::HideView(views::View* view, bool hide) { | 1172 void AppsGridView::HideView(views::View* view, bool hide) { |
1153 #if defined(USE_AURA) | 1173 #if defined(USE_AURA) |
1154 ui::ScopedLayerAnimationSettings animator(view->layer()->GetAnimator()); | 1174 ui::ScopedLayerAnimationSettings animator(view->layer()->GetAnimator()); |
1155 animator.SetPreemptionStrategy(ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); | 1175 animator.SetPreemptionStrategy(ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET); |
1156 view->layer()->SetOpacity(hide ? 0 : 1); | 1176 view->layer()->SetOpacity(hide ? 0 : 1); |
1157 #endif | 1177 #endif |
1158 } | 1178 } |
1159 | 1179 |
1160 } // namespace app_list | 1180 } // namespace app_list |
OLD | NEW |