Simplifying drag preview generation
> Fixing wrong icon normalization when dragging a folder icon
> Reusing the preview bitmap for creating dragOutline
> Generating drag outline on the background thread
Bug: 35428783
Change-Id: I01e724ba63404302090ee1e562f6c2fc7147ba2f
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index dfcb331..c82731f 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -252,8 +252,6 @@
private boolean mAddToExistingFolderOnDrop = false;
private float mMaxDistanceForFolderCreation;
- private final Canvas mCanvas = new Canvas();
-
// Variables relating to touch disambiguation (scrolling workspace vs. scrolling a widget)
private float mXDown;
private float mYDown;
@@ -351,12 +349,9 @@
/**
* Estimates the size of an item using spans: hSpan, vSpan.
*
- * @param springLoaded True if we are in spring loaded mode.
- * @param unscaledSize True if caller wants to return the unscaled size
* @return MAX_VALUE for each dimension if unsuccessful.
*/
- public int[] estimateItemSize(ItemInfo itemInfo, boolean springLoaded, boolean unscaledSize) {
- float shrinkFactor = mLauncher.getDeviceProfile().workspaceSpringLoadShrinkFactor;
+ public int[] estimateItemSize(ItemInfo itemInfo) {
int[] size = new int[2];
if (getChildCount() > 0) {
// Use the first page to estimate the child position
@@ -373,15 +368,10 @@
size[0] = r.width();
size[1] = r.height();
- if (isWidget && unscaledSize) {
+ if (isWidget) {
size[0] /= scale;
size[1] /= scale;
}
-
- if (springLoaded) {
- size[0] *= shrinkFactor;
- size[1] *= shrinkFactor;
- }
return size;
} else {
size[0] = Integer.MAX_VALUE;
@@ -408,8 +398,12 @@
}
if (mOutlineProvider != null) {
- // The outline is used to visualize where the item will land if dropped
- mOutlineProvider.generateDragOutline(mCanvas);
+ if (dragObject.dragView != null) {
+ Bitmap preview = dragObject.dragView.getPreviewBitmap();
+
+ // The outline is used to visualize where the item will land if dropped
+ mOutlineProvider.generateDragOutline(preview);
+ }
}
updateChildrenLayersEnabled(false);
@@ -1833,7 +1827,7 @@
mOutlineProvider = previewProvider;
// The drag bitmap follows the touch point around on the screen
- final Bitmap b = previewProvider.createDragBitmap(mCanvas);
+ final Bitmap b = previewProvider.createDragBitmap();
int halfPadding = previewProvider.previewPadding / 2;
float scale = previewProvider.getScaleAndPosition(b, mTempXY);
@@ -1881,7 +1875,6 @@
DragView dv = mDragController.startDrag(b, dragLayerX, dragLayerY, source,
dragObject, dragVisualizeOffset, dragRect, scale, dragOptions);
dv.setIntrinsicIconScaleFactor(source.getIntrinsicIconScaleFactor());
- b.recycle();
return dv;
}
@@ -2992,7 +2985,7 @@
}
public Bitmap createWidgetBitmap(ItemInfo widgetInfo, View layout) {
- int[] unScaledSize = mLauncher.getWorkspace().estimateItemSize(widgetInfo, false, true);
+ int[] unScaledSize = estimateItemSize(widgetInfo);
int visibility = layout.getVisibility();
layout.setVisibility(VISIBLE);
@@ -3000,12 +2993,9 @@
int height = MeasureSpec.makeMeasureSpec(unScaledSize[1], MeasureSpec.EXACTLY);
Bitmap b = Bitmap.createBitmap(unScaledSize[0], unScaledSize[1],
Bitmap.Config.ARGB_8888);
- mCanvas.setBitmap(b);
-
layout.measure(width, height);
layout.layout(0, 0, unScaledSize[0], unScaledSize[1]);
- layout.draw(mCanvas);
- mCanvas.setBitmap(null);
+ layout.draw(new Canvas(b));
layout.setVisibility(visibility);
return b;
}
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index 33d4fa6..17fad84 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -169,7 +169,7 @@
}
});
- mBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight());
+ mBitmap = bitmap;
setDragRegion(new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()));
// The point in our scaled bitmap that the touch events are located
@@ -427,6 +427,10 @@
return mDragRegion;
}
+ public Bitmap getPreviewBitmap() {
+ return mBitmap;
+ }
+
@Override
protected void onDraw(Canvas canvas) {
mHasDrawn = true;
diff --git a/src/com/android/launcher3/graphics/DragPreviewProvider.java b/src/com/android/launcher3/graphics/DragPreviewProvider.java
index 10e91c0..0989921 100644
--- a/src/com/android/launcher3/graphics/DragPreviewProvider.java
+++ b/src/com/android/launcher3/graphics/DragPreviewProvider.java
@@ -18,19 +18,27 @@
import android.content.Context;
import android.graphics.Bitmap;
+import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.Region.Op;
import android.graphics.drawable.Drawable;
+import android.os.Handler;
import android.view.View;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherAppWidgetHostView;
+import com.android.launcher3.LauncherModel;
import com.android.launcher3.R;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.folder.FolderIcon;
+import java.nio.ByteBuffer;
+
/**
* A utility class to generate preview bitmap for dragging.
*/
@@ -45,6 +53,7 @@
protected final int blurSizeOutline;
+ private OutlineGeneratorCallback mOutlineGeneratorCallback;
public Bitmap generatedDragOutline;
public DragPreviewProvider(View view) {
@@ -106,7 +115,7 @@
* Returns a new bitmap to show when the {@link #mView} is being dragged around.
* Responsibility for the bitmap is transferred to the caller.
*/
- public Bitmap createDragBitmap(Canvas canvas) {
+ public Bitmap createDragBitmap() {
float scale = 1f;
int width = mView.getWidth();
int height = mView.getHeight();
@@ -124,7 +133,7 @@
Bitmap b = Bitmap.createBitmap(width + blurSizeOutline, height + blurSizeOutline,
Bitmap.Config.ARGB_8888);
- canvas.setBitmap(b);
+ Canvas canvas = new Canvas(b);
canvas.save();
canvas.scale(scale, scale);
@@ -136,43 +145,13 @@
return b;
}
- public final void generateDragOutline(Canvas canvas) {
- if (FeatureFlags.IS_DOGFOOD_BUILD && generatedDragOutline != null) {
+ public final void generateDragOutline(Bitmap preview) {
+ if (FeatureFlags.IS_DOGFOOD_BUILD && mOutlineGeneratorCallback != null) {
throw new RuntimeException("Drag outline generated twice");
}
- generatedDragOutline = createDragOutline(canvas);
- }
-
- /**
- * Returns a new bitmap to be used as the object outline, e.g. to visualize the drop location.
- * Responsibility for the bitmap is transferred to the caller.
- */
- public Bitmap createDragOutline(Canvas canvas) {
- float scale = 1f;
- int width = mView.getWidth();
- int height = mView.getHeight();
-
- if (mView instanceof LauncherAppWidgetHostView) {
- scale = ((LauncherAppWidgetHostView) mView).getScaleToFit();
- width = (int) Math.floor(mView.getWidth() * scale);
- height = (int) Math.floor(mView.getHeight() * scale);
- }
-
- Bitmap b = Bitmap.createBitmap(width + blurSizeOutline, height + blurSizeOutline,
- Bitmap.Config.ALPHA_8);
- canvas.setBitmap(b);
-
- canvas.save();
- canvas.scale(scale, scale);
- drawDragView(canvas);
- canvas.restore();
-
- HolographicOutlineHelper.getInstance(mView.getContext())
- .applyExpensiveOutlineWithBlur(b, canvas);
-
- canvas.setBitmap(null);
- return b;
+ mOutlineGeneratorCallback = new OutlineGeneratorCallback(preview);
+ new Handler(LauncherModel.getWorkerLooper()).postAtFrontOfQueue(mOutlineGeneratorCallback);
}
protected static Rect getDrawableBounds(Drawable d) {
@@ -201,4 +180,89 @@
- previewPadding / 2);
return scale;
}
+
+ protected Bitmap convertPreviewToAlphaBitmap(Bitmap preview) {
+ return preview.copy(Bitmap.Config.ALPHA_8, true);
+ }
+
+ private class OutlineGeneratorCallback implements Runnable {
+
+ private final Bitmap mPreviewSnapshot;
+ private final Context mContext;
+
+ OutlineGeneratorCallback(Bitmap preview) {
+ mPreviewSnapshot = preview;
+ mContext = mView.getContext();
+ }
+
+ @Override
+ public void run() {
+ Bitmap preview = convertPreviewToAlphaBitmap(mPreviewSnapshot);
+
+ // We start by removing most of the alpha channel so as to ignore shadows, and
+ // other types of partial transparency when defining the shape of the object
+ byte[] pixels = new byte[preview.getWidth() * preview.getHeight()];
+ ByteBuffer buffer = ByteBuffer.wrap(pixels);
+ buffer.rewind();
+ preview.copyPixelsToBuffer(buffer);
+
+ for (int i = 0; i < pixels.length; i++) {
+ if ((pixels[i] & 0xFF) < 188) {
+ pixels[i] = 0;
+ }
+ }
+
+ buffer.rewind();
+ preview.copyPixelsFromBuffer(buffer);
+
+ final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+ Canvas canvas = new Canvas();
+
+ // calculate the outer blur first
+ paint.setMaskFilter(new BlurMaskFilter(blurSizeOutline, BlurMaskFilter.Blur.OUTER));
+ int[] outerBlurOffset = new int[2];
+ Bitmap thickOuterBlur = preview.extractAlpha(paint, outerBlurOffset);
+
+ paint.setMaskFilter(new BlurMaskFilter(
+ mContext.getResources().getDimension(R.dimen.blur_size_thin_outline),
+ BlurMaskFilter.Blur.OUTER));
+ int[] brightOutlineOffset = new int[2];
+ Bitmap brightOutline = preview.extractAlpha(paint, brightOutlineOffset);
+
+ // calculate the inner blur
+ canvas.setBitmap(preview);
+ canvas.drawColor(0xFF000000, PorterDuff.Mode.SRC_OUT);
+ paint.setMaskFilter(new BlurMaskFilter(blurSizeOutline, BlurMaskFilter.Blur.NORMAL));
+ int[] thickInnerBlurOffset = new int[2];
+ Bitmap thickInnerBlur = preview.extractAlpha(paint, thickInnerBlurOffset);
+
+ // mask out the inner blur
+ paint.setMaskFilter(null);
+ paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
+ canvas.setBitmap(thickInnerBlur);
+ canvas.drawBitmap(preview, -thickInnerBlurOffset[0],
+ -thickInnerBlurOffset[1], paint);
+ canvas.drawRect(0, 0, -thickInnerBlurOffset[0], thickInnerBlur.getHeight(), paint);
+ canvas.drawRect(0, 0, thickInnerBlur.getWidth(), -thickInnerBlurOffset[1], paint);
+
+ // draw the inner and outer blur
+ paint.setXfermode(null);
+ canvas.setBitmap(preview);
+ canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+ canvas.drawBitmap(thickInnerBlur, thickInnerBlurOffset[0], thickInnerBlurOffset[1],
+ paint);
+ canvas.drawBitmap(thickOuterBlur, outerBlurOffset[0], outerBlurOffset[1], paint);
+
+ // draw the bright outline
+ canvas.drawBitmap(brightOutline, brightOutlineOffset[0], brightOutlineOffset[1], paint);
+
+ // cleanup
+ canvas.setBitmap(null);
+ brightOutline.recycle();
+ thickOuterBlur.recycle();
+ thickInnerBlur.recycle();
+
+ generatedDragOutline = preview;
+ }
+ }
}
diff --git a/src/com/android/launcher3/graphics/HolographicOutlineHelper.java b/src/com/android/launcher3/graphics/HolographicOutlineHelper.java
index b221828..9e67f56 100644
--- a/src/com/android/launcher3/graphics/HolographicOutlineHelper.java
+++ b/src/com/android/launcher3/graphics/HolographicOutlineHelper.java
@@ -17,7 +17,6 @@
package com.android.launcher3.graphics;
import android.content.Context;
-import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
@@ -31,9 +30,6 @@
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.R;
-import com.android.launcher3.config.FeatureFlags;
-
-import java.nio.ByteBuffer;
/**
* Utility class to generate shadow and outline effect, which are used for click feedback
@@ -44,14 +40,9 @@
private static HolographicOutlineHelper sInstance;
private final Canvas mCanvas = new Canvas();
- private final Paint mDrawPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
private final Paint mBlurPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
private final Paint mErasePaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
- private final BlurMaskFilter mMediumOuterBlurMaskFilter;
- private final BlurMaskFilter mThinOuterBlurMaskFilter;
- private final BlurMaskFilter mMediumInnerBlurMaskFilter;
-
private final float mShadowBitmapShift;
private final BlurMaskFilter mShadowBlurMaskFilter;
@@ -59,18 +50,8 @@
private final SparseArray<Bitmap> mBitmapCache = new SparseArray<>(4);
private HolographicOutlineHelper(Context context) {
- Resources res = context.getResources();
-
- float mediumBlur = res.getDimension(R.dimen.blur_size_medium_outline);
- mMediumOuterBlurMaskFilter = new BlurMaskFilter(mediumBlur, BlurMaskFilter.Blur.OUTER);
- mMediumInnerBlurMaskFilter = new BlurMaskFilter(mediumBlur, BlurMaskFilter.Blur.NORMAL);
-
- mThinOuterBlurMaskFilter = new BlurMaskFilter(
- res.getDimension(R.dimen.blur_size_thin_outline), BlurMaskFilter.Blur.OUTER);
-
- mShadowBitmapShift = res.getDimension(R.dimen.blur_size_click_shadow);
+ mShadowBitmapShift = context.getResources().getDimension(R.dimen.blur_size_click_shadow);
mShadowBlurMaskFilter = new BlurMaskFilter(mShadowBitmapShift, BlurMaskFilter.Blur.NORMAL);
-
mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
}
@@ -81,75 +62,6 @@
return sInstance;
}
- /**
- * Applies a more expensive and accurate outline to whatever is currently drawn in a specified
- * bitmap.
- */
- public void applyExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas) {
- if (FeatureFlags.IS_DOGFOOD_BUILD && srcDst.getConfig() != Bitmap.Config.ALPHA_8) {
- throw new RuntimeException("Outline blue is only supported on alpha bitmaps");
- }
-
- // We start by removing most of the alpha channel so as to ignore shadows, and
- // other types of partial transparency when defining the shape of the object
- byte[] pixels = new byte[srcDst.getWidth() * srcDst.getHeight()];
- ByteBuffer buffer = ByteBuffer.wrap(pixels);
- buffer.rewind();
- srcDst.copyPixelsToBuffer(buffer);
-
- for (int i = 0; i < pixels.length; i++) {
- if ((pixels[i] & 0xFF) < 188) {
- pixels[i] = 0;
- }
- }
-
- buffer.rewind();
- srcDst.copyPixelsFromBuffer(buffer);
-
- // calculate the outer blur first
- mBlurPaint.setMaskFilter(mMediumOuterBlurMaskFilter);
- int[] outerBlurOffset = new int[2];
- Bitmap thickOuterBlur = srcDst.extractAlpha(mBlurPaint, outerBlurOffset);
-
- mBlurPaint.setMaskFilter(mThinOuterBlurMaskFilter);
- int[] brightOutlineOffset = new int[2];
- Bitmap brightOutline = srcDst.extractAlpha(mBlurPaint, brightOutlineOffset);
-
- // calculate the inner blur
- srcDstCanvas.setBitmap(srcDst);
- srcDstCanvas.drawColor(0xFF000000, PorterDuff.Mode.SRC_OUT);
- mBlurPaint.setMaskFilter(mMediumInnerBlurMaskFilter);
- int[] thickInnerBlurOffset = new int[2];
- Bitmap thickInnerBlur = srcDst.extractAlpha(mBlurPaint, thickInnerBlurOffset);
-
- // mask out the inner blur
- srcDstCanvas.setBitmap(thickInnerBlur);
- srcDstCanvas.drawBitmap(srcDst, -thickInnerBlurOffset[0],
- -thickInnerBlurOffset[1], mErasePaint);
- srcDstCanvas.drawRect(0, 0, -thickInnerBlurOffset[0], thickInnerBlur.getHeight(),
- mErasePaint);
- srcDstCanvas.drawRect(0, 0, thickInnerBlur.getWidth(), -thickInnerBlurOffset[1],
- mErasePaint);
-
- // draw the inner and outer blur
- srcDstCanvas.setBitmap(srcDst);
- srcDstCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
- srcDstCanvas.drawBitmap(thickInnerBlur, thickInnerBlurOffset[0], thickInnerBlurOffset[1],
- mDrawPaint);
- srcDstCanvas.drawBitmap(thickOuterBlur, outerBlurOffset[0], outerBlurOffset[1],
- mDrawPaint);
-
- // draw the bright outline
- srcDstCanvas.drawBitmap(brightOutline, brightOutlineOffset[0], brightOutlineOffset[1],
- mDrawPaint);
-
- // cleanup
- srcDstCanvas.setBitmap(null);
- brightOutline.recycle();
- thickOuterBlur.recycle();
- thickInnerBlur.recycle();
- }
-
public Bitmap createMediumDropShadow(BubbleTextView view) {
Drawable drawable = view.getIcon();
if (drawable == null) {
diff --git a/src/com/android/launcher3/graphics/IconNormalizer.java b/src/com/android/launcher3/graphics/IconNormalizer.java
index 28fc423..5ee6a30 100644
--- a/src/com/android/launcher3/graphics/IconNormalizer.java
+++ b/src/com/android/launcher3/graphics/IconNormalizer.java
@@ -28,12 +28,15 @@
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.Utilities;
+import com.android.launcher3.dragndrop.FolderAdaptiveIcon;
+
import java.io.File;
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
@@ -231,12 +234,17 @@
*/
public synchronized float getScale(@NonNull Drawable d, @Nullable RectF outBounds,
@Nullable Path path, @Nullable boolean[] outMaskShape) {
- if (Utilities.ATLEAST_OREO && d instanceof AdaptiveIconDrawable &&
- mAdaptiveIconScale != SCALE_NOT_INITIALIZED) {
- if (outBounds != null) {
- outBounds.set(mAdaptiveIconBounds);
+ if (Utilities.ATLEAST_OREO && d instanceof AdaptiveIconDrawable) {
+ if (mAdaptiveIconScale != SCALE_NOT_INITIALIZED) {
+ if (outBounds != null) {
+ outBounds.set(mAdaptiveIconBounds);
+ }
+ return mAdaptiveIconScale;
}
- return mAdaptiveIconScale;
+ if (d instanceof FolderAdaptiveIcon) {
+ // Since we just want the scale, avoid heavy drawing operations
+ d = new AdaptiveIconDrawable(new ColorDrawable(Color.BLACK), null);
+ }
}
int width = d.getIntrinsicWidth();
int height = d.getIntrinsicHeight();
diff --git a/src/com/android/launcher3/shortcuts/ShortcutDragPreviewProvider.java b/src/com/android/launcher3/shortcuts/ShortcutDragPreviewProvider.java
index e9d2b50..cfb9258 100644
--- a/src/com/android/launcher3/shortcuts/ShortcutDragPreviewProvider.java
+++ b/src/com/android/launcher3/shortcuts/ShortcutDragPreviewProvider.java
@@ -26,7 +26,6 @@
import com.android.launcher3.Launcher;
import com.android.launcher3.Utilities;
import com.android.launcher3.graphics.DragPreviewProvider;
-import com.android.launcher3.graphics.HolographicOutlineHelper;
/**
* Extension of {@link DragPreviewProvider} which generates bitmaps scaled to the default icon size.
@@ -40,35 +39,17 @@
mPositionShift = shift;
}
- @Override
- public Bitmap createDragOutline(Canvas canvas) {
- Bitmap b = drawScaledPreview(canvas, Bitmap.Config.ALPHA_8);
-
- HolographicOutlineHelper.getInstance(mView.getContext())
- .applyExpensiveOutlineWithBlur(b, canvas);
- canvas.setBitmap(null);
- return b;
- }
-
- @Override
- public Bitmap createDragBitmap(Canvas canvas) {
- Bitmap b = drawScaledPreview(canvas, Bitmap.Config.ARGB_8888);
- canvas.setBitmap(null);
- return b;
- }
-
- private Bitmap drawScaledPreview(Canvas canvas, Bitmap.Config config) {
+ public Bitmap createDragBitmap() {
Drawable d = mView.getBackground();
Rect bounds = getDrawableBounds(d);
int size = Launcher.getLauncher(mView.getContext()).getDeviceProfile().iconSizePx;
-
final Bitmap b = Bitmap.createBitmap(
size + blurSizeOutline,
size + blurSizeOutline,
- config);
+ Bitmap.Config.ARGB_8888);
- canvas.setBitmap(b);
+ Canvas canvas = new Canvas(b);
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.translate(blurSizeOutline / 2, blurSizeOutline / 2);
canvas.scale(((float) size) / bounds.width(), ((float) size) / bounds.height(), 0, 0);
diff --git a/src/com/android/launcher3/widget/PendingItemDragHelper.java b/src/com/android/launcher3/widget/PendingItemDragHelper.java
index 19be28d..c5cf5e2 100644
--- a/src/com/android/launcher3/widget/PendingItemDragHelper.java
+++ b/src/com/android/launcher3/widget/PendingItemDragHelper.java
@@ -22,7 +22,6 @@
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
-import android.os.Build;
import android.view.View;
import android.widget.RemoteViews;
@@ -32,11 +31,9 @@
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.PendingAddItemInfo;
import com.android.launcher3.R;
-import com.android.launcher3.Workspace;
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.dragndrop.LivePreviewWidgetCell;
import com.android.launcher3.graphics.DragPreviewProvider;
-import com.android.launcher3.graphics.HolographicOutlineHelper;
import com.android.launcher3.graphics.LauncherIcons;
/**
@@ -48,8 +45,8 @@
private static final float MAX_WIDGET_SCALE = 1.25f;
private final PendingAddItemInfo mAddInfo;
+ private int[] mEstimatedCellSize;
- private Bitmap mPreviewBitmap;
private RemoteViews mPreview;
public PendingItemDragHelper(View view) {
@@ -80,12 +77,12 @@
final Point dragOffset;
final Rect dragRegion;
+ mEstimatedCellSize = launcher.getWorkspace().estimateItemSize(mAddInfo);
if (mAddInfo instanceof PendingAddWidgetInfo) {
PendingAddWidgetInfo createWidgetInfo = (PendingAddWidgetInfo) mAddInfo;
- int[] size = launcher.getWorkspace().estimateItemSize(createWidgetInfo, true, false);
- int maxWidth = Math.min((int) (previewBitmapWidth * MAX_WIDGET_SCALE), size[0]);
+ int maxWidth = Math.min((int) (previewBitmapWidth * MAX_WIDGET_SCALE), mEstimatedCellSize[0]);
int[] previewSizeBeforeScale = new int[1];
@@ -117,14 +114,12 @@
PendingAddShortcutInfo createShortcutInfo = (PendingAddShortcutInfo) mAddInfo;
Drawable icon = createShortcutInfo.activityInfo.getFullResIcon(app.getIconCache());
preview = LauncherIcons.createScaledBitmapWithoutShadow(icon, launcher, 0);
- mAddInfo.spanX = mAddInfo.spanY = 1;
scale = ((float) launcher.getDeviceProfile().iconSizePx) / preview.getWidth();
dragOffset = new Point(previewPadding / 2, previewPadding / 2);
// Create a preview same as the workspace cell size and draw the icon at the
// appropriate position.
- int[] size = launcher.getWorkspace().estimateItemSize(mAddInfo, false, true);
DeviceProfile dp = launcher.getDeviceProfile();
int iconSize = dp.iconSizePx;
@@ -134,9 +129,10 @@
previewBounds.top += padding;
dragRegion = new Rect();
- dragRegion.left = (size[0] - iconSize) / 2;
+ dragRegion.left = (mEstimatedCellSize[0] - iconSize) / 2;
dragRegion.right = dragRegion.left + iconSize;
- dragRegion.top = (size[1] - iconSize - dp.iconTextSizePx - dp.iconDrawablePaddingPx) / 2;
+ dragRegion.top = (mEstimatedCellSize[1]
+ - iconSize - dp.iconTextSizePx - dp.iconDrawablePaddingPx) / 2;
dragRegion.bottom = dragRegion.top + iconSize;
}
@@ -149,60 +145,31 @@
int dragLayerY = screenPos.y + previewBounds.top
+ (int) ((scale * preview.getHeight() - preview.getHeight()) / 2);
- mPreviewBitmap = preview;
// Start the drag
launcher.getDragController().startDrag(preview, dragLayerX, dragLayerY, source, mAddInfo,
dragOffset, dragRegion, scale, options);
}
-
@Override
- public Bitmap createDragOutline(Canvas canvas) {
- if (mAddInfo instanceof PendingAddShortcutInfo) {
- int width = mPreviewBitmap.getWidth();
- int height = mPreviewBitmap.getHeight();
- Bitmap b = Bitmap.createBitmap(width + blurSizeOutline, height + blurSizeOutline,
- Bitmap.Config.ALPHA_8);
- canvas.setBitmap(b);
-
- Launcher launcher = Launcher.getLauncher(mView.getContext());
- int size = launcher.getDeviceProfile().iconSizePx;
-
- Rect src = new Rect(0, 0, mPreviewBitmap.getWidth(), mPreviewBitmap.getHeight());
- Rect dst = new Rect(0, 0, size, size);
- dst.offset(blurSizeOutline / 2, blurSizeOutline / 2);
- canvas.drawBitmap(mPreviewBitmap, src, dst, new Paint(Paint.FILTER_BITMAP_FLAG));
-
- HolographicOutlineHelper.getInstance(mView.getContext())
- .applyExpensiveOutlineWithBlur(b, canvas);
-
- canvas.setBitmap(null);
- return b;
+ protected Bitmap convertPreviewToAlphaBitmap(Bitmap preview) {
+ if (mAddInfo instanceof PendingAddShortcutInfo || mEstimatedCellSize == null) {
+ return super.convertPreviewToAlphaBitmap(preview);
}
- Workspace workspace = Launcher.getLauncher(mView.getContext()).getWorkspace();
- int[] size = workspace.estimateItemSize(mAddInfo, false, false);
-
- int w = size[0];
- int h = size[1];
+ int w = mEstimatedCellSize[0];
+ int h = mEstimatedCellSize[1];
final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ALPHA_8);
- canvas.setBitmap(b);
+ Rect src = new Rect(0, 0, preview.getWidth(), preview.getHeight());
- Rect src = new Rect(0, 0, mPreviewBitmap.getWidth(), mPreviewBitmap.getHeight());
- float scaleFactor = Math.min((w - blurSizeOutline) / (float) mPreviewBitmap.getWidth(),
- (h - blurSizeOutline) / (float) mPreviewBitmap.getHeight());
- int scaledWidth = (int) (scaleFactor * mPreviewBitmap.getWidth());
- int scaledHeight = (int) (scaleFactor * mPreviewBitmap.getHeight());
+ float scaleFactor = Math.min((w - blurSizeOutline) / (float) preview.getWidth(),
+ (h - blurSizeOutline) / (float) preview.getHeight());
+ int scaledWidth = (int) (scaleFactor * preview.getWidth());
+ int scaledHeight = (int) (scaleFactor * preview.getHeight());
Rect dst = new Rect(0, 0, scaledWidth, scaledHeight);
// center the image
dst.offset((w - scaledWidth) / 2, (h - scaledHeight) / 2);
-
- canvas.drawBitmap(mPreviewBitmap, src, dst, null);
- HolographicOutlineHelper.getInstance(mView.getContext())
- .applyExpensiveOutlineWithBlur(b, canvas);
- canvas.setBitmap(null);
-
+ new Canvas(b).drawBitmap(preview, src, dst, new Paint(Paint.FILTER_BITMAP_FLAG));
return b;
}
}
diff --git a/src/com/android/launcher3/widget/WidgetHostViewLoader.java b/src/com/android/launcher3/widget/WidgetHostViewLoader.java
index e6f8bb6..8dcdd44 100644
--- a/src/com/android/launcher3/widget/WidgetHostViewLoader.java
+++ b/src/com/android/launcher3/widget/WidgetHostViewLoader.java
@@ -129,7 +129,7 @@
mWidgetLoadingId = -1;
hostView.setVisibility(View.INVISIBLE);
- int[] unScaledSize = mLauncher.getWorkspace().estimateItemSize(mInfo, false, true);
+ int[] unScaledSize = mLauncher.getWorkspace().estimateItemSize(mInfo);
// We want the first widget layout to be the correct size. This will be important
// for width size reporting to the AppWidgetManager.
DragLayer.LayoutParams lp = new DragLayer.LayoutParams(unScaledSize[0],