Merge "Adding support for dynamically adding shadows to the icon" into ub-launcher3-calgary
This commit is contained in:
@@ -307,7 +307,7 @@ public class ShortcutInfo extends ItemInfo {
|
||||
.getShortcutIconDrawable(shortcutInfo,
|
||||
launcherAppState.getInvariantDeviceProfile().fillResIconDpi);
|
||||
Bitmap icon = unbadgedIcon == null ? null
|
||||
: Utilities.createBadgedIconBitmap(unbadgedIcon, user, context);
|
||||
: Utilities.createBadgedIconBitmapWithShadow(unbadgedIcon, user, context);
|
||||
setIcon(icon != null ? icon : launcherAppState.getIconCache().getDefaultIcon(user));
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PaintFlagsDrawFilter;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.PaintDrawable;
|
||||
@@ -64,6 +65,7 @@ import android.widget.Toast;
|
||||
import com.android.launcher3.compat.UserHandleCompat;
|
||||
import com.android.launcher3.config.FeatureFlags;
|
||||
import com.android.launcher3.config.ProviderConfig;
|
||||
import com.android.launcher3.graphics.ShadowGenerator;
|
||||
import com.android.launcher3.util.IconNormalizer;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -244,7 +246,7 @@ public final class Utilities {
|
||||
public static Bitmap createBadgedIconBitmap(
|
||||
Drawable icon, UserHandleCompat user, Context context) {
|
||||
float scale = FeatureFlags.LAUNCHER3_DISABLE_ICON_NORMALIZATION ?
|
||||
1 : IconNormalizer.getInstance().getScale(icon);
|
||||
1 : IconNormalizer.getInstance().getScale(icon, null);
|
||||
Bitmap bitmap = createIconBitmap(icon, context, scale);
|
||||
if (Utilities.ATLEAST_LOLLIPOP && user != null
|
||||
&& !UserHandleCompat.myUserHandle().equals(user)) {
|
||||
@@ -261,6 +263,34 @@ public final class Utilities {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link #createBadgedIconBitmap} but adds a shadow before badging the icon
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
public static Bitmap createBadgedIconBitmapWithShadow(
|
||||
Drawable icon, UserHandleCompat user, Context context) {
|
||||
RectF iconBounds = new RectF();
|
||||
float scale = FeatureFlags.LAUNCHER3_DISABLE_ICON_NORMALIZATION ?
|
||||
1 : IconNormalizer.getInstance().getScale(icon, iconBounds);
|
||||
scale = Math.min(scale, ShadowGenerator.getScaleForBounds(iconBounds));
|
||||
|
||||
Bitmap bitmap = createIconBitmap(icon, context, scale);
|
||||
bitmap = ShadowGenerator.getInstance().recreateIcon(bitmap);
|
||||
if (Utilities.ATLEAST_LOLLIPOP && user != null
|
||||
&& !UserHandleCompat.myUserHandle().equals(user)) {
|
||||
BitmapDrawable drawable = new FixedSizeBitmapDrawable(bitmap);
|
||||
Drawable badged = context.getPackageManager().getUserBadgedIcon(
|
||||
drawable, user.getUser());
|
||||
if (badged instanceof BitmapDrawable) {
|
||||
return ((BitmapDrawable) badged).getBitmap();
|
||||
} else {
|
||||
return createIconBitmap(badged, context);
|
||||
}
|
||||
} else {
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a bitmap suitable for the all apps view.
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.launcher3.graphics;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Bitmap.Config;
|
||||
import android.graphics.BlurMaskFilter;
|
||||
import android.graphics.BlurMaskFilter.Blur;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.RectF;
|
||||
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
import com.android.launcher3.util.Preconditions;
|
||||
|
||||
/**
|
||||
* Utility class to add shadows to bitmaps.
|
||||
*/
|
||||
public class ShadowGenerator {
|
||||
|
||||
// Percent of actual icon size
|
||||
private static final float HALF_DISTANCE = 0.5f;
|
||||
private static final float BLUR_FACTOR = 0.5f/48;
|
||||
|
||||
// Percent of actual icon size
|
||||
private static final float KEY_SHADOW_DISTANCE = 1f/48;
|
||||
private static final int KEY_SHADOW_ALPHA = 61;
|
||||
|
||||
private static final int AMBIENT_SHADOW_ALPHA = 30;
|
||||
|
||||
private static final Object LOCK = new Object();
|
||||
// Singleton object guarded by {@link #LOCK}
|
||||
private static ShadowGenerator sShadowGenerator;
|
||||
|
||||
private final int mIconSize;
|
||||
|
||||
private final Canvas mCanvas;
|
||||
private final Paint mBlurPaint;
|
||||
private final Paint mDrawPaint;
|
||||
|
||||
private ShadowGenerator() {
|
||||
mIconSize = LauncherAppState.getInstance().getInvariantDeviceProfile().iconBitmapSize;
|
||||
mCanvas = new Canvas();
|
||||
mBlurPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
|
||||
mBlurPaint.setMaskFilter(new BlurMaskFilter(mIconSize * BLUR_FACTOR, Blur.NORMAL));
|
||||
mDrawPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
|
||||
}
|
||||
|
||||
public synchronized Bitmap recreateIcon(Bitmap icon) {
|
||||
int[] offset = new int[2];
|
||||
Bitmap shadow = icon.extractAlpha(mBlurPaint, offset);
|
||||
Bitmap result = Bitmap.createBitmap(mIconSize, mIconSize, Config.ARGB_8888);
|
||||
mCanvas.setBitmap(result);
|
||||
|
||||
// Draw ambient shadow
|
||||
mDrawPaint.setAlpha(AMBIENT_SHADOW_ALPHA);
|
||||
mCanvas.drawBitmap(shadow, offset[0], offset[1], mDrawPaint);
|
||||
|
||||
// Draw key shadow
|
||||
mDrawPaint.setAlpha(KEY_SHADOW_ALPHA);
|
||||
mCanvas.drawBitmap(shadow, offset[0], offset[1] + KEY_SHADOW_DISTANCE * mIconSize, mDrawPaint);
|
||||
|
||||
// Draw the icon
|
||||
mDrawPaint.setAlpha(255);
|
||||
mCanvas.drawBitmap(icon, 0, 0, mDrawPaint);
|
||||
|
||||
mCanvas.setBitmap(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static ShadowGenerator getInstance() {
|
||||
Preconditions.assertNonUiThread();
|
||||
synchronized (LOCK) {
|
||||
if (sShadowGenerator == null) {
|
||||
sShadowGenerator = new ShadowGenerator();
|
||||
}
|
||||
}
|
||||
return sShadowGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum amount by which an icon with {@param bounds} should be scaled
|
||||
* so that the shadows do not get clipped.
|
||||
*/
|
||||
public static float getScaleForBounds(RectF bounds) {
|
||||
float scale = 1;
|
||||
|
||||
// For top, left & right, we need same space.
|
||||
float minSide = Math.min(Math.min(bounds.left, bounds.right), bounds.top);
|
||||
if (minSide < BLUR_FACTOR) {
|
||||
scale = (HALF_DISTANCE - BLUR_FACTOR) / (HALF_DISTANCE - minSide);
|
||||
}
|
||||
|
||||
float bottomSpace = BLUR_FACTOR + KEY_SHADOW_DISTANCE;
|
||||
if (bounds.bottom < bottomSpace) {
|
||||
scale = Math.min(scale, (HALF_DISTANCE - bottomSpace) / (HALF_DISTANCE - bounds.bottom));
|
||||
}
|
||||
return scale;
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,7 @@ package com.android.launcher3.util;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import com.android.launcher3.LauncherAppState;
|
||||
@@ -74,8 +75,10 @@ public class IconNormalizer {
|
||||
*
|
||||
* This closeness is used to determine the ratio of hull area to the full icon size.
|
||||
* Refer {@link #MAX_CIRCLE_AREA_FACTOR} and {@link #MAX_SQUARE_AREA_FACTOR}
|
||||
*
|
||||
* @param outBounds optional rect to receive the fraction distance from each edge.
|
||||
*/
|
||||
public synchronized float getScale(Drawable d) {
|
||||
public synchronized float getScale(Drawable d, RectF outBounds) {
|
||||
int width = d.getIntrinsicWidth();
|
||||
int height = d.getIntrinsicHeight();
|
||||
if (width <= 0 || height <= 0) {
|
||||
@@ -168,6 +171,14 @@ public class IconNormalizer {
|
||||
scaleRequired = MAX_SQUARE_AREA_FACTOR + LINEAR_SCALE_SLOPE * (1 - hullByRect);
|
||||
}
|
||||
|
||||
if (outBounds != null) {
|
||||
outBounds.left = ((float) leftX) / width;
|
||||
outBounds.right = 1 - ((float) rightX) / width;
|
||||
|
||||
outBounds.top = ((float) topY) / height;
|
||||
outBounds.bottom = 1 - ((float) bottomY) / height;
|
||||
}
|
||||
|
||||
float areaScale = area / (width * height);
|
||||
// Use sqrt of the final ratio as the images is scaled across both width and height.
|
||||
float scale = areaScale > scaleRequired ? (float) Math.sqrt(scaleRequired / areaScale) : 1;
|
||||
|
||||
Reference in New Issue
Block a user