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

Commit fd2b002b authored by Chet Haase's avatar Chet Haase
Browse files

Add 3D rotation to View

Change-Id: I4aa2542eb821e82d44e13d69b0938de13ffd4f0d
parent f0cfe343
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