Commit eaae121b authored by calamity's avatar calamity Committed by Commit bot

Fix app list duplication on drag.

This CL fixes a bug where drop targets were not being calculated correctly
which led to duplication on reparents.

BUG=415530
TEST=Drag an app from inside a folder onto the page switcher. The app
should disappear from the folder and appear in the root grid.

Review URL: https://codereview.chromium.org/583263004

Cr-Commit-Position: refs/heads/master@{#296125}
parent 1170aa08
......@@ -264,12 +264,9 @@ TEST_F(AppListMainViewTest, DragLastItemFromFolderAndDropAtLastSlot) {
drop_target_tile.Offset(first_slot_tile.width() * 2, 0);
gfx::Point point = drop_target_tile.CenterPoint();
SimulateUpdateDrag(FolderGridView(), AppsGridView::MOUSE, dragged, point);
SimulateUpdateDrag(FolderGridView(), AppsGridView::MOUSE, dragged, point);
base::RunLoop().RunUntilIdle();
// Drop it.
FolderGridView()->EndDrag(false);
base::RunLoop().RunUntilIdle();
// Folder icon view should be gone and there is only one item view.
EXPECT_EQ(1, RootViewModel()->view_size());
......@@ -286,6 +283,35 @@ TEST_F(AppListMainViewTest, DragLastItemFromFolderAndDropAtLastSlot) {
delegate_->GetTestModel()->FindFolderItem("single_item_folder"));
}
// Tests dragging an item out of a single item folder and dropping it onto the
// page switcher. Regression test for http://crbug.com/415530/.
TEST_F(AppListMainViewTest, DragReparentItemOntoPageSwitcher) {
AppListItemView* folder_item_view = CreateAndOpenSingleItemFolder();
const gfx::Rect first_slot_tile = folder_item_view->bounds();
delegate_->GetTestModel()->PopulateApps(20);
EXPECT_EQ(1, FolderViewModel()->view_size());
EXPECT_EQ(21, RootViewModel()->view_size());
AppListItemView* dragged = StartDragForReparent(0);
gfx::Rect main_view_bounds = main_view_->bounds();
// Drag the reparent item to the page switcher.
gfx::Point point =
gfx::Point(main_view_bounds.width() / 2,
main_view_bounds.bottom() - first_slot_tile.height());
SimulateUpdateDrag(FolderGridView(), AppsGridView::MOUSE, dragged, point);
// Drop it.
FolderGridView()->EndDrag(false);
// The folder should be destroyed.
EXPECT_EQ(21, RootViewModel()->view_size());
EXPECT_EQ(NULL,
delegate_->GetTestModel()->FindFolderItem("single_item_folder"));
}
// Test that an interrupted drag while reparenting an item from a folder, when
// canceled via the root grid, correctly forwards the cancelation to the drag
// ocurring from the folder.
......
......@@ -1401,6 +1401,7 @@ bool AppsGridView::CalculateFolderDropTarget(const gfx::Point& point,
!IsFolderItem(drag_view_->item()) &&
CanDropIntoTarget(nearest_tile_index)) {
*drop_target = nearest_tile_index;
DCHECK(IsValidIndex(*drop_target));
return true;
}
......@@ -1437,6 +1438,7 @@ void AppsGridView::CalculateReorderDropTarget(const gfx::Point& point,
*drop_target =
std::min(Index(pagination_model_.selected_page(), row * cols_ + col),
GetLastViewIndex());
DCHECK(IsValidIndex(*drop_target));
}
void AppsGridView::OnReorderTimer() {
......@@ -1551,6 +1553,8 @@ void AppsGridView::EndDragFromReparentItemInRootLevel(
} else if (drop_attempt_ == DROP_FOR_FOLDER &&
IsValidIndex(folder_drop_target_)) {
ReparentItemToAnotherFolder(drag_view_, folder_drop_target_);
} else {
NOTREACHED();
}
SetViewHidden(drag_view_, false /* show */, true /* no animate */);
}
......@@ -2096,9 +2100,10 @@ AppsGridView::Index AppsGridView::GetNearestTileIndexForPoint(
gfx::Rect bounds = GetContentsBounds();
gfx::Size total_tile_size = GetTotalTileSize();
int col = ClampToRange(
(point.x() - bounds.x()) / total_tile_size.width(), 0, cols_);
int row = ClampToRange(
(point.y() - bounds.y()) / total_tile_size.height(), 0, rows_per_page_);
(point.x() - bounds.x()) / total_tile_size.width(), 0, cols_ - 1);
int row = ClampToRange((point.y() - bounds.y()) / total_tile_size.height(),
0,
rows_per_page_ - 1);
return Index(pagination_model_.selected_page(), row * cols_ + col);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment