From 7d87cb1a6ef7321857ea4581872bfed6e305cd81 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Mon, 13 Feb 2017 10:44:43 -0800 Subject: Updating the shortcut preview generation logic Drawing a shortcut icon on a white round-rect with shadow Also center aligning the preview Bug: 34819119 Change-Id: Ic25be6bf301aeb11315a5050f009259b26c6134a --- res/values/dimens.xml | 1 + src/com/android/launcher3/WidgetPreviewLoader.java | 106 ++++++++++----------- .../launcher3/widget/PendingItemDragHelper.java | 6 ++ .../android/launcher3/widget/WidgetImageView.java | 25 +++-- 4 files changed, 77 insertions(+), 61 deletions(-) diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 70f5b32c7..f6bb3adc8 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -89,6 +89,7 @@ 1dp 2dp 0.5dp + 8dp 56dp 40dp diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java index 3512210c7..689cc9b3e 100644 --- a/src/com/android/launcher3/WidgetPreviewLoader.java +++ b/src/com/android/launcher3/WidgetPreviewLoader.java @@ -14,22 +14,24 @@ import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Canvas; -import android.graphics.ColorMatrix; -import android.graphics.ColorMatrixColorFilter; +import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; +import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Handler; import android.os.UserHandle; +import android.support.v4.graphics.ColorUtils; import android.util.Log; import android.util.LongSparseArray; import com.android.launcher3.compat.AppWidgetManagerCompat; import com.android.launcher3.compat.ShortcutConfigActivityInfo; import com.android.launcher3.compat.UserManagerCompat; +import com.android.launcher3.graphics.LauncherIcons; import com.android.launcher3.graphics.ShadowGenerator; import com.android.launcher3.model.WidgetItem; import com.android.launcher3.util.ComponentKey; @@ -366,30 +368,13 @@ public class WidgetPreviewLoader { drawable.setBounds(x, 0, x + previewWidth, previewHeight); drawable.draw(c); } else { - Resources res = mContext.getResources(); - float shadowBlur = res.getDimension(R.dimen.widget_preview_shadow_blur); - float keyShadowDistance = res.getDimension(R.dimen.widget_preview_key_shadow_distance); - float corner = res.getDimension(R.dimen.widget_preview_corner_radius); - - RectF boxRect = new RectF(shadowBlur, shadowBlur, - previewWidth - shadowBlur, previewHeight - shadowBlur - keyShadowDistance); - final Paint p = new Paint(Paint.ANTI_ALIAS_FLAG); - p.setColor(0xFFFFFFFF); - - // Key shadow - p.setShadowLayer(shadowBlur, 0, keyShadowDistance, - ShadowGenerator.KEY_SHADOW_ALPHA << 24); - c.drawRoundRect(boxRect, corner, corner, p); - - // Ambient shadow - p.setShadowLayer(shadowBlur, 0, 0, ShadowGenerator.AMBIENT_SHADOW_ALPHA << 24); - c.drawRoundRect(boxRect, corner, corner, p); + RectF boxRect = drawBoxWithShadow(c, p, previewWidth, previewHeight); // Draw horizontal and vertical lines to represent individual columns. - p.clearShadowLayer(); p.setStyle(Paint.Style.STROKE); - p.setStrokeWidth(res.getDimension(R.dimen.widget_preview_cell_divider_width)); + p.setStrokeWidth(mContext.getResources() + .getDimension(R.dimen.widget_preview_cell_divider_width)); p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); float t = boxRect.left; @@ -426,47 +411,63 @@ public class WidgetPreviewLoader { return preview; } + private RectF drawBoxWithShadow(Canvas c, Paint p, int width, int height) { + Resources res = mContext.getResources(); + float shadowBlur = res.getDimension(R.dimen.widget_preview_shadow_blur); + float keyShadowDistance = res.getDimension(R.dimen.widget_preview_key_shadow_distance); + float corner = res.getDimension(R.dimen.widget_preview_corner_radius); + + RectF bounds = new RectF(shadowBlur, shadowBlur, + width - shadowBlur, height - shadowBlur - keyShadowDistance); + p.setColor(Color.WHITE); + + // Key shadow + p.setShadowLayer(shadowBlur, 0, keyShadowDistance, + ShadowGenerator.KEY_SHADOW_ALPHA << 24); + c.drawRoundRect(bounds, corner, corner, p); + + // Ambient shadow + p.setShadowLayer(shadowBlur, 0, 0, + ColorUtils.setAlphaComponent(Color.BLACK, ShadowGenerator.AMBIENT_SHADOW_ALPHA)); + c.drawRoundRect(bounds, corner, corner, p); + + p.clearShadowLayer(); + return bounds; + } + private Bitmap generateShortcutPreview(BaseActivity launcher, ShortcutConfigActivityInfo info, int maxWidth, int maxHeight, Bitmap preview) { + int iconSize = launcher.getDeviceProfile().iconSizePx; + int padding = launcher.getResources() + .getDimensionPixelSize(R.dimen.widget_preview_shortcut_padding); + + int size = iconSize + 2 * padding; + if (maxHeight < size || maxWidth < size) { + throw new RuntimeException("Max size is too small for preview"); + } final Canvas c = new Canvas(); - if (preview == null) { - preview = Bitmap.createBitmap(maxWidth, maxHeight, Config.ARGB_8888); + if (preview == null || preview.getWidth() < size || preview.getHeight() < size) { + preview = Bitmap.createBitmap(size, size, Config.ARGB_8888); c.setBitmap(preview); - } else if (preview.getWidth() != maxWidth || preview.getHeight() != maxHeight) { - throw new RuntimeException("Improperly sized bitmap passed as argument"); } else { + if (preview.getWidth() > size || preview.getHeight() > size) { + preview.reconfigure(size, size, preview.getConfig()); + } + // Reusing bitmap. Clear it. c.setBitmap(preview); c.drawColor(0, PorterDuff.Mode.CLEAR); } + Paint p = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG); + RectF boxRect = drawBoxWithShadow(c, p, size, size); - Drawable icon = mutateOnMainThread(info.getFullResIcon(mIconCache)); - icon.setFilterBitmap(true); - - // Draw a desaturated/scaled version of the icon in the background as a watermark - ColorMatrix colorMatrix = new ColorMatrix(); - colorMatrix.setSaturation(0); - icon.setColorFilter(new ColorMatrixColorFilter(colorMatrix)); - icon.setAlpha((int) (255 * 0.06f)); - - Resources res = mContext.getResources(); - int paddingTop = res.getDimensionPixelOffset(R.dimen.shortcut_preview_padding_top); - int paddingLeft = res.getDimensionPixelOffset(R.dimen.shortcut_preview_padding_left); - int paddingRight = res.getDimensionPixelOffset(R.dimen.shortcut_preview_padding_right); - int scaledIconWidth = (maxWidth - paddingLeft - paddingRight); - icon.setBounds(paddingLeft, paddingTop, - paddingLeft + scaledIconWidth, paddingTop + scaledIconWidth); - icon.draw(c); - - // Draw the final icon at top left corner. - // TODO: use top right for RTL - int appIconSize = launcher.getDeviceProfile().iconSizePx; - - icon.setAlpha(255); - icon.setColorFilter(null); - icon.setBounds(0, 0, appIconSize, appIconSize); - icon.draw(c); + Bitmap icon = LauncherIcons.createScaledBitmapWithoutShadow( + mutateOnMainThread(info.getFullResIcon(mIconCache)), mContext); + Rect src = new Rect(0, 0, icon.getWidth(), icon.getHeight()); + boxRect.set(0, 0, iconSize, iconSize); + boxRect.offset(padding, padding); + c.drawBitmap(icon, src, boxRect, p); c.setBitmap(null); return preview; } @@ -664,7 +665,6 @@ public class WidgetPreviewLoader { private static final class WidgetCacheKey extends ComponentKey { - // TODO: remove dependency on size @Thunk final String size; public WidgetCacheKey(ComponentName componentName, UserHandle user, String size) { diff --git a/src/com/android/launcher3/widget/PendingItemDragHelper.java b/src/com/android/launcher3/widget/PendingItemDragHelper.java index c723f9e8b..6f4c2864b 100644 --- a/src/com/android/launcher3/widget/PendingItemDragHelper.java +++ b/src/com/android/launcher3/widget/PendingItemDragHelper.java @@ -29,6 +29,7 @@ import com.android.launcher3.DragSource; import com.android.launcher3.Launcher; 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.graphics.DragPreviewProvider; @@ -112,6 +113,11 @@ public class PendingItemDragHelper extends DragPreviewProvider { DeviceProfile dp = launcher.getDeviceProfile(); int iconSize = dp.iconSizePx; + int padding = launcher.getResources() + .getDimensionPixelSize(R.dimen.widget_preview_shortcut_padding); + previewBounds.left += padding; + previewBounds.top += padding; + dragRegion = new Rect(); dragRegion.left = (size[0] - iconSize) / 2; dragRegion.right = dragRegion.left + iconSize; diff --git a/src/com/android/launcher3/widget/WidgetImageView.java b/src/com/android/launcher3/widget/WidgetImageView.java index 1211c08a5..df2bcffc1 100644 --- a/src/com/android/launcher3/widget/WidgetImageView.java +++ b/src/com/android/launcher3/widget/WidgetImageView.java @@ -89,16 +89,25 @@ public class WidgetImageView extends View { } private void updateDstRectF() { - if (mBitmap.getWidth() > getWidth()) { - float scale = ((float) getWidth()) / mBitmap.getWidth(); - mDstRectF.set(0, 0, getWidth(), scale * mBitmap.getHeight()); + float myWidth = getWidth(); + float myHeight = getHeight(); + float bitmapWidth = mBitmap.getWidth(); + + final float scale = bitmapWidth > myWidth ? myWidth / bitmapWidth : 1; + float scaledWidth = bitmapWidth * scale; + float scaledHeight = mBitmap.getHeight() * scale; + + mDstRectF.left = (myWidth - scaledWidth) / 2; + mDstRectF.right = (myWidth + scaledWidth) / 2; + + if (scaledHeight > myHeight) { + mDstRectF.top = 0; + mDstRectF.bottom = scaledHeight; } else { - mDstRectF.set( - (getWidth() - mBitmap.getWidth()) * 0.5f, - 0, - (getWidth() + mBitmap.getWidth()) * 0.5f, - mBitmap.getHeight()); + mDstRectF.top = (myHeight - scaledHeight) / 2; + mDstRectF.bottom = (myHeight + scaledHeight) / 2; } + if (mBadge != null) { Rect bounds = mBadge.getBounds(); int left = Utilities.boundToRange( -- cgit v1.2.3