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

Commit 737552d7 authored by Bobby Georgescu's avatar Bobby Georgescu Committed by Android (Google) Code Review
Browse files

Merge "Big refactor, additions to state transition animations" into gb-ub-photos-arches

parents 0addfc7f 4831c749
Loading
Loading
Loading
Loading
+108 −30
Original line number Diff line number Diff line
@@ -17,61 +17,139 @@
package com.android.gallery3d.anim;

import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;

import com.android.gallery3d.ui.GLCanvas;
import com.android.gallery3d.ui.GLView;
import com.android.gallery3d.ui.RawTexture;
import com.android.gallery3d.ui.TiledScreenNail;

public class StateTransitionAnimation extends Animation {
    private static final float BACKGROUND_ALPHA_FROM = 1f;
    private static final float BACKGROUND_ALPHA_TO = 0f;
    private static final float BACKGROUND_SCALE_FROM = 1f;
    private static final float BACKGROUND_SCALE_TO = 0f;
    private static final float FOREGROUND_ALPHA_FROM = 0.9f;
    private static final float FOREGROUND_ALPHA_TO = 1f;
    private static final float FOREGROUND_SCALE_FROM = 3f;
    private static final float FOREGROUND_SCALE_TO = 1f;

    private float mCurrentForegroundScale;

    public static class Spec {
        public static final Spec OUTGOING;
        public static final Spec INCOMING;

        public int duration = 330;
        public float backgroundAlphaFrom = 0;
        public float backgroundAlphaTo = 0;
        public float backgroundScaleFrom = 0;
        public float backgroundScaleTo = 0;
        public float contentAlphaFrom = 1;
        public float contentAlphaTo = 1;
        public float contentScaleFrom = 1;
        public float contentScaleTo = 1;
        public float overlayAlphaFrom = 0;
        public float overlayAlphaTo = 0;
        public float overlayScaleFrom = 0;
        public float overlayScaleTo = 0;
        public Interpolator interpolator;

        static {
            OUTGOING = new Spec();
            OUTGOING.backgroundAlphaFrom = 1f;
            OUTGOING.backgroundAlphaTo = 0f;
            OUTGOING.backgroundScaleFrom = 1f;
            OUTGOING.backgroundScaleTo = 0f;
            OUTGOING.contentAlphaFrom = 0.9f;
            OUTGOING.contentAlphaTo = 1f;
            OUTGOING.contentScaleFrom = 3f;
            OUTGOING.contentScaleTo = 1f;
            OUTGOING.interpolator = new DecelerateInterpolator();

            INCOMING = new Spec();
            INCOMING.overlayAlphaFrom = 1f;
            INCOMING.overlayAlphaTo = 0f;
            INCOMING.overlayScaleFrom = 1f;
            INCOMING.overlayScaleTo = 3f;
            INCOMING.contentAlphaFrom = 0f;
            INCOMING.contentAlphaTo = 1f;
            INCOMING.contentScaleFrom = 0.25f;
            INCOMING.contentScaleTo = 1f;
            INCOMING.interpolator = new DecelerateInterpolator();
        }
    }

    private final Spec mTransitionSpec;
    private float mCurrentContentScale;
    private float mCurrentContentAlpha;
    private float mCurrentBackgroundScale;
    private float mCurrentBackgroundAlpha;
    private float mCurrentForegroundAlpha;
    private float mCurrentOverlayScale;
    private float mCurrentOverlayAlpha;
    private RawTexture mOldScreenTexture;

    public StateTransitionAnimation(Spec spec, RawTexture oldScreen) {
        mTransitionSpec = spec != null ? spec : Spec.OUTGOING;
        setDuration(mTransitionSpec.duration);
        setInterpolator(mTransitionSpec.interpolator);
        mOldScreenTexture = oldScreen;
        if (mOldScreenTexture != null) {
            TiledScreenNail.disableDrawPlaceholder();
        }
    }

    public StateTransitionAnimation(int duration) {
        setDuration(duration);
        setInterpolator(new DecelerateInterpolator());
    @Override
    public boolean calculate(long currentTimeMillis) {
        boolean retval = super.calculate(currentTimeMillis);
        if (mOldScreenTexture != null && !isActive()) {
            mOldScreenTexture.recycle();
            mOldScreenTexture = null;
            TiledScreenNail.enableDrawPlaceholder();
        }
        return retval;
    }

    @Override
    protected void onCalculate(float progress) {
        mCurrentForegroundScale = FOREGROUND_SCALE_FROM
                + (FOREGROUND_SCALE_TO - FOREGROUND_SCALE_FROM) * progress;
        mCurrentForegroundAlpha = FOREGROUND_ALPHA_FROM
                + (FOREGROUND_ALPHA_TO - FOREGROUND_ALPHA_FROM) * progress;
        mCurrentBackgroundAlpha = BACKGROUND_ALPHA_FROM
                + (BACKGROUND_ALPHA_TO - BACKGROUND_ALPHA_FROM) * progress;
        mCurrentBackgroundScale = BACKGROUND_SCALE_FROM
                + (BACKGROUND_SCALE_TO - BACKGROUND_SCALE_FROM) * progress;
        mCurrentContentScale = mTransitionSpec.contentScaleFrom
                + (mTransitionSpec.contentScaleTo - mTransitionSpec.contentScaleFrom) * progress;
        mCurrentContentAlpha = mTransitionSpec.contentAlphaFrom
                + (mTransitionSpec.contentAlphaTo - mTransitionSpec.contentAlphaFrom) * progress;
        mCurrentBackgroundAlpha = mTransitionSpec.backgroundAlphaFrom
                + (mTransitionSpec.backgroundAlphaTo - mTransitionSpec.backgroundAlphaFrom)
                * progress;
        mCurrentBackgroundScale = mTransitionSpec.backgroundScaleFrom
                + (mTransitionSpec.backgroundScaleTo - mTransitionSpec.backgroundScaleFrom)
                * progress;
        mCurrentOverlayScale = mTransitionSpec.overlayScaleFrom
                + (mTransitionSpec.overlayScaleTo - mTransitionSpec.overlayScaleFrom) * progress;
        mCurrentOverlayAlpha = mTransitionSpec.overlayAlphaFrom
                + (mTransitionSpec.overlayAlphaTo - mTransitionSpec.overlayAlphaFrom) * progress;
    }

    public void applyBackground(GLView view, GLCanvas canvas, RawTexture fadeTexture) {
        canvas.clearBuffer(view.getBackgroundColor());
    private void applyOldTexture(GLView view, GLCanvas canvas, float alpha, float scale, boolean clear) {
        if (mOldScreenTexture == null)
            return;
        if (clear) canvas.clearBuffer(view.getBackgroundColor());
        canvas.save();
        canvas.setAlpha(mCurrentBackgroundAlpha);
        canvas.setAlpha(alpha);
        int xOffset = view.getWidth() / 2;
        int yOffset = view.getHeight() / 2;
        canvas.translate(xOffset, yOffset);
        canvas.scale(mCurrentBackgroundScale, mCurrentBackgroundScale, 1);
        fadeTexture.draw(canvas, -xOffset, -yOffset);
        canvas.scale(scale, scale, 1);
        mOldScreenTexture.draw(canvas, -xOffset, -yOffset);
        canvas.restore();
    }

    public void applyForegroundTransformation(GLView view, GLCanvas canvas) {
    public void applyBackground(GLView view, GLCanvas canvas) {
        if (mCurrentBackgroundAlpha > 0f) {
            applyOldTexture(view, canvas, mCurrentBackgroundAlpha, mCurrentBackgroundScale, true);
        }
    }

    public void applyContentTransform(GLView view, GLCanvas canvas) {
        int xOffset = view.getWidth() / 2;
        int yOffset = view.getHeight() / 2;
        canvas.translate(xOffset, yOffset);
        canvas.scale(mCurrentForegroundScale, mCurrentForegroundScale, 1);
        canvas.scale(mCurrentContentScale, mCurrentContentScale, 1);
        canvas.translate(-xOffset, -yOffset);
        canvas.setAlpha(mCurrentForegroundAlpha);
        canvas.setAlpha(mCurrentContentAlpha);
    }

    public void applyOverlay(GLView view, GLCanvas canvas) {
        if (mCurrentOverlayAlpha > 0f) {
            applyOldTexture(view, canvas, mCurrentOverlayAlpha, mCurrentOverlayScale, false);
        }
    }
}
+29 −18
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.view.Window;
import android.view.WindowManager;

import com.android.gallery3d.R;
import com.android.gallery3d.anim.StateTransitionAnimation;
import com.android.gallery3d.ui.GLView;
import com.android.gallery3d.ui.PreparePageFadeoutTexture;
import com.android.gallery3d.ui.RawTexture;
@@ -70,19 +71,19 @@ abstract public class ActivityState {

    private static final String KEY_TRANSITION_IN = "transition-in";

    private RawTexture mFadeOutTexture;
    public static enum StateTransition { None, Outgoing, Incoming };
    private StateTransition mNextTransition = StateTransition.None;
    private StateTransitionAnimation mIntroAnimation;
    private GLView mContentPane;
    private boolean mWantFadeOut = false;
    private boolean mTransitionIn;

    protected ActivityState() {
    }

    protected void setContentPane(GLView content) {
        mContentPane = content;
        if (mTransitionIn) {
            mContentPane.setFadeOutTexture(mFadeOutTexture);
            mFadeOutTexture = null;
        if (mNextTransition != StateTransition.None) {
            mContentPane.setIntroAnimation(mIntroAnimation);
            mIntroAnimation = null;
        }
        mContentPane.setBackgroundColor(getBackgroundColor());
        mActivity.getGLRoot().setContentPane(mContentPane);
@@ -99,9 +100,6 @@ abstract public class ActivityState {
    }

    protected void onBackPressed() {
        if (mActivity.getStateManager().getStateCount() > 1) {
            fadeOutOnNextPause();
        }
        mActivity.getStateManager().finishState(this);
    }

@@ -175,19 +173,25 @@ abstract public class ActivityState {
        win.setAttributes(params);
    }

    protected void fadeOutOnNextPause() {
        mWantFadeOut = true;
    protected void transitionOnNextPause(Class<? extends ActivityState> outgoing,
            Class<? extends ActivityState> incoming, StateTransition hint) {
        if (outgoing == PhotoPage.class && incoming == AlbumPage.class) {
            mNextTransition = StateTransition.Outgoing;
        } else if (outgoing == AlbumPage.class && incoming == PhotoPage.class) {
            mNextTransition = StateTransition.Incoming;
        } else {
            mNextTransition = hint;
        }
    }

    protected void onPause() {
        if (0 != (mFlags & FLAG_SCREEN_ON_WHEN_PLUGGED)) {
            ((Activity) mActivity).unregisterReceiver(mPowerIntentReceiver);
        }
        if (mWantFadeOut) {
            mWantFadeOut = false;
            if (PreparePageFadeoutTexture.prepareFadeOutTexture(mActivity, mContentPane)) {
                mActivity.getTransitionStore().put(KEY_TRANSITION_IN, true);
            }
        if (mNextTransition != StateTransition.None) {
            mActivity.getTransitionStore().put(KEY_TRANSITION_IN, mNextTransition);
            PreparePageFadeoutTexture.prepareFadeOutTexture(mActivity, mContentPane);
            mNextTransition = StateTransition.None;
        }
    }

@@ -242,9 +246,16 @@ abstract public class ActivityState {

    // a subclass of ActivityState should override the method to resume itself
    protected void onResume() {
        mFadeOutTexture = mActivity.getTransitionStore().get(
        RawTexture fade = mActivity.getTransitionStore().get(
                PreparePageFadeoutTexture.KEY_FADE_TEXTURE);
        mTransitionIn = mActivity.getTransitionStore().get(KEY_TRANSITION_IN, false);
        mNextTransition = mActivity.getTransitionStore().get(
                KEY_TRANSITION_IN, StateTransition.None);
        if (mNextTransition != StateTransition.None) {
            mIntroAnimation = new StateTransitionAnimation(
                    (mNextTransition == StateTransition.Incoming) ?
                            StateTransitionAnimation.Spec.INCOMING :
                            StateTransitionAnimation.Spec.OUTGOING, fade);
        }
    }

    protected boolean onCreateActionBar(Menu menu) {
+14 −9
Original line number Diff line number Diff line
@@ -57,7 +57,8 @@ public class StateManager {
        }
        if (!mStack.isEmpty()) {
            ActivityState top = getTopState();
            top.fadeOutOnNextPause();
            top.transitionOnNextPause(top.getClass(), klass,
                    ActivityState.StateTransition.Incoming);
            if (mIsResumed) top.onPause();
        }
        state.initialize(mActivity, data);
@@ -82,7 +83,8 @@ public class StateManager {

        if (!mStack.isEmpty()) {
            ActivityState as = getTopState();
            as.fadeOutOnNextPause();
            as.transitionOnNextPause(as.getClass(), klass,
                    ActivityState.StateTransition.Incoming);
            as.mReceivedResults = state.mResult;
            if (mIsResumed) as.onPause();
        } else {
@@ -188,15 +190,18 @@ public class StateManager {
        // Remove the top state.
        mStack.pop();
        state.mIsFinishing = true;
        if (mIsResumed && fireOnPause) state.onPause();
        ActivityState top = !mStack.isEmpty() ? mStack.peek().activityState : null;
        if (mIsResumed && fireOnPause) {
            if (top != null) {
                state.transitionOnNextPause(state.getClass(), top.getClass(),
                        ActivityState.StateTransition.Outgoing);
            }
            state.onPause();
        }
        mActivity.getGLRoot().setContentPane(null);
        state.onDestroy();

        if (!mStack.isEmpty()) {
            // Restore the immediately previous state
            ActivityState top = mStack.peek().activityState;
            if (mIsResumed) top.resume();
        }
        if (top != null && mIsResumed) top.resume();
    }

    public void switchState(ActivityState oldState,
@@ -211,7 +216,7 @@ public class StateManager {
        mStack.pop();
        if (!data.containsKey(PhotoPage.KEY_APP_BRIDGE)) {
            // Do not do the fade out stuff when we are switching camera modes
            oldState.fadeOutOnNextPause();
            oldState.transitionOnNextPause(oldState.getClass(), klass, ActivityState.StateTransition.Incoming);
        }
        if (mIsResumed) oldState.onPause();
        oldState.onDestroy();
+19 −21
Original line number Diff line number Diff line
@@ -78,10 +78,8 @@ public class GLView {
    protected int mScrollHeight = 0;
    protected int mScrollWidth = 0;

    public static final int ANIM_TIME_OPENING = 400;
    private RawTexture mFadeOutTexture;
    private float [] mBackgroundColor;
    private StateTransitionAnimation mTransition = new StateTransitionAnimation(ANIM_TIME_OPENING);
    private StateTransitionAnimation mTransition;

    public void startAnimation(CanvasAnimation animation) {
        GLRoot root = getGLRoot();
@@ -223,22 +221,28 @@ public class GLView {
    }

    protected void render(GLCanvas canvas) {
        if (mTransition.calculate(AnimationTime.get())) invalidate();
        canvas.save();
        boolean transitionActive = false;
        if (mTransition != null && mTransition.calculate(AnimationTime.get())) {
            invalidate();
            transitionActive = mTransition.isActive();
        }
        renderBackground(canvas);
        if (mTransition.isActive()) mTransition.applyForegroundTransformation(this, canvas);
        canvas.save();
        if (transitionActive) {
            mTransition.applyContentTransform(this, canvas);
        }
        for (int i = 0, n = getComponentCount(); i < n; ++i) {
            renderChild(canvas, getComponent(i));
        }
        canvas.restore();
        if (transitionActive) {
            mTransition.applyOverlay(this, canvas);
        }

    public void setFadeOutTexture(RawTexture texture) {
        mFadeOutTexture = texture;
        if (mFadeOutTexture != null) {
            TiledScreenNail.disableDrawPlaceholder();
    }
        mTransition.start();

    public void setIntroAnimation(StateTransitionAnimation intro) {
        mTransition = intro;
        if (mTransition != null) mTransition.start();
    }

    public float [] getBackgroundColor() {
@@ -253,17 +257,11 @@ public class GLView {
        if (mBackgroundColor != null) {
            view.clearBuffer(mBackgroundColor);
        }
        if (mFadeOutTexture != null) {
            if (!mTransition.isActive()) {
                mFadeOutTexture.recycle();
                mFadeOutTexture = null;
                TiledScreenNail.enableDrawPlaceholder();
            } else {
                mTransition.applyBackground(this, view, mFadeOutTexture);
        if (mTransition != null && mTransition.isActive()) {
            mTransition.applyBackground(this, view);
            return;
        }
    }
    }

    protected void renderChild(GLCanvas canvas, GLView component) {
        if (component.getVisibility() != GLView.VISIBLE
+1 −1
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ class PositionController {
        SNAPBACK_ANIMATION_TIME,  // ANIM_KIND_SNAPBACK
        400,  // ANIM_KIND_SLIDE
        300,  // ANIM_KIND_ZOOM
        GLView.ANIM_TIME_OPENING,  // ANIM_KIND_OPENING
        300,  // ANIM_KIND_OPENING
        0,    // ANIM_KIND_FLING (the duration is calculated dynamically)
        0,    // ANIM_KIND_FLING_X (see the comment above)
        0,    // ANIM_KIND_DELETE (the duration is calculated dynamically)
Loading