Home | History | Annotate | Download | only in launcher2
      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.launcher2;
     18 
     19 import android.content.Context;
     20 import android.content.res.ColorStateList;
     21 import android.content.res.Configuration;
     22 import android.content.res.Resources;
     23 import android.graphics.PorterDuff;
     24 import android.graphics.PorterDuffColorFilter;
     25 import android.graphics.Rect;
     26 import android.graphics.drawable.TransitionDrawable;
     27 import android.util.AttributeSet;
     28 import android.view.View;
     29 import android.view.ViewGroup;
     30 import android.view.animation.DecelerateInterpolator;
     31 
     32 import com.android.launcher.R;
     33 
     34 public class DeleteDropTarget extends ButtonDropTarget {
     35 
     36     private static int DELETE_ANIMATION_DURATION = 250;
     37     private ColorStateList mOriginalTextColor;
     38     private TransitionDrawable mDrawable;
     39     private int mHoverColor = 0xFFFF0000;
     40 
     41     public DeleteDropTarget(Context context, AttributeSet attrs) {
     42         this(context, attrs, 0);
     43     }
     44 
     45     public DeleteDropTarget(Context context, AttributeSet attrs, int defStyle) {
     46         super(context, attrs, defStyle);
     47     }
     48 
     49     @Override
     50     protected void onFinishInflate() {
     51         super.onFinishInflate();
     52 
     53         // Get the drawable
     54         mOriginalTextColor = getTextColors();
     55 
     56         // Get the hover color
     57         Resources r = getResources();
     58         mHoverColor = r.getColor(R.color.delete_target_hover_tint);
     59         mHoverPaint.setColorFilter(new PorterDuffColorFilter(
     60                 mHoverColor, PorterDuff.Mode.SRC_ATOP));
     61         mDrawable = (TransitionDrawable) getCompoundDrawables()[0];
     62         mDrawable.setCrossFadeEnabled(true);
     63 
     64         // Remove the text in the Phone UI in landscape
     65         int orientation = getResources().getConfiguration().orientation;
     66         if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
     67             if (!LauncherApplication.isScreenLarge()) {
     68                 setText("");
     69             }
     70         }
     71     }
     72 
     73     private boolean isAllAppsApplication(DragSource source, Object info) {
     74         return (source instanceof AppsCustomizePagedView) && (info instanceof ApplicationInfo);
     75     }
     76     private boolean isAllAppsWidget(DragSource source, Object info) {
     77         return (source instanceof AppsCustomizePagedView) && (info instanceof PendingAddWidgetInfo);
     78     }
     79     private boolean isDragSourceWorkspaceOrFolder(DragObject d) {
     80         return (d.dragSource instanceof Workspace) || (d.dragSource instanceof Folder);
     81     }
     82     private boolean isWorkspaceOrFolderApplication(DragObject d) {
     83         return isDragSourceWorkspaceOrFolder(d) && (d.dragInfo instanceof ShortcutInfo);
     84     }
     85     private boolean isWorkspaceOrFolderWidget(DragObject d) {
     86         return isDragSourceWorkspaceOrFolder(d) && (d.dragInfo instanceof LauncherAppWidgetInfo);
     87     }
     88     private boolean isWorkspaceFolder(DragObject d) {
     89         return (d.dragSource instanceof Workspace) && (d.dragInfo instanceof FolderInfo);
     90     }
     91 
     92     @Override
     93     public boolean acceptDrop(DragObject d) {
     94         // We can remove everything including App shortcuts, folders, widgets, etc.
     95         return true;
     96     }
     97 
     98     @Override
     99     public void onDragStart(DragSource source, Object info, int dragAction) {
    100         boolean isVisible = true;
    101         boolean isUninstall = false;
    102 
    103         // If we are dragging a widget from AppsCustomize, hide the delete target
    104         if (isAllAppsWidget(source, info)) {
    105             isVisible = false;
    106         }
    107 
    108         // If we are dragging an application from AppsCustomize, only show the control if we can
    109         // delete the app (it was downloaded), and rename the string to "uninstall" in such a case
    110         if (isAllAppsApplication(source, info)) {
    111             ApplicationInfo appInfo = (ApplicationInfo) info;
    112             if ((appInfo.flags & ApplicationInfo.DOWNLOADED_FLAG) != 0) {
    113                 isUninstall = true;
    114             } else {
    115                 isVisible = false;
    116             }
    117         }
    118 
    119         mActive = isVisible;
    120         mDrawable.resetTransition();
    121         setTextColor(mOriginalTextColor);
    122         ((ViewGroup) getParent()).setVisibility(isVisible ? View.VISIBLE : View.GONE);
    123         if (getText().length() > 0) {
    124             setText(isUninstall ? R.string.delete_target_uninstall_label
    125                 : R.string.delete_target_label);
    126         }
    127     }
    128 
    129     @Override
    130     public void onDragEnd() {
    131         super.onDragEnd();
    132         mActive = false;
    133     }
    134 
    135     public void onDragEnter(DragObject d) {
    136         super.onDragEnter(d);
    137 
    138         mDrawable.startTransition(mTransitionDuration);
    139         setTextColor(mHoverColor);
    140     }
    141 
    142     public void onDragExit(DragObject d) {
    143         super.onDragExit(d);
    144 
    145         if (!d.dragComplete) {
    146             mDrawable.resetTransition();
    147             setTextColor(mOriginalTextColor);
    148         }
    149     }
    150 
    151     private void animateToTrashAndCompleteDrop(final DragObject d) {
    152         DragLayer dragLayer = mLauncher.getDragLayer();
    153         Rect from = new Rect();
    154         Rect to = new Rect();
    155         dragLayer.getViewRectRelativeToSelf(d.dragView, from);
    156         dragLayer.getViewRectRelativeToSelf(this, to);
    157 
    158         int width = mDrawable.getIntrinsicWidth();
    159         int height = mDrawable.getIntrinsicHeight();
    160         to.set(to.left + getPaddingLeft(), to.top + getPaddingTop(),
    161                 to.left + getPaddingLeft() + width, to.bottom);
    162 
    163         // Center the destination rect about the trash icon
    164         int xOffset = (int) -(d.dragView.getMeasuredWidth() - width) / 2;
    165         int yOffset = (int) -(d.dragView.getMeasuredHeight() - height) / 2;
    166         to.offset(xOffset, yOffset);
    167 
    168         mSearchDropTargetBar.deferOnDragEnd();
    169         Runnable onAnimationEndRunnable = new Runnable() {
    170             @Override
    171             public void run() {
    172                 mSearchDropTargetBar.onDragEnd();
    173                 mLauncher.exitSpringLoadedDragMode();
    174                 completeDrop(d);
    175             }
    176         };
    177         dragLayer.animateView(d.dragView, from, to, 0.1f, 0.1f,
    178                 DELETE_ANIMATION_DURATION, new DecelerateInterpolator(2),
    179                 new DecelerateInterpolator(1.5f), onAnimationEndRunnable, false);
    180     }
    181 
    182     private void completeDrop(DragObject d) {
    183         ItemInfo item = (ItemInfo) d.dragInfo;
    184 
    185         if (isAllAppsApplication(d.dragSource, item)) {
    186             // Uninstall the application if it is being dragged from AppsCustomize
    187             mLauncher.startApplicationUninstallActivity((ApplicationInfo) item);
    188         } else if (isWorkspaceOrFolderApplication(d)) {
    189             LauncherModel.deleteItemFromDatabase(mLauncher, item);
    190         } else if (isWorkspaceFolder(d)) {
    191             // Remove the folder from the workspace and delete the contents from launcher model
    192             FolderInfo folderInfo = (FolderInfo) item;
    193             mLauncher.removeFolder(folderInfo);
    194             LauncherModel.deleteFolderContentsFromDatabase(mLauncher, folderInfo);
    195         } else if (isWorkspaceOrFolderWidget(d)) {
    196             // Remove the widget from the workspace
    197             mLauncher.removeAppWidget((LauncherAppWidgetInfo) item);
    198             LauncherModel.deleteItemFromDatabase(mLauncher, item);
    199 
    200             final LauncherAppWidgetInfo launcherAppWidgetInfo = (LauncherAppWidgetInfo) item;
    201             final LauncherAppWidgetHost appWidgetHost = mLauncher.getAppWidgetHost();
    202             if (appWidgetHost != null) {
    203                 // Deleting an app widget ID is a void call but writes to disk before returning
    204                 // to the caller...
    205                 new Thread("deleteAppWidgetId") {
    206                     public void run() {
    207                         appWidgetHost.deleteAppWidgetId(launcherAppWidgetInfo.appWidgetId);
    208                     }
    209                 }.start();
    210             }
    211         }
    212     }
    213 
    214     public void onDrop(DragObject d) {
    215         animateToTrashAndCompleteDrop(d);
    216     }
    217 }
    218