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

Commit 8cc82c6f authored by Chet Haase's avatar Chet Haase Committed by Android (Google) Code Review
Browse files

Merge "Add 3D rotation to View"

parents 898d5cdd fd2b002b
Loading
Loading
Loading
Loading
+59 −0
Original line number Diff line number Diff line
@@ -193711,6 +193711,28 @@
 visibility="public"
>
</method>
<method name="getRotationX"
 return="float"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getRotationY"
 return="float"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getScaleX"
 return="float"
 abstract="false"
@@ -195881,6 +195903,32 @@
<parameter name="rotation" type="float">
</parameter>
</method>
<method name="setRotationX"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="rotationX" type="float">
</parameter>
</method>
<method name="setRotationY"
 return="void"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="rotationY" type="float">
</parameter>
</method>
<method name="setSaveEnabled"
 return="void"
 abstract="false"
@@ -213266,6 +213314,17 @@
 visibility="public"
>
</method>
<method name="getVisibleTitleHeight"
 return="int"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
</method>
<method name="getZoomControls"
 return="android.view.View"
 abstract="false"
+145 −10
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.view;

import android.graphics.Camera;
import com.android.internal.R;
import com.android.internal.view.menu.MenuBuilder;

@@ -1536,6 +1537,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
     */
    private static final int AWAKEN_SCROLL_BARS_ON_ATTACH = 0x08000000;

    /**
     * Indicates that pivotX or pivotY were explicitly set and we should not assume the center
     * for transform operations
     *
     * @hide
     */
    private static final int PIVOT_EXPLICITLY_SET = 0x10000000;

    /**
     * The parent this view is attached to.
     * {@hide}
@@ -1626,6 +1635,42 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
     */
    private boolean mMatrixIsIdentity = true;

    /**
     * The Camera object is used to compute a 3D matrix when rotationX or rotationY are set.
     */
    private Camera mCamera = null;

    /**
     * This matrix is used when computing the matrix for 3D rotations.
     */
    private Matrix matrix3D = null;

    /**
     * These prev values are used to recalculate a centered pivot point when necessary. The
     * pivot point is only used in matrix operations (when rotation, scale, or translation are
     * set), so thes values are only used then as well.
     */
    private int mPrevWidth = -1;
    private int mPrevHeight = -1;

    /**
     * Convenience value to check for float values that are close enough to zero to be considered
     * zero.
     */
    private static float NONZERO_EPSILON = .001f;

    /**
     * The degrees rotation around the vertical axis through the pivot point.
     */
    @ViewDebug.ExportedProperty
    private float mRotationY = 0f;

    /**
     * The degrees rotation around the horizontal axis through the pivot point.
     */
    @ViewDebug.ExportedProperty
    private float mRotationX = 0f;

    /**
     * The degrees rotation around the pivot point.
     */
@@ -4887,6 +4932,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
        return mMatrix;
    }

    /**
     * Utility function to determine if the value is far enough away from zero to be
     * considered non-zero.
     * @param value A floating point value to check for zero-ness
     * @return whether the passed-in value is far enough away from zero to be considered non-zero
     */
    private static boolean nonzero(float value) {
        return (value < -NONZERO_EPSILON || value > NONZERO_EPSILON);
    }

    /**
     * Recomputes the transform matrix if necessary.
     * 
@@ -4896,10 +4951,34 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
        if (mMatrixDirty) {
            // transform-related properties have changed since the last time someone
            // asked for the matrix; recalculate it with the current values

            // Figure out if we need to update the pivot point
            if ((mPrivateFlags & PIVOT_EXPLICITLY_SET) == 0) {
                if ((mRight - mLeft) != mPrevWidth && (mBottom - mTop) != mPrevHeight) {
                    mPrevWidth = mRight - mLeft;
                    mPrevHeight = mBottom - mTop;
                    mPivotX = (float) mPrevWidth / 2f;
                    mPivotY = (float) mPrevHeight / 2f;
                }
            }
            mMatrix.reset();
            mMatrix.setTranslate(mTranslationX, mTranslationY);
            mMatrix.preRotate(mRotation, mPivotX, mPivotY);
            mMatrix.preScale(mScaleX, mScaleY, mPivotX, mPivotY);
            if (nonzero(mRotationX) || nonzero(mRotationY)) {
                if (mCamera == null) {
                    mCamera = new Camera();
                    matrix3D = new Matrix();
                }
                mCamera.save();
                mCamera.rotateX(mRotationX);
                mCamera.rotateY(mRotationY);
                mCamera.getMatrix(matrix3D);
                matrix3D.preTranslate(-mPivotX, -mPivotY);
                matrix3D.postTranslate(mPivotX, mPivotY);
                mMatrix.postConcat(matrix3D);
                mCamera.restore();
            }
            mMatrixDirty = false;
            mMatrixIsIdentity = mMatrix.isIdentity();
            mInverseMatrixDirty = true;
@@ -4954,6 +5033,64 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
        }
    }

    /**
     * The degrees that the view is rotated around the vertical axis through the pivot point.
     *
     * @see #getPivotX()
     * @see #getPivotY()
     * @return The degrees of Y rotation.
     */
    public float getRotationY() {
        return mRotationY;
    }

    /**
     * Sets the degrees that the view is rotated around the vertical axis through pivot point.
     *
     * @param rotationY The degrees of Y rotation.
     * @see #getPivotX()
     * @see #getPivotY()
     */
    public void setRotationY(float rotationY) {
        if (mRotationY != rotationY) {
            // Double-invalidation is necessary to capture view's old and new areas
            invalidate();
            mRotationY = rotationY;
            mMatrixDirty = true;
            mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
            invalidate();
        }
    }

    /**
     * The degrees that the view is rotated around the horizontal axis through the pivot point.
     *
     * @see #getPivotX()
     * @see #getPivotY()
     * @return The degrees of X rotation.
     */
    public float getRotationX() {
        return mRotationX;
    }

    /**
     * Sets the degrees that the view is rotated around the horizontal axis through pivot point.
     *
     * @param rotationX The degrees of X rotation.
     * @see #getPivotX()
     * @see #getPivotY()
     */
    public void setRotationX(float rotationX) {
        if (mRotationX != rotationX) {
            // Double-invalidation is necessary to capture view's old and new areas
            invalidate();
            mRotationX = rotationX;
            mMatrixDirty = true;
            mPrivateFlags |= DRAWN; // force another invalidation with the new orientation
            invalidate();
        }
    }

    /**
     * The amount that the view is scaled in x around the pivot point, as a proportion of
     * the view's unscaled width. A value of 1, the default, means that no scaling is applied.
@@ -5035,6 +5172,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
    /**
     * Sets the x location of the point around which the view is
     * {@link #setRotation(float) rotated} and {@link #setScaleX(float) scaled}.
     * By default, the pivot point is centered on the object.
     * Setting this property disables this behavior and causes the view to use only the
     * explicitly set pivotX and pivotY values.
     *
     * @param pivotX The x location of the pivot point.
     * @see #getRotation()
@@ -5043,6 +5183,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
     * @see #getPivotY()
     */
    public void setPivotX(float pivotX) {
        mPrivateFlags |= PIVOT_EXPLICITLY_SET;
        if (mPivotX != pivotX) {
            // Double-invalidation is necessary to capture view's old and new areas
            invalidate();
@@ -5069,7 +5210,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility

    /**
     * Sets the y location of the point around which the view is {@link #setRotation(float) rotated}
     * and {@link #setScaleY(float) scaled}.
     * and {@link #setScaleY(float) scaled}. By default, the pivot point is centered on the object.
     * Setting this property disables this behavior and causes the view to use only the
     * explicitly set pivotX and pivotY values.
     *
     * @param pivotY The y location of the pivot point.
     * @see #getRotation()
@@ -5078,6 +5221,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
     * @see #getPivotY()
     */
    public void setPivotY(float pivotY) {
        mPrivateFlags |= PIVOT_EXPLICITLY_SET;
        if (mPivotY != pivotY) {
            // Double-invalidation is necessary to capture view's old and new areas
            invalidate();
@@ -5312,15 +5456,6 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility
     * is still within the view.
     */
    private boolean pointInView(float localX, float localY, float slop) {
        if (!hasIdentityMatrix() && mAttachInfo != null) {
            // non-identity matrix: transform the point into the view's coordinates
            final float[] localXY = mAttachInfo.mTmpTransformLocation;
            localXY[0] = localX;
            localXY[1] = localY;
            getInverseMatrix().mapPoints(localXY);
            localX = localXY[0];
            localY = localXY[1];
        }
        return localX > -slop && localY > -slop && localX < ((mRight - mLeft) + slop) &&
                localY < ((mBottom - mTop) + slop);
    }
+7 −10
Original line number Diff line number Diff line
@@ -905,19 +905,16 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
        }

        // Calculate the offset point into the target's local coordinates
        float xc;
        float yc;
        if (target.hasIdentityMatrix() || mAttachInfo == null) {
            xc = scrolledXFloat - (float) target.mLeft;
            yc = scrolledYFloat - (float) target.mTop;
        } else {
        float xc = scrolledXFloat - (float) target.mLeft;
        float yc = scrolledYFloat - (float) target.mTop;
        if (!target.hasIdentityMatrix() && mAttachInfo != null) {
            // non-identity matrix: transform the point into the view's coordinates
            final float[] localXY = mAttachInfo.mTmpTransformLocation;
            localXY[0] = scrolledXFloat;
            localXY[1] = scrolledYFloat;
            localXY[0] = xc;
            localXY[1] = yc;
            target.getInverseMatrix().mapPoints(localXY);
            xc = localXY[0] - (float) target.mLeft;
            yc = localXY[1] - (float) target.mTop;
            xc = localXY[0];
            yc = localXY[1];
        }

        // if have a target, see if we're allowed to and want to intercept its