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

Unified Diff: ui/app_list/views/apps_grid_view.cc

Issue 136303008: Implement ui for re-parenting an item from an app list folder to another position or folder in the … (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address review comments. Created 6 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/app_list/views/apps_grid_view.h ('k') | ui/app_list/views/contents_view.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/app_list/views/apps_grid_view.cc
diff --git a/ui/app_list/views/apps_grid_view.cc b/ui/app_list/views/apps_grid_view.cc
index d371ed90cf3fcde99ec0346fef9ec865d881b169..5625c6d4ad0626093849bbf1aff6338f9f471d00 100644
--- a/ui/app_list/views/apps_grid_view.cc
+++ b/ui/app_list/views/apps_grid_view.cc
@@ -21,6 +21,7 @@
#include "ui/app_list/views/apps_grid_view_delegate.h"
#include "ui/app_list/views/page_switcher.h"
#include "ui/app_list/views/pulsing_block_view.h"
+#include "ui/app_list/views/top_icon_animation_view.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/events/event.h"
#include "ui/gfx/animation/animation.h"
@@ -86,6 +87,9 @@ const int kFolderDroppingDelay = 250;
// Delays in milliseconds to show re-order preview.
const int kReorderDelay = 50;
+// Delays in milliseconds to show folder item reparent UI.
+const int kFolderItemReparentDealy = 50;
+
// Radius of the circle, in which if entered, show folder dropping preview
// UI.
const int kFolderDroppingCircleRadius = 15;
@@ -316,7 +320,8 @@ AppsGridView::AppsGridView(AppsGridViewDelegate* delegate,
page_flip_delay_in_ms_(kPageFlipDelayInMs),
bounds_animator_(this),
is_root_level_(true),
- activated_item_view_(NULL) {
+ activated_item_view_(NULL),
+ dragging_for_reparent_item_(false) {
SetPaintToLayer(true);
SetFillsBoundsOpaquely(false);
@@ -478,6 +483,9 @@ void AppsGridView::UpdateDragFromItem(Pointer pointer,
const ui::LocatedEvent& event) {
DCHECK(drag_view_);
+ if (!is_root_level_)
+ UpdateDragStateInsideFolder(pointer, event);
+
gfx::Point drag_point_in_grid_view;
ExtractDragLocation(event, &drag_point_in_grid_view);
UpdateDrag(pointer, drag_point_in_grid_view);
@@ -508,7 +516,8 @@ void AppsGridView::UpdateDrag(Pointer pointer, const gfx::Point& point) {
ReorderChildView(drag_view_, -1);
bounds_animator_.StopAnimatingView(drag_view_);
StartSettingUpSynchronousDrag();
- StartDragAndDropHostDrag(point);
+ if (!dragging_for_reparent_item_)
+ StartDragAndDropHostDrag(point);
}
if (drag_pointer_ != pointer)
@@ -562,21 +571,36 @@ void AppsGridView::EndDrag(bool cancel) {
// EndDrag was called before if |drag_view_| is NULL.
if (!drag_view_)
return;
+
// Coming here a drag and drop was in progress.
bool landed_in_drag_and_drop_host = forward_events_to_drag_and_drop_host_;
if (forward_events_to_drag_and_drop_host_) {
+ DCHECK(!IsDraggingForReparentInRootLevelGridView());
forward_events_to_drag_and_drop_host_ = false;
drag_and_drop_host_->EndDrag(cancel);
+ if (IsDraggingForReprentInHiddenGridView()) {
+ static_cast<AppListFolderView*>(parent())->
+ DispatchEndDragEventForReparent(true);
+ }
} else if (!cancel && dragging()) {
- CalculateDropTarget(last_drag_point_, true);
- if (IsValidIndex(drop_target_)) {
- if (!EnableFolderDragDropUI()) {
- MoveItemInModel(drag_view_, drop_target_);
- } else {
- if (drop_attempt_ == DROP_FOR_REORDER)
- MoveItemInModel(drag_view_, drop_target_);
- else if (drop_attempt_ == DROP_FOR_FOLDER)
- MoveItemToFolder(drag_view_, drop_target_);
+ if (IsDraggingForReprentInHiddenGridView()) {
+ // Forward the EndDrag event to the root level grid view.
+ static_cast<AppListFolderView*>(parent())->
+ DispatchEndDragEventForReparent(false);
+ EndDragForReparentInHiddenFolderGridView();
+ return;
+ } else {
+ // Regular drag ending path, ie, not for reparenting.
+ CalculateDropTarget(last_drag_point_, true);
+ if (IsValidIndex(drop_target_)) {
+ if (!EnableFolderDragDropUI()) {
+ MoveItemInModel(drag_view_, drop_target_);
+ } else {
+ if (drop_attempt_ == DROP_FOR_REORDER)
+ MoveItemInModel(drag_view_, drop_target_);
+ else if (drop_attempt_ == DROP_FOR_FOLDER)
+ MoveItemToFolder(drag_view_, drop_target_);
+ }
}
}
}
@@ -594,8 +618,8 @@ void AppsGridView::EndDrag(bool cancel) {
}
// Fade in slowly if it landed in the shelf.
SetViewHidden(drag_view_,
- false /* hide */,
- !landed_in_drag_and_drop_host /* animate */);
+ false /* show */,
+ !landed_in_drag_and_drop_host /* animate */);
}
// The drag can be ended after the synchronous drag is created but before it
@@ -611,9 +635,18 @@ void AppsGridView::EndDrag(bool cancel) {
drag_start_grid_view_ = gfx::Point();
drag_start_page_ = -1;
drag_view_offset_ = gfx::Point();
+ if (IsDraggingForReprentInHiddenGridView())
+ dragging_for_reparent_item_ = false;
AnimateToIdealBounds();
StopPageFlipTimer();
+
+ // If user releases mouse inside a folder's grid view, burst the folder
+ // container ink bubble.
+ if (!is_root_level_ && !IsDraggingForReprentInHiddenGridView()) {
+ static_cast<AppListFolderView*>(parent())->
+ UpdateFolderViewBackground(false);
+ }
}
void AppsGridView::StopPageFlipTimer() {
@@ -650,6 +683,54 @@ void AppsGridView::ScheduleShowHideAnimation(bool show) {
layer()->SetOpacity(show ? 1.0f : 0.0f);
}
+void AppsGridView::InitiateDragFromReparentItemInRootLevelGridView(
+ AppListItemView* original_drag_view,
+ const gfx::Rect& drag_view_rect,
+ const gfx::Point& drag_point) {
+ DCHECK(original_drag_view && !drag_view_);
+ DCHECK(!dragging_for_reparent_item_);
+
+ // Create a new AppListItemView to duplicate the original_drag_view in the
+ // folder's grid view.
+ AppListItemView* view = new AppListItemView(this, original_drag_view->item());
+ AddChildView(view);
+ drag_view_ = view;
+ drag_view_->SetPaintToLayer(true);
+ // Note: For testing purpose, SetFillsBoundsOpaquely can be set to true to
+ // show the gray background.
+ drag_view_->SetFillsBoundsOpaquely(false);
+ drag_view_->SetIconSize(icon_size_);
+ drag_view_->SetBoundsRect(drag_view_rect);
+ drag_view_->SetDragUIState(); // Hide the title of the drag_view_.
+
+ // Hide the drag_view_ for drag icon proxy.
+ SetViewHidden(drag_view_,
+ true /* hide */,
+ true /* no animate */);
+
+ // Add drag_view_ to the end of the view_model_.
+ view_model_.Add(drag_view_, view_model_.view_size());
+
+ drag_start_page_ = pagination_model_->selected_page();
+ drag_start_grid_view_ = drag_point;
+
+ drag_view_start_ = gfx::Point(drag_view_->x(), drag_view_->y());
+
+ // Set the flag in root level grid view.
+ dragging_for_reparent_item_ = true;
+}
+
+void AppsGridView::UpdateDragFromReparentItem(
+ Pointer pointer,
+ const ui::LocatedEvent& event) {
+ DCHECK(drag_view_);
+ DCHECK(IsDraggingForReparentInRootLevelGridView());
+
+ gfx::Point drag_point_in_grid_view;
+ ExtractDragLocation(event, &drag_point_in_grid_view);
+ UpdateDrag(pointer, drag_point_in_grid_view);
+}
+
bool AppsGridView::IsDraggedView(const views::View* view) const {
return drag_view_ == view;
}
@@ -1202,11 +1283,173 @@ void AppsGridView::OnReorderTimer() {
AnimateToIdealBounds();
}
+void AppsGridView::OnFolderItemReparentTimer() {
+ DCHECK(!is_root_level_);
+ if (drag_out_of_folder_container_) {
+ static_cast<AppListFolderView*>(parent())->ReparentItem(
+ drag_view_, last_drag_point_);
+
+ // Set the flag in the folder's grid view.
+ dragging_for_reparent_item_ = true;
+
+ // Do not observe any data change since it is going to be hidden.
+ item_list_->RemoveObserver(this);
+ item_list_ = NULL;
+ }
+}
+
void AppsGridView::OnFolderDroppingTimer() {
if (drop_attempt_ == DROP_FOR_FOLDER)
SetAsFolderDroppingTarget(drop_target_, true);
}
+void AppsGridView::UpdateDragStateInsideFolder(
+ Pointer pointer,
+ const ui::LocatedEvent& event) {
+ if (IsDraggingForReprentInHiddenGridView()) {
+ // Dispatch drag event to root level grid view for re-parenting folder
+ // folder item purpose.
+ DispatchDragEventForReparent(pointer, event);
+ return;
+ }
+
+ // Regular drag and drop in a folder's grid view.
+ AppListFolderView* folder_view = static_cast<AppListFolderView*>(parent());
+ folder_view->UpdateFolderViewBackground(true);
+
+ // Calculate if the drag_view_ is dragged out of the folder's container
+ // ink bubble.
+ gfx::Rect bounds_to_folder_view = ConvertRectToParent(drag_view_->bounds());
+ gfx::Point pt = bounds_to_folder_view.CenterPoint();
+ bool is_item_dragged_out_of_folder =
+ folder_view->IsPointOutsideOfFolderBoundray(pt);
+ if (is_item_dragged_out_of_folder) {
+ if (!drag_out_of_folder_container_) {
+ folder_item_reparent_timer_.Start(FROM_HERE,
+ base::TimeDelta::FromMilliseconds(kFolderItemReparentDealy),
+ this, &AppsGridView::OnFolderItemReparentTimer);
+ drag_out_of_folder_container_ = true;
+ }
+ } else {
+ folder_item_reparent_timer_.Stop();
+ drag_out_of_folder_container_ = false;
+ }
+}
+
+bool AppsGridView::IsDraggingForReparentInRootLevelGridView() const {
+ return (is_root_level_ && dragging_for_reparent_item_);
+}
+
+bool AppsGridView::IsDraggingForReprentInHiddenGridView() const {
+ return (!is_root_level_ && dragging_for_reparent_item_);
+}
+
+gfx::Rect AppsGridView::GetTargetIconRectInFolder(
+ AppListItemView* drag_item_view,
+ AppListItemView* folder_item_view) {
+ gfx::Rect view_ideal_bounds = view_model_.ideal_bounds(
+ view_model_.GetIndexOfView(folder_item_view));
+ gfx::Rect icon_ideal_bounds =
+ folder_item_view->GetIconBoundsForTargetViewBounds(view_ideal_bounds);
+ AppListFolderItem* folder_item =
+ static_cast<AppListFolderItem*>(folder_item_view->item());
+ return folder_item->GetTargetIconRectInFolderForItem(
+ drag_item_view->item(), icon_ideal_bounds);
+}
+
+void AppsGridView::DispatchDragEventForReparent(
+ Pointer pointer,
+ const ui::LocatedEvent& event) {
+ static_cast<AppListFolderView*>(parent())->
+ DispatchDragEventForReparent(pointer, event);
+}
+
+void AppsGridView::EndDragFromReparentItemInRootLevel(
+ bool events_forwarded_to_drag_drop_host) {
+ // EndDrag was called before if |drag_view_| is NULL.
+ if (!drag_view_)
+ return;
+
+ DCHECK(IsDraggingForReparentInRootLevelGridView());
+ bool cancel_reparent = false;
+ scoped_ptr<AppListItemView> cached_drag_view;
+ if (!events_forwarded_to_drag_drop_host) {
+ CalculateDropTarget(last_drag_point_, true);
+ if (IsValidIndex(drop_target_)) {
+ if (drop_attempt_ == DROP_FOR_REORDER)
+ ReparentItemForReorder(drag_view_, drop_target_);
+ else if (drop_attempt_ == DROP_FOR_FOLDER)
+ ReparentItemToAnotherFolder(drag_view_, drop_target_);
+ else { // DROP_FOR_NONE_
+ cancel_reparent = true;
+ // Note(jennyz): cached_drag_view makes sure drag_view_ will be deleted
+ // after AnimateToIdealBounds() is called.
+ // There is a problem in layer() animation which cause DCHECK failure
+ // if a child view is deleted immediately before re-creating layer in
+ // layer animation. The layer tree seems marked dirty, and complaining
+ // when we try to re-create layer in AnimationBetweenRows when calling
+ // AnimateToIdealBounds.
+ cached_drag_view.reset(drag_view_);
+ }
+ }
+
+ if (!cancel_reparent) {
+ SetViewHidden(drag_view_,
+ false /* show */,
+ true /* no animate */);
+ }
+ }
+
+ // The drag can be ended after the synchronous drag is created but before it
+ // is Run().
+ CleanUpSynchronousDrag();
+
+ SetAsFolderDroppingTarget(drop_target_, false);
+ drop_attempt_ = DROP_FOR_NONE;
+ drag_pointer_ = NONE;
+ drop_target_ = Index();
+ if (!cancel_reparent)
+ drag_view_->OnDragEnded();
+ drag_view_ = NULL;
+ drag_start_grid_view_ = gfx::Point();
+ drag_start_page_ = -1;
+ drag_view_offset_ = gfx::Point();
+ dragging_for_reparent_item_ = false;
+ if (cancel_reparent)
+ CancelFolderItemReparent(cached_drag_view.get());
+ AnimateToIdealBounds();
+
+ StopPageFlipTimer();
+}
+
+void AppsGridView::EndDragForReparentInHiddenFolderGridView() {
+ if (drag_and_drop_host_) {
+ // If we had a drag and drop proxy icon, we delete it and make the real
+ // item visible again.
+ drag_and_drop_host_->DestroyDragIconProxy();
+ }
+
+ // The drag can be ended after the synchronous drag is created but before it
+ // is Run().
+ CleanUpSynchronousDrag();
+
+ SetAsFolderDroppingTarget(drop_target_, false);
+ drop_attempt_ = DROP_FOR_NONE;
+ drag_pointer_ = NONE;
+ drop_target_ = Index();
+ drag_view_->OnDragEnded();
+ drag_view_ = NULL;
+ drag_start_grid_view_ = gfx::Point();
+ drag_start_page_ = -1;
+ drag_view_offset_ = gfx::Point();
+ dragging_for_reparent_item_ = false;
+}
+
+void AppsGridView::OnFolderItemRemoved() {
+ DCHECK(!is_root_level_);
+ item_list_ = NULL;
+}
+
void AppsGridView::StartDragAndDropHostDrag(const gfx::Point& grid_location) {
// When a drag and drop host is given, the item can be dragged out of the app
// list window. In that case a proxy widget needs to be used.
@@ -1226,6 +1469,7 @@ void AppsGridView::StartDragAndDropHostDrag(const gfx::Point& grid_location) {
// We have to hide the original item since the drag and drop host will do
// the OS dependent code to "lift off the dragged item".
+ DCHECK(!IsDraggingForReparentInRootLevelGridView());
drag_and_drop_host_->CreateDragIconProxy(screen_location,
drag_view_->item()->icon(),
drag_view_,
@@ -1240,7 +1484,8 @@ void AppsGridView::DispatchDragEventToDragAndDropHost(
const gfx::Point& location_in_screen_coordinates) {
if (!drag_view_ || !drag_and_drop_host_)
return;
- if (bounds().Contains(last_drag_point_)) {
+
+ if (GetLocalBounds().Contains(last_drag_point_)) {
// The event was issued inside the app menu and we should get all events.
if (forward_events_to_drag_and_drop_host_) {
// The DnD host was previously called and needs to be informed that the
@@ -1331,30 +1576,33 @@ void AppsGridView::MoveItemInModel(views::View* item_view,
void AppsGridView::MoveItemToFolder(views::View* item_view,
const Index& target) {
- const std::string& source_id =
+ const std::string& source_item_id =
static_cast<AppListItemView*>(item_view)->item()->id();
AppListItemView* target_view =
static_cast<AppListItemView*>(GetViewAtSlotOnCurrentPage(target.slot));
- const std::string& target_id = target_view->item()->id();
+ const std::string& target_view_item_id = target_view->item()->id();
// Make change to data model.
item_list_->RemoveObserver(this);
- std::string folder_id = model_->MergeItems(target_id, source_id);
+
+ std::string folder_item_id =
+ model_->MergeItems(target_view_item_id, source_item_id);
item_list_->AddObserver(this);
- if (folder_id != target_id) {
+ if (folder_item_id != target_view_item_id) {
// New folder was created, change the view model to replace the old target
// view with the new folder item view.
- size_t folder_index;
- if (item_list_->FindItemIndex(folder_id, &folder_index)) {
- int target_index = view_model_.GetIndexOfView(target_view);
- view_model_.Remove(target_index);
+ size_t folder_item_index;
+ if (item_list_->FindItemIndex(folder_item_id, &folder_item_index)) {
+ int target_view_index = view_model_.GetIndexOfView(target_view);
+ view_model_.Remove(target_view_index);
delete target_view;
- views::View* target_folder_view = CreateViewForItemAtIndex(folder_index);
- view_model_.Add(target_folder_view, target_index);
+ views::View* target_folder_view =
+ CreateViewForItemAtIndex(folder_item_index);
+ view_model_.Add(target_folder_view, target_view_index);
AddChildView(target_folder_view);
} else {
- LOG(ERROR) << "Folder no longer in item_list: " << folder_id;
+ LOG(ERROR) << "Folder no longer in item_list: " << folder_item_id;
}
}
@@ -1364,10 +1612,141 @@ void AppsGridView::MoveItemToFolder(views::View* item_view,
bounds_animator_.AnimateViewTo(drag_view_, drag_view_->bounds());
bounds_animator_.SetAnimationDelegate(
drag_view_, new ItemRemoveAnimationDelegate(drag_view_), true);
+ UpdatePaging();
+}
+
+void AppsGridView::ReparentItemForReorder(views::View* item_view,
+ const Index& target) {
+ item_list_->RemoveObserver(this);
+ model_->RemoveObserver(this);
+
+ AppListItem* reparent_item = static_cast<AppListItemView*>(item_view)->item();
+ DCHECK(reparent_item->IsInFolder());
+ AppListFolderItem* source_folder = static_cast<AppListFolderItem*>(
+ item_list_->FindItem(reparent_item->folder_id()));
+ // Move the item from its parent folder to top level item list.
+ // Must move to target_model_index, the location we expect the target item
+ // to be, not the item location we want to insert before.
+ int target_model_index = GetModelIndexFromIndex(target);
+ int current_model_index = view_model_.GetIndexOfView(item_view);
+ syncer::StringOrdinal target_position;
+ if (target_model_index < static_cast<int>(item_list_->item_count()))
+ target_position = item_list_->item_at(target_model_index)->position();
+ model_->MoveItemToFolderAt(reparent_item, "", target_position);
+ view_model_.Move(current_model_index, target_model_index);
+
+ if (source_folder->ChildItemCount() == 1)
+ RemoveLastItemFromReparentItemFolder(source_folder);
+
+ item_list_->AddObserver(this);
+ model_->AddObserver(this);
UpdatePaging();
}
+void AppsGridView::ReparentItemToAnotherFolder(views::View* item_view,
+ const Index& target) {
+ DCHECK(IsDraggingForReparentInRootLevelGridView());
+
+ // Make change to data model.
+ item_list_->RemoveObserver(this);
+
+ AppListItem* reparent_item = static_cast<AppListItemView*>(item_view)->item();
+ DCHECK(reparent_item->IsInFolder());
+ AppListFolderItem* source_folder = static_cast<AppListFolderItem*>(
+ item_list_->FindItem(reparent_item->folder_id()));
+
+ AppListItemView* target_view =
+ static_cast<AppListItemView*>(GetViewAtSlotOnCurrentPage(target.slot));
+ AppListItem* target_item = target_view->item();
+
+ // Move item to the target folder.
+ const std::string& target_id_after_merge =
+ model_->MergeItems(target_item->id(), reparent_item->id());
+
+ if (target_id_after_merge != target_item->id()) {
+ // New folder was created, change the view model to replace the old target
+ // view with the new folder item view.
+ const std::string& new_folder_id = reparent_item->folder_id();
+ size_t new_folder_index;
+ if (item_list_->FindItemIndex(new_folder_id, &new_folder_index)) {
+ int target_view_index = view_model_.GetIndexOfView(target_view);
+ view_model_.Remove(target_view_index);
+ delete target_view;
+ views::View* new_folder_view =
+ CreateViewForItemAtIndex(new_folder_index);
+ view_model_.Add(new_folder_view, target_view_index);
+ AddChildView(new_folder_view);
+ } else {
+ LOG(ERROR) << "Folder no longer in item_list: " << new_folder_id;
+ }
+ }
+
+ if (source_folder->ChildItemCount() == 1)
+ RemoveLastItemFromReparentItemFolder(source_folder);
+
+ item_list_->AddObserver(this);
+
+ // Fade out the drag_view_ and delete it when animation ends.
+ int drag_view_index = view_model_.GetIndexOfView(drag_view_);
+ view_model_.Remove(drag_view_index);
+ bounds_animator_.AnimateViewTo(drag_view_, drag_view_->bounds());
+ bounds_animator_.SetAnimationDelegate(
+ drag_view_, new ItemRemoveAnimationDelegate(drag_view_), true);
+ UpdatePaging();
+}
+
+// After moving the re-parenting item out of the folder, if there is only 1 item
+// left, remove the last item out of the folder, delete the folder and insert it
+// to the data model at the same position. Make the same change to view_model_
+// accordingly.
+void AppsGridView::RemoveLastItemFromReparentItemFolder(
+ AppListFolderItem* source_folder) {
+ DCHECK(source_folder->ChildItemCount() == 1);
+
+ // Delete view associated with the folder item to be removed.
+ AppListItemView* folder_item_view = activated_item_view();
+ int folder_model_index = view_model_.GetIndexOfView(folder_item_view);
+ view_model_.Remove(folder_model_index);
+ delete folder_item_view;
+
+ // Now make the data change to remove the folder item in model.
+ AppListItem* last_item = source_folder->item_list()->item_at(0);
+ model_->MoveItemToFolderAt(last_item, "", source_folder->position());
+
+ // Create a new item view for the last item in folder.
+ size_t last_item_index;
+ item_list_->FindItemIndex(last_item->id(), &last_item_index);
+ views::View* last_item_view = CreateViewForItemAtIndex(last_item_index);
+ view_model_.Add(last_item_view, last_item_index);
+ AddChildView(last_item_view);
+}
+
+void AppsGridView::CancelFolderItemReparent(AppListItemView* drag_item_view) {
+ // The icon of the dragged item must target to its final ideal bounds after
+ // the animation completes.
+ CalculateIdealBounds();
+
+ // Remove drag_view_ from view_model_, it will be deleted after the animation.
+ int drag_view_index = view_model_.GetIndexOfView(drag_item_view);
+ view_model_.Remove(drag_view_index);
+
+ gfx::Rect target_icon_rect =
+ GetTargetIconRectInFolder(drag_item_view, activated_item_view_);
+
+ gfx::Rect drag_view_icon_to_grid =
+ drag_item_view->ConvertRectToParent(drag_item_view->GetIconBounds());
+ drag_view_icon_to_grid.ClampToCenteredSize(
+ gfx::Size(kPreferredIconDimension, kPreferredIconDimension));
+ TopIconAnimationView* icon_view = new TopIconAnimationView(
+ drag_item_view->item()->icon(),
+ target_icon_rect,
+ false); /* animate like closing folder */
+ AddChildView(icon_view);
+ icon_view->SetBoundsRect(drag_view_icon_to_grid);
+ icon_view->TransformView();
+}
+
void AppsGridView::CancelContextMenusOnCurrentPage() {
int start = pagination_model_->selected_page() * tiles_per_page();
int end = std::min(view_model_.view_size(), start + tiles_per_page());
@@ -1582,6 +1961,14 @@ AppsGridView::Index AppsGridView::GetNearestTileForDragView() {
drop_attempt_ = DROP_FOR_NONE;
reorder_timer_.Stop();
folder_dropping_timer_.Stop();
+
+ // When dragging for reparent a folder item, it should go back to its parent
+ // folder item if there is no drop target.
+ if (IsDraggingForReparentInRootLevelGridView()) {
+ DCHECK(activated_item_view_);
+ return GetIndexOfView(activated_item_view_);
+ }
+
return GetIndexOfView(drag_view_);
}
« no previous file with comments | « ui/app_list/views/apps_grid_view.h ('k') | ui/app_list/views/contents_view.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698