• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.launcher3;
18 
19 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_CANCEL;
20 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ITEM_DROPPED_ON_REMOVE;
21 import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_UNDO;
22 
23 import android.content.Context;
24 import android.text.TextUtils;
25 import android.util.AttributeSet;
26 import android.view.View;
27 
28 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
29 import com.android.launcher3.dragndrop.DragOptions;
30 import com.android.launcher3.logging.StatsLogManager;
31 import com.android.launcher3.model.ModelWriter;
32 import com.android.launcher3.model.data.FolderInfo;
33 import com.android.launcher3.model.data.ItemInfo;
34 import com.android.launcher3.model.data.LauncherAppWidgetInfo;
35 import com.android.launcher3.model.data.WorkspaceItemInfo;
36 import com.android.launcher3.views.Snackbar;
37 
38 public class DeleteDropTarget extends ButtonDropTarget {
39 
40     private final StatsLogManager mStatsLogManager;
41 
42     private StatsLogManager.LauncherEvent mLauncherEvent;
43 
DeleteDropTarget(Context context, AttributeSet attrs)44     public DeleteDropTarget(Context context, AttributeSet attrs) {
45         this(context, attrs, 0);
46     }
47 
DeleteDropTarget(Context context, AttributeSet attrs, int defStyle)48     public DeleteDropTarget(Context context, AttributeSet attrs, int defStyle) {
49         super(context, attrs, defStyle);
50         this.mStatsLogManager = StatsLogManager.newInstance(context);
51     }
52 
53     @Override
onFinishInflate()54     protected void onFinishInflate() {
55         super.onFinishInflate();
56         setDrawable(R.drawable.ic_remove_no_shadow);
57     }
58 
59     @Override
onDragStart(DropTarget.DragObject dragObject, DragOptions options)60     public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) {
61         super.onDragStart(dragObject, options);
62         setTextBasedOnDragSource(dragObject.dragInfo);
63         setControlTypeBasedOnDragSource(dragObject.dragInfo);
64     }
65 
66     /**
67      * @return true for items that should have a "Remove" action in accessibility.
68      */
69     @Override
supportsAccessibilityDrop(ItemInfo info, View view)70     public boolean supportsAccessibilityDrop(ItemInfo info, View view) {
71         if (info instanceof WorkspaceItemInfo) {
72             // Support the action unless the item is in a context menu.
73             return canRemove(info);
74         }
75 
76         return (info instanceof LauncherAppWidgetInfo)
77                 || (info instanceof FolderInfo);
78     }
79 
80     @Override
getAccessibilityAction()81     public int getAccessibilityAction() {
82         return LauncherAccessibilityDelegate.REMOVE;
83     }
84 
85     @Override
supportsDrop(ItemInfo info)86     protected boolean supportsDrop(ItemInfo info) {
87         return true;
88     }
89 
90     /**
91      * Set the drop target's text to either "Remove" or "Cancel" depending on the drag item.
92      */
setTextBasedOnDragSource(ItemInfo item)93     private void setTextBasedOnDragSource(ItemInfo item) {
94         if (!TextUtils.isEmpty(mText)) {
95             mText = getResources().getString(canRemove(item)
96                     ? R.string.remove_drop_target_label
97                     : android.R.string.cancel);
98             setContentDescription(mText);
99             requestLayout();
100         }
101     }
102 
canRemove(ItemInfo item)103     private boolean canRemove(ItemInfo item) {
104         return item.id != ItemInfo.NO_ID;
105     }
106 
107     /**
108      * Set mControlType depending on the drag item.
109      */
setControlTypeBasedOnDragSource(ItemInfo item)110     private void setControlTypeBasedOnDragSource(ItemInfo item) {
111         mLauncherEvent = item.id != ItemInfo.NO_ID ? LAUNCHER_ITEM_DROPPED_ON_REMOVE
112                 : LAUNCHER_ITEM_DROPPED_ON_CANCEL;
113     }
114 
115     @Override
onDrop(DragObject d, DragOptions options)116     public void onDrop(DragObject d, DragOptions options) {
117         if (canRemove(d.dragInfo)) {
118             mLauncher.getModelWriter().prepareToUndoDelete();
119             d.dragInfo.container = NO_ID;
120         }
121         super.onDrop(d, options);
122         mStatsLogManager.logger().withInstanceId(d.logInstanceId)
123                 .log(mLauncherEvent);
124     }
125 
126     @Override
completeDrop(DragObject d)127     public void completeDrop(DragObject d) {
128         ItemInfo item = d.dragInfo;
129         if (canRemove(item)) {
130             int itemPage = mLauncher.getWorkspace().getCurrentPage();
131             onAccessibilityDrop(null, item);
132             ModelWriter modelWriter = mLauncher.getModelWriter();
133             Runnable onUndoClicked = () -> {
134                 mLauncher.setPageToBindSynchronously(itemPage);
135                 modelWriter.abortDelete();
136                 mLauncher.getStatsLogManager().logger().log(LAUNCHER_UNDO);
137             };
138             Snackbar.show(mLauncher, R.string.item_removed, R.string.undo,
139                     modelWriter::commitDelete, onUndoClicked);
140         }
141     }
142 
143     /**
144      * Removes the item from the workspace. If the view is not null, it also removes the view.
145      */
146     @Override
onAccessibilityDrop(View view, ItemInfo item)147     public void onAccessibilityDrop(View view, ItemInfo item) {
148         // Remove the item from launcher and the db, we can ignore the containerInfo in this call
149         // because we already remove the drag view from the folder (if the drag originated from
150         // a folder) in Folder.beginDrag()
151         mLauncher.removeItem(view, item, true /* deleteFromDb */);
152         mLauncher.getWorkspace().stripEmptyScreens();
153         mLauncher.getDragLayer()
154                 .announceForAccessibility(getContext().getString(R.string.item_removed));
155     }
156 }
157