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

Commit 5c7d76ab authored by Michael Bestas's avatar Michael Bestas Committed by LuK1337
Browse files

Gallery2: Remove 3D overscroll effect

Change-Id: Ia711a824e353ac45a3f0013c315e8727f0c40c3e
parent 15b29230
Loading
Loading
Loading
Loading
+0 −183
Original line number Diff line number Diff line
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.gallery3d.ui;

import android.graphics.Rect;
import android.opengl.Matrix;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;

import com.android.gallery3d.common.Utils;

// This class does the overscroll effect.
class Paper {
    @SuppressWarnings("unused")
    private static final String TAG = "Paper";
    private static final int ROTATE_FACTOR = 4;
    private EdgeAnimation mAnimationLeft = new EdgeAnimation();
    private EdgeAnimation mAnimationRight = new EdgeAnimation();
    private int mWidth;
    private float[] mMatrix = new float[16];

    public void overScroll(float distance) {
        distance /= mWidth;  // make it relative to width
        if (distance < 0) {
            mAnimationLeft.onPull(-distance);
        } else {
            mAnimationRight.onPull(distance);
        }
    }

    public void edgeReached(float velocity) {
        velocity /= mWidth;  // make it relative to width
        if (velocity < 0) {
            mAnimationRight.onAbsorb(-velocity);
        } else {
            mAnimationLeft.onAbsorb(velocity);
        }
    }

    public void onRelease() {
        mAnimationLeft.onRelease();
        mAnimationRight.onRelease();
    }

    public boolean advanceAnimation() {
        // Note that we use "|" because we want both animations get updated.
        return mAnimationLeft.update() | mAnimationRight.update();
    }

    public void setSize(int width, int height) {
        mWidth = width;
    }

    public float[] getTransform(Rect rect, float scrollX) {
        float left = mAnimationLeft.getValue();
        float right = mAnimationRight.getValue();
        float screenX = rect.centerX() - scrollX;
        // We linearly interpolate the value [left, right] for the screenX
        // range int [-1/4, 5/4]*mWidth. So if part of the thumbnail is outside
        // the screen, we still get some transform.
        float x = screenX + mWidth / 4;
        int range = 3 * mWidth / 2;
        float t = ((range - x) * left - x * right) / range;
        // compress t to the range (-1, 1) by the function
        // f(t) = (1 / (1 + e^-t) - 0.5) * 2
        // then multiply by 90 to make the range (-45, 45)
        float degrees =
                (1 / (1 + (float) Math.exp(-t * ROTATE_FACTOR)) - 0.5f) * 2 * -45;
        Matrix.setIdentityM(mMatrix, 0);
        Matrix.translateM(mMatrix, 0, mMatrix, 0, rect.centerX(), rect.centerY(), 0);
        Matrix.rotateM(mMatrix, 0, degrees, 0, 1, 0);
        Matrix.translateM(mMatrix, 0, mMatrix, 0, -rect.width() / 2, -rect.height() / 2, 0);
        return mMatrix;
    }
}

// This class follows the structure of frameworks's EdgeEffect class.
class EdgeAnimation {
    @SuppressWarnings("unused")
    private static final String TAG = "EdgeAnimation";

    private static final int STATE_IDLE = 0;
    private static final int STATE_PULL = 1;
    private static final int STATE_ABSORB = 2;
    private static final int STATE_RELEASE = 3;

    // Time it will take the effect to fully done in ms
    private static final int ABSORB_TIME = 200;
    private static final int RELEASE_TIME = 500;

    private static final float VELOCITY_FACTOR = 0.1f;

    private final Interpolator mInterpolator;

    private int mState;
    private float mValue;

    private float mValueStart;
    private float mValueFinish;
    private long mStartTime;
    private long mDuration;

    public EdgeAnimation() {
        mInterpolator = new DecelerateInterpolator();
        mState = STATE_IDLE;
    }

    private void startAnimation(float start, float finish, long duration,
            int newState) {
        mValueStart = start;
        mValueFinish = finish;
        mDuration = duration;
        mStartTime = now();
        mState = newState;
    }

    // The deltaDistance's magnitude is in the range of -1 (no change) to 1.
    // The value 1 is the full length of the view. Negative values means the
    // movement is in the opposite direction.
    public void onPull(float deltaDistance) {
        if (mState == STATE_ABSORB) return;
        mValue = Utils.clamp(mValue + deltaDistance, -1.0f, 1.0f);
        mState = STATE_PULL;
    }

    public void onRelease() {
        if (mState == STATE_IDLE || mState == STATE_ABSORB) return;
        startAnimation(mValue, 0, RELEASE_TIME, STATE_RELEASE);
    }

    public void onAbsorb(float velocity) {
        float finish = Utils.clamp(mValue + velocity * VELOCITY_FACTOR,
                -1.0f, 1.0f);
        startAnimation(mValue, finish, ABSORB_TIME, STATE_ABSORB);
    }

    public boolean update() {
        if (mState == STATE_IDLE) return false;
        if (mState == STATE_PULL) return true;

        float t = Utils.clamp((float)(now() - mStartTime) / mDuration, 0.0f, 1.0f);
        /* Use linear interpolation for absorb, quadratic for others */
        float interp = (mState == STATE_ABSORB)
                ? t : mInterpolator.getInterpolation(t);

        mValue = mValueStart + (mValueFinish - mValueStart) * interp;

        if (t >= 1.0f) {
            switch (mState) {
                case STATE_ABSORB:
                    startAnimation(mValue, 0, RELEASE_TIME, STATE_RELEASE);
                    break;
                case STATE_RELEASE:
                    mState = STATE_IDLE;
                    break;
            }
        }

        return true;
    }

    public float getValue() {
        return mValue;
    }

    private long now() {
        return AnimationTime.get();
    }
}
+1 −6
Original line number Diff line number Diff line
@@ -25,7 +25,6 @@ import com.android.gallery3d.common.Utils;
public class ScrollerHelper {
    private OverScroller mScroller;
    private int mOverflingDistance;
    private boolean mOverflingEnabled;

    public ScrollerHelper(Context context) {
        mScroller = new OverScroller(context);
@@ -33,10 +32,6 @@ public class ScrollerHelper {
        mOverflingDistance = configuration.getScaledOverflingDistance();
    }

    public void setOverfling(boolean enabled) {
        mOverflingEnabled = enabled;
    }

    /**
     * Call this when you want to know the new location. The position will be
     * updated and can be obtained by getPosition(). Returns true if  the
@@ -78,7 +73,7 @@ public class ScrollerHelper {
                velocity, 0,   // velocityX, velocityY
                min, max,      // minX, maxX
                0, 0,          // minY, maxY
                mOverflingEnabled ? mOverflingDistance : 0, 0);
                mOverflingDistance, 0);
    }

    // Returns the distance that over the scroll limit.
+4 −47
Original line number Diff line number Diff line
@@ -68,7 +68,6 @@ public class SlotView extends GLView {

    private final GestureDetector mGestureDetector;
    private final ScrollerHelper mScroller;
    private final Paper mPaper = new Paper();

    private Listener mListener;
    private UserInteractionListener mUIListener;
@@ -80,17 +79,12 @@ public class SlotView extends GLView {

    // whether the down action happened while the view is scrolling.
    private boolean mDownInScrolling;
    private int mOverscrollEffect = OVERSCROLL_3D;
    private final Handler mHandler;

    private SlotRenderer mRenderer;

    private int[] mRequestRenderSlots = new int[16];

    public static final int OVERSCROLL_3D = 0;
    public static final int OVERSCROLL_SYSTEM = 1;
    public static final int OVERSCROLL_NONE = 2;

    // to prevent allocating memory
    private final Rect mTempRect = new Rect();

@@ -179,9 +173,6 @@ public class SlotView extends GLView {
                (mLayout.getVisibleStart() + mLayout.getVisibleEnd()) / 2;
        mLayout.setSize(r - l, b - t);
        makeSlotVisible(visibleIndex);
        if (mOverscrollEffect == OVERSCROLL_3D) {
            mPaper.setSize(r - l, b - t);
        }
    }

    public void startScatteringAnimation(RelativePosition position) {
@@ -226,7 +217,6 @@ public class SlotView extends GLView {
                mScroller.forceFinished();
                break;
            case MotionEvent.ACTION_UP:
                mPaper.onRelease();
                invalidate();
                break;
        }
@@ -241,11 +231,6 @@ public class SlotView extends GLView {
        mUIListener = listener;
    }

    public void setOverscrollEffect(int kind) {
        mOverscrollEffect = kind;
        mScroller.setOverfling(kind == OVERSCROLL_SYSTEM);
    }

    private static int[] expandIntArray(int array[], int capacity) {
        while (array.length < capacity) {
            array = new int[array.length * 2];
@@ -266,25 +251,6 @@ public class SlotView extends GLView {
        int oldX = mScrollX;
        updateScrollPosition(mScroller.getPosition(), false);

        boolean paperActive = false;
        if (mOverscrollEffect == OVERSCROLL_3D) {
            // Check if an edge is reached and notify mPaper if so.
            int newX = mScrollX;
            int limit = mLayout.getScrollLimit();
            if (oldX > 0 && newX == 0 || oldX < limit && newX == limit) {
                float v = mScroller.getCurrVelocity();
                if (newX == limit) v = -v;

                // I don't know why, but getCurrVelocity() can return NaN.
                if (!Float.isNaN(v)) {
                    mPaper.edgeReached(v);
                }
            }
            paperActive = mPaper.advanceAnimation();
        }

        more |= paperActive;

        if (mAnimation != null) {
            more |= mAnimation.calculate(animTime);
        }
@@ -296,7 +262,7 @@ public class SlotView extends GLView {
                mLayout.mVisibleEnd - mLayout.mVisibleStart);

        for (int i = mLayout.mVisibleEnd - 1; i >= mLayout.mVisibleStart; --i) {
            int r = renderItem(canvas, i, 0, paperActive);
            int r = renderItem(canvas, i, 0);
            if ((r & RENDER_MORE_FRAME) != 0) more = true;
            if ((r & RENDER_MORE_PASS) != 0) requestedSlot[requestCount++] = i;
        }
@@ -304,8 +270,7 @@ public class SlotView extends GLView {
        for (int pass = 1; requestCount != 0; ++pass) {
            int newCount = 0;
            for (int i = 0; i < requestCount; ++i) {
                int r = renderItem(canvas,
                        requestedSlot[i], pass, paperActive);
                int r = renderItem(canvas, requestedSlot[i], pass);
                if ((r & RENDER_MORE_FRAME) != 0) more = true;
                if ((r & RENDER_MORE_PASS) != 0) requestedSlot[newCount++] = i;
            }
@@ -328,15 +293,10 @@ public class SlotView extends GLView {
        mMoreAnimation = more;
    }

    private int renderItem(
            GLCanvas canvas, int index, int pass, boolean paperActive) {
    private int renderItem(GLCanvas canvas, int index, int pass) {
        canvas.save(GLCanvas.SAVE_FLAG_ALPHA | GLCanvas.SAVE_FLAG_MATRIX);
        Rect rect = mLayout.getSlotRect(index, mTempRect);
        if (paperActive) {
            canvas.multiplyMatrix(mPaper.getTransform(rect, mScrollX), 0);
        } else {
        canvas.translate(rect.left, rect.top, 0);
        }
        if (mAnimation != null && mAnimation.isActive()) {
            mAnimation.apply(canvas, index, rect);
        }
@@ -720,9 +680,6 @@ public class SlotView extends GLView {
            float distance = WIDE ? distanceX : distanceY;
            int overDistance = mScroller.startScroll(
                    Math.round(distance), 0, mLayout.getScrollLimit());
            if (mOverscrollEffect == OVERSCROLL_3D && overDistance != 0) {
                mPaper.overScroll(overDistance);
            }
            invalidate();
            return true;
        }
+3 −32
Original line number Diff line number Diff line
@@ -71,14 +71,11 @@ public class TimeLineSlotView extends GLView {

    // whether the down action happened while the view is scrolling.
    private boolean mDownInScrolling;
    private int mOverscrollEffect = OVERSCROLL_3D;

    private TimeLineSlotRenderer mRenderer;

    private int[] mRequestRenderSlots = new int[16];

    public static final int OVERSCROLL_3D = 0;

    // Flag to check whether it is come from Photo Page.
    private boolean isFromPhotoPage = false;

@@ -137,7 +134,6 @@ public class TimeLineSlotView extends GLView {
        isFromPhotoPage = flag;
    }


    public void setScrollPosition(int position) {
        position = Utils.clamp(position, 0, mLayout.getScrollLimit());
        mScroller.setPosition(position);
@@ -160,8 +156,6 @@ public class TimeLineSlotView extends GLView {
                (mLayout.getVisibleStart() + mLayout.getVisibleEnd()) / 2;
        mLayout.setSize(r - l, b - t);
        makeSlotVisible(visibleIndex);
        if (mOverscrollEffect == OVERSCROLL_3D) {
        }
    }

    public void startScatteringAnimation(RelativePosition position) {
@@ -230,24 +224,6 @@ public class TimeLineSlotView extends GLView {
        int oldX = mScrollX;
        updateScrollPosition(mScroller.getPosition(), false);

        if (mOverscrollEffect == OVERSCROLL_3D) {
            // Check if an edge is reached and notify mPaper if so
            int newX = mScrollX;
            int limit = mLayout.getScrollLimit();
            if (oldX > 0 && newX == 0 || oldX < limit && newX == limit) {
                float v = mScroller.getCurrVelocity();
                if (newX == limit) v = -v;

                // I don't know why, but getCurrVelocity() can return NaN.
                if (!Float.isNaN(v)) {
                    //mPaper.edgeReached(v);
                }
                //paperActive = mPaper.advanceAnimation();
            }
        }

        //more |= paperActive;

        if (mAnimation != null) {
            more |= mAnimation.calculate(animTime);
        }
@@ -259,7 +235,7 @@ public class TimeLineSlotView extends GLView {
                mLayout.getVisibleEnd() - mLayout.getVisibleStart());

        for (int i = mLayout.getVisibleEnd() - 1; i >= mLayout.getVisibleStart(); --i) {
            int r = renderItem(canvas, i, 0, false);
            int r = renderItem(canvas, i, 0);
            if ((r & RENDER_MORE_FRAME) != 0) more = true;
            if ((r & RENDER_MORE_PASS) != 0) requestedSlot[requestCount++] = i;
        }
@@ -267,8 +243,7 @@ public class TimeLineSlotView extends GLView {
        for (int pass = 1; requestCount != 0; ++pass) {
            int newCount = 0;
            for (int i = 0; i < requestCount; ++i) {
                int r = renderItem(canvas,
                        requestedSlot[i], pass, false);
                int r = renderItem(canvas, requestedSlot[i], pass);
                if ((r & RENDER_MORE_FRAME) != 0) more = false;
                if ((r & RENDER_MORE_PASS) != 0) requestedSlot[newCount++] = i;
            }
@@ -281,8 +256,7 @@ public class TimeLineSlotView extends GLView {

    }

    private int renderItem(
            GLCanvas canvas, int index, int pass, boolean paperActive) {
    private int renderItem(GLCanvas canvas, int index, int pass) {
        Rect rect = mLayout.getSlotRect(index);
        if (rect == null) return 0;
        canvas.save(GLCanvas.SAVE_FLAG_ALPHA | GLCanvas.SAVE_FLAG_MATRIX);
@@ -388,9 +362,6 @@ public class TimeLineSlotView extends GLView {
            cancelDown(false);
            int overDistance = mScroller.startScroll(
                    Math.round(distanceY), 0, mLayout.getScrollLimit());
            if (mOverscrollEffect == OVERSCROLL_3D && overDistance != 0) {
                //mPaper.overScroll(overDistance);
            }
            invalidate();
            return true;
        }