1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.view.animation;
18 
19 import android.content.Context;
20 import android.content.res.TypedArray;
21 import android.util.AttributeSet;
22 
23 /**
24  * An animation that controls the rotation of an object. This rotation takes
25  * place in the X-Y plane. You can specify the point to use for the center of
26  * the rotation, where (0,0) is the top left point. If not specified, (0,0) is
27  * the default rotation point.
28  *
29  */
30 public class RotateAnimation extends Animation {
31     private float mFromDegrees;
32     private float mToDegrees;
33 
34     private int mPivotXType = ABSOLUTE;
35     private int mPivotYType = ABSOLUTE;
36     private float mPivotXValue = 0.0f;
37     private float mPivotYValue = 0.0f;
38 
39     private float mPivotX;
40     private float mPivotY;
41 
42     /**
43      * Constructor used when a RotateAnimation is loaded from a resource.
44      *
45      * @param context Application context to use
46      * @param attrs Attribute set from which to read values
47      */
RotateAnimation(Context context, AttributeSet attrs)48     public RotateAnimation(Context context, AttributeSet attrs) {
49         super(context, attrs);
50 
51         TypedArray a = context.obtainStyledAttributes(attrs,
52                 com.android.internal.R.styleable.RotateAnimation);
53 
54         mFromDegrees = a.getFloat(
55                 com.android.internal.R.styleable.RotateAnimation_fromDegrees, 0.0f);
56         mToDegrees = a.getFloat(com.android.internal.R.styleable.RotateAnimation_toDegrees, 0.0f);
57 
58         Description d = Description.parseValue(a.peekValue(
59                 com.android.internal.R.styleable.RotateAnimation_pivotX), context);
60         mPivotXType = d.type;
61         mPivotXValue = d.value;
62 
63         d = Description.parseValue(a.peekValue(
64                 com.android.internal.R.styleable.RotateAnimation_pivotY), context);
65         mPivotYType = d.type;
66         mPivotYValue = d.value;
67 
68         a.recycle();
69 
70         initializePivotPoint();
71     }
72 
73     /**
74      * Constructor to use when building a RotateAnimation from code.
75      * Default pivotX/pivotY point is (0,0).
76      *
77      * @param fromDegrees Rotation offset to apply at the start of the
78      *        animation.
79      *
80      * @param toDegrees Rotation offset to apply at the end of the animation.
81      */
RotateAnimation(float fromDegrees, float toDegrees)82     public RotateAnimation(float fromDegrees, float toDegrees) {
83         mFromDegrees = fromDegrees;
84         mToDegrees = toDegrees;
85         mPivotX = 0.0f;
86         mPivotY = 0.0f;
87     }
88 
89     /**
90      * Constructor to use when building a RotateAnimation from code
91      *
92      * @param fromDegrees Rotation offset to apply at the start of the
93      *        animation.
94      *
95      * @param toDegrees Rotation offset to apply at the end of the animation.
96      *
97      * @param pivotX The X coordinate of the point about which the object is
98      *        being rotated, specified as an absolute number where 0 is the left
99      *        edge.
100      * @param pivotY The Y coordinate of the point about which the object is
101      *        being rotated, specified as an absolute number where 0 is the top
102      *        edge.
103      */
RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY)104     public RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY) {
105         mFromDegrees = fromDegrees;
106         mToDegrees = toDegrees;
107 
108         mPivotXType = ABSOLUTE;
109         mPivotYType = ABSOLUTE;
110         mPivotXValue = pivotX;
111         mPivotYValue = pivotY;
112         initializePivotPoint();
113     }
114 
115     /**
116      * Constructor to use when building a RotateAnimation from code
117      *
118      * @param fromDegrees Rotation offset to apply at the start of the
119      *        animation.
120      *
121      * @param toDegrees Rotation offset to apply at the end of the animation.
122      *
123      * @param pivotXType Specifies how pivotXValue should be interpreted. One of
124      *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
125      *        Animation.RELATIVE_TO_PARENT.
126      * @param pivotXValue The X coordinate of the point about which the object
127      *        is being rotated, specified as an absolute number where 0 is the
128      *        left edge. This value can either be an absolute number if
129      *        pivotXType is ABSOLUTE, or a percentage (where 1.0 is 100%)
130      *        otherwise.
131      * @param pivotYType Specifies how pivotYValue should be interpreted. One of
132      *        Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF, or
133      *        Animation.RELATIVE_TO_PARENT.
134      * @param pivotYValue The Y coordinate of the point about which the object
135      *        is being rotated, specified as an absolute number where 0 is the
136      *        top edge. This value can either be an absolute number if
137      *        pivotYType is ABSOLUTE, or a percentage (where 1.0 is 100%)
138      *        otherwise.
139      */
RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)140     public RotateAnimation(float fromDegrees, float toDegrees, int pivotXType, float pivotXValue,
141             int pivotYType, float pivotYValue) {
142         mFromDegrees = fromDegrees;
143         mToDegrees = toDegrees;
144 
145         mPivotXValue = pivotXValue;
146         mPivotXType = pivotXType;
147         mPivotYValue = pivotYValue;
148         mPivotYType = pivotYType;
149         initializePivotPoint();
150     }
151 
152     /**
153      * Called at the end of constructor methods to initialize, if possible, values for
154      * the pivot point. This is only possible for ABSOLUTE pivot values.
155      */
initializePivotPoint()156     private void initializePivotPoint() {
157         if (mPivotXType == ABSOLUTE) {
158             mPivotX = mPivotXValue;
159         }
160         if (mPivotYType == ABSOLUTE) {
161             mPivotY = mPivotYValue;
162         }
163     }
164 
165     @Override
applyTransformation(float interpolatedTime, Transformation t)166     protected void applyTransformation(float interpolatedTime, Transformation t) {
167         float degrees = mFromDegrees + ((mToDegrees - mFromDegrees) * interpolatedTime);
168         float scale = getScaleFactor();
169 
170         if (mPivotX == 0.0f && mPivotY == 0.0f) {
171             t.getMatrix().setRotate(degrees);
172         } else {
173             t.getMatrix().setRotate(degrees, mPivotX * scale, mPivotY * scale);
174         }
175     }
176 
177     @Override
initialize(int width, int height, int parentWidth, int parentHeight)178     public void initialize(int width, int height, int parentWidth, int parentHeight) {
179         super.initialize(width, height, parentWidth, parentHeight);
180         mPivotX = resolveSize(mPivotXType, mPivotXValue, width, parentWidth);
181         mPivotY = resolveSize(mPivotYType, mPivotYValue, height, parentHeight);
182     }
183 }
184