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

Commit 3af4a2c6 authored by Derek Sollenberger's avatar Derek Sollenberger Committed by Android (Google) Code Review
Browse files

Merge "eoving Zoom animation logic from WebView into ZoomManager. This is pick...

Merge "eoving Zoom animation logic from WebView into ZoomManager. This is pick bad5ede Revert "Refactor the on-screen zoom controls into a separate class.""
parents 7e6eaa9a 87b17be5
Loading
Loading
Loading
Loading
+11 −29
Original line number Diff line number Diff line
@@ -1892,7 +1892,7 @@ public class WebView extends AbsoluteLayout
        msg.sendToTarget();
    }

    private static int pinLoc(int x, int viewMax, int docMax) {
    static int pinLoc(int x, int viewMax, int docMax) {
//        Log.d(LOGTAG, "-- pinLoc " + x + " " + viewMax + " " + docMax);
        if (docMax < viewMax) {   // the doc has room on the sides for "blank"
            // pin the short document to the top/left of the screen
@@ -3283,17 +3283,12 @@ public class WebView extends AbsoluteLayout
            }
        }
        if (animateZoom) {
            float zoomScale;
            int interval = (int) (SystemClock.uptimeMillis() - mZoomManager.mZoomStart);
            if (interval < mZoomManager.ZOOM_ANIMATION_LENGTH) {
                float ratio = (float) interval / mZoomManager.ZOOM_ANIMATION_LENGTH;
                zoomScale = 1.0f / (mZoomManager.mInvInitialZoomScale
                        + (mZoomManager.mInvFinalZoomScale - mZoomManager.mInvInitialZoomScale) * ratio);
            final float[] zoomValues = mZoomManager.animateZoom();
            final boolean isStillAnimating = mZoomManager.isZoomAnimating();

            if (isStillAnimating) {
                invalidate();
            } else {
                zoomScale = mZoomManager.mZoomScale;
                // set mZoomScale to be 0 as we have done animation
                mZoomManager.mZoomScale = 0;
                WebViewCore.resumeUpdatePicture(mWebViewCore);
                // call invalidate() again to draw with the final filters
                invalidate();
@@ -3307,24 +3302,11 @@ public class WebView extends AbsoluteLayout
                    }
                }
            }
            // calculate the intermediate scroll position. As we need to use
            // zoomScale, we can't use pinLocX/Y directly. Copy the logic here.
            float scale = zoomScale * mZoomManager.mInvInitialZoomScale;
            int tx = Math.round(scale * (mZoomManager.mInitialScrollX + mZoomManager.mZoomCenterX)
                    - mZoomManager.mZoomCenterX);
            tx = -pinLoc(tx, getViewWidth(), Math.round(mContentWidth
                    * zoomScale)) + mScrollX;
            int titleHeight = getTitleHeight();
            int ty = Math.round(scale
                    * (mZoomManager.mInitialScrollY + mZoomManager.mZoomCenterY - titleHeight)
                    - (mZoomManager.mZoomCenterY - titleHeight));
            ty = -(ty <= titleHeight ? Math.max(ty, 0) : pinLoc(ty
                    - titleHeight, getViewHeight(), Math.round(mContentHeight
                    * zoomScale)) + titleHeight) + mScrollY;
            canvas.translate(tx, ty);
            canvas.scale(zoomScale, zoomScale);
            if (inEditingMode() && !mNeedToAdjustWebTextView
                    && mZoomManager.isZoomAnimating()) {

            canvas.translate(zoomValues[0], zoomValues[1]);
            canvas.scale(zoomValues[2], zoomValues[2]);

            if (inEditingMode() && !mNeedToAdjustWebTextView && isStillAnimating) {
                // The WebTextView is up.  Keep track of this so we can adjust
                // its size and placement when we finish zooming
                mNeedToAdjustWebTextView = true;
@@ -5796,7 +5778,7 @@ public class WebView extends AbsoluteLayout
            float zoomCenterY = (oldScreenY * scale - newScreenY * actualScale)
                    / (scale - actualScale);
            mZoomManager.setZoomCenter(zoomCenterX, zoomCenterY);
            mZoomManager.animateZoom(scale, false);
            mZoomManager.startZoomAnimation(scale, false);
        }
    }

+82 −17
Original line number Diff line number Diff line
@@ -16,7 +16,9 @@

package android.webkit;

import android.graphics.Canvas;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;

class ZoomManager {
@@ -53,8 +55,9 @@ class ZoomManager {
    // the last zoom scale.
    boolean mInZoomOverview = false;

    // These keep track of the center point of the zoom.  They are used to
    // determine the point around which we should zoom.
    // These keep track of the center point of the zoom and they are used to
    // determine the point around which we should zoom. They are stored in view
    // coordinates.
    float mZoomCenterX;
    float mZoomCenterY;

@@ -75,13 +78,19 @@ class ZoomManager {
    // the current computed zoom scale and its inverse.
    float mActualScale;
    float mInvActualScale;
    // if this is non-zero, it is used on drawing rather than mActualScale
    float mZoomScale;
    float mInvInitialZoomScale;
    float mInvFinalZoomScale;
    int mInitialScrollX;
    int mInitialScrollY;
    long mZoomStart;
    
    /*
     * The following member variables are only to be used for animating zoom. If
     * mZoomScale is non-zero then we are in the middle of a zoom animation. The
     * other variables are used as a cache (e.g. inverse) or as a way to store
     * the state of the view prior to animating (e.g. initial scroll coords).
     */
    private float mZoomScale;
    private float mInvInitialZoomScale;
    private float mInvFinalZoomScale;
    private int mInitialScrollX;
    private int mInitialScrollY;
    private long mZoomStart;
    static final int ZOOM_ANIMATION_LENGTH = 500;

    public ZoomManager(WebView webView, CallbackProxy callbackProxy) {
@@ -133,10 +142,6 @@ class ZoomManager {
        return mActualScale - mMinZoomScale <= MINIMUM_SCALE_INCREMENT;
    }

    public boolean isZoomAnimating() {
        return mZoomScale != 0;
    }

    public boolean zoomIn() {
        mInZoomOverview = false;
        return zoom(1.25f);
@@ -156,7 +161,7 @@ class ZoomManager {
        int anchorX = mWebView.viewToContentX((int) mZoomCenterX + mWebView.getScrollX());
        int anchorY = mWebView.viewToContentY((int) mZoomCenterY + mWebView.getScrollY());
        mWebView.setViewSizeAnchor(anchorX, anchorY);
        return animateZoom(mActualScale * zoomMultiplier, true);
        return startZoomAnimation(mActualScale * zoomMultiplier, true);
    }

    public void zoomToOverview() {
@@ -166,15 +171,20 @@ class ZoomManager {
        if (scrollY < mWebView.getTitleHeight()) {
            mWebView.updateScrollCoordinates(mWebView.getScrollX(), 0);
        }
        animateZoom((float) mWebView.getViewWidth() / mZoomOverviewWidth, true);
        startZoomAnimation((float) mWebView.getViewWidth() / mZoomOverviewWidth, true);
    }

    public void zoomToDefaultLevel(boolean reflowText) {
        mInZoomOverview = false;
        animateZoom(mDefaultScale, reflowText);
        startZoomAnimation(mDefaultScale, reflowText);
    }

    public boolean animateZoom(float scale, boolean reflowText) {
    /**
     * Initiates an animated zoom of the WebView.
     *
     * @return true if the new scale triggered an animation and false otherwise.
     */
    public boolean startZoomAnimation(float scale, boolean reflowText) {
        float oldScale = mActualScale;
        mInitialScrollX = mWebView.getScrollX();
        mInitialScrollY = mWebView.getScrollY();
@@ -200,6 +210,61 @@ class ZoomManager {
        }
    }

    /**
     * Computes and returns the relevant data needed by the WebView's drawing
     * model to animate a zoom.
     *
     * This method is to be called when a zoom animation is occurring. The
     * animation begins by calling startZoomAnimation(...).  The caller can
     * check to see if the animation has completed by calling isZoomAnimating().
     *
     * @return an array containing the values needed to animate the drawing
     * surface.
     * [0] = delta for the new scrollX position
     * [1] = delta for the new scrollY position
     * [2] = current zoom scale
     */
    public float[] animateZoom() {
        if (mZoomScale == 0) {
            Log.w(LOGTAG, "A WebView is attempting to animate a zoom when no " +
                    "zoom is in progress");
            float[] result = {0, 0, mActualScale};
            return result;
        }

        float zoomScale;
        int interval = (int) (SystemClock.uptimeMillis() - mZoomStart);
        if (interval < ZOOM_ANIMATION_LENGTH) {
            float ratio = (float) interval / ZOOM_ANIMATION_LENGTH;
            zoomScale = 1.0f / (mInvInitialZoomScale
                    + (mInvFinalZoomScale - mInvInitialZoomScale) * ratio);
        } else {
            zoomScale = mZoomScale;
            // set mZoomScale to be 0 as we have finished animating
            mZoomScale = 0;
        }
        // calculate the intermediate scroll position. Since we need to use
        // zoomScale, we can't use the WebView's pinLocX/Y functions directly.
        float scale = zoomScale * mInvInitialZoomScale;
        int tx = Math.round(scale * (mInitialScrollX + mZoomCenterX) - mZoomCenterX);
        tx = -WebView.pinLoc(tx, mWebView.getViewWidth(), Math.round(mWebView.getContentWidth()
                * zoomScale)) + mWebView.getScrollX();
        int titleHeight = mWebView.getTitleHeight();
        int ty = Math.round(scale
                * (mInitialScrollY + mZoomCenterY - titleHeight)
                - (mZoomCenterY - titleHeight));
        ty = -(ty <= titleHeight ? Math.max(ty, 0) : WebView.pinLoc(ty
                - titleHeight, mWebView.getViewHeight(), Math.round(mWebView.getContentHeight()
                * zoomScale)) + titleHeight) + mWebView.getScrollY();

        float[] result = {tx, ty, zoomScale};
        return result;
    }

    public boolean isZoomAnimating() {
        return mZoomScale != 0;
    }

    public void refreshZoomScale(boolean reflowText) {
        setZoomScale(mActualScale, reflowText, true);
    }