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

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

Issue 553753003: Rework app list item drag zones. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@fasdaj
Patch Set: 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
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
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 virtual void AnimationCanceled(const gfx::Animation* animation) OVERRIDE { 182 virtual void AnimationCanceled(const gfx::Animation* animation) OVERRIDE {
183 view_->SchedulePaint(); 183 view_->SchedulePaint();
184 } 184 }
185 185
186 private: 186 private:
187 views::View* view_; 187 views::View* view_;
188 188
189 DISALLOW_COPY_AND_ASSIGN(ItemMoveAnimationDelegate); 189 DISALLOW_COPY_AND_ASSIGN(ItemMoveAnimationDelegate);
190 }; 190 };
191 191
192 // Gets the distance between the centers of the |rect_1| and |rect_2|.
193 int GetDistanceBetweenRects(gfx::Rect rect_1,
194 gfx::Rect rect_2) {
195 return (rect_1.CenterPoint() - rect_2.CenterPoint()).Length();
196 }
197
198 // Returns true if the |item| is an folder item. 192 // Returns true if the |item| is an folder item.
199 bool IsFolderItem(AppListItem* item) { 193 bool IsFolderItem(AppListItem* item) {
200 return (item->GetItemType() == AppListFolderItem::kItemType); 194 return (item->GetItemType() == AppListFolderItem::kItemType);
201 } 195 }
202 196
203 bool IsOEMFolderItem(AppListItem* item) { 197 bool IsOEMFolderItem(AppListItem* item) {
204 return IsFolderItem(item) && 198 return IsFolderItem(item) &&
205 (static_cast<AppListFolderItem*>(item))->folder_type() == 199 (static_cast<AppListFolderItem*>(item))->folder_type() ==
206 AppListFolderItem::FOLDER_TYPE_OEM; 200 AppListFolderItem::FOLDER_TYPE_OEM;
207 } 201 }
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
481 Pointer pointer, 475 Pointer pointer,
482 const ui::LocatedEvent& event) { 476 const ui::LocatedEvent& event) {
483 DCHECK(view); 477 DCHECK(view);
484 if (drag_view_ || pulsing_blocks_model_.view_size()) 478 if (drag_view_ || pulsing_blocks_model_.view_size())
485 return; 479 return;
486 480
487 drag_view_ = view; 481 drag_view_ = view;
488 drag_view_init_index_ = GetIndexOfView(drag_view_); 482 drag_view_init_index_ = GetIndexOfView(drag_view_);
489 drag_view_offset_ = event.location(); 483 drag_view_offset_ = event.location();
490 drag_start_page_ = pagination_model_.selected_page(); 484 drag_start_page_ = pagination_model_.selected_page();
485 reorder_placeholder_ = GetIndexOfView(drag_view_);
tapted 2014/09/11 08:08:54 nit: GetIndexOfView(drag_view_); -> drag_view_init
calamity 2014/09/15 03:26:10 Done.
tapted 2014/09/15 06:12:53 missed?
calamity 2014/09/15 06:36:15 Done for real.
491 ExtractDragLocation(event, &drag_start_grid_view_); 486 ExtractDragLocation(event, &drag_start_grid_view_);
492 drag_view_start_ = gfx::Point(drag_view_->x(), drag_view_->y()); 487 drag_view_start_ = gfx::Point(drag_view_->x(), drag_view_->y());
493 } 488 }
494 489
495 void AppsGridView::StartSettingUpSynchronousDrag() { 490 void AppsGridView::StartSettingUpSynchronousDrag() {
496 #if defined(OS_WIN) 491 #if defined(OS_WIN)
497 if (!delegate_ || !use_synchronous_drag_) 492 if (!delegate_ || !use_synchronous_drag_)
498 return; 493 return;
499 494
500 // Folders and downloading items can't be integrated with the OS. 495 // Folders and downloading items can't be integrated with the OS.
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 layer()->SetOpacity(show ? 1.0f : 0.0f); 772 layer()->SetOpacity(show ? 1.0f : 0.0f);
778 } 773 }
779 774
780 void AppsGridView::InitiateDragFromReparentItemInRootLevelGridView( 775 void AppsGridView::InitiateDragFromReparentItemInRootLevelGridView(
781 AppListItemView* original_drag_view, 776 AppListItemView* original_drag_view,
782 const gfx::Rect& drag_view_rect, 777 const gfx::Rect& drag_view_rect,
783 const gfx::Point& drag_point) { 778 const gfx::Point& drag_point) {
784 DCHECK(original_drag_view && !drag_view_); 779 DCHECK(original_drag_view && !drag_view_);
785 DCHECK(!dragging_for_reparent_item_); 780 DCHECK(!dragging_for_reparent_item_);
786 781
782 // Since the item is new, it's placeholder is conceptually at the back of the
tapted 2014/09/11 08:08:54 nit: `it's` -> `its`
calamity 2014/09/15 03:26:09 Done.
783 // entire apps grid.
784 reorder_placeholder_ = GetLastViewIndex();
785
787 // Create a new AppListItemView to duplicate the original_drag_view in the 786 // Create a new AppListItemView to duplicate the original_drag_view in the
788 // folder's grid view. 787 // folder's grid view.
789 AppListItemView* view = new AppListItemView(this, original_drag_view->item()); 788 AppListItemView* view = new AppListItemView(this, original_drag_view->item());
790 AddChildView(view); 789 AddChildView(view);
791 drag_view_ = view; 790 drag_view_ = view;
792 drag_view_->SetPaintToLayer(true); 791 drag_view_->SetPaintToLayer(true);
793 // Note: For testing purpose, SetFillsBoundsOpaquely can be set to true to 792 // Note: For testing purpose, SetFillsBoundsOpaquely can be set to true to
794 // show the gray background. 793 // show the gray background.
795 drag_view_->SetFillsBoundsOpaquely(false); 794 drag_view_->SetFillsBoundsOpaquely(false);
796 drag_view_->SetBoundsRect(drag_view_rect); 795 drag_view_->SetBoundsRect(drag_view_rect);
(...skipping 29 matching lines...) Expand all
826 825
827 bool AppsGridView::IsDraggedView(const views::View* view) const { 826 bool AppsGridView::IsDraggedView(const views::View* view) const {
828 return drag_view_ == view; 827 return drag_view_ == view;
829 } 828 }
830 829
831 void AppsGridView::ClearDragState() { 830 void AppsGridView::ClearDragState() {
832 drop_attempt_ = DROP_FOR_NONE; 831 drop_attempt_ = DROP_FOR_NONE;
833 drag_pointer_ = NONE; 832 drag_pointer_ = NONE;
834 reorder_drop_target_ = Index(); 833 reorder_drop_target_ = Index();
835 folder_drop_target_ = Index(); 834 folder_drop_target_ = Index();
835 reorder_placeholder_ = Index();
836 drag_start_grid_view_ = gfx::Point(); 836 drag_start_grid_view_ = gfx::Point();
837 drag_start_page_ = -1; 837 drag_start_page_ = -1;
838 drag_view_offset_ = gfx::Point(); 838 drag_view_offset_ = gfx::Point();
839 839
840 if (drag_view_) { 840 if (drag_view_) {
841 drag_view_->OnDragEnded(); 841 drag_view_->OnDragEnded();
842 if (IsDraggingForReparentInRootLevelGridView()) { 842 if (IsDraggingForReparentInRootLevelGridView()) {
843 const int drag_view_index = view_model_.GetIndexOfView(drag_view_); 843 const int drag_view_index = view_model_.GetIndexOfView(drag_view_);
844 CHECK_EQ(view_model_.view_size() - 1, drag_view_index); 844 CHECK_EQ(view_model_.view_size() - 1, drag_view_index);
845 DeleteItemViewAtIndex(drag_view_index); 845 DeleteItemViewAtIndex(drag_view_index);
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
1108 } 1108 }
1109 1109
1110 views::View* AppsGridView::GetViewAtIndex(const Index& index) const { 1110 views::View* AppsGridView::GetViewAtIndex(const Index& index) const {
1111 if (!IsValidIndex(index)) 1111 if (!IsValidIndex(index))
1112 return NULL; 1112 return NULL;
1113 1113
1114 const int model_index = GetModelIndexFromIndex(index); 1114 const int model_index = GetModelIndexFromIndex(index);
1115 return view_model_.view_at(model_index); 1115 return view_model_.view_at(model_index);
1116 } 1116 }
1117 1117
1118 AppsGridView::Index AppsGridView::GetLastViewIndex() const {
1119 int view_index = view_model_.view_size() - 1;
tapted 2014/09/11 08:08:53 DCHECK(!view_model_.empty()); .. assuming we can
calamity 2014/09/15 03:26:10 It'll be a shoddy guarantee.. (A component app sho
tapted 2014/09/15 06:12:52 Yep - that's all i'm after really. Since if it is
1120 return Index(view_index / tiles_per_page(), view_index % tiles_per_page());
1121 }
1122
1118 void AppsGridView::MoveSelected(int page_delta, 1123 void AppsGridView::MoveSelected(int page_delta,
1119 int slot_x_delta, 1124 int slot_x_delta,
1120 int slot_y_delta) { 1125 int slot_y_delta) {
1121 if (!selected_view_) 1126 if (!selected_view_)
1122 return SetSelectedItemByIndex(Index(pagination_model_.selected_page(), 0)); 1127 return SetSelectedItemByIndex(Index(pagination_model_.selected_page(), 0));
1123 1128
1124 const Index& selected = GetIndexOfView(selected_view_); 1129 const Index& selected = GetIndexOfView(selected_view_);
1125 int target_slot = selected.slot + slot_x_delta + slot_y_delta * cols_; 1130 int target_slot = selected.slot + slot_x_delta + slot_y_delta * cols_;
1126 1131
1127 if (selected.slot % cols_ == 0 && slot_x_delta == -1) { 1132 if (selected.slot % cols_ == 0 && slot_x_delta == -1) {
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after
1379 // Limits to the last possible slot on last page. 1384 // Limits to the last possible slot on last page.
1380 if (reorder_drop_target_.page == pagination_model_.total_pages() - 1) { 1385 if (reorder_drop_target_.page == pagination_model_.total_pages() - 1) {
1381 reorder_drop_target_.slot = 1386 reorder_drop_target_.slot =
1382 std::min((view_model_.view_size() - 1) % tiles_per_page(), 1387 std::min((view_model_.view_size() - 1) % tiles_per_page(),
1383 reorder_drop_target_.slot); 1388 reorder_drop_target_.slot);
1384 } 1389 }
1385 } 1390 }
1386 1391
1387 1392
1388 void AppsGridView::CalculateDropTargetWithFolderEnabled( 1393 void AppsGridView::CalculateDropTargetWithFolderEnabled(
1389 const gfx::Point& drag_point, 1394 const gfx::Point& drag_point,
tapted 2014/09/11 08:08:53 |drag_point| looks unused now -> remove?
calamity 2014/09/15 03:26:10 Done.
1390 bool use_page_button_hovering) { 1395 bool use_page_button_hovering) {
1391 gfx::Point point(drag_point); 1396 gfx::Point point = drag_view_->icon()->bounds().CenterPoint();
1392 if (!IsPointWithinDragBuffer(drag_point)) { 1397 views::View::ConvertPointToTarget(drag_view_, this, &point);
1393 point = drag_start_grid_view_; 1398 if (!IsPointWithinDragBuffer(point)) {
1399 // Reset the reorder target to the original position if the cursor is
1400 // outside the drag buffer.
1401 if (!IsDraggingForReparentInRootLevelGridView())
1402 reorder_drop_target_ = GetIndexOfView(drag_view_);
tapted 2014/09/11 08:08:53 maybe.. drag_view_init_index_
calamity 2014/09/15 03:26:11 Done.
1403 drop_attempt_ = DROP_FOR_NONE;
1404 return;
1394 } 1405 }
1395 1406
1396 if (use_page_button_hovering && page_switcher_view_ && 1407 if (use_page_button_hovering && page_switcher_view_ &&
1397 page_switcher_view_->bounds().Contains(point)) { 1408 page_switcher_view_->bounds().Contains(point)) {
1398 gfx::Point page_switcher_point(point); 1409 gfx::Point page_switcher_point(point);
1399 views::View::ConvertPointToTarget(this, page_switcher_view_, 1410 views::View::ConvertPointToTarget(this, page_switcher_view_,
1400 &page_switcher_point); 1411 &page_switcher_point);
1401 int page = page_switcher_view_->GetPageForPoint(page_switcher_point); 1412 int page = page_switcher_view_->GetPageForPoint(page_switcher_point);
1402 if (pagination_model_.is_valid_page(page)) 1413 if (pagination_model_.is_valid_page(page))
1403 drop_attempt_ = DROP_FOR_NONE; 1414 drop_attempt_ = DROP_FOR_NONE;
1404 } else { 1415 } else {
tapted 2014/09/11 08:08:54 early return before this. no else.
calamity 2014/09/15 03:26:10 Done.
1405 DCHECK(drag_view_); 1416 DCHECK(drag_view_);
tapted 2014/09/11 08:08:54 move this to the start of the function
calamity 2014/09/15 03:26:09 Done.
1406 // Try to find the nearest target for folder dropping or re-ordering. 1417 const int d_folder_dropping =
tapted 2014/09/11 08:08:55 d looks like an abbreviation - maybe `folder_thres
calamity 2014/09/15 03:26:09 I think this is saying the radius is the distance
tapted 2014/09/15 06:12:52 yep - much nicer
1407 CalculateNearestTileForDragView(); 1418 kFolderDroppingCircleRadius + kGridIconDimension / 2;
1419
1420 Index nearest_tile_index(pagination_model_.selected_page(),
1421 GetNearestTileSlotForPoint(point));
1422
1423 int distance_to_tile_center =
1424 (point - GetExpectedTileBounds(nearest_tile_index.slot).CenterPoint())
1425 .Length();
1426 if (nearest_tile_index != reorder_placeholder_ &&
1427 distance_to_tile_center < d_folder_dropping &&
1428 !IsFolderItem(drag_view_->item()) &&
1429 CanDropIntoTarget(nearest_tile_index)) {
tapted 2014/09/11 08:08:54 CanDropIntoTarget returns true if the drop_target
calamity 2014/09/15 03:26:09 Nope. Fixed.
1430 drop_attempt_ = DROP_FOR_FOLDER;
1431 folder_drop_target_ = nearest_tile_index;
1432 return;
tapted 2014/09/11 08:08:53 there's a lot of state above that isn't used for t
calamity 2014/09/15 03:26:11 Done.
1433 }
1434
1435 gfx::Rect bounds = GetContentsBounds();
1436 // Get coordinates in tile grid space.
1437 int x = point.x() - bounds.x();
1438 int y = point.y() - bounds.y();
1439 int row = y / kPreferredTileHeight;
1440 int grid_col = x / kPreferredTileWidth;
1441 Index grid_index(pagination_model_.selected_page(),
1442 std::min(row * cols_ + grid_col, view_model_.view_size()));
tapted 2014/09/11 08:08:54 This is pretty fiddly... but I don't see an obviou
calamity 2014/09/15 03:26:11 Done.
1443 gfx::Point reorder_placeholder_origin =
1444 GetExpectedTileBounds(reorder_placeholder_.slot).CenterPoint();
1445
1446 int dir = 0;
tapted 2014/09/11 08:08:54 dir isn't a good name - maybe column_offset?
calamity 2014/09/15 03:26:09 Done.
1447 if (grid_index == reorder_placeholder_) {
1448 dir = reorder_placeholder_origin.x() < point.x() ? 1 : -1;
1449 } else {
1450 dir = reorder_placeholder_ < grid_index ? 1 : -1;
1451 }
1452
1453 // Offset the target column base on the direction of the target. This will
tapted 2014/09/11 08:08:54 nit: base->based
calamity 2014/09/15 03:26:09 Done.
1454 // result in earlier targets getting their reorder zone shifted backwards
1455 // and later targets getting their reorder zones shifted forwards.
1456 //
1457 // This causes the animation to trigger when slotting items into the spaces
1458 // between apps.
1459 int col = (x - dir * kPreferredTileWidth / 3) / kPreferredTileWidth;
1460 col = std::min(std::max(col, 0), cols_ - 1);
1461 drop_attempt_ = DROP_FOR_REORDER;
1462 reorder_drop_target_ =
1463 std::min(Index(pagination_model_.selected_page(), row * cols_ + col),
1464 GetLastViewIndex());
1408 } 1465 }
1409 } 1466 }
1410 1467
1411 void AppsGridView::OnReorderTimer() { 1468 void AppsGridView::OnReorderTimer() {
1412 if (drop_attempt_ == DROP_FOR_REORDER) 1469 if (drop_attempt_ == DROP_FOR_REORDER) {
1470 reorder_placeholder_ = reorder_drop_target_;
1413 AnimateToIdealBounds(); 1471 AnimateToIdealBounds();
1472 }
1414 } 1473 }
1415 1474
1416 void AppsGridView::OnFolderItemReparentTimer() { 1475 void AppsGridView::OnFolderItemReparentTimer() {
1417 DCHECK(folder_delegate_); 1476 DCHECK(folder_delegate_);
1418 if (drag_out_of_folder_container_ && drag_view_) { 1477 if (drag_out_of_folder_container_ && drag_view_) {
1419 folder_delegate_->ReparentItem(drag_view_, last_drag_point_); 1478 folder_delegate_->ReparentItem(drag_view_, last_drag_point_);
1420 1479
1421 // Set the flag in the folder's grid view. 1480 // Set the flag in the folder's grid view.
1422 dragging_for_reparent_item_ = true; 1481 dragging_for_reparent_item_ = true;
1423 1482
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after
2033 view->layer()->SetOpacity(hide ? 0 : 1); 2092 view->layer()->SetOpacity(hide ? 0 : 1);
2034 } 2093 }
2035 2094
2036 void AppsGridView::OnImplicitAnimationsCompleted() { 2095 void AppsGridView::OnImplicitAnimationsCompleted() {
2037 if (layer()->opacity() == 0.0f) 2096 if (layer()->opacity() == 0.0f)
2038 SetVisible(false); 2097 SetVisible(false);
2039 } 2098 }
2040 2099
2041 bool AppsGridView::EnableFolderDragDropUI() { 2100 bool AppsGridView::EnableFolderDragDropUI() {
2042 // Enable drag and drop folder UI only if it is at the app list root level 2101 // Enable drag and drop folder UI only if it is at the app list root level
2043 // and the switch is on and the target folder can still accept new items. 2102 // and the switch is on.
2044 return model_->folders_enabled() && !folder_delegate_ && 2103 return model_->folders_enabled() && !folder_delegate_;
2045 CanDropIntoTarget(folder_drop_target_);
tapted 2014/09/11 08:08:54 I don't think this belongs here. I'd always assume
calamity 2014/09/15 03:26:09 Nothing afaict. It was obviously needed for the "c
2046 } 2104 }
2047 2105
2048 bool AppsGridView::CanDropIntoTarget(const Index& drop_target) { 2106 bool AppsGridView::CanDropIntoTarget(const Index& drop_target) {
2049 views::View* target_view = GetViewAtSlotOnCurrentPage(drop_target.slot); 2107 views::View* target_view = GetViewAtSlotOnCurrentPage(drop_target.slot);
2050 if (!target_view) 2108 if (!target_view)
2051 return true; 2109 return true;
2052 2110
2053 AppListItem* target_item = 2111 AppListItem* target_item =
2054 static_cast<AppListItemView*>(target_view)->item(); 2112 static_cast<AppListItemView*>(target_view)->item();
2055 // Items can be dropped into non-folders (which have no children) or folders 2113 // Items can be dropped into non-folders (which have no children) or folders
2056 // that have fewer than the max allowed items. 2114 // that have fewer than the max allowed items.
2057 // OEM folder does not allow to drag/drop other items in it. 2115 // OEM folder does not allow to drag/drop other items in it.
2058 return target_item->ChildItemCount() < kMaxFolderItems && 2116 return target_item->ChildItemCount() < kMaxFolderItems &&
2059 !IsOEMFolderItem(target_item); 2117 !IsOEMFolderItem(target_item);
2060 } 2118 }
2061 2119
2062 // TODO(jennyz): Optimize the calculation for finding nearest tile. 2120 int AppsGridView::GetNearestTileSlotForPoint(const gfx::Point& point) {
2063 void AppsGridView::CalculateNearestTileForDragView() { 2121 gfx::Rect bounds = GetContentsBounds();
tapted 2014/09/11 08:08:54 maybe DCHECK(IsPointWithinDragBuffer(point)); befo
calamity 2014/09/15 03:26:09 Hmm. Unfortunately IsPointWithinDragBuffer include
tapted 2014/09/15 06:12:52 sweet
2064 Index nearest_tile; 2122 int col = (point.x() - bounds.x()) / kPreferredTileWidth;
2065 nearest_tile.page = -1; 2123 int row = (point.y() - bounds.y()) / kPreferredTileHeight;
2066 nearest_tile.slot = -1; 2124 return row * cols_ + col;
2067 int d_min = -1;
2068
2069 // Calculate the top left tile |drag_view| intersects.
2070 gfx::Point pt = drag_view_->bounds().origin();
2071 CalculateNearestTileForVertex(pt, &nearest_tile, &d_min);
2072
2073 // Calculate the top right tile |drag_view| intersects.
2074 pt = drag_view_->bounds().top_right();
2075 CalculateNearestTileForVertex(pt, &nearest_tile, &d_min);
2076
2077 // Calculate the bottom left tile |drag_view| intersects.
2078 pt = drag_view_->bounds().bottom_left();
2079 CalculateNearestTileForVertex(pt, &nearest_tile, &d_min);
2080
2081 // Calculate the bottom right tile |drag_view| intersects.
2082 pt = drag_view_->bounds().bottom_right();
2083 CalculateNearestTileForVertex(pt, &nearest_tile, &d_min);
2084
2085 const int d_folder_dropping =
2086 kFolderDroppingCircleRadius + kGridIconDimension / 2;
2087 const int d_reorder = kReorderDroppingCircleRadius + kGridIconDimension / 2;
2088
2089 // If user drags an item across pages to the last page, and targets it
2090 // to the last empty slot on it, push the last item for re-ordering.
2091 if (IsLastPossibleDropTarget(nearest_tile) && d_min < d_reorder) {
2092 drop_attempt_ = DROP_FOR_REORDER;
2093 nearest_tile.slot = nearest_tile.slot - 1;
2094 reorder_drop_target_ = nearest_tile;
2095 return;
2096 }
2097
2098 if (IsValidIndex(nearest_tile)) {
2099 if (d_min < d_folder_dropping) {
2100 views::View* target_view = GetViewAtSlotOnCurrentPage(nearest_tile.slot);
2101 if (target_view &&
2102 !IsFolderItem(static_cast<AppListItemView*>(drag_view_)->item())) {
2103 // If a non-folder item is dragged to the target slot with an item
2104 // sitting on it, attempt to drop the dragged item into the folder
2105 // containing the item on nearest_tile.
2106 drop_attempt_ = DROP_FOR_FOLDER;
2107 folder_drop_target_ = nearest_tile;
2108 return;
2109 } else {
2110 // If the target slot is blank, or the dragged item is a folder, attempt
2111 // to re-order.
2112 drop_attempt_ = DROP_FOR_REORDER;
2113 reorder_drop_target_ = nearest_tile;
2114 return;
2115 }
2116 } else if (d_min < d_reorder) {
2117 // Entering the re-order circle of the slot.
2118 drop_attempt_ = DROP_FOR_REORDER;
2119 reorder_drop_target_ = nearest_tile;
2120 return;
2121 }
2122 }
2123
2124 // If |drag_view| is not entering the re-order or fold dropping region of
2125 // any items, cancel any previous re-order or folder dropping timer.
2126 drop_attempt_ = DROP_FOR_NONE;
2127 reorder_timer_.Stop();
2128 folder_dropping_timer_.Stop();
2129
2130 // When dragging for reparent a folder item, it should go back to its parent
2131 // folder item if there is no drop target.
2132 if (IsDraggingForReparentInRootLevelGridView()) {
2133 DCHECK(activated_folder_item_view_);
2134 folder_drop_target_ = GetIndexOfView(activated_folder_item_view_);
2135 }
2136 }
2137
2138 void AppsGridView::CalculateNearestTileForVertex(const gfx::Point& vertex,
2139 Index* nearest_tile,
2140 int* d_min) {
2141 Index target_index;
2142 gfx::Rect target_bounds = GetTileBoundsForPoint(vertex, &target_index);
2143
2144 if (target_bounds.IsEmpty() || target_index == *nearest_tile)
2145 return;
2146
2147 // Do not count the tile, where drag_view_ used to sit on and is still moving
2148 // on top of it, in calculating nearest tile for drag_view_.
2149 views::View* target_view = GetViewAtSlotOnCurrentPage(target_index.slot);
2150 if (target_index == drag_view_init_index_ && !target_view &&
2151 !IsDraggingForReparentInRootLevelGridView()) {
2152 return;
2153 }
2154
2155 int d_center = GetDistanceBetweenRects(drag_view_->bounds(), target_bounds);
2156 if (*d_min < 0 || d_center < *d_min) {
2157 *d_min = d_center;
2158 *nearest_tile = target_index;
2159 }
2160 }
2161
2162 gfx::Rect AppsGridView::GetTileBoundsForPoint(const gfx::Point& point,
2163 Index *tile_index) {
2164 // Check if |point| is outside of contents bounds.
2165 gfx::Rect bounds(GetContentsBounds());
2166 if (!bounds.Contains(point))
2167 return gfx::Rect();
2168
2169 // Calculate which tile |point| is enclosed in.
2170 int x = point.x();
2171 int y = point.y();
2172 int col = (x - bounds.x()) / kPreferredTileWidth;
2173 int row = (y - bounds.y()) / kPreferredTileHeight;
2174 gfx::Rect tile_rect = GetExpectedTileBounds(row, col);
2175
2176 // Check if |point| is outside a valid item's tile.
2177 Index index(pagination_model_.selected_page(), row * cols_ + col);
2178 *tile_index = index;
2179 return tile_rect;
2180 } 2125 }
2181 2126
2182 gfx::Size AppsGridView::GetTileGridSize() const { 2127 gfx::Size AppsGridView::GetTileGridSize() const {
2183 gfx::Rect bounds = GetExpectedTileBounds(0, 0); 2128 gfx::Rect bounds = GetExpectedTileBounds(0, 0);
2184 bounds.Union(GetExpectedTileBounds(rows_per_page_ - 1, cols_ - 1)); 2129 bounds.Union(GetExpectedTileBounds(rows_per_page_ - 1, cols_ - 1));
2185 return bounds.size(); 2130 return bounds.size();
2186 } 2131 }
2187 2132
2133 gfx::Rect AppsGridView::GetExpectedTileBounds(int slot) const {
2134 return GetExpectedTileBounds(slot / cols_, slot % cols_);
2135 }
2136
2188 gfx::Rect AppsGridView::GetExpectedTileBounds(int row, int col) const { 2137 gfx::Rect AppsGridView::GetExpectedTileBounds(int row, int col) const {
2189 gfx::Rect bounds(GetContentsBounds()); 2138 gfx::Rect bounds(GetContentsBounds());
2190 gfx::Size tile_size(kPreferredTileWidth, kPreferredTileHeight); 2139 gfx::Size tile_size(kPreferredTileWidth, kPreferredTileHeight);
2191 return gfx::Rect(gfx::Point(bounds.x() + col * tile_size.width(), 2140 return gfx::Rect(gfx::Point(bounds.x() + col * tile_size.width(),
2192 bounds.y() + row * tile_size.height()), 2141 bounds.y() + row * tile_size.height()),
2193 tile_size); 2142 tile_size);
2194 } 2143 }
2195 2144
2196 bool AppsGridView::IsLastPossibleDropTarget(const Index& index) const {
2197 int last_possible_slot = view_model_.view_size() % tiles_per_page();
2198 return (index.page == pagination_model_.total_pages() - 1 &&
2199 index.slot == last_possible_slot + 1);
2200 }
2201
2202 views::View* AppsGridView::GetViewAtSlotOnCurrentPage(int slot) { 2145 views::View* AppsGridView::GetViewAtSlotOnCurrentPage(int slot) {
2203 if (slot < 0) 2146 if (slot < 0)
2204 return NULL; 2147 return NULL;
2205 2148
2206 // Calculate the original bound of the tile at |index|. 2149 // Calculate the original bound of the tile at |index|.
2207 int row = slot / cols_; 2150 int row = slot / cols_;
2208 int col = slot % cols_; 2151 int col = slot % cols_;
2209 gfx::Rect tile_rect = GetExpectedTileBounds(row, col); 2152 gfx::Rect tile_rect = GetExpectedTileBounds(row, col);
2210 2153
2211 for (int i = 0; i < view_model_.view_size(); ++i) { 2154 for (int i = 0; i < view_model_.view_size(); ++i) {
2212 views::View* view = view_model_.view_at(i); 2155 views::View* view = view_model_.view_at(i);
2213 if (view->bounds() == tile_rect && view != drag_view_) 2156 if (view->bounds() == tile_rect && view != drag_view_)
2214 return view; 2157 return view;
2215 } 2158 }
2216 return NULL; 2159 return NULL;
2217 } 2160 }
2218 2161
2219 void AppsGridView::SetAsFolderDroppingTarget(const Index& target_index, 2162 void AppsGridView::SetAsFolderDroppingTarget(const Index& target_index,
2220 bool is_target_folder) { 2163 bool is_target_folder) {
2221 AppListItemView* target_view = 2164 AppListItemView* target_view =
2222 static_cast<AppListItemView*>( 2165 static_cast<AppListItemView*>(
2223 GetViewAtSlotOnCurrentPage(target_index.slot)); 2166 GetViewAtSlotOnCurrentPage(target_index.slot));
2224 if (target_view) 2167 if (target_view)
2225 target_view->SetAsAttemptedFolderTarget(is_target_folder); 2168 target_view->SetAsAttemptedFolderTarget(is_target_folder);
2226 } 2169 }
2227 2170
2228 } // namespace app_list 2171 } // namespace app_list
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698