blob: 33f384f0de7cfb46effdd08c74da5cbb116ebc47 [file] [log] [blame]
The Android Open Source Project31dd5032009-03-03 19:32:27 -08001/*
2 * Copyright (C) 2008 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
Joe Onoratoa5902522009-07-30 13:37:37 -070017package com.android.launcher2;
The Android Open Source Project31dd5032009-03-03 19:32:27 -080018
The Android Open Source Project31dd5032009-03-03 19:32:27 -080019import android.content.Context;
20import android.content.res.TypedArray;
Joe Onorato00acb122009-08-04 16:04:30 -040021import android.graphics.Paint;
22import android.graphics.PorterDuff;
23import android.graphics.PorterDuffColorFilter;
Michael Jurka3adcb0c2010-10-15 18:07:21 -070024import android.graphics.Rect;
The Android Open Source Project31dd5032009-03-03 19:32:27 -080025import android.graphics.RectF;
26import android.graphics.drawable.TransitionDrawable;
Patrick Dubroybc6840b2010-09-01 11:54:27 -070027import android.util.AttributeSet;
Patrick Dubroybc6840b2010-09-01 11:54:27 -070028import android.view.View;
29import android.view.animation.AccelerateInterpolator;
30import android.view.animation.AlphaAnimation;
31import android.view.animation.Animation;
32import android.view.animation.AnimationSet;
33import android.view.animation.TranslateAnimation;
34import android.widget.ImageView;
Romain Guyedcce092010-03-04 13:03:17 -080035
Adam Cohencdc30d52010-12-01 15:09:47 -080036import com.android.launcher.R;
37
The Android Open Source Project31dd5032009-03-03 19:32:27 -080038public class DeleteZone extends ImageView implements DropTarget, DragController.DragListener {
39 private static final int ORIENTATION_HORIZONTAL = 1;
40 private static final int TRANSITION_DURATION = 250;
41 private static final int ANIMATION_DURATION = 200;
42
43 private final int[] mLocation = new int[2];
44
45 private Launcher mLauncher;
46 private boolean mTrashMode;
47
Patrick Dubroydea9e932010-09-22 15:04:29 -070048 /**
49 * If true, this View responsible for managing its own visibility, and that of its handle.
50 * This is generally the case, but it will be set to false when this is part of the
51 * Contextual Action Bar.
52 */
Adam Cohencdc30d52010-12-01 15:09:47 -080053 private boolean mDragAndDropEnabled = true;
Patrick Dubroydea9e932010-09-22 15:04:29 -070054
The Android Open Source Project31dd5032009-03-03 19:32:27 -080055 private AnimationSet mInAnimation;
56 private AnimationSet mOutAnimation;
57 private Animation mHandleInAnimation;
58 private Animation mHandleOutAnimation;
59
60 private int mOrientation;
Joe Onorato00acb122009-08-04 16:04:30 -040061 private DragController mDragController;
The Android Open Source Project31dd5032009-03-03 19:32:27 -080062
Michael Jurka3adcb0c2010-10-15 18:07:21 -070063 private final RectF mRegionF = new RectF();
64 private final Rect mRegion = new Rect();
The Android Open Source Project31dd5032009-03-03 19:32:27 -080065 private TransitionDrawable mTransition;
Joe Onorato00acb122009-08-04 16:04:30 -040066 private final Paint mTrashPaint = new Paint();
The Android Open Source Project31dd5032009-03-03 19:32:27 -080067
Patrick Dubroydea9e932010-09-22 15:04:29 -070068 /** The View that this view will replace. */
69 private View mHandle = null;
70
The Android Open Source Project31dd5032009-03-03 19:32:27 -080071 public DeleteZone(Context context, AttributeSet attrs) {
72 this(context, attrs, 0);
73 }
74
75 public DeleteZone(Context context, AttributeSet attrs, int defStyle) {
76 super(context, attrs, defStyle);
77
Joe Onorato00acb122009-08-04 16:04:30 -040078 final int srcColor = context.getResources().getColor(R.color.delete_color_filter);
79 mTrashPaint.setColorFilter(new PorterDuffColorFilter(srcColor, PorterDuff.Mode.SRC_ATOP));
80
The Android Open Source Project31dd5032009-03-03 19:32:27 -080081 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DeleteZone, defStyle, 0);
82 mOrientation = a.getInt(R.styleable.DeleteZone_direction, ORIENTATION_HORIZONTAL);
83 a.recycle();
84 }
85
86 @Override
87 protected void onFinishInflate() {
88 super.onFinishInflate();
Joe Onoratoa9c28f62009-09-14 18:38:49 -040089 mTransition = (TransitionDrawable) getDrawable();
The Android Open Source Project31dd5032009-03-03 19:32:27 -080090 }
91
92 public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
Joe Onorato00acb122009-08-04 16:04:30 -040093 DragView dragView, Object dragInfo) {
The Android Open Source Project31dd5032009-03-03 19:32:27 -080094 return true;
95 }
96
Joe Onorato00acb122009-08-04 16:04:30 -040097 public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset,
98 DragView dragView, Object dragInfo) {
Adam Cohencdc30d52010-12-01 15:09:47 -080099 if (!mDragAndDropEnabled) return;
100
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800101 final ItemInfo item = (ItemInfo) dragInfo;
102
Patrick Dubroybc6840b2010-09-01 11:54:27 -0700103 // On x-large screens, you can uninstall an app by dragging from all apps
104 if (item instanceof ApplicationInfo && LauncherApplication.isScreenXLarge()) {
Patrick Dubroy5539af72010-09-07 15:22:01 -0700105 mLauncher.startApplicationUninstallActivity((ApplicationInfo) item);
Patrick Dubroybc6840b2010-09-01 11:54:27 -0700106 }
107
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800108 if (item.container == -1) return;
109
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800110 if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
The Android Open Source Project7376fae2009-03-11 12:11:58 -0700111 if (item instanceof LauncherAppWidgetInfo) {
Joe Onorato9c1289c2009-08-17 11:03:03 -0400112 mLauncher.removeAppWidget((LauncherAppWidgetInfo) item);
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800113 }
Patrick Dubroybc6840b2010-09-01 11:54:27 -0700114 } else if (source instanceof UserFolder) {
115 final UserFolder userFolder = (UserFolder) source;
116 final UserFolderInfo userFolderInfo = (UserFolderInfo) userFolder.getInfo();
117 // Item must be a ShortcutInfo otherwise it couldn't have been in the folder
118 // in the first place.
119 userFolderInfo.remove((ShortcutInfo)item);
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800120 }
Patrick Dubroybc6840b2010-09-01 11:54:27 -0700121
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800122 if (item instanceof UserFolderInfo) {
123 final UserFolderInfo userFolderInfo = (UserFolderInfo)item;
124 LauncherModel.deleteUserFolderContentsFromDatabase(mLauncher, userFolderInfo);
Joe Onorato9c1289c2009-08-17 11:03:03 -0400125 mLauncher.removeFolder(userFolderInfo);
The Android Open Source Project7376fae2009-03-11 12:11:58 -0700126 } else if (item instanceof LauncherAppWidgetInfo) {
127 final LauncherAppWidgetInfo launcherAppWidgetInfo = (LauncherAppWidgetInfo) item;
128 final LauncherAppWidgetHost appWidgetHost = mLauncher.getAppWidgetHost();
129 if (appWidgetHost != null) {
Brad Fitzpatrick73013bf2010-09-14 12:15:32 -0700130 final int appWidgetId = launcherAppWidgetInfo.appWidgetId;
131 // Deleting an app widget ID is a void call but writes to disk before returning
132 // to the caller...
133 new Thread("deleteAppWidgetId") {
134 public void run() {
135 appWidgetHost.deleteAppWidgetId(launcherAppWidgetInfo.appWidgetId);
136 }
137 }.start();
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800138 }
139 }
Patrick Dubroybc6840b2010-09-01 11:54:27 -0700140
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800141 LauncherModel.deleteItemFromDatabase(mLauncher, item);
142 }
143
144 public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
Joe Onorato00acb122009-08-04 16:04:30 -0400145 DragView dragView, Object dragInfo) {
Adam Cohencdc30d52010-12-01 15:09:47 -0800146 if (!mDragAndDropEnabled) return;
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800147 mTransition.reverseTransition(TRANSITION_DURATION);
Joe Onorato00acb122009-08-04 16:04:30 -0400148 dragView.setPaint(mTrashPaint);
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800149 }
150
151 public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
Joe Onorato00acb122009-08-04 16:04:30 -0400152 DragView dragView, Object dragInfo) {
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800153 }
154
155 public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
Joe Onorato00acb122009-08-04 16:04:30 -0400156 DragView dragView, Object dragInfo) {
Adam Cohencdc30d52010-12-01 15:09:47 -0800157 if (!mDragAndDropEnabled) return;
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800158 mTransition.reverseTransition(TRANSITION_DURATION);
Joe Onorato00acb122009-08-04 16:04:30 -0400159 dragView.setPaint(null);
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800160 }
161
Joe Onorato5162ea92009-09-03 09:39:42 -0700162 public void onDragStart(DragSource source, Object info, int dragAction) {
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800163 final ItemInfo item = (ItemInfo) info;
Adam Cohencdc30d52010-12-01 15:09:47 -0800164 if (item != null && mDragAndDropEnabled) {
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800165 mTrashMode = true;
Michael Jurka3adcb0c2010-10-15 18:07:21 -0700166 getHitRect(mRegion);
167 mRegionF.set(mRegion);
168
169 if (LauncherApplication.isScreenXLarge()) {
170 // This region will be a "dead zone" for scrolling; make it extend to the edge of
171 // the screen so users don't accidentally trigger a scroll while deleting items
172 mRegionF.top = mLauncher.getWorkspace().getTop();
173 mRegionF.right = mLauncher.getWorkspace().getRight();
174 }
175
176 mDragController.setDeleteRegion(mRegionF);
Patrick Dubroydea9e932010-09-22 15:04:29 -0700177
178 // Make sure the icon is set to the default drawable, not the hover drawable
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800179 mTransition.resetTransition();
Patrick Dubroydea9e932010-09-22 15:04:29 -0700180
Adam Cohencdc30d52010-12-01 15:09:47 -0800181 createAnimations();
182 startAnimation(mInAnimation);
183 if (mHandle != null) {
Patrick Dubroydea9e932010-09-22 15:04:29 -0700184 mHandle.startAnimation(mHandleOutAnimation);
Patrick Dubroydea9e932010-09-22 15:04:29 -0700185 }
Adam Cohencdc30d52010-12-01 15:09:47 -0800186 setVisibility(VISIBLE);
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800187 }
188 }
189
190 public void onDragEnd() {
Adam Cohencdc30d52010-12-01 15:09:47 -0800191 if (mTrashMode && mDragAndDropEnabled) {
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800192 mTrashMode = false;
Joe Onorato00acb122009-08-04 16:04:30 -0400193 mDragController.setDeleteRegion(null);
Patrick Dubroydea9e932010-09-22 15:04:29 -0700194
195 if (mOutAnimation != null) startAnimation(mOutAnimation);
Adam Cohencdc30d52010-12-01 15:09:47 -0800196 if (mHandleInAnimation != null && mHandle != null) {
197 mHandle.startAnimation(mHandleInAnimation);
Patrick Dubroydea9e932010-09-22 15:04:29 -0700198 }
Adam Cohencdc30d52010-12-01 15:09:47 -0800199 setVisibility(GONE);
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800200 }
201 }
202
Michael Jurka0280c3b2010-09-17 15:00:07 -0700203 public boolean isDropEnabled() {
204 return true;
205 }
206
Michael Jurka3adcb0c2010-10-15 18:07:21 -0700207 @Override
208 public void getHitRect(Rect outRect) {
209 super.getHitRect(outRect);
210 if (LauncherApplication.isScreenXLarge()) {
Michael Jurka774bd372010-10-22 13:40:50 -0700211 // TODO: This is a temporary hack. mManageVisiblity = false when you're in CAB mode.
212 // In that case, this icon is more tightly spaced next to the delete icon so we want
213 // it to have a smaller drag region. When the new drag&drop system comes in, we'll
214 // dispatch the drag/drop by calculating what target you're overlapping
Adam Cohencdc30d52010-12-01 15:09:47 -0800215 final int padding = R.dimen.delete_zone_padding;
Adam Lesinski6b879f02010-11-04 16:15:23 -0700216 final int outerDragPadding =
217 getResources().getDimensionPixelSize(R.dimen.delete_zone_size);
Adam Cohencdc30d52010-12-01 15:09:47 -0800218 final int innerDragPadding = getResources().getDimensionPixelSize(padding);
Adam Lesinski6b879f02010-11-04 16:15:23 -0700219 outRect.top -= outerDragPadding;
220 outRect.left -= innerDragPadding;
221 outRect.bottom += outerDragPadding;
222 outRect.right += innerDragPadding;
Michael Jurka3adcb0c2010-10-15 18:07:21 -0700223 }
224 }
225
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800226 private void createAnimations() {
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800227 if (mHandleInAnimation == null) {
Daniel Sandlerc9b18772010-04-22 14:37:59 -0400228 mHandleInAnimation = new AlphaAnimation(0.0f, 1.0f);
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800229 mHandleInAnimation.setDuration(ANIMATION_DURATION);
230 }
Adam Lesinski6b879f02010-11-04 16:15:23 -0700231
232 if (mInAnimation == null) {
233 mInAnimation = new FastAnimationSet();
234 if (!LauncherApplication.isScreenXLarge()) {
235 final AnimationSet animationSet = mInAnimation;
236 animationSet.setInterpolator(new AccelerateInterpolator());
237 animationSet.addAnimation(new AlphaAnimation(0.0f, 1.0f));
238 if (mOrientation == ORIENTATION_HORIZONTAL) {
239 animationSet.addAnimation(new TranslateAnimation(Animation.ABSOLUTE, 0.0f,
240 Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f,
241 Animation.RELATIVE_TO_SELF, 0.0f));
242 } else {
243 animationSet.addAnimation(new TranslateAnimation(Animation.RELATIVE_TO_SELF,
244 1.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.ABSOLUTE, 0.0f,
245 Animation.ABSOLUTE, 0.0f));
246 }
247 animationSet.setDuration(ANIMATION_DURATION);
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800248 } else {
Adam Lesinski6b879f02010-11-04 16:15:23 -0700249 mInAnimation.addAnimation(mHandleInAnimation);
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800250 }
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800251 }
Adam Lesinski6b879f02010-11-04 16:15:23 -0700252
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800253 if (mHandleOutAnimation == null) {
Daniel Sandlerc9b18772010-04-22 14:37:59 -0400254 mHandleOutAnimation = new AlphaAnimation(1.0f, 0.0f);
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800255 mHandleOutAnimation.setFillAfter(true);
256 mHandleOutAnimation.setDuration(ANIMATION_DURATION);
257 }
Adam Lesinski6b879f02010-11-04 16:15:23 -0700258
259 if (mOutAnimation == null) {
260 mOutAnimation = new FastAnimationSet();
261 if (!LauncherApplication.isScreenXLarge()) {
262 final AnimationSet animationSet = mOutAnimation;
263 animationSet.setInterpolator(new AccelerateInterpolator());
264 animationSet.addAnimation(new AlphaAnimation(1.0f, 0.0f));
265 if (mOrientation == ORIENTATION_HORIZONTAL) {
266 animationSet.addAnimation(new FastTranslateAnimation(Animation.ABSOLUTE, 0.0f,
267 Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
268 Animation.RELATIVE_TO_SELF, 1.0f));
269 } else {
270 animationSet.addAnimation(new FastTranslateAnimation(Animation.RELATIVE_TO_SELF,
271 0.0f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.ABSOLUTE, 0.0f,
272 Animation.ABSOLUTE, 0.0f));
273 }
274 animationSet.setDuration(ANIMATION_DURATION);
275 } else {
276 mOutAnimation.addAnimation(mHandleOutAnimation);
277 }
278 }
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800279 }
280
281 void setLauncher(Launcher launcher) {
282 mLauncher = launcher;
283 }
284
Joe Onorato00acb122009-08-04 16:04:30 -0400285 void setDragController(DragController dragController) {
286 mDragController = dragController;
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800287 }
288
289 void setHandle(View view) {
290 mHandle = view;
291 }
292
Adam Cohencdc30d52010-12-01 15:09:47 -0800293 void setDragAndDropEnabled(boolean enabled) {
294 mDragAndDropEnabled = enabled;
Patrick Dubroydea9e932010-09-22 15:04:29 -0700295 }
296
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800297 private static class FastTranslateAnimation extends TranslateAnimation {
298 public FastTranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,
299 int fromYType, float fromYValue, int toYType, float toYValue) {
300 super(fromXType, fromXValue, toXType, toXValue,
301 fromYType, fromYValue, toYType, toYValue);
302 }
303
304 @Override
305 public boolean willChangeTransformationMatrix() {
306 return true;
307 }
308
309 @Override
310 public boolean willChangeBounds() {
311 return false;
312 }
313 }
314
315 private static class FastAnimationSet extends AnimationSet {
316 FastAnimationSet() {
317 super(false);
318 }
319
320 @Override
321 public boolean willChangeTransformationMatrix() {
322 return true;
323 }
324
325 @Override
326 public boolean willChangeBounds() {
327 return false;
328 }
329 }
Patrick Dubroy440c3602010-07-13 17:50:32 -0700330
331 @Override
332 public DropTarget getDropTargetDelegate(DragSource source, int x, int y, int xOffset, int yOffset,
333 DragView dragView, Object dragInfo) {
334 return null;
335 }
The Android Open Source Project31dd5032009-03-03 19:32:27 -0800336}