diff options
author | Tony Wickham <twickham@google.com> | 2019-05-03 11:27:32 -0700 |
---|---|---|
committer | Sunny Goyal <sunnygoyal@google.com> | 2019-05-06 10:42:55 -0700 |
commit | e1cb93f95744e5d2be5c48fc5bd3025f1453006b (patch) | |
tree | 184bdee68538b2167d2faedd66d8ef42b1779226 /iconloaderlib | |
parent | 227b6e021cef474de05f7dfbd4e641bf860ac011 (diff) | |
download | android_packages_apps_Trebuchet-e1cb93f95744e5d2be5c48fc5bd3025f1453006b.tar.gz android_packages_apps_Trebuchet-e1cb93f95744e5d2be5c48fc5bd3025f1453006b.tar.bz2 android_packages_apps_Trebuchet-e1cb93f95744e5d2be5c48fc5bd3025f1453006b.zip |
Always place notification dots directly on adaptive icon path
- Calculate point on icon path nearest to top right corner, and
use that as center for the dot
- Cleanup code related to dot offset
Test:
Set each style (different icon shape) and verify dot is in correct
placement for each of:
- Folders
- Icons in folders
- Icons in all apps
- Icons on workspace
Bug: 124414511
Change-Id: I036ed3677e8af222f00d4fad4a36a7e4d9b49ad9
Diffstat (limited to 'iconloaderlib')
-rw-r--r-- | iconloaderlib/src/com/android/launcher3/icons/DotRenderer.java | 73 |
1 files changed, 48 insertions, 25 deletions
diff --git a/iconloaderlib/src/com/android/launcher3/icons/DotRenderer.java b/iconloaderlib/src/com/android/launcher3/icons/DotRenderer.java index 6bc859aa6..af07aa3a9 100644 --- a/iconloaderlib/src/com/android/launcher3/icons/DotRenderer.java +++ b/iconloaderlib/src/com/android/launcher3/icons/DotRenderer.java @@ -23,8 +23,10 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; -import android.graphics.Point; +import android.graphics.Path; +import android.graphics.PathMeasure; import android.graphics.Rect; +import android.graphics.RectF; import android.util.Log; import android.view.ViewDebug; @@ -36,33 +38,51 @@ public class DotRenderer { private static final String TAG = "DotRenderer"; // The dot size is defined as a percentage of the app icon size. - private static final float SIZE_PERCENTAGE = 0.38f; + private static final float SIZE_PERCENTAGE = 0.228f; - // Extra scale down of the dot - private static final float DOT_SCALE = 0.6f; - - // Offset the dot slightly away from the icon if there's space. - private static final float OFFSET_PERCENTAGE = 0.02f; - - private final float mDotCenterOffset; - private final int mOffset; private final float mCircleRadius; private final Paint mCirclePaint = new Paint(ANTI_ALIAS_FLAG | FILTER_BITMAP_FLAG); private final Bitmap mBackgroundWithShadow; private final float mBitmapOffset; - public DotRenderer(int iconSizePx) { - mDotCenterOffset = SIZE_PERCENTAGE * iconSizePx; - mOffset = (int) (OFFSET_PERCENTAGE * iconSizePx); + // Stores the center x and y position as a percentage (0 to 1) of the icon size + private final float[] mRightDotPosition; + private final float[] mLeftDotPosition; - int size = (int) (DOT_SCALE * mDotCenterOffset); + public DotRenderer(int iconSizePx, Path iconShapePath, int pathSize) { + int size = Math.round(SIZE_PERCENTAGE * iconSizePx); ShadowGenerator.Builder builder = new ShadowGenerator.Builder(Color.TRANSPARENT); builder.ambientShadowAlpha = 88; mBackgroundWithShadow = builder.setupBlurForSize(size).createPill(size, size); mCircleRadius = builder.radius; mBitmapOffset = -mBackgroundWithShadow.getHeight() * 0.5f; // Same as width. + + // Find the points on the path that are closest to the top left and right corners. + mLeftDotPosition = getPathPoint(iconShapePath, pathSize, -1); + mRightDotPosition = getPathPoint(iconShapePath, pathSize, 1); + } + + private static float[] getPathPoint(Path path, float size, float direction) { + float halfSize = size / 2; + // Small delta so that we don't get a zero size triangle + float delta = 1; + + float x = halfSize + direction * halfSize; + Path trianglePath = new Path(); + trianglePath.moveTo(halfSize, halfSize); + trianglePath.lineTo(x + delta * direction, 0); + trianglePath.lineTo(x, -delta); + trianglePath.close(); + + trianglePath.op(path, Path.Op.INTERSECT); + float[] pos = new float[2]; + new PathMeasure(trianglePath, false).getPosTan(0, pos, null); + + pos[0] = pos[0] / size; + pos[1] = pos[1] / size; + return pos; } /** @@ -74,15 +94,21 @@ public class DotRenderer { return; } canvas.save(); + + Rect iconBounds = params.iconBounds; + float[] dotPosition = params.leftAlign ? mLeftDotPosition : mRightDotPosition; + float dotCenterX = iconBounds.left + iconBounds.width() * dotPosition[0]; + float dotCenterY = iconBounds.top + iconBounds.height() * dotPosition[1]; + + // Ensure dot fits entirely in canvas clip bounds. + Rect canvasBounds = canvas.getClipBounds(); + float offsetX = params.leftAlign + ? Math.max(0, canvasBounds.left - (dotCenterX + mBitmapOffset)) + : Math.min(0, canvasBounds.right - (dotCenterX - mBitmapOffset)); + float offsetY = Math.max(0, canvasBounds.top - (dotCenterY + mBitmapOffset)); + // We draw the dot relative to its center. - float dotCenterX = params.leftAlign - ? params.iconBounds.left + mDotCenterOffset / 2 - : params.iconBounds.right - mDotCenterOffset / 2; - float dotCenterY = params.iconBounds.top + mDotCenterOffset / 2; - - int offsetX = Math.min(mOffset, params.spaceForOffset.x); - int offsetY = Math.min(mOffset, params.spaceForOffset.y); - canvas.translate(dotCenterX + offsetX, dotCenterY - offsetY); + canvas.translate(dotCenterX + offsetX, dotCenterY + offsetY); canvas.scale(params.scale, params.scale); mCirclePaint.setColor(Color.BLACK); @@ -102,9 +128,6 @@ public class DotRenderer { /** The progress of the animation, from 0 to 1. */ @ViewDebug.ExportedProperty(category = "notification dot") public float scale; - /** Overrides internally calculated offset if specified value is smaller. */ - @ViewDebug.ExportedProperty(category = "notification dot") - public Point spaceForOffset = new Point(); /** Whether the dot should align to the top left of the icon rather than the top right. */ @ViewDebug.ExportedProperty(category = "notification dot") public boolean leftAlign; |