Loading packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java +86 −42 Original line number Diff line number Diff line Loading @@ -14,6 +14,10 @@ package com.android.systemui.qs; import static com.android.systemui.qs.tileimpl.QSIconViewImpl.QS_ANIM_LENGTH; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.ColorInt; import android.annotation.IntRange; import android.annotation.NonNull; Loading @@ -24,25 +28,35 @@ import android.graphics.ColorFilter; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Path.Direction; import android.graphics.PorterDuff.Mode; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.util.Log; import android.util.FloatProperty; public class SlashDrawable extends Drawable { private final Path mPath = new Path(); private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private static float[] OFFSET = { 1.3f / 24f,-1.3f / 24f }; private static float[][] PATH = { {21.9f / 24f, 21.9f / 24f}, {2.1f / 24f, 2.1f / 24f}, {0.8f / 24f, 3.4f / 24f}, {20.6f / 24f, 23.2f / 24f}, }; // These values are derived in un-rotated (vertical) orientation private static final float SLASH_WIDTH = 1.8384776f; private static final float SLASH_HEIGHT = 28f; private static final float CENTER_X = 10.65f; private static final float CENTER_Y = 11.869239f; private static final float SCALE = 24f; // Bottom is derived during animation private static final float LEFT = (CENTER_X - (SLASH_WIDTH / 2)) / SCALE; private static final float TOP = (CENTER_Y - (SLASH_HEIGHT / 2)) / SCALE; private static final float RIGHT = (CENTER_X + (SLASH_WIDTH / 2)) / SCALE; // Draw the slash washington-monument style; rotate to no-u-turn style private static final float DEFAULT_ROTATION = -45f; private Drawable mDrawable; private final RectF mSlashRect = new RectF(0, 0, 0, 0); private float mRotation; private boolean mSlashed; private Mode mTintMode; Loading Loading @@ -83,47 +97,70 @@ public class SlashDrawable extends Drawable { invalidateSelf(); } // Animate this value on change private float mCurrentSlashLength; private final FloatProperty mSlashLengthProp = new FloatProperty<SlashDrawable>("slashLength") { @Override public void setValue(SlashDrawable object, float value) { object.mCurrentSlashLength = value; } @Override public Float get(SlashDrawable object) { return object.mCurrentSlashLength; } }; public void setSlashed(boolean slashed) { if (mSlashed == slashed) return; // TODO: Animate. mSlashed = slashed; final float end = mSlashed ? SLASH_HEIGHT / SCALE : 0f; final float start = mSlashed ? 0f : SLASH_HEIGHT / SCALE; ObjectAnimator anim = ObjectAnimator.ofFloat(this, mSlashLengthProp, start, end); anim.addUpdateListener((ValueAnimator valueAnimator) -> { invalidateSelf(); }); anim.setDuration(QS_ANIM_LENGTH); anim.start(); } @Override public void draw(@NonNull Canvas canvas) { canvas.save(); if (mSlashed) { Matrix m = new Matrix(); int width = getBounds().width(); int height = getBounds().height(); final int width = getBounds().width(); final int height = getBounds().height(); final float radiusX = scale(1f, width); final float radiusY = scale(1f, height); updateRect( scale(LEFT, width), scale(TOP, height), scale(RIGHT, width), scale(TOP + mCurrentSlashLength, height) ); mPath.reset(); mPath.moveTo(scale(PATH[0][0], width), scale(PATH[0][1], height)); mPath.lineTo(scale(PATH[1][0], width), scale(PATH[1][1], height)); mPath.lineTo(scale(PATH[2][0], width), scale(PATH[2][1], height)); mPath.lineTo(scale(PATH[3][0], width), scale(PATH[3][1], height)); mPath.close(); m = new Matrix(); m.setRotate(mRotation, width / 2, height / 2); // Draw the slash vertically mPath.addRoundRect(mSlashRect, radiusX, radiusY, Direction.CW); // Rotate -45 + desired rotation m.setRotate(mRotation + DEFAULT_ROTATION, width / 2, height / 2); mPath.transform(m); canvas.drawPath(mPath, mPaint); m = new Matrix(); m.setRotate(-mRotation, width / 2, height / 2); // Rotate back to vertical m.setRotate(-mRotation - DEFAULT_ROTATION, width / 2, height / 2); mPath.transform(m); m = new Matrix(); m.setTranslate(scale(OFFSET[0], width), scale(OFFSET[1], height)); // Draw another rect right next to the first, for clipping m.setTranslate(mSlashRect.width(), 0); mPath.transform(m); mPath.moveTo(scale(PATH[0][0], width), scale(PATH[0][1], height)); mPath.lineTo(scale(PATH[1][0], width), scale(PATH[1][1], height)); mPath.lineTo(scale(PATH[2][0], width), scale(PATH[2][1], height)); mPath.lineTo(scale(PATH[3][0], width), scale(PATH[3][1], height)); mPath.close(); m = new Matrix(); m.setRotate(mRotation, width / 2, height / 2); mPath.addRoundRect(mSlashRect, 1.0f * width, 1.0f * height, Direction.CW); m.setRotate(mRotation + DEFAULT_ROTATION, width / 2, height / 2); mPath.transform(m); canvas.clipOutPath(mPath); } mDrawable.draw(canvas); canvas.restore(); Loading @@ -133,6 +170,13 @@ public class SlashDrawable extends Drawable { return frac * width; } private void updateRect(float left, float top, float right, float bottom) { mSlashRect.left = left; mSlashRect.top = top; mSlashRect.right = right; mSlashRect.bottom = bottom; } @Override public void setTint(@ColorInt int tintColor) { super.setTint(tintColor); Loading packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java +3 −1 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ import java.util.Objects; public class QSIconViewImpl extends QSIconView { public static final long QS_ANIM_LENGTH = 350; protected final View mIcon; protected final int mIconSizePx; protected final int mTilePaddingBelowIconPx; Loading Loading @@ -148,7 +150,7 @@ public class QSIconViewImpl extends QSIconView { final float toChannel = Color.red(toColor); ValueAnimator anim = ValueAnimator.ofFloat(0, 1); anim.setDuration(350); anim.setDuration(QS_ANIM_LENGTH); anim.addUpdateListener(animation -> { float fraction = animation.getAnimatedFraction(); Loading packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java +1 −1 Original line number Diff line number Diff line Loading @@ -152,7 +152,7 @@ public class WifiTile extends QSTileImpl<SignalState> { } if (state.slash == null) { state.slash = new SlashState(); state.slash.rotation = 8; state.slash.rotation = 6; } state.slash.isSlashed = false; state.state = Tile.STATE_ACTIVE; Loading Loading
packages/SystemUI/src/com/android/systemui/qs/SlashDrawable.java +86 −42 Original line number Diff line number Diff line Loading @@ -14,6 +14,10 @@ package com.android.systemui.qs; import static com.android.systemui.qs.tileimpl.QSIconViewImpl.QS_ANIM_LENGTH; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.annotation.ColorInt; import android.annotation.IntRange; import android.annotation.NonNull; Loading @@ -24,25 +28,35 @@ import android.graphics.ColorFilter; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Path.Direction; import android.graphics.PorterDuff.Mode; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.util.Log; import android.util.FloatProperty; public class SlashDrawable extends Drawable { private final Path mPath = new Path(); private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private static float[] OFFSET = { 1.3f / 24f,-1.3f / 24f }; private static float[][] PATH = { {21.9f / 24f, 21.9f / 24f}, {2.1f / 24f, 2.1f / 24f}, {0.8f / 24f, 3.4f / 24f}, {20.6f / 24f, 23.2f / 24f}, }; // These values are derived in un-rotated (vertical) orientation private static final float SLASH_WIDTH = 1.8384776f; private static final float SLASH_HEIGHT = 28f; private static final float CENTER_X = 10.65f; private static final float CENTER_Y = 11.869239f; private static final float SCALE = 24f; // Bottom is derived during animation private static final float LEFT = (CENTER_X - (SLASH_WIDTH / 2)) / SCALE; private static final float TOP = (CENTER_Y - (SLASH_HEIGHT / 2)) / SCALE; private static final float RIGHT = (CENTER_X + (SLASH_WIDTH / 2)) / SCALE; // Draw the slash washington-monument style; rotate to no-u-turn style private static final float DEFAULT_ROTATION = -45f; private Drawable mDrawable; private final RectF mSlashRect = new RectF(0, 0, 0, 0); private float mRotation; private boolean mSlashed; private Mode mTintMode; Loading Loading @@ -83,47 +97,70 @@ public class SlashDrawable extends Drawable { invalidateSelf(); } // Animate this value on change private float mCurrentSlashLength; private final FloatProperty mSlashLengthProp = new FloatProperty<SlashDrawable>("slashLength") { @Override public void setValue(SlashDrawable object, float value) { object.mCurrentSlashLength = value; } @Override public Float get(SlashDrawable object) { return object.mCurrentSlashLength; } }; public void setSlashed(boolean slashed) { if (mSlashed == slashed) return; // TODO: Animate. mSlashed = slashed; final float end = mSlashed ? SLASH_HEIGHT / SCALE : 0f; final float start = mSlashed ? 0f : SLASH_HEIGHT / SCALE; ObjectAnimator anim = ObjectAnimator.ofFloat(this, mSlashLengthProp, start, end); anim.addUpdateListener((ValueAnimator valueAnimator) -> { invalidateSelf(); }); anim.setDuration(QS_ANIM_LENGTH); anim.start(); } @Override public void draw(@NonNull Canvas canvas) { canvas.save(); if (mSlashed) { Matrix m = new Matrix(); int width = getBounds().width(); int height = getBounds().height(); final int width = getBounds().width(); final int height = getBounds().height(); final float radiusX = scale(1f, width); final float radiusY = scale(1f, height); updateRect( scale(LEFT, width), scale(TOP, height), scale(RIGHT, width), scale(TOP + mCurrentSlashLength, height) ); mPath.reset(); mPath.moveTo(scale(PATH[0][0], width), scale(PATH[0][1], height)); mPath.lineTo(scale(PATH[1][0], width), scale(PATH[1][1], height)); mPath.lineTo(scale(PATH[2][0], width), scale(PATH[2][1], height)); mPath.lineTo(scale(PATH[3][0], width), scale(PATH[3][1], height)); mPath.close(); m = new Matrix(); m.setRotate(mRotation, width / 2, height / 2); // Draw the slash vertically mPath.addRoundRect(mSlashRect, radiusX, radiusY, Direction.CW); // Rotate -45 + desired rotation m.setRotate(mRotation + DEFAULT_ROTATION, width / 2, height / 2); mPath.transform(m); canvas.drawPath(mPath, mPaint); m = new Matrix(); m.setRotate(-mRotation, width / 2, height / 2); // Rotate back to vertical m.setRotate(-mRotation - DEFAULT_ROTATION, width / 2, height / 2); mPath.transform(m); m = new Matrix(); m.setTranslate(scale(OFFSET[0], width), scale(OFFSET[1], height)); // Draw another rect right next to the first, for clipping m.setTranslate(mSlashRect.width(), 0); mPath.transform(m); mPath.moveTo(scale(PATH[0][0], width), scale(PATH[0][1], height)); mPath.lineTo(scale(PATH[1][0], width), scale(PATH[1][1], height)); mPath.lineTo(scale(PATH[2][0], width), scale(PATH[2][1], height)); mPath.lineTo(scale(PATH[3][0], width), scale(PATH[3][1], height)); mPath.close(); m = new Matrix(); m.setRotate(mRotation, width / 2, height / 2); mPath.addRoundRect(mSlashRect, 1.0f * width, 1.0f * height, Direction.CW); m.setRotate(mRotation + DEFAULT_ROTATION, width / 2, height / 2); mPath.transform(m); canvas.clipOutPath(mPath); } mDrawable.draw(canvas); canvas.restore(); Loading @@ -133,6 +170,13 @@ public class SlashDrawable extends Drawable { return frac * width; } private void updateRect(float left, float top, float right, float bottom) { mSlashRect.left = left; mSlashRect.top = top; mSlashRect.right = right; mSlashRect.bottom = bottom; } @Override public void setTint(@ColorInt int tintColor) { super.setTint(tintColor); Loading
packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSIconViewImpl.java +3 −1 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ import java.util.Objects; public class QSIconViewImpl extends QSIconView { public static final long QS_ANIM_LENGTH = 350; protected final View mIcon; protected final int mIconSizePx; protected final int mTilePaddingBelowIconPx; Loading Loading @@ -148,7 +150,7 @@ public class QSIconViewImpl extends QSIconView { final float toChannel = Color.red(toColor); ValueAnimator anim = ValueAnimator.ofFloat(0, 1); anim.setDuration(350); anim.setDuration(QS_ANIM_LENGTH); anim.addUpdateListener(animation -> { float fraction = animation.getAnimatedFraction(); Loading
packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java +1 −1 Original line number Diff line number Diff line Loading @@ -152,7 +152,7 @@ public class WifiTile extends QSTileImpl<SignalState> { } if (state.slash == null) { state.slash = new SlashState(); state.slash.rotation = 8; state.slash.rotation = 6; } state.slash.isSlashed = false; state.state = Tile.STATE_ACTIVE; Loading