blob: 997ded2d3c80ea407b3290e9bfd3dbc711ec285f [file] [log] [blame]
Winson Chung4c98d922011-05-31 16:50:48 -07001/*
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
Daniel Sandler325dc232013-06-05 22:57:57 -040017package com.android.launcher3;
Winson Chung4c98d922011-05-31 16:50:48 -070018
Winson Chung043f2af2012-03-01 16:09:54 -080019import android.animation.TimeInterpolator;
Winson Chung4c98d922011-05-31 16:50:48 -070020import android.content.Context;
Winson Chung043f2af2012-03-01 16:09:54 -080021import android.graphics.PointF;
Winson Chung4c98d922011-05-31 16:50:48 -070022import android.util.AttributeSet;
23import android.view.View;
Winson Chung043f2af2012-03-01 16:09:54 -080024import android.view.animation.AnimationUtils;
Winson Chung4c98d922011-05-31 16:50:48 -070025
Vadim Tryshevfedca432015-08-19 17:55:02 -070026import com.android.launcher3.dragndrop.DragLayer;
Sunny Goyal26119432016-02-18 22:09:23 +000027import com.android.launcher3.folder.Folder;
Sunny Goyalddec7342015-04-29 18:12:37 -070028import com.android.launcher3.util.FlingAnimation;
Adam Cohen091440a2015-03-18 14:16:05 -070029import com.android.launcher3.util.Thunk;
Kenny Guyed131872014-04-30 03:02:21 +010030
Winson Chung61fa4192011-06-12 15:15:29 -070031public class DeleteDropTarget extends ButtonDropTarget {
Sunny Goyalfa401a12015-04-10 13:45:42 -070032
Winson Chung4c98d922011-05-31 16:50:48 -070033 public DeleteDropTarget(Context context, AttributeSet attrs) {
34 this(context, attrs, 0);
35 }
36
37 public DeleteDropTarget(Context context, AttributeSet attrs, int defStyle) {
38 super(context, attrs, defStyle);
39 }
40
41 @Override
42 protected void onFinishInflate() {
43 super.onFinishInflate();
Winson Chung4c98d922011-05-31 16:50:48 -070044 // Get the hover color
Sunny Goyalfa401a12015-04-10 13:45:42 -070045 mHoverColor = getResources().getColor(R.color.delete_target_hover_tint);
Adam Cohenebea84d2011-11-09 17:20:41 -080046
Sunny Goyal40b626b2015-06-04 22:40:14 -070047 setDrawable(R.drawable.ic_remove_launcher);
Winson Chung4c98d922011-05-31 16:50:48 -070048 }
49
Tony Wickham9aae47f2015-10-01 13:04:22 -070050 @Override
51 public void onDragStart(DragSource source, ItemInfo info, int dragAction) {
52 super.onDragStart(source, info, dragAction);
53 setTextBasedOnDragSource(source);
54 }
55
56 /** @return true for items that should have a "Remove" action in accessibility. */
57 public static boolean supportsAccessibleDrop(ItemInfo info) {
Sunny Goyal1a70cef2015-04-22 11:29:51 -070058 return (info instanceof ShortcutInfo)
59 || (info instanceof LauncherAppWidgetInfo)
60 || (info instanceof FolderInfo);
Winson Chunga48487a2012-03-20 16:19:37 -070061 }
62
Winson Chung4c98d922011-05-31 16:50:48 -070063 @Override
Sunny Goyalaa8ef112015-06-12 20:04:41 -070064 protected boolean supportsDrop(DragSource source, ItemInfo info) {
Tony Wickham9aae47f2015-10-01 13:04:22 -070065 return true;
66 }
67
68 /**
69 * Set the drop target's text to either "Remove" or "Cancel" depending on the drag source.
70 */
71 public void setTextBasedOnDragSource(DragSource dragSource) {
72 if (!mDeviceProfile.isVerticalBarLayout()) {
73 setText(dragSource.supportsDeleteDropTarget() ? R.string.remove_drop_target_label
74 : android.R.string.cancel);
75 }
Winson Chung4c98d922011-05-31 16:50:48 -070076 }
77
78 @Override
Adam Cohen091440a2015-03-18 14:16:05 -070079 @Thunk void completeDrop(DragObject d) {
Sunny Goyalaa8ef112015-06-12 20:04:41 -070080 ItemInfo item = d.dragInfo;
Sunny Goyalfa401a12015-04-10 13:45:42 -070081 if ((d.dragSource instanceof Workspace) || (d.dragSource instanceof Folder)) {
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080082 removeWorkspaceOrFolderItem(mLauncher, item, null);
Winson Chung4c98d922011-05-31 16:50:48 -070083 }
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080084 }
85
86 /**
87 * Removes the item from the workspace. If the view is not null, it also removes the view.
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080088 */
Sunny Goyale78e3d72015-09-24 11:23:31 -070089 public static void removeWorkspaceOrFolderItem(Launcher launcher, ItemInfo item, View view) {
Winsonfa56b3f2015-09-14 12:01:13 -070090 // Remove the item from launcher and the db, we can ignore the containerInfo in this call
91 // because we already remove the drag view from the folder (if the drag originated from
92 // a folder) in Folder.beginDrag()
Winson2949fb52015-09-24 09:56:11 -070093 launcher.removeItem(view, item, true /* deleteFromDb */);
Winsonc0b52fe2015-09-09 16:38:15 -070094 launcher.getWorkspace().stripEmptyScreens();
Sunny Goyale78e3d72015-09-24 11:23:31 -070095 launcher.getDragLayer().announceForAccessibility(launcher.getString(R.string.item_removed));
Sunny Goyal71b5c0b2015-01-08 16:59:04 -080096 }
97
Sunny Goyalddec7342015-04-29 18:12:37 -070098 @Override
99 public void onFlingToDelete(final DragObject d, PointF vel) {
Winson Chung043f2af2012-03-01 16:09:54 -0800100 // Don't highlight the icon as it's animating
101 d.dragView.setColor(0);
Winson Chung043f2af2012-03-01 16:09:54 -0800102
Winson Chung043f2af2012-03-01 16:09:54 -0800103 final DragLayer dragLayer = mLauncher.getDragLayer();
Sunny Goyalddec7342015-04-29 18:12:37 -0700104 FlingAnimation fling = new FlingAnimation(d, vel,
105 getIconRect(d.dragView.getMeasuredWidth(), d.dragView.getMeasuredHeight(),
106 mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight()),
107 dragLayer);
108
109 final int duration = fling.getDuration();
Winson Chung043f2af2012-03-01 16:09:54 -0800110 final long startTime = AnimationUtils.currentAnimationTimeMillis();
111
112 // NOTE: Because it takes time for the first frame of animation to actually be
113 // called and we expect the animation to be a continuation of the fling, we have
114 // to account for the time that has elapsed since the fling finished. And since
115 // we don't have a startDelay, we will always get call to update when we call
116 // start() (which we want to ignore).
117 final TimeInterpolator tInterpolator = new TimeInterpolator() {
118 private int mCount = -1;
119 private float mOffset = 0f;
120
121 @Override
122 public float getInterpolation(float t) {
123 if (mCount < 0) {
124 mCount++;
125 } else if (mCount == 0) {
126 mOffset = Math.min(0.5f, (float) (AnimationUtils.currentAnimationTimeMillis() -
127 startTime) / duration);
128 mCount++;
129 }
130 return Math.min(1f, mOffset + t);
131 }
132 };
Michael Jurka1e2f4652013-07-08 18:03:46 -0700133
Winson Chung043f2af2012-03-01 16:09:54 -0800134 Runnable onAnimationEndRunnable = new Runnable() {
135 @Override
136 public void run() {
Sunny Goyalddec7342015-04-29 18:12:37 -0700137 mLauncher.exitSpringLoadedDragMode();
138 completeDrop(d);
Winson Chunga48487a2012-03-20 16:19:37 -0700139 mLauncher.getDragController().onDeferredEndFling(d);
Winson Chung043f2af2012-03-01 16:09:54 -0800140 }
141 };
Sunny Goyalddec7342015-04-29 18:12:37 -0700142
143 dragLayer.animateView(d.dragView, fling, duration, tInterpolator, onAnimationEndRunnable,
Winson Chung043f2af2012-03-01 16:09:54 -0800144 DragLayer.ANIMATION_END_DISAPPEAR, null);
145 }
Winson Chung4c98d922011-05-31 16:50:48 -0700146}