Merge "Removing some dependency on icon shape" into sc-dev

This commit is contained in:
Sunny Goyal
2021-04-26 17:27:12 +00:00
committed by Android (Google) Code Review
5 changed files with 65 additions and 117 deletions
@@ -15,12 +15,11 @@
*/
package com.android.launcher3.uioverrides;
import static com.android.launcher3.graphics.IconShape.getShape;
import android.content.Context;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
@@ -37,6 +36,7 @@ import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
import com.android.launcher3.graphics.IconPalette;
import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.icons.IconNormalizer;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.model.data.WorkspaceItemInfo;
@@ -58,9 +58,13 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView {
private final DeviceProfile mDeviceProfile;
private final Paint mIconRingPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Path mRingPath = new Path();
private boolean mIsPinned = false;
private final int mNormalizedIconRadius;
private final int mNormalizedIconSize;
private final Path mShapePath;
private final Matrix mTmpMatrix = new Matrix();
private final BlurMaskFilter mShadowFilter;
private boolean mIsPinned = false;
private int mPlateColor;
boolean mDrawForDrag = false;
@@ -75,24 +79,18 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView {
public PredictedAppIcon(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mDeviceProfile = ActivityContext.lookupContext(context).getDeviceProfile();
mNormalizedIconRadius = IconNormalizer.getNormalizedCircleSize(getIconSize()) / 2;
mNormalizedIconSize = IconNormalizer.getNormalizedCircleSize(getIconSize());
int shadowSize = context.getResources().getDimensionPixelSize(
R.dimen.blur_size_thin_outline);
mShadowFilter = new BlurMaskFilter(shadowSize, BlurMaskFilter.Blur.OUTER);
mShapePath = GraphicsUtils.getShapePath(mNormalizedIconSize);
}
@Override
public void onDraw(Canvas canvas) {
int count = canvas.save();
if (!mIsPinned) {
boolean isBadged = false;
if (getTag() instanceof WorkspaceItemInfo) {
WorkspaceItemInfo info = (WorkspaceItemInfo) getTag();
isBadged = !Process.myUserHandle().equals(info.user)
|| info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT
|| info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
}
drawEffect(canvas, isBadged);
drawEffect(canvas);
canvas.translate(getWidth() * RING_EFFECT_RATIO, getHeight() * RING_EFFECT_RATIO);
canvas.scale(1 - 2 * RING_EFFECT_RATIO, 1 - 2 * RING_EFFECT_RATIO);
}
@@ -161,33 +159,58 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView {
}
private int getOutlineOffsetX() {
return (getMeasuredWidth() / 2) - mNormalizedIconRadius;
return (getMeasuredWidth() - mNormalizedIconSize) / 2;
}
private int getOutlineOffsetY() {
if (mDisplay != DISPLAY_TASKBAR) {
return getPaddingTop() + mDeviceProfile.folderIconOffsetYPx;
}
return (getMeasuredHeight() / 2) - mNormalizedIconRadius;
return (getMeasuredHeight() - mNormalizedIconSize) / 2;
}
private void drawEffect(Canvas canvas, boolean isBadged) {
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
updateRingPath();
}
@Override
public void setTag(Object tag) {
super.setTag(tag);
updateRingPath();
}
private void updateRingPath() {
boolean isBadged = false;
if (getTag() instanceof WorkspaceItemInfo) {
WorkspaceItemInfo info = (WorkspaceItemInfo) getTag();
isBadged = !Process.myUserHandle().equals(info.user)
|| info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT
|| info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
}
mRingPath.reset();
mTmpMatrix.setTranslate(getOutlineOffsetX(), getOutlineOffsetY());
mRingPath.addPath(mShapePath, mTmpMatrix);
if (isBadged) {
float outlineSize = mNormalizedIconSize * RING_EFFECT_RATIO;
float iconSize = getIconSize() * (1 - 2 * RING_EFFECT_RATIO);
float badgeSize = LauncherIcons.getBadgeSizeForIconSize((int) iconSize) + outlineSize;
float scale = badgeSize / mNormalizedIconSize;
mTmpMatrix.postTranslate(mNormalizedIconSize, mNormalizedIconSize);
mTmpMatrix.preScale(scale, scale);
mTmpMatrix.preTranslate(-mNormalizedIconSize, -mNormalizedIconSize);
mRingPath.addPath(mShapePath, mTmpMatrix);
}
}
private void drawEffect(Canvas canvas) {
// Don't draw ring effect if item is about to be dragged.
if (mDrawForDrag) {
return;
}
mRingPath.reset();
getShape().addToPath(mRingPath, getOutlineOffsetX(), getOutlineOffsetY(),
mNormalizedIconRadius);
if (isBadged) {
float outlineSize = mNormalizedIconRadius * RING_EFFECT_RATIO * 2;
float iconSize = getIconSize() * (1 - 2 * RING_EFFECT_RATIO);
float badgeSize = LauncherIcons.getBadgeSizeForIconSize((int) iconSize) + outlineSize;
float badgeInset = mNormalizedIconRadius * 2 - badgeSize;
getShape().addToPath(mRingPath, getOutlineOffsetX() + badgeInset,
getOutlineOffsetY() + badgeInset, badgeSize / 2);
}
mIconRingPaint.setColor(RING_SHADOW_COLOR);
mIconRingPaint.setMaskFilter(mShadowFilter);
canvas.drawPath(mRingPath, mIconRingPaint);
@@ -249,8 +272,10 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView {
*/
@Override
public void drawUnderItem(Canvas canvas) {
getShape().drawShape(canvas, mIcon.getOutlineOffsetX(), mIcon.getOutlineOffsetY(),
mIcon.mNormalizedIconRadius, mOutlinePaint);
canvas.save();
canvas.translate(mIcon.getOutlineOffsetX(), mIcon.getOutlineOffsetY());
canvas.drawPath(mIcon.mShapePath, mOutlinePaint);
canvas.restore();
}
/**
+1 -49
View File
@@ -16,7 +16,6 @@
package com.android.launcher3;
import static com.android.launcher3.graphics.IconShape.getShape;
import static com.android.launcher3.graphics.PreloadIconDrawable.newPendingIcon;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
@@ -26,16 +25,13 @@ import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Process;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
import android.util.Property;
@@ -50,7 +46,6 @@ import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dot.DotInfo;
import com.android.launcher3.dragndrop.DraggableView;
import com.android.launcher3.folder.FolderIcon;
@@ -60,7 +55,6 @@ import com.android.launcher3.graphics.PreloadIconDrawable;
import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.icons.PlaceHolderIconDrawable;
import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.model.data.AppInfo;
@@ -97,11 +91,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
private float mScaleForReorderBounce = 1f;
protected final Paint mHighlightPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Path mHighlightPath = new Path();
protected int mHighlightColor = Color.TRANSPARENT;
private final BlurMaskFilter mHighlightShadowFilter;
private static final Property<BubbleTextView, Float> DOT_SCALE_PROPERTY
= new Property<BubbleTextView, Float>(Float.TYPE, "dotScale") {
@Override
@@ -220,10 +209,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
setEllipsize(TruncateAt.END);
setAccessibilityDelegate(mActivity.getAccessibilityDelegate());
setTextAlpha(1f);
int shadowSize = context.getResources().getDimensionPixelSize(
R.dimen.blur_size_click_shadow);
mHighlightShadowFilter = new BlurMaskFilter(shadowSize, BlurMaskFilter.Blur.INNER);
}
@Override
@@ -451,41 +436,10 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
@Override
public void onDraw(Canvas canvas) {
if (FeatureFlags.ENABLE_DEVICE_SEARCH.get() && mHighlightColor != Color.TRANSPARENT) {
int count = canvas.save();
drawFocusHighlight(canvas);
canvas.restoreToCount(count);
}
super.onDraw(canvas);
drawDotIfNecessary(canvas);
}
protected void drawFocusHighlight(Canvas canvas) {
boolean isBadged = getTag() instanceof ItemInfo && !Process.myUserHandle().equals(
((ItemInfo) getTag()).user);
float insetScale = (HIGHLIGHT_SCALE - 1) / 2;
canvas.translate(-getIconSize() * insetScale, -insetScale * getIconSize());
float outlineSize = getIconSize() * HIGHLIGHT_SCALE;
mHighlightPath.reset();
mHighlightPaint.reset();
getIconBounds(mDotParams.iconBounds);
getShape().addToPath(mHighlightPath, mDotParams.iconBounds.left, mDotParams.iconBounds.top,
outlineSize / 2);
if (isBadged) {
float borderSize = outlineSize - getIconSize();
float badgeSize = LauncherIcons.getBadgeSizeForIconSize(getIconSize()) + borderSize;
float badgeInset = outlineSize - badgeSize;
getShape().addToPath(mHighlightPath, mDotParams.iconBounds.left + badgeInset,
mDotParams.iconBounds.top + badgeInset, badgeSize / 2);
}
mHighlightPaint.setMaskFilter(mHighlightShadowFilter);
mHighlightPaint.setColor(mDotParams.color);
canvas.drawPath(mHighlightPath, mHighlightPaint);
mHighlightPaint.setMaskFilter(null);
mHighlightPaint.setColor(mHighlightColor);
canvas.drawPath(mHighlightPath, mHighlightPaint);
}
/**
* Draws the notification dot in the top right corner of the icon bounds.
*
@@ -921,11 +875,9 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
@Override
public SafeCloseable prepareDrawDragView() {
int highlightColor = mHighlightColor;
mHighlightColor = Color.TRANSPARENT;
resetIconScale();
setForceHideDot(true);
return () -> mHighlightColor = highlightColor;
return () -> { };
}
private void resetIconScale() {
+6 -5
View File
@@ -25,6 +25,7 @@ import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
@@ -38,8 +39,8 @@ import android.view.WindowManager;
import com.android.launcher3.CellLayout.ContainerType;
import com.android.launcher3.DevicePaddings.DevicePadding;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.icons.IconNormalizer;
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.DisplayController;
@@ -54,6 +55,7 @@ public class DeviceProfile {
private static final float TABLET_MIN_DPS = 600;
private static final float LARGE_TABLET_MIN_DPS = 720;
private static final int DEFAULT_DOT_SIZE = 100;
public final InvariantDeviceProfile inv;
private final Info mInfo;
@@ -366,11 +368,10 @@ public class DeviceProfile {
updateWorkspacePadding();
// This is done last, after iconSizePx is calculated above.
mDotRendererWorkSpace = new DotRenderer(iconSizePx, IconShape.getShapePath(),
IconShape.DEFAULT_PATH_SIZE);
Path dotPath = GraphicsUtils.getShapePath(DEFAULT_DOT_SIZE);
mDotRendererWorkSpace = new DotRenderer(iconSizePx, dotPath, DEFAULT_DOT_SIZE);
mDotRendererAllApps = iconSizePx == allAppsIconSizePx ? mDotRendererWorkSpace :
new DotRenderer(allAppsIconSizePx, IconShape.getShapePath(),
IconShape.DEFAULT_PATH_SIZE);
new DotRenderer(allAppsIconSizePx, dotPath, DEFAULT_DOT_SIZE);
}
private void setCellLayoutBorderSpacing(int borderSpacing) {
@@ -37,20 +37,14 @@ import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.util.AttributeSet;
import android.util.SparseArray;
import android.util.TypedValue;
import android.util.Xml;
import android.view.View;
import android.view.ViewOutlineProvider;
import androidx.annotation.Nullable;
import com.android.launcher3.R;
import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.icons.IconNormalizer;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ClipPathView;
import org.xmlpull.v1.XmlPullParser;
@@ -66,30 +60,16 @@ import java.util.List;
public abstract class IconShape {
private static IconShape sInstance = new Circle();
private static Path sShapePath;
private static float sNormalizationScale = ICON_VISIBLE_AREA_FACTOR;
public static final int DEFAULT_PATH_SIZE = 100;
public static IconShape getShape() {
return sInstance;
}
public static Path getShapePath() {
if (sShapePath == null) {
Path p = new Path();
getShape().addToPath(p, 0, 0, DEFAULT_PATH_SIZE * 0.5f);
sShapePath = p;
}
return sShapePath;
}
public static float getNormalizationScale() {
return sNormalizationScale;
}
private SparseArray<TypedValue> mAttrs;
public boolean enableShapeDetection(){
return false;
};
@@ -102,11 +82,6 @@ public abstract class IconShape {
public abstract <T extends View & ClipPathView> Animator createRevealAnimator(T target,
Rect startRect, Rect endRect, float endRadius, boolean isReversed);
@Nullable
public TypedValue getAttrValue(int attr) {
return mAttrs == null ? null : mAttrs.get(attr);
}
/**
* Abstract shape where the reveal animation is a derivative of a round rect animation
*/
@@ -410,7 +385,6 @@ public abstract class IconShape {
final int depth = parser.getDepth();
int[] radiusAttr = new int[] {R.attr.folderIconRadius};
IntArray keysToIgnore = new IntArray(0);
while (((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
@@ -421,7 +395,6 @@ public abstract class IconShape {
IconShape shape = getShapeDefinition(parser.getName(), a.getFloat(0, 1));
a.recycle();
shape.mAttrs = Themes.createValueMap(context, attrs, keysToIgnore);
result.add(shape);
}
}
@@ -467,8 +440,6 @@ public abstract class IconShape {
}
// Initialize shape properties
drawable.setBounds(0, 0, DEFAULT_PATH_SIZE, DEFAULT_PATH_SIZE);
sShapePath = new Path(drawable.getIconMask());
sNormalizationScale = IconNormalizer.normalizeAdaptiveIcon(drawable, size, null);
}
}
@@ -17,9 +17,6 @@
package com.android.launcher3.graphics;
import static com.android.launcher3.graphics.IconShape.DEFAULT_PATH_SIZE;
import static com.android.launcher3.graphics.IconShape.getShapePath;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
@@ -39,6 +36,7 @@ import android.view.ContextThemeWrapper;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.GraphicsUtils;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.util.Themes;
@@ -62,6 +60,7 @@ public class PreloadIconDrawable extends FastBitmapDrawable {
}
};
private static final int DEFAULT_PATH_SIZE = 100;
private static final float PROGRESS_WIDTH = 7;
private static final float PROGRESS_GAP = 2;
private static final int MAX_PAINT_ALPHA = 255;
@@ -132,7 +131,7 @@ public class PreloadIconDrawable extends FastBitmapDrawable {
boolean isDarkMode) {
super(info.bitmap);
mItem = info;
mShapePath = getShapePath();
mShapePath = GraphicsUtils.getShapePath(DEFAULT_PATH_SIZE);
mScaledTrackPath = new Path();
mScaledProgressPath = new Path();