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

Commit f1de89b1 authored by George Mount's avatar George Mount
Browse files

Placeholder implementation of stretch overscroll using offset

Temporarily use an offset RenderEffect for the stretch overscroll.
This makes it possible to visually validate the effect and start
writing CTS tests to ensure it is functioning.

Bug: 178807038
Test: Iab32812bfa626ae6932f52c1a9af78069b5dc6ac
Change-Id: I5b0da0e669d36f4149cd58b4b3aff149a1fa7e14
parent 40ad7812
Loading
Loading
Loading
Loading
+69 −21
Original line number Diff line number Diff line
@@ -25,8 +25,12 @@ import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RecordingCanvas;
import android.graphics.Rect;
import android.graphics.RenderEffect;
import android.graphics.RenderNode;
import android.os.Build;
import android.util.AttributeSet;
import android.view.animation.AnimationUtils;
@@ -149,6 +153,8 @@ public class EdgeEffect {
    private float mDisplacement = 0.5f;
    private float mTargetDisplacement = 0.5f;
    private @EdgeEffectType int mEdgeEffectType = TYPE_GLOW;
    private Matrix mTmpMatrix = null;
    private float[] mTmpPoints = null;

    /**
     * Construct a new EdgeEffect with a theme appropriate for the provided context.
@@ -250,12 +256,19 @@ public class EdgeEffect {
    public void onPull(float deltaDistance, float displacement) {
        final long now = AnimationUtils.currentAnimationTimeMillis();
        mTargetDisplacement = displacement;
        if (mState == STATE_PULL_DECAY && now - mStartTime < mDuration) {
        if (mState == STATE_PULL_DECAY && now - mStartTime < mDuration
                && mEdgeEffectType == TYPE_GLOW) {
            return;
        }
        if (mState != STATE_PULL) {
            if (mEdgeEffectType == TYPE_STRETCH) {
                // Restore the mPullDistance to the fraction it is currently showing -- we want
                // to "catch" the current stretch value.
                mPullDistance = mDistance;
            } else {
                mGlowScaleY = Math.max(PULL_GLOW_BEGIN, mGlowScaleY);
            }
        }
        mState = STATE_PULL;

        mStartTime = now;
@@ -313,6 +326,15 @@ public class EdgeEffect {
    public float onPullDistance(float deltaDistance, float displacement) {
        float finalDistance = Math.max(0f, deltaDistance + mDistance);
        float delta = finalDistance - mDistance;
        if (delta == 0f && mDistance == 0f) {
            return 0f; // No pull, don't do anything.
        }

        if (mState != STATE_PULL && mState != STATE_PULL_DECAY && mEdgeEffectType == TYPE_GLOW) {
            // Catch the edge glow in the middle of an animation.
            mPullDistance = mDistance;
            mState = STATE_PULL;
        }
        onPull(delta, displacement);
        return delta;
    }
@@ -466,15 +488,16 @@ public class EdgeEffect {
     * Draw into the provided canvas. Assumes that the canvas has been rotated
     * accordingly and the size has been set. The effect will be drawn the full
     * width of X=0 to X=width, beginning from Y=0 and extending to some factor <
     * 1.f of height.
     * 1.f of height. The {@link #TYPE_STRETCH} effect will only be visible on a
     * hardware canvas, e.g. {@link RenderNode#beginRecording()}.
     *
     * @param canvas Canvas to draw into
     * @return true if drawing should continue beyond this frame to continue the
     *         animation
     */
    public boolean draw(Canvas canvas) {
        if (mEdgeEffectType == TYPE_GLOW) {
            update();

            final int count = canvas.save();

            final float centerX = mBounds.centerX();
@@ -490,9 +513,34 @@ public class EdgeEffect {
            mPaint.setAlpha((int) (0xff * mGlowAlpha));
            canvas.drawCircle(centerX, centerY, mRadius, mPaint);
            canvas.restoreToCount(count);
        } else if (canvas instanceof RecordingCanvas) {
            if (mState != STATE_PULL) {
                update();
            }
            RecordingCanvas recordingCanvas = (RecordingCanvas) canvas;
            if (mTmpMatrix == null) {
                mTmpMatrix = new Matrix();
                mTmpPoints = new float[4];
            }
            //noinspection deprecation
            recordingCanvas.getMatrix(mTmpMatrix);
            mTmpPoints[0] = mBounds.width() * mDisplacement;
            mTmpPoints[1] = mDistance * mBounds.height();
            mTmpPoints[2] = mTmpPoints[0];
            mTmpPoints[3] = 0;
            mTmpMatrix.mapPoints(mTmpPoints);
            float x = mTmpPoints[0] - mTmpPoints[2];
            float y = mTmpPoints[1] - mTmpPoints[3];

            RenderNode renderNode = recordingCanvas.mNode;

            // TODO: use stretchy RenderEffect and use internal API when it is ready
            // TODO: wrap existing RenderEffect
            renderNode.setRenderEffect(RenderEffect.createOffsetEffect(x, y));
        }

        boolean oneLastFrame = false;
        if (mState == STATE_RECEDE && mGlowScaleY == 0) {
        if (mState == STATE_RECEDE && mDistance == 0) {
            mState = STATE_IDLE;
            oneLastFrame = true;
        }