15585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu/*
25585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu * Copyright (C) 2012 The Android Open Source Project
35585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu *
45585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu * Licensed under the Apache License, Version 2.0 (the "License");
55585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu * you may not use this file except in compliance with the License.
65585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu * You may obtain a copy of the License at
75585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu *
85585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu *      http://www.apache.org/licenses/LICENSE-2.0
95585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu *
105585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu * Unless required by applicable law or agreed to in writing, software
115585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu * distributed under the License is distributed on an "AS IS" BASIS,
125585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu * See the License for the specific language governing permissions and
145585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu * limitations under the License.
155585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu */
165585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu
175585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescupackage com.android.gallery3d.anim;
185585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu
19b1b0ab99bebae3629a55c634cdf842d0d2f212d9Bobby Georgescuimport android.view.animation.AccelerateInterpolator;
205585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescuimport android.view.animation.DecelerateInterpolator;
214831c7494373c360062a7becac820eba3bc39287Bobby Georgescuimport android.view.animation.Interpolator;
225585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu
23a4eae1abb4f2547dfbda84301ee764ce35464881John Reckimport com.android.gallery3d.glrenderer.GLCanvas;
24a4eae1abb4f2547dfbda84301ee764ce35464881John Reckimport com.android.gallery3d.glrenderer.RawTexture;
255585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescuimport com.android.gallery3d.ui.GLView;
264831c7494373c360062a7becac820eba3bc39287Bobby Georgescuimport com.android.gallery3d.ui.TiledScreenNail;
275585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu
285585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescupublic class StateTransitionAnimation extends Animation {
294831c7494373c360062a7becac820eba3bc39287Bobby Georgescu
304831c7494373c360062a7becac820eba3bc39287Bobby Georgescu    public static class Spec {
314831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        public static final Spec OUTGOING;
324831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        public static final Spec INCOMING;
3326e119cebe732582df086ff56ec564d2989042fdBobby Georgescu        public static final Spec PHOTO_INCOMING;
344831c7494373c360062a7becac820eba3bc39287Bobby Georgescu
35b1b0ab99bebae3629a55c634cdf842d0d2f212d9Bobby Georgescu        private static final Interpolator DEFAULT_INTERPOLATOR =
36b1b0ab99bebae3629a55c634cdf842d0d2f212d9Bobby Georgescu                new DecelerateInterpolator();
37b1b0ab99bebae3629a55c634cdf842d0d2f212d9Bobby Georgescu
38b1b0ab99bebae3629a55c634cdf842d0d2f212d9Bobby Georgescu        public int duration = 330;
394831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        public float backgroundAlphaFrom = 0;
404831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        public float backgroundAlphaTo = 0;
414831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        public float backgroundScaleFrom = 0;
424831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        public float backgroundScaleTo = 0;
434831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        public float contentAlphaFrom = 1;
444831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        public float contentAlphaTo = 1;
454831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        public float contentScaleFrom = 1;
464831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        public float contentScaleTo = 1;
474831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        public float overlayAlphaFrom = 0;
484831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        public float overlayAlphaTo = 0;
494831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        public float overlayScaleFrom = 0;
504831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        public float overlayScaleTo = 0;
51b1b0ab99bebae3629a55c634cdf842d0d2f212d9Bobby Georgescu        public Interpolator interpolator = DEFAULT_INTERPOLATOR;
524831c7494373c360062a7becac820eba3bc39287Bobby Georgescu
534831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        static {
544831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            OUTGOING = new Spec();
55a41c877619656e2a8f07efc1efcf9dcecffd5f9dBobby Georgescu            OUTGOING.backgroundAlphaFrom = 0.5f;
564831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            OUTGOING.backgroundAlphaTo = 0f;
574831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            OUTGOING.backgroundScaleFrom = 1f;
584831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            OUTGOING.backgroundScaleTo = 0f;
59b1b0ab99bebae3629a55c634cdf842d0d2f212d9Bobby Georgescu            OUTGOING.contentAlphaFrom = 0.5f;
604831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            OUTGOING.contentAlphaTo = 1f;
614831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            OUTGOING.contentScaleFrom = 3f;
624831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            OUTGOING.contentScaleTo = 1f;
634831c7494373c360062a7becac820eba3bc39287Bobby Georgescu
644831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            INCOMING = new Spec();
654831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            INCOMING.overlayAlphaFrom = 1f;
664831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            INCOMING.overlayAlphaTo = 0f;
674831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            INCOMING.overlayScaleFrom = 1f;
684831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            INCOMING.overlayScaleTo = 3f;
694831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            INCOMING.contentAlphaFrom = 0f;
704831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            INCOMING.contentAlphaTo = 1f;
714831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            INCOMING.contentScaleFrom = 0.25f;
724831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            INCOMING.contentScaleTo = 1f;
7326e119cebe732582df086ff56ec564d2989042fdBobby Georgescu
74b1b0ab99bebae3629a55c634cdf842d0d2f212d9Bobby Georgescu            PHOTO_INCOMING = INCOMING;
7526e119cebe732582df086ff56ec564d2989042fdBobby Georgescu        }
7626e119cebe732582df086ff56ec564d2989042fdBobby Georgescu
7726e119cebe732582df086ff56ec564d2989042fdBobby Georgescu        private static Spec specForTransition(Transition t) {
7826e119cebe732582df086ff56ec564d2989042fdBobby Georgescu            switch (t) {
7926e119cebe732582df086ff56ec564d2989042fdBobby Georgescu                case Outgoing:
8026e119cebe732582df086ff56ec564d2989042fdBobby Georgescu                    return Spec.OUTGOING;
8126e119cebe732582df086ff56ec564d2989042fdBobby Georgescu                case Incoming:
8226e119cebe732582df086ff56ec564d2989042fdBobby Georgescu                    return Spec.INCOMING;
8326e119cebe732582df086ff56ec564d2989042fdBobby Georgescu                case PhotoIncoming:
8426e119cebe732582df086ff56ec564d2989042fdBobby Georgescu                    return Spec.PHOTO_INCOMING;
8526e119cebe732582df086ff56ec564d2989042fdBobby Georgescu                case None:
8626e119cebe732582df086ff56ec564d2989042fdBobby Georgescu                default:
8726e119cebe732582df086ff56ec564d2989042fdBobby Georgescu                    return null;
8826e119cebe732582df086ff56ec564d2989042fdBobby Georgescu            }
894831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        }
904831c7494373c360062a7becac820eba3bc39287Bobby Georgescu    }
914831c7494373c360062a7becac820eba3bc39287Bobby Georgescu
9226e119cebe732582df086ff56ec564d2989042fdBobby Georgescu    public static enum Transition { None, Outgoing, Incoming, PhotoIncoming }
9326e119cebe732582df086ff56ec564d2989042fdBobby Georgescu
944831c7494373c360062a7becac820eba3bc39287Bobby Georgescu    private final Spec mTransitionSpec;
954831c7494373c360062a7becac820eba3bc39287Bobby Georgescu    private float mCurrentContentScale;
964831c7494373c360062a7becac820eba3bc39287Bobby Georgescu    private float mCurrentContentAlpha;
975585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu    private float mCurrentBackgroundScale;
985585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu    private float mCurrentBackgroundAlpha;
994831c7494373c360062a7becac820eba3bc39287Bobby Georgescu    private float mCurrentOverlayScale;
1004831c7494373c360062a7becac820eba3bc39287Bobby Georgescu    private float mCurrentOverlayAlpha;
1014831c7494373c360062a7becac820eba3bc39287Bobby Georgescu    private RawTexture mOldScreenTexture;
1025585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu
10326e119cebe732582df086ff56ec564d2989042fdBobby Georgescu    public StateTransitionAnimation(Transition t, RawTexture oldScreen) {
10426e119cebe732582df086ff56ec564d2989042fdBobby Georgescu        this(Spec.specForTransition(t), oldScreen);
10526e119cebe732582df086ff56ec564d2989042fdBobby Georgescu    }
10626e119cebe732582df086ff56ec564d2989042fdBobby Georgescu
1074831c7494373c360062a7becac820eba3bc39287Bobby Georgescu    public StateTransitionAnimation(Spec spec, RawTexture oldScreen) {
1084831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        mTransitionSpec = spec != null ? spec : Spec.OUTGOING;
1094831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        setDuration(mTransitionSpec.duration);
1104831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        setInterpolator(mTransitionSpec.interpolator);
1114831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        mOldScreenTexture = oldScreen;
11226e119cebe732582df086ff56ec564d2989042fdBobby Georgescu        TiledScreenNail.disableDrawPlaceholder();
1134831c7494373c360062a7becac820eba3bc39287Bobby Georgescu    }
1144831c7494373c360062a7becac820eba3bc39287Bobby Georgescu
1154831c7494373c360062a7becac820eba3bc39287Bobby Georgescu    @Override
1164831c7494373c360062a7becac820eba3bc39287Bobby Georgescu    public boolean calculate(long currentTimeMillis) {
1174831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        boolean retval = super.calculate(currentTimeMillis);
11826e119cebe732582df086ff56ec564d2989042fdBobby Georgescu        if (!isActive()) {
11926e119cebe732582df086ff56ec564d2989042fdBobby Georgescu            if (mOldScreenTexture != null) {
12026e119cebe732582df086ff56ec564d2989042fdBobby Georgescu                mOldScreenTexture.recycle();
12126e119cebe732582df086ff56ec564d2989042fdBobby Georgescu                mOldScreenTexture = null;
12226e119cebe732582df086ff56ec564d2989042fdBobby Georgescu            }
1234831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            TiledScreenNail.enableDrawPlaceholder();
1244831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        }
1254831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        return retval;
1265585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu    }
1275585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu
1285585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu    @Override
1295585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu    protected void onCalculate(float progress) {
1304831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        mCurrentContentScale = mTransitionSpec.contentScaleFrom
1314831c7494373c360062a7becac820eba3bc39287Bobby Georgescu                + (mTransitionSpec.contentScaleTo - mTransitionSpec.contentScaleFrom) * progress;
1324831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        mCurrentContentAlpha = mTransitionSpec.contentAlphaFrom
1334831c7494373c360062a7becac820eba3bc39287Bobby Georgescu                + (mTransitionSpec.contentAlphaTo - mTransitionSpec.contentAlphaFrom) * progress;
1344831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        mCurrentBackgroundAlpha = mTransitionSpec.backgroundAlphaFrom
1354831c7494373c360062a7becac820eba3bc39287Bobby Georgescu                + (mTransitionSpec.backgroundAlphaTo - mTransitionSpec.backgroundAlphaFrom)
1364831c7494373c360062a7becac820eba3bc39287Bobby Georgescu                * progress;
1374831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        mCurrentBackgroundScale = mTransitionSpec.backgroundScaleFrom
1384831c7494373c360062a7becac820eba3bc39287Bobby Georgescu                + (mTransitionSpec.backgroundScaleTo - mTransitionSpec.backgroundScaleFrom)
1394831c7494373c360062a7becac820eba3bc39287Bobby Georgescu                * progress;
1404831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        mCurrentOverlayScale = mTransitionSpec.overlayScaleFrom
1414831c7494373c360062a7becac820eba3bc39287Bobby Georgescu                + (mTransitionSpec.overlayScaleTo - mTransitionSpec.overlayScaleFrom) * progress;
1424831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        mCurrentOverlayAlpha = mTransitionSpec.overlayAlphaFrom
1434831c7494373c360062a7becac820eba3bc39287Bobby Georgescu                + (mTransitionSpec.overlayAlphaTo - mTransitionSpec.overlayAlphaFrom) * progress;
1445585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu    }
1455585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu
1464831c7494373c360062a7becac820eba3bc39287Bobby Georgescu    private void applyOldTexture(GLView view, GLCanvas canvas, float alpha, float scale, boolean clear) {
1474831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        if (mOldScreenTexture == null)
1484831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            return;
1494831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        if (clear) canvas.clearBuffer(view.getBackgroundColor());
1505585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu        canvas.save();
1514831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        canvas.setAlpha(alpha);
1525585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu        int xOffset = view.getWidth() / 2;
1535585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu        int yOffset = view.getHeight() / 2;
1545585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu        canvas.translate(xOffset, yOffset);
1554831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        canvas.scale(scale, scale, 1);
1564831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        mOldScreenTexture.draw(canvas, -xOffset, -yOffset);
1575585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu        canvas.restore();
1585585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu    }
1595585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu
1604831c7494373c360062a7becac820eba3bc39287Bobby Georgescu    public void applyBackground(GLView view, GLCanvas canvas) {
1614831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        if (mCurrentBackgroundAlpha > 0f) {
1624831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            applyOldTexture(view, canvas, mCurrentBackgroundAlpha, mCurrentBackgroundScale, true);
1634831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        }
1644831c7494373c360062a7becac820eba3bc39287Bobby Georgescu    }
1654831c7494373c360062a7becac820eba3bc39287Bobby Georgescu
1664831c7494373c360062a7becac820eba3bc39287Bobby Georgescu    public void applyContentTransform(GLView view, GLCanvas canvas) {
1675585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu        int xOffset = view.getWidth() / 2;
1685585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu        int yOffset = view.getHeight() / 2;
1695585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu        canvas.translate(xOffset, yOffset);
1704831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        canvas.scale(mCurrentContentScale, mCurrentContentScale, 1);
1715585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu        canvas.translate(-xOffset, -yOffset);
1724831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        canvas.setAlpha(mCurrentContentAlpha);
1734831c7494373c360062a7becac820eba3bc39287Bobby Georgescu    }
1744831c7494373c360062a7becac820eba3bc39287Bobby Georgescu
1754831c7494373c360062a7becac820eba3bc39287Bobby Georgescu    public void applyOverlay(GLView view, GLCanvas canvas) {
1764831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        if (mCurrentOverlayAlpha > 0f) {
1774831c7494373c360062a7becac820eba3bc39287Bobby Georgescu            applyOldTexture(view, canvas, mCurrentOverlayAlpha, mCurrentOverlayScale, false);
1784831c7494373c360062a7becac820eba3bc39287Bobby Georgescu        }
1795585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu    }
1805585826e68c62c3719fb346d40fd1999438c6c6bBobby Georgescu}
181