• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.launcher2;
18 
19 import android.widget.ImageView;
20 import android.content.Context;
21 import android.content.res.TypedArray;
22 import android.graphics.Paint;
23 import android.graphics.PorterDuff;
24 import android.graphics.PorterDuffColorFilter;
25 import android.graphics.Rect;
26 import android.util.AttributeSet;
27 import android.view.View;
28 import android.view.animation.TranslateAnimation;
29 import android.view.animation.Animation;
30 import android.view.animation.AnimationSet;
31 import android.view.animation.AccelerateInterpolator;
32 import android.view.animation.AlphaAnimation;
33 import android.graphics.RectF;
34 import android.graphics.drawable.TransitionDrawable;
35 
36 import com.android.launcher.R;
37 
38 public 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 
48     private AnimationSet mInAnimation;
49     private AnimationSet mOutAnimation;
50     private Animation mHandleInAnimation;
51     private Animation mHandleOutAnimation;
52 
53     private int mOrientation;
54     private DragController mDragController;
55 
56     private final RectF mRegion = new RectF();
57     private TransitionDrawable mTransition;
58     private View mHandle;
59     private final Paint mTrashPaint = new Paint();
60 
DeleteZone(Context context, AttributeSet attrs)61     public DeleteZone(Context context, AttributeSet attrs) {
62         this(context, attrs, 0);
63     }
64 
DeleteZone(Context context, AttributeSet attrs, int defStyle)65     public DeleteZone(Context context, AttributeSet attrs, int defStyle) {
66         super(context, attrs, defStyle);
67 
68         final int srcColor = context.getResources().getColor(R.color.delete_color_filter);
69         mTrashPaint.setColorFilter(new PorterDuffColorFilter(srcColor, PorterDuff.Mode.SRC_ATOP));
70 
71         TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DeleteZone, defStyle, 0);
72         mOrientation = a.getInt(R.styleable.DeleteZone_direction, ORIENTATION_HORIZONTAL);
73         a.recycle();
74     }
75 
76     @Override
onFinishInflate()77     protected void onFinishInflate() {
78         super.onFinishInflate();
79         mTransition = (TransitionDrawable) getDrawable();
80     }
81 
acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo)82     public boolean acceptDrop(DragSource source, int x, int y, int xOffset, int yOffset,
83             DragView dragView, Object dragInfo) {
84         return true;
85     }
86 
estimateDropLocation(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo, Rect recycle)87     public Rect estimateDropLocation(DragSource source, int x, int y, int xOffset, int yOffset,
88             DragView dragView, Object dragInfo, Rect recycle) {
89         return null;
90     }
91 
onDrop(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo)92     public void onDrop(DragSource source, int x, int y, int xOffset, int yOffset,
93             DragView dragView, Object dragInfo) {
94         final ItemInfo item = (ItemInfo) dragInfo;
95 
96         if (item.container == -1) return;
97 
98         if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
99             if (item instanceof LauncherAppWidgetInfo) {
100                 mLauncher.removeAppWidget((LauncherAppWidgetInfo) item);
101             }
102         } else {
103             if (source instanceof UserFolder) {
104                 final UserFolder userFolder = (UserFolder) source;
105                 final UserFolderInfo userFolderInfo = (UserFolderInfo) userFolder.getInfo();
106                 // Item must be a ShortcutInfo otherwise it couldn't have been in the folder
107                 // in the first place.
108                 userFolderInfo.remove((ShortcutInfo)item);
109             }
110         }
111         if (item instanceof UserFolderInfo) {
112             final UserFolderInfo userFolderInfo = (UserFolderInfo)item;
113             LauncherModel.deleteUserFolderContentsFromDatabase(mLauncher, userFolderInfo);
114             mLauncher.removeFolder(userFolderInfo);
115         } else if (item instanceof LauncherAppWidgetInfo) {
116             final LauncherAppWidgetInfo launcherAppWidgetInfo = (LauncherAppWidgetInfo) item;
117             final LauncherAppWidgetHost appWidgetHost = mLauncher.getAppWidgetHost();
118             if (appWidgetHost != null) {
119                 final int appWidgetId = launcherAppWidgetInfo.appWidgetId;
120                 // Deleting an app widget ID is a void call but writes to disk before returning
121                 // to the caller...
122                 new Thread("deleteAppWidgetId") {
123                     public void run() {
124                         appWidgetHost.deleteAppWidgetId(launcherAppWidgetInfo.appWidgetId);
125                     }
126                 }.start();
127             }
128         }
129         LauncherModel.deleteItemFromDatabase(mLauncher, item);
130     }
131 
onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo)132     public void onDragEnter(DragSource source, int x, int y, int xOffset, int yOffset,
133             DragView dragView, Object dragInfo) {
134         mTransition.reverseTransition(TRANSITION_DURATION);
135         dragView.setPaint(mTrashPaint);
136     }
137 
onDragOver(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo)138     public void onDragOver(DragSource source, int x, int y, int xOffset, int yOffset,
139             DragView dragView, Object dragInfo) {
140     }
141 
onDragExit(DragSource source, int x, int y, int xOffset, int yOffset, DragView dragView, Object dragInfo)142     public void onDragExit(DragSource source, int x, int y, int xOffset, int yOffset,
143             DragView dragView, Object dragInfo) {
144         mTransition.reverseTransition(TRANSITION_DURATION);
145         dragView.setPaint(null);
146     }
147 
onDragStart(DragSource source, Object info, int dragAction)148     public void onDragStart(DragSource source, Object info, int dragAction) {
149         final ItemInfo item = (ItemInfo) info;
150         if (item != null) {
151             mTrashMode = true;
152             createAnimations();
153             final int[] location = mLocation;
154             getLocationOnScreen(location);
155             mRegion.set(location[0], location[1], location[0] + mRight - mLeft,
156                     location[1] + mBottom - mTop);
157             mDragController.setDeleteRegion(mRegion);
158             mTransition.resetTransition();
159             startAnimation(mInAnimation);
160             mHandle.startAnimation(mHandleOutAnimation);
161             setVisibility(VISIBLE);
162         }
163     }
164 
onDragEnd()165     public void onDragEnd() {
166         if (mTrashMode) {
167             mTrashMode = false;
168             mDragController.setDeleteRegion(null);
169             startAnimation(mOutAnimation);
170             mHandle.startAnimation(mHandleInAnimation);
171             setVisibility(GONE);
172         }
173     }
174 
createAnimations()175     private void createAnimations() {
176         if (mInAnimation == null) {
177             mInAnimation = new FastAnimationSet();
178             final AnimationSet animationSet = mInAnimation;
179             animationSet.setInterpolator(new AccelerateInterpolator());
180             animationSet.addAnimation(new AlphaAnimation(0.0f, 1.0f));
181             if (mOrientation == ORIENTATION_HORIZONTAL) {
182                 animationSet.addAnimation(new TranslateAnimation(Animation.ABSOLUTE, 0.0f,
183                         Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 1.0f,
184                         Animation.RELATIVE_TO_SELF, 0.0f));
185             } else {
186                 animationSet.addAnimation(new TranslateAnimation(Animation.RELATIVE_TO_SELF,
187                         1.0f, Animation.RELATIVE_TO_SELF, 0.0f, Animation.ABSOLUTE, 0.0f,
188                         Animation.ABSOLUTE, 0.0f));
189             }
190             animationSet.setDuration(ANIMATION_DURATION);
191         }
192         if (mHandleInAnimation == null) {
193             mHandleInAnimation = new AlphaAnimation(0.0f, 1.0f);
194             mHandleInAnimation.setDuration(ANIMATION_DURATION);
195         }
196         if (mOutAnimation == null) {
197             mOutAnimation = new FastAnimationSet();
198             final AnimationSet animationSet = mOutAnimation;
199             animationSet.setInterpolator(new AccelerateInterpolator());
200             animationSet.addAnimation(new AlphaAnimation(1.0f, 0.0f));
201             if (mOrientation == ORIENTATION_HORIZONTAL) {
202                 animationSet.addAnimation(new FastTranslateAnimation(Animation.ABSOLUTE, 0.0f,
203                         Animation.ABSOLUTE, 0.0f, Animation.RELATIVE_TO_SELF, 0.0f,
204                         Animation.RELATIVE_TO_SELF, 1.0f));
205             } else {
206                 animationSet.addAnimation(new FastTranslateAnimation(Animation.RELATIVE_TO_SELF,
207                         0.0f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.ABSOLUTE, 0.0f,
208                         Animation.ABSOLUTE, 0.0f));
209             }
210             animationSet.setDuration(ANIMATION_DURATION);
211         }
212         if (mHandleOutAnimation == null) {
213             mHandleOutAnimation = new AlphaAnimation(1.0f, 0.0f);
214             mHandleOutAnimation.setFillAfter(true);
215             mHandleOutAnimation.setDuration(ANIMATION_DURATION);
216         }
217     }
218 
setLauncher(Launcher launcher)219     void setLauncher(Launcher launcher) {
220         mLauncher = launcher;
221     }
222 
setDragController(DragController dragController)223     void setDragController(DragController dragController) {
224         mDragController = dragController;
225     }
226 
setHandle(View view)227     void setHandle(View view) {
228         mHandle = view;
229     }
230 
231     private static class FastTranslateAnimation extends TranslateAnimation {
FastTranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue, int fromYType, float fromYValue, int toYType, float toYValue)232         public FastTranslateAnimation(int fromXType, float fromXValue, int toXType, float toXValue,
233                 int fromYType, float fromYValue, int toYType, float toYValue) {
234             super(fromXType, fromXValue, toXType, toXValue,
235                     fromYType, fromYValue, toYType, toYValue);
236         }
237 
238         @Override
willChangeTransformationMatrix()239         public boolean willChangeTransformationMatrix() {
240             return true;
241         }
242 
243         @Override
willChangeBounds()244         public boolean willChangeBounds() {
245             return false;
246         }
247     }
248 
249     private static class FastAnimationSet extends AnimationSet {
FastAnimationSet()250         FastAnimationSet() {
251             super(false);
252         }
253 
254         @Override
willChangeTransformationMatrix()255         public boolean willChangeTransformationMatrix() {
256             return true;
257         }
258 
259         @Override
willChangeBounds()260         public boolean willChangeBounds() {
261             return false;
262         }
263     }
264 }
265