Home | History | Annotate | Download | only in launcher3
      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 android.animation.TimeInterpolator;
     20 import android.content.Context;
     21 import android.graphics.PointF;
     22 import android.util.AttributeSet;
     23 import android.view.View;
     24 import android.view.animation.AnimationUtils;
     25 
     26 import com.android.launcher3.util.FlingAnimation;
     27 import com.android.launcher3.util.Thunk;
     28 
     29 public class DeleteDropTarget extends ButtonDropTarget {
     30 
     31     public DeleteDropTarget(Context context, AttributeSet attrs) {
     32         this(context, attrs, 0);
     33     }
     34 
     35     public DeleteDropTarget(Context context, AttributeSet attrs, int defStyle) {
     36         super(context, attrs, defStyle);
     37     }
     38 
     39     @Override
     40     protected void onFinishInflate() {
     41         super.onFinishInflate();
     42         // Get the hover color
     43         mHoverColor = getResources().getColor(R.color.delete_target_hover_tint);
     44 
     45         setDrawable(R.drawable.ic_remove_launcher);
     46     }
     47 
     48     public static boolean supportsDrop(Object info) {
     49         return (info instanceof ShortcutInfo)
     50                 || (info instanceof LauncherAppWidgetInfo)
     51                 || (info instanceof FolderInfo);
     52     }
     53 
     54     @Override
     55     protected boolean supportsDrop(DragSource source, Object info) {
     56         return source.supportsDeleteDropTarget() && supportsDrop(info);
     57     }
     58 
     59     @Override
     60     @Thunk void completeDrop(DragObject d) {
     61         ItemInfo item = (ItemInfo) d.dragInfo;
     62         if ((d.dragSource instanceof Workspace) || (d.dragSource instanceof Folder)) {
     63             removeWorkspaceOrFolderItem(mLauncher, item, null);
     64         }
     65     }
     66 
     67     /**
     68      * Removes the item from the workspace. If the view is not null, it also removes the view.
     69      */
     70     public static void removeWorkspaceOrFolderItem(Launcher launcher, ItemInfo item, View view) {
     71         // Remove the item from launcher and the db, we can ignore the containerInfo in this call
     72         // because we already remove the drag view from the folder (if the drag originated from
     73         // a folder) in Folder.beginDrag()
     74         launcher.removeItem(view, item, true /* deleteFromDb */);
     75         launcher.getWorkspace().stripEmptyScreens();
     76         launcher.getDragLayer().announceForAccessibility(launcher.getString(R.string.item_removed));
     77     }
     78 
     79     @Override
     80     public void onFlingToDelete(final DragObject d, PointF vel) {
     81         // Don't highlight the icon as it's animating
     82         d.dragView.setColor(0);
     83         d.dragView.updateInitialScaleToCurrentScale();
     84 
     85         final DragLayer dragLayer = mLauncher.getDragLayer();
     86         FlingAnimation fling = new FlingAnimation(d, vel,
     87                 getIconRect(d.dragView.getMeasuredWidth(), d.dragView.getMeasuredHeight(),
     88                         mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight()),
     89                         dragLayer);
     90 
     91         final int duration = fling.getDuration();
     92         final long startTime = AnimationUtils.currentAnimationTimeMillis();
     93 
     94         // NOTE: Because it takes time for the first frame of animation to actually be
     95         // called and we expect the animation to be a continuation of the fling, we have
     96         // to account for the time that has elapsed since the fling finished.  And since
     97         // we don't have a startDelay, we will always get call to update when we call
     98         // start() (which we want to ignore).
     99         final TimeInterpolator tInterpolator = new TimeInterpolator() {
    100             private int mCount = -1;
    101             private float mOffset = 0f;
    102 
    103             @Override
    104             public float getInterpolation(float t) {
    105                 if (mCount < 0) {
    106                     mCount++;
    107                 } else if (mCount == 0) {
    108                     mOffset = Math.min(0.5f, (float) (AnimationUtils.currentAnimationTimeMillis() -
    109                             startTime) / duration);
    110                     mCount++;
    111                 }
    112                 return Math.min(1f, mOffset + t);
    113             }
    114         };
    115 
    116         Runnable onAnimationEndRunnable = new Runnable() {
    117             @Override
    118             public void run() {
    119                 mLauncher.exitSpringLoadedDragMode();
    120                 completeDrop(d);
    121                 mLauncher.getDragController().onDeferredEndFling(d);
    122             }
    123         };
    124 
    125         dragLayer.animateView(d.dragView, fling, duration, tInterpolator, onAnimationEndRunnable,
    126                 DragLayer.ANIMATION_END_DISAPPEAR, null);
    127     }
    128 }
    129