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