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

Commit 7ccc4625 authored by Hyunyoung Song's avatar Hyunyoung Song Committed by Peter Schiller
Browse files

Responsive caret drawable

Change-Id: I9d40052d001c80d99db511af6134227f8e4e4239
parent 64035e9e
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -66,6 +66,11 @@
  public void setAnimationProgress(float);
}

-keep class com.android.launcher3.pageindicators.CaretDrawable {
  public float getCaretProgress();
  public void setCaretProgress(float);
}

-keep class com.android.launcher3.Workspace {
  public float getBackgroundAlpha();
  public void setBackgroundAlpha(float);
+1 −1
Original line number Diff line number Diff line
@@ -705,7 +705,7 @@ public class LauncherStateTransitionAnimation {
        if (!animated || !initialized) {
            if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP &&
                    fromWorkspaceState == Workspace.State.NORMAL_HIDDEN) {
                mAllAppsController.finishPullDown(false);
                mAllAppsController.finishPullDown();
            }
            fromView.setVisibility(View.GONE);
            dispatchOnLauncherTransitionPrepare(fromView, animated, multiplePagesVisible);
+51 −23
Original line number Diff line number Diff line
@@ -59,6 +59,8 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
    private ObjectAnimator mCaretAnimator;
    private final long mCaretAnimationDuration;
    private final Interpolator mCaretInterpolator;
    private CaretDrawable mCaretDrawable;
    private float mLastCaretProgress;

    private float mStatusBarHeight;

@@ -76,6 +78,8 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
    private float mShiftRange;      // changes depending on the orientation
    private float mProgress;        // [0, 1], mShiftRange * mProgress = shiftCurrent

    private float mVelocityForCaret;

    private static final float DEFAULT_SHIFT_RANGE = 10;

    private static final float RECATCH_REJECTION_FRACTION = .0875f;
@@ -203,8 +207,12 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
        if (mAppsView == null) {
            return false;   // early termination.
        }

        mVelocityForCaret = velocity;

        float shift = Math.min(Math.max(0, mShiftStart + displacement), mShiftRange);
        setProgress(shift / mShiftRange);

        return true;
    }

@@ -329,6 +337,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
        mWorkspace.setWorkspaceYTranslationAndAlpha(
                PARALLAX_COEFFICIENT * (-mShiftRange + shiftCurrent),
                interpolation);
        updateCaret(progress);
        updateLightStatusBar(shiftCurrent);
    }

@@ -352,6 +361,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
            return;
        }
        if (mDetector.isIdleState()) {
            mVelocityForCaret = -VerticalPullDetector.RELEASE_VELOCITY_PX_MS;
            preparePull(true);
            mAnimationDuration = duration;
            mShiftStart = mAppsView.getTranslationY();
@@ -404,7 +414,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul

            @Override
            public void onAnimationEnd(Animator animator) {
                finishPullDown(false);
                finishPullDown();
                mDiscoBounceAnimation = null;
                mIsTranslateWithoutWorkspace = false;
            }
@@ -424,6 +434,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
        }
        Interpolator interpolator;
        if (mDetector.isIdleState()) {
            mVelocityForCaret = VerticalPullDetector.RELEASE_VELOCITY_PX_MS;
            preparePull(true);
            mAnimationDuration = duration;
            mShiftStart = mAppsView.getTranslationY();
@@ -452,7 +463,7 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
                if (canceled) {
                    return;
                } else {
                    finishPullDown(true);
                    finishPullDown();
                    cleanUpAnimation();
                    mDetector.finishedScrolling();
                }
@@ -464,21 +475,14 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
    public void finishPullUp() {
        mHotseat.setVisibility(View.INVISIBLE);
        setProgress(0f);
        animateCaret();
    }

    public void finishPullDown(boolean animated) {
    public void finishPullDown() {
        mAppsView.setVisibility(View.INVISIBLE);
        mHotseat.setBackgroundTransparent(false /* transparent */);
        mHotseat.setVisibility(View.VISIBLE);
        mAppsView.reset();
        setProgress(1f);
        if (animated) {
            animateCaret();
        } else {
            mWorkspace.getPageIndicator().getCaretDrawable()
                    .setLevel(CaretDrawable.LEVEL_CARET_POINTING_UP);
        }
    }

    private void cancelAnimation() {
@@ -501,17 +505,41 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
        mCurrentAnimation = null;
    }

    private void animateCaret() {
        if (mCaretAnimator.isRunning()) {
            mCaretAnimator.cancel(); // stop the animator in its tracks
    private void updateCaret(float shift) {
        // Animate to a neutral state by default
        float newCaretProgress = CaretDrawable.PROGRESS_CARET_NEUTRAL;

        // If we're in portrait and the shift is not 0 or 1, adjust the caret based on velocity
        if (0f < shift && shift < 1f && !mLauncher.useVerticalBarLayout()) {
            // How fast are we moving as a percentage of the minimum fling velocity?
            final float pctOfFlingVelocity = Math.max(-1, Math.min(
                    mVelocityForCaret / VerticalPullDetector.RELEASE_VELOCITY_PX_MS, 1));

            mCaretDrawable.setCaretProgress(pctOfFlingVelocity);

            // Set the last caret progress to this progress to prevent animator cancellation
            mLastCaretProgress = pctOfFlingVelocity;
        } else if (!mDetector.isDraggingState()) {
            // Otherwise, if we're not dragging, match the caret to the appropriate state
            if (Float.compare(shift, 0f) == 0) { // All Apps is up
                newCaretProgress = CaretDrawable.PROGRESS_CARET_POINTING_DOWN;
            } else if (Float.compare(shift, 1f) == 0) { // All Apps is down
                newCaretProgress = CaretDrawable.PROGRESS_CARET_POINTING_UP;
            }
        }

        if (mLauncher.isAllAppsVisible()) {
            mCaretAnimator.setIntValues(CaretDrawable.LEVEL_CARET_POINTING_DOWN);
        } else {
            mCaretAnimator.setIntValues(CaretDrawable.LEVEL_CARET_POINTING_UP);
        // If the new progress is the same as the last progress we animated to, terminate early
        if (Float.compare(mLastCaretProgress, newCaretProgress) == 0) {
            return;
        }

        if (mCaretAnimator.isRunning()) {
            mCaretAnimator.cancel(); // Stop the animator in its tracks
        }

        // Update the progress and start the animation
        mLastCaretProgress = newCaretProgress;
        mCaretAnimator.setFloatValues(newCaretProgress);
        mCaretAnimator.start();
    }

@@ -519,12 +547,14 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
        mAppsView = appsView;
        mHotseat = hotseat;
        mWorkspace = workspace;
        mCaretAnimator = ObjectAnimator.ofInt(mWorkspace.getPageIndicator().getCaretDrawable(),
                "level", CaretDrawable.LEVEL_CARET_POINTING_UP); // we will set values later
        mCaretAnimator.setDuration(mCaretAnimationDuration);
        mCaretAnimator.setInterpolator(mCaretInterpolator);
        mCaretDrawable = mWorkspace.getPageIndicator().getCaretDrawable();
        mHotseat.addOnLayoutChangeListener(this);
        mHotseat.bringToFront();

        // we will set values later
        mCaretAnimator = ObjectAnimator.ofFloat(mCaretDrawable, "caretProgress", 0);
        mCaretAnimator.setDuration(mCaretAnimationDuration);
        mCaretAnimator.setInterpolator(mCaretInterpolator);
    }

    @Override
@@ -537,6 +567,4 @@ public class AllAppsTransitionController implements TouchController, VerticalPul
        }
        setProgress(mProgress);
    }


}
+5 −1
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ public class VerticalPullDetector {
    /**
     * The minimum release velocity in pixels per millisecond that triggers fling..
     */
    private static final float RELEASE_VELOCITY_PX_MS = 1.0f;
    public static final float RELEASE_VELOCITY_PX_MS = 1.0f;

    /**
     * The time constant used to calculate dampening in the low-pass filter of scroll velocity.
@@ -87,6 +87,10 @@ public class VerticalPullDetector {
        return mState == ScrollState.SETTLING;
    }

    public boolean isDraggingState() {
        return mState == ScrollState.DRAGGING;
    }

    private float mDownX;
    private float mDownY;
    private float mDownMillis;
+36 −11
Original line number Diff line number Diff line
@@ -28,11 +28,11 @@ import com.android.launcher3.R;
import android.graphics.drawable.Drawable;

public class CaretDrawable extends Drawable {
    public static final int LEVEL_CARET_POINTING_UP = 0; // minimum possible level value
    public static final int LEVEL_CARET_POINTING_DOWN = 10000; // maximum possible level value
    public static final int LEVEL_CARET_NEUTRAL = LEVEL_CARET_POINTING_DOWN / 2;
    public static final float PROGRESS_CARET_POINTING_UP = -1f;
    public static final float PROGRESS_CARET_POINTING_DOWN = 1f;
    public static final float PROGRESS_CARET_NEUTRAL = 0;

    private float mCaretProgress;
    private float mCaretProgress = PROGRESS_CARET_NEUTRAL;

    private Paint mShadowPaint = new Paint();
    private Paint mCaretPaint = new Paint();
@@ -72,23 +72,48 @@ public class CaretDrawable extends Drawable {
        final float left = getBounds().left + (mShadowPaint.getStrokeWidth() / 2);
        final float top = getBounds().top + (mShadowPaint.getStrokeWidth() / 2);

        // When the bounds are square, this will result in a caret with a right angle
        final float verticalInset = (height / 4);
        final float caretHeight = (height - (verticalInset * 2));

        mPath.reset();
        mPath.moveTo(left, top + caretHeight * (1 - mCaretProgress));
        mPath.lineTo(left + (width / 2), top + caretHeight * mCaretProgress);
        mPath.lineTo(left + width, top + caretHeight * (1 - mCaretProgress));
        mPath.moveTo(left, top + caretHeight * (1 - getNormalizedCaretProgress()));
        mPath.lineTo(left + (width / 2), top + caretHeight * getNormalizedCaretProgress());
        mPath.lineTo(left + width, top + caretHeight * (1 - getNormalizedCaretProgress()));

        canvas.drawPath(mPath, mShadowPaint);
        canvas.drawPath(mPath, mCaretPaint);
    }

    @Override
    protected boolean onLevelChange(int level) {
        mCaretProgress = (float) level / (float) LEVEL_CARET_POINTING_DOWN;
    /**
     * Sets the caret progress
     *
     * @param progress The progress ({@value #PROGRESS_CARET_POINTING_UP} for pointing up,
     * {@value #PROGRESS_CARET_POINTING_DOWN} for pointing down, {@value #PROGRESS_CARET_NEUTRAL}
     * for neutral)
     */
    public void setCaretProgress(float progress) {
        mCaretProgress = progress;
        invalidateSelf();
        return true;
    }

    /**
     * Returns the caret progress
     *
     * @return The progress
     */
    public float getCaretProgress() {
        return mCaretProgress;
    }

    /**
     * Returns the caret progress normalized to [0..1]
     *
     * @return The normalized progress
     */
    public float getNormalizedCaretProgress() {
        return (mCaretProgress - PROGRESS_CARET_POINTING_UP) /
                (PROGRESS_CARET_POINTING_DOWN - PROGRESS_CARET_POINTING_UP);
    }

    @Override