Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b996d809 authored by Alan Viverette's avatar Alan Viverette
Browse files

Update ripple spec, fix ripple mask, rotate progress drawable

Change-Id: I4fc155bf2f12d9f324c354dee81479f9cddafac4
parent 88db5c37
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -19,10 +19,8 @@
    <color name="background_quantum_dark">#ff212121</color>
    <color name="background_quantum_light">#fffafafa</color>

    <!-- Black 27% -->
    <color name="ripple_quantum_light">#45000000</color>
    <!-- White 19% -->
    <color name="ripple_quantum_dark">#30ffffff</color>
    <color name="ripple_quantum_light">#20444444</color>
    <color name="ripple_quantum_dark">#20ffffff</color>

    <color name="button_quantum_dark">#ff5a595b</color>
    <color name="button_quantum_light">#ffd6d7d7</color>
+33 −4
Original line number Diff line number Diff line
@@ -54,6 +54,12 @@ class QuantumProgressDrawable extends Drawable implements Animatable {
    private static final TimeInterpolator END_CURVE_INTERPOLATOR = new EndCurveInterpolator();
    private static final TimeInterpolator START_CURVE_INTERPOLATOR = new StartCurveInterpolator();

    /** The duration of a single progress spin in milliseconds. */
    private static final int ANIMATION_DURATION = 1000 * 80 / 60;

    /** The number of points in the progress "star". */
    private static final int NUM_POINTS = 5;

    /** The list of animators operating on this drawable. */
    private final ArrayList<Animator> mAnimators = new ArrayList<Animator>();

@@ -62,6 +68,9 @@ class QuantumProgressDrawable extends Drawable implements Animatable {

    private QuantumProgressState mState;

    /** Canvas rotation in degrees. */
    private float mRotation;

    private boolean mMutated;

    public QuantumProgressDrawable() {
@@ -187,7 +196,11 @@ class QuantumProgressDrawable extends Drawable implements Animatable {

    @Override
    public void draw(Canvas c) {
        mRing.draw(c, getBounds());
        final Rect bounds = getBounds();
        final int saveCount = c.save();
        c.rotate(mRotation, bounds.exactCenterX(), bounds.exactCenterY());
        mRing.draw(c, bounds);
        c.restoreToCount(saveCount);
    }

    @Override
@@ -210,6 +223,15 @@ class QuantumProgressDrawable extends Drawable implements Animatable {
        return mRing.getColorFilter();
    }

    private void setRotation(float rotation) {
        mRotation = rotation;
        invalidateSelf();
    }

    private float getRotation() {
        return mRotation;
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSLUCENT;
@@ -256,26 +278,33 @@ class QuantumProgressDrawable extends Drawable implements Animatable {
        final Ring ring = mRing;

        final ObjectAnimator endTrim = ObjectAnimator.ofFloat(ring, "endTrim", 0, 0.75f);
        endTrim.setDuration(1000 * 80 / 60);
        endTrim.setDuration(ANIMATION_DURATION);
        endTrim.setInterpolator(START_CURVE_INTERPOLATOR);
        endTrim.setRepeatCount(ObjectAnimator.INFINITE);
        endTrim.setRepeatMode(ObjectAnimator.RESTART);

        final ObjectAnimator startTrim = ObjectAnimator.ofFloat(ring, "startTrim", 0.0f, 0.75f);
        startTrim.setDuration(1000 * 80 / 60);
        startTrim.setDuration(ANIMATION_DURATION);
        startTrim.setInterpolator(END_CURVE_INTERPOLATOR);
        startTrim.setRepeatCount(ObjectAnimator.INFINITE);
        startTrim.setRepeatMode(ObjectAnimator.RESTART);

        final ObjectAnimator rotation = ObjectAnimator.ofFloat(ring, "rotation", 0.0f, 0.25f);
        rotation.setDuration(1000 * 80 / 60);
        rotation.setDuration(ANIMATION_DURATION);
        rotation.setInterpolator(LINEAR_INTERPOLATOR);
        rotation.setRepeatCount(ObjectAnimator.INFINITE);
        rotation.setRepeatMode(ObjectAnimator.RESTART);

        final ObjectAnimator groupRotation = ObjectAnimator.ofFloat(this, "rotation", 0.0f, 360.0f);
        groupRotation.setDuration(NUM_POINTS * ANIMATION_DURATION);
        groupRotation.setInterpolator(LINEAR_INTERPOLATOR);
        groupRotation.setRepeatCount(ObjectAnimator.INFINITE);
        groupRotation.setRepeatMode(ObjectAnimator.RESTART);

        mAnimators.add(endTrim);
        mAnimators.add(startTrim);
        mAnimators.add(rotation);
        mAnimators.add(groupRotation);
    }

    private final Callback mCallback = new Callback() {
+18 −9
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.graphics.Rect;
import android.util.MathUtils;
import android.view.HardwareCanvas;
import android.view.RenderNodeAnimator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;

import java.util.ArrayList;
@@ -37,13 +38,16 @@ import java.util.ArrayList;
 */
class Ripple {
    private static final TimeInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
    private static final TimeInterpolator DECEL_INTERPOLATOR = new DecelerateInterpolator(4);

    private static final float GLOBAL_SPEED = 1.0f;
    private static final float WAVE_TOUCH_DOWN_ACCELERATION = 512.0f * GLOBAL_SPEED;
    private static final float WAVE_TOUCH_UP_ACCELERATION = 1024.0f * GLOBAL_SPEED;
    private static final float WAVE_OPACITY_DECAY_VELOCITY = 1.6f / GLOBAL_SPEED;
    private static final float WAVE_TOUCH_DOWN_ACCELERATION = 1024.0f * GLOBAL_SPEED;
    private static final float WAVE_TOUCH_UP_ACCELERATION = 3096.0f * GLOBAL_SPEED;
    private static final float WAVE_OPACITY_DECAY_VELOCITY = 1.9f / GLOBAL_SPEED;
    private static final float WAVE_OUTER_OPACITY_VELOCITY = 1.2f * GLOBAL_SPEED;

    private static final long RIPPLE_ENTER_DELAY = 100;

    // Hardware animators.
    private final ArrayList<RenderNodeAnimator> mRunningAnimations = new ArrayList<>();
    private final ArrayList<RenderNodeAnimator> mPendingAnimations = new ArrayList<>();
@@ -287,14 +291,19 @@ class Ripple {
        radius.setAutoCancel(true);
        radius.setDuration(radiusDuration);
        radius.setInterpolator(LINEAR_INTERPOLATOR);
        radius.setStartDelay(RIPPLE_ENTER_DELAY);

        final ObjectAnimator cX = ObjectAnimator.ofFloat(this, "xGravity", 1);
        cX.setAutoCancel(true);
        cX.setDuration(radiusDuration);
        cX.setInterpolator(LINEAR_INTERPOLATOR);
        cX.setStartDelay(RIPPLE_ENTER_DELAY);

        final ObjectAnimator cY = ObjectAnimator.ofFloat(this, "yGravity", 1);
        cY.setAutoCancel(true);
        cY.setDuration(radiusDuration);
        cY.setInterpolator(LINEAR_INTERPOLATOR);
        cY.setStartDelay(RIPPLE_ENTER_DELAY);

        final ObjectAnimator outer = ObjectAnimator.ofFloat(this, "outerOpacity", 0, 1);
        outer.setAutoCancel(true);
@@ -377,15 +386,15 @@ class Ripple {

        final RenderNodeAnimator radiusAnim = new RenderNodeAnimator(mPropRadius, mOuterRadius);
        radiusAnim.setDuration(radiusDuration);
        radiusAnim.setInterpolator(LINEAR_INTERPOLATOR);
        radiusAnim.setInterpolator(DECEL_INTERPOLATOR);

        final RenderNodeAnimator xAnim = new RenderNodeAnimator(mPropX, mOuterX);
        xAnim.setDuration(radiusDuration);
        xAnim.setInterpolator(LINEAR_INTERPOLATOR);
        xAnim.setInterpolator(DECEL_INTERPOLATOR);

        final RenderNodeAnimator yAnim = new RenderNodeAnimator(mPropY, mOuterY);
        yAnim.setDuration(radiusDuration);
        yAnim.setInterpolator(LINEAR_INTERPOLATOR);
        yAnim.setInterpolator(DECEL_INTERPOLATOR);

        final RenderNodeAnimator opacityAnim = new RenderNodeAnimator(mPropPaint,
                RenderNodeAnimator.PAINT_ALPHA, 0);
@@ -439,17 +448,17 @@ class Ripple {
        final ObjectAnimator radiusAnim = ObjectAnimator.ofFloat(this, "radiusGravity", 1);
        radiusAnim.setAutoCancel(true);
        radiusAnim.setDuration(radiusDuration);
        radiusAnim.setInterpolator(LINEAR_INTERPOLATOR);
        radiusAnim.setInterpolator(DECEL_INTERPOLATOR);

        final ObjectAnimator xAnim = ObjectAnimator.ofFloat(this, "xGravity", 1);
        xAnim.setAutoCancel(true);
        xAnim.setDuration(radiusDuration);
        xAnim.setInterpolator(LINEAR_INTERPOLATOR);
        xAnim.setInterpolator(DECEL_INTERPOLATOR);

        final ObjectAnimator yAnim = ObjectAnimator.ofFloat(this, "yGravity", 1);
        yAnim.setAutoCancel(true);
        yAnim.setDuration(radiusDuration);
        yAnim.setInterpolator(LINEAR_INTERPOLATOR);
        yAnim.setInterpolator(DECEL_INTERPOLATOR);

        final ObjectAnimator opacityAnim = ObjectAnimator.ofFloat(this, "opacity", 0);
        opacityAnim.setAutoCancel(true);
+16 −14
Original line number Diff line number Diff line
@@ -95,6 +95,9 @@ public class RippleDrawable extends LayerDrawable {

    private final RippleState mState;

    /** The masking layer, e.g. the layer with id R.id.mask. */
    private Drawable mMask;

    /** The current hotspot. May be actively animating or pending entry. */
    private Ripple mHotspot;

@@ -261,21 +264,14 @@ public class RippleDrawable extends LayerDrawable {
        super.inflate(r, parser, attrs, theme);

        setTargetDensity(r.getDisplayMetrics());

        // Find the mask
        final int N = getNumberOfLayers();
        for (int i = 0; i < N; i++) {
            if (mLayerState.mChildren[i].mId == R.id.mask) {
                mState.mMask = mLayerState.mChildren[i].mDrawable;
            }
        }
        initializeFromState();
    }

    @Override
    public boolean setDrawableByLayerId(int id, Drawable drawable) {
        if (super.setDrawableByLayerId(id, drawable)) {
            if (id == R.id.mask) {
                mState.mMask = drawable;
                mMask = drawable;
            }

            return true;
@@ -361,6 +357,8 @@ public class RippleDrawable extends LayerDrawable {
        } finally {
            a.recycle();
        }

        initializeFromState();
    }

    @Override
@@ -527,7 +525,7 @@ public class RippleDrawable extends LayerDrawable {

    private int drawContentLayer(Canvas canvas, Rect bounds, PorterDuffXfermode mode) {
        final int count = mLayerState.mNum;
        if (count == 0 || (mState.mMask != null && count == 1)) {
        if (count == 0 || (mMask != null && count == 1)) {
            return -1;
        }

@@ -611,7 +609,7 @@ public class RippleDrawable extends LayerDrawable {
    }

    private int drawMaskingLayer(Canvas canvas, Rect bounds, PorterDuffXfermode mode) {
        final Drawable mask = mState.mMask;
        final Drawable mask = mMask;
        if (mask == null) {
            return -1;
        }
@@ -667,7 +665,6 @@ public class RippleDrawable extends LayerDrawable {
        int[] mTouchThemeAttrs;
        ColorStateList mTint = null;
        PorterDuffXfermode mTintXfermode = SRC_ATOP;
        Drawable mMask;
        int mMaxRadius = RADIUS_AUTO;
        boolean mPinned = false;

@@ -763,8 +760,6 @@ public class RippleDrawable extends LayerDrawable {
        }

        mState = ns;
        mState.mMask = findDrawableByLayerId(R.id.mask);

        mLayerState = ns;

        if (ns.mNum > 0) {
@@ -774,5 +769,12 @@ public class RippleDrawable extends LayerDrawable {
        if (needsTheme) {
            applyTheme(theme);
        }

        initializeFromState();
    }

    private void initializeFromState() {
        // Initialize from constant state.
        mMask = findDrawableByLayerId(R.id.mask);
    }
}