summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorWinson Chung <winsonc@google.com>2010-10-27 17:18:37 -0700
committerWinson Chung <winsonc@google.com>2010-10-27 18:35:04 -0700
commita9abd0e0bdedb5cbbd12b84cb83037a735e79a20 (patch)
treeaef5a8d3a3f53ef8f46208a32482f3f21f216841 /src
parent625a647badd1dcf0551aa03319a36a79bc3be8f3 (diff)
downloadandroid_packages_apps_Trebuchet-a9abd0e0bdedb5cbbd12b84cb83037a735e79a20.tar.gz
android_packages_apps_Trebuchet-a9abd0e0bdedb5cbbd12b84cb83037a735e79a20.tar.bz2
android_packages_apps_Trebuchet-a9abd0e0bdedb5cbbd12b84cb83037a735e79a20.zip
Initial changes to allow dragging external shortcuts to launcher using the same InstallShortcut intent.
Change-Id: I21b57115429ed37d604084ae01308d1d3f33ee7e
Diffstat (limited to 'src')
-rw-r--r--src/com/android/launcher2/CellLayout.java32
-rw-r--r--src/com/android/launcher2/InstallShortcutReceiver.java2
-rw-r--r--src/com/android/launcher2/Launcher.java4
-rw-r--r--src/com/android/launcher2/LauncherModel.java23
-rw-r--r--src/com/android/launcher2/Workspace.java126
5 files changed, 165 insertions, 22 deletions
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index 63da108d0..3c82290f8 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -16,7 +16,7 @@
package com.android.launcher2;
-import com.android.launcher.R;
+import java.util.Arrays;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
@@ -26,6 +26,7 @@ import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.app.WallpaperManager;
+import android.content.ClipDescription;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -41,6 +42,7 @@ import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.ContextMenu;
+import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewDebug;
@@ -49,7 +51,7 @@ import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LayoutAnimationController;
-import java.util.Arrays;
+import com.android.launcher.R;
public class CellLayout extends ViewGroup implements Dimmable {
static final String TAG = "CellLayout";
@@ -972,7 +974,11 @@ public class CellLayout extends ViewGroup implements Dimmable {
final int oldDragCellX = mDragCell[0];
final int oldDragCellY = mDragCell[1];
final int[] nearest = findNearestVacantArea(originX, originY, spanX, spanY, v, mDragCell);
- mDragCenter.set(originX + (v.getWidth() / 2), originY + (v.getHeight() / 2));
+ if (v != null) {
+ mDragCenter.set(originX + (v.getWidth() / 2), originY + (v.getHeight() / 2));
+ } else {
+ mDragCenter.set(originX, originY);
+ }
if (nearest != null && (nearest[0] != oldDragCellX || nearest[1] != oldDragCellY)) {
// Find the top left corner of the rect the object will occupy
@@ -982,15 +988,17 @@ public class CellLayout extends ViewGroup implements Dimmable {
int left = topLeft[0];
int top = topLeft[1];
- if (v.getParent() instanceof CellLayout) {
- LayoutParams lp = (LayoutParams) v.getLayoutParams();
- left += lp.leftMargin;
- top += lp.topMargin;
- }
+ if (v != null) {
+ if (v.getParent() instanceof CellLayout) {
+ LayoutParams lp = (LayoutParams) v.getLayoutParams();
+ left += lp.leftMargin;
+ top += lp.topMargin;
+ }
- // Offsets due to the size difference between the View and the dragOutline
- left += (v.getWidth() - dragOutline.getWidth()) / 2;
- top += (v.getHeight() - dragOutline.getHeight()) / 2;
+ // Offsets due to the size difference between the View and the dragOutline
+ left += (v.getWidth() - dragOutline.getWidth()) / 2;
+ top += (v.getHeight() - dragOutline.getHeight()) / 2;
+ }
final int oldIndex = mDragOutlineCurrent;
mDragOutlineAnims[oldIndex].animateOut();
@@ -1271,7 +1279,7 @@ public class CellLayout extends ViewGroup implements Dimmable {
* It may have begun over this layout (in which case onDragChild is called first),
* or it may have begun on another layout.
*/
- void onDragEnter(View dragView) {
+ void onDragEnter() {
if (!mDragging) {
// Fade in the drag indicators
if (mCrosshairsAnimator != null) {
diff --git a/src/com/android/launcher2/InstallShortcutReceiver.java b/src/com/android/launcher2/InstallShortcutReceiver.java
index caeb12b4a..8d72531d5 100644
--- a/src/com/android/launcher2/InstallShortcutReceiver.java
+++ b/src/com/android/launcher2/InstallShortcutReceiver.java
@@ -26,7 +26,7 @@ import android.widget.Toast;
import com.android.launcher.R;
public class InstallShortcutReceiver extends BroadcastReceiver {
- private static final String ACTION_INSTALL_SHORTCUT =
+ public static final String ACTION_INSTALL_SHORTCUT =
"com.android.launcher.action.INSTALL_SHORTCUT";
private final int[] mCoordinates = new int[2];
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 444357ebc..346e472c5 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -1144,6 +1144,10 @@ public final class Launcher extends Activity
return mAppWidgetHost;
}
+ public LauncherModel getModel() {
+ return mModel;
+ }
+
void closeSystemDialogs() {
getWindow().closeAllPanels();
diff --git a/src/com/android/launcher2/LauncherModel.java b/src/com/android/launcher2/LauncherModel.java
index 1e58ca0e4..179a5d5c0 100644
--- a/src/com/android/launcher2/LauncherModel.java
+++ b/src/com/android/launcher2/LauncherModel.java
@@ -1513,14 +1513,25 @@ public class LauncherModel extends BroadcastReceiver {
ShortcutInfo addShortcut(Context context, Intent data,
int screen, int cellX, int cellY, boolean notify) {
- final ShortcutInfo info = infoFromShortcutIntent(context, data);
+ final ShortcutInfo info = infoFromShortcutIntent(context, data, null);
addItemToDatabase(context, info, LauncherSettings.Favorites.CONTAINER_DESKTOP,
screen, cellX, cellY, notify);
return info;
}
- private ShortcutInfo infoFromShortcutIntent(Context context, Intent data) {
+ /**
+ * Ensures that a given shortcut intent actually has all the fields that we need to create a
+ * proper ShortcutInfo.
+ */
+ boolean validateShortcutIntent(Intent data) {
+ // We don't require Intent.EXTRA_SHORTCUT_ICON, since we can pull a default fallback icon
+ return InstallShortcutReceiver.ACTION_INSTALL_SHORTCUT.equals(data.getAction()) &&
+ (data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT) != null) &&
+ (data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME) != null);
+ }
+
+ ShortcutInfo infoFromShortcutIntent(Context context, Intent data, Bitmap fallbackIcon) {
Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
Parcelable bitmap = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
@@ -1553,8 +1564,12 @@ public class LauncherModel extends BroadcastReceiver {
final ShortcutInfo info = new ShortcutInfo();
if (icon == null) {
- icon = getFallbackIcon();
- info.usingFallbackIcon = true;
+ if (fallbackIcon != null) {
+ icon = fallbackIcon;
+ } else {
+ icon = getFallbackIcon();
+ info.usingFallbackIcon = true;
+ }
}
info.setIcon(icon);
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index ce613f135..07faed101 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -16,7 +16,8 @@
package com.android.launcher2;
-import com.android.launcher.R;
+import java.util.ArrayList;
+import java.util.HashSet;
import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
@@ -27,6 +28,8 @@ import android.animation.PropertyValuesHolder;
import android.app.WallpaperManager;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
+import android.content.ClipData;
+import android.content.ClipDescription;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -36,8 +39,11 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Color;
import android.graphics.Matrix;
+import android.graphics.Paint;
import android.graphics.Rect;
+import android.graphics.RectF;
import android.graphics.Region.Op;
import android.graphics.drawable.Drawable;
import android.net.Uri;
@@ -45,12 +51,13 @@ import android.os.IBinder;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
+import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
+import android.widget.Toast;
-import java.util.ArrayList;
-import java.util.HashSet;
+import com.android.launcher.R;
/**
* The workspace is a wide area with a wallpaper and a finite number of pages.
@@ -144,6 +151,9 @@ public class Workspace extends SmoothPagedView
private final Rect mTempRect = new Rect();
private final int[] mTempXY = new int[2];
+ // Paint used to draw external drop outline
+ private final Paint mExternalDragOutlinePaint = new Paint();
+
/**
* Used to inflate the Workspace from XML.
*
@@ -193,6 +203,7 @@ public class Workspace extends SmoothPagedView
Launcher.setScreen(mCurrentPage);
LauncherApplication app = (LauncherApplication)context.getApplicationContext();
mIconCache = app.getIconCache();
+ mExternalDragOutlinePaint.setAntiAlias(true);
mUnshrinkAnimationListener = new AnimatorListenerAdapter() {
public void onAnimationStart(Animator animation) {
@@ -984,6 +995,29 @@ public class Workspace extends SmoothPagedView
}
/**
+ * Creates a drag outline to represent a drop (that we don't have the actual information for
+ * yet). May be changed in the future to alter the drop outline slightly depending on the
+ * clip description mime data.
+ */
+ private Bitmap createExternalDragOutline(Canvas canvas, int padding) {
+ Resources r = getResources();
+ final int outlineColor = r.getColor(R.color.drag_outline_color);
+ final int iconWidth = r.getDimensionPixelSize(R.dimen.workspace_cell_width);
+ final int iconHeight = r.getDimensionPixelSize(R.dimen.workspace_cell_height);
+ final int rectRadius = r.getDimensionPixelSize(R.dimen.external_drop_icon_rect_radius);
+ final int inset = (int) (Math.min(iconWidth, iconHeight) * 0.2f);
+ final Bitmap b = Bitmap.createBitmap(
+ iconWidth + padding, iconHeight + padding, Bitmap.Config.ARGB_8888);
+
+ canvas.setBitmap(b);
+ canvas.drawRoundRect(new RectF(inset, inset, iconWidth - inset, iconHeight - inset),
+ rectRadius, rectRadius, mExternalDragOutlinePaint);
+ mOutlineHelper.applyExpensiveOuterOutline(b, canvas, outlineColor, true);
+
+ return b;
+ }
+
+ /**
* Returns a new bitmap to show when the given View is being dragged around.
* Responsibility for the bitmap is transferred to the caller.
*/
@@ -1136,7 +1170,7 @@ public class Workspace extends SmoothPagedView
if (!mIsSmall) {
mDragTargetLayout = getCurrentDropLayout();
- mDragTargetLayout.onDragEnter(dragView);
+ mDragTargetLayout.onDragEnter();
showOutlines();
}
}
@@ -1182,6 +1216,88 @@ public class Workspace extends SmoothPagedView
return null;
}
+ /**
+ * Global drag and drop handler
+ */
+ @Override
+ public boolean onDragEvent(DragEvent event) {
+ final CellLayout layout = (CellLayout) getChildAt(mCurrentPage);
+ final int[] pos = new int[2];
+ layout.getLocationOnScreen(pos);
+ // We need to offset the drag coordinates to layout coordinate space
+ final int x = (int) event.getX() - pos[0];
+ final int y = (int) event.getY() - pos[1];
+
+ switch (event.getAction()) {
+ case DragEvent.ACTION_DRAG_STARTED:
+ // Check if we have enough space on this screen to add a new shortcut
+ if (!layout.findCellForSpan(pos, 1, 1)) {
+ Toast.makeText(mContext, mContext.getString(R.string.out_of_space),
+ Toast.LENGTH_SHORT).show();
+ return false;
+ }
+
+ ClipDescription desc = event.getClipDescription();
+ if (desc.filterMimeTypes(ClipDescription.MIMETYPE_TEXT_INTENT) != null) {
+ // Create the drag outline
+ // We need to add extra padding to the bitmap to make room for the glow effect
+ final Canvas canvas = new Canvas();
+ final int bitmapPadding = HolographicOutlineHelper.OUTER_BLUR_RADIUS;
+ mDragOutline = createExternalDragOutline(canvas, bitmapPadding);
+
+ // Show the current page outlines to indicate that we can accept this drop
+ showOutlines();
+ layout.setHover(true);
+ layout.onDragEnter();
+ layout.visualizeDropLocation(null, mDragOutline, x, y, 1, 1);
+
+ return true;
+ }
+ break;
+ case DragEvent.ACTION_DRAG_LOCATION:
+ // Visualize the drop location
+ layout.visualizeDropLocation(null, mDragOutline, x, y, 1, 1);
+ return true;
+ case DragEvent.ACTION_DROP:
+ // Check if we have enough space on this screen to add a new shortcut
+ if (!layout.findCellForSpan(pos, 1, 1)) {
+ Toast.makeText(mContext, mContext.getString(R.string.out_of_space),
+ Toast.LENGTH_SHORT).show();
+ return false;
+ }
+
+ // Try and add any shortcuts
+ int newDropCount = 0;
+ final LauncherModel model = mLauncher.getModel();
+ final ClipData data = event.getClipData();
+ final int itemCount = data.getItemCount();
+ for (int i = 0; i < itemCount; ++i) {
+ final Intent intent = data.getItem(i).getIntent();
+ if (intent != null && model.validateShortcutIntent(intent)) {
+ ShortcutInfo info = model.infoFromShortcutIntent(mContext, intent, data.
+ getIcon());
+ onDropExternal(x, y, info, layout);
+ newDropCount++;
+ }
+ }
+
+ // Show error message if we couldn't accept any of the items
+ if (newDropCount <= 0) {
+ Toast.makeText(mContext, "Only Shortcut Intents accepted.",
+ Toast.LENGTH_SHORT).show();
+ }
+
+ return true;
+ case DragEvent.ACTION_DRAG_ENDED:
+ // Hide the page outlines after the drop
+ layout.setHover(false);
+ layout.onDragExit();
+ hideOutlines();
+ return true;
+ }
+ return super.onDragEvent(event);
+ }
+
/*
*
* Convert the 2D coordinate xy from the parent View's coordinate space to this CellLayout's
@@ -1382,7 +1498,7 @@ public class Workspace extends SmoothPagedView
if (mDragTargetLayout != null) {
mDragTargetLayout.onDragExit();
}
- layout.onDragEnter(dragView);
+ layout.onDragEnter();
mDragTargetLayout = layout;
}