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.annotation.FloatRange;
20 import android.graphics.Matrix;
21 import android.graphics.Rect;
22 
23 import java.io.PrintWriter;
24 
25 /**
26  * Defines the transformation to be applied at
27  * one point in time of an Animation.
28  *
29  */
30 public class Transformation {
31     /**
32      * Indicates a transformation that has no effect (alpha = 1 and identity matrix.)
33      */
34     public static final int TYPE_IDENTITY = 0x0;
35     /**
36      * Indicates a transformation that applies an alpha only (uses an identity matrix.)
37      */
38     public static final int TYPE_ALPHA = 0x1;
39     /**
40      * Indicates a transformation that applies a matrix only (alpha = 1.)
41      */
42     public static final int TYPE_MATRIX = 0x2;
43     /**
44      * Indicates a transformation that applies an alpha and a matrix.
45      */
46     public static final int TYPE_BOTH = TYPE_ALPHA | TYPE_MATRIX;
47 
48     protected Matrix mMatrix;
49     protected float mAlpha;
50     protected int mTransformationType;
51 
52     private boolean mHasClipRect;
53     private Rect mClipRect = new Rect();
54 
55     /**
56      * Creates a new transformation with alpha = 1 and the identity matrix.
57      */
Transformation()58     public Transformation() {
59         clear();
60     }
61 
62     /**
63      * Reset the transformation to a state that leaves the object
64      * being animated in an unmodified state. The transformation type is
65      * {@link #TYPE_BOTH} by default.
66      */
clear()67     public void clear() {
68         if (mMatrix == null) {
69             mMatrix = new Matrix();
70         } else {
71             mMatrix.reset();
72         }
73         mClipRect.setEmpty();
74         mHasClipRect = false;
75         mAlpha = 1.0f;
76         mTransformationType = TYPE_BOTH;
77     }
78 
79     /**
80      * Indicates the nature of this transformation.
81      *
82      * @return {@link #TYPE_ALPHA}, {@link #TYPE_MATRIX},
83      *         {@link #TYPE_BOTH} or {@link #TYPE_IDENTITY}.
84      */
getTransformationType()85     public int getTransformationType() {
86         return mTransformationType;
87     }
88 
89     /**
90      * Sets the transformation type.
91      *
92      * @param transformationType One of {@link #TYPE_ALPHA},
93      *        {@link #TYPE_MATRIX}, {@link #TYPE_BOTH} or
94      *        {@link #TYPE_IDENTITY}.
95      */
setTransformationType(int transformationType)96     public void setTransformationType(int transformationType) {
97         mTransformationType = transformationType;
98     }
99 
100     /**
101      * Clones the specified transformation.
102      *
103      * @param t The transformation to clone.
104      */
set(Transformation t)105     public void set(Transformation t) {
106         mAlpha = t.getAlpha();
107         mMatrix.set(t.getMatrix());
108         if (t.mHasClipRect) {
109             setClipRect(t.getClipRect());
110         } else {
111             mHasClipRect = false;
112             mClipRect.setEmpty();
113         }
114         mTransformationType = t.getTransformationType();
115     }
116 
117     /**
118      * Apply this Transformation to an existing Transformation, e.g. apply
119      * a scale effect to something that has already been rotated.
120      * @param t
121      */
compose(Transformation t)122     public void compose(Transformation t) {
123         mAlpha *= t.getAlpha();
124         mMatrix.preConcat(t.getMatrix());
125         if (t.mHasClipRect) {
126             Rect bounds = t.getClipRect();
127             if (mHasClipRect) {
128                 setClipRect(mClipRect.left + bounds.left, mClipRect.top + bounds.top,
129                         mClipRect.right + bounds.right, mClipRect.bottom + bounds.bottom);
130             } else {
131                 setClipRect(bounds);
132             }
133         }
134     }
135 
136     /**
137      * Like {@link #compose(Transformation)} but does this.postConcat(t) of
138      * the transformation matrix.
139      * @hide
140      */
postCompose(Transformation t)141     public void postCompose(Transformation t) {
142         mAlpha *= t.getAlpha();
143         mMatrix.postConcat(t.getMatrix());
144         if (t.mHasClipRect) {
145             Rect bounds = t.getClipRect();
146             if (mHasClipRect) {
147                 setClipRect(mClipRect.left + bounds.left, mClipRect.top + bounds.top,
148                         mClipRect.right + bounds.right, mClipRect.bottom + bounds.bottom);
149             } else {
150                 setClipRect(bounds);
151             }
152         }
153     }
154 
155     /**
156      * @return The 3x3 Matrix representing the trnasformation to apply to the
157      * coordinates of the object being animated
158      */
getMatrix()159     public Matrix getMatrix() {
160         return mMatrix;
161     }
162 
163     /**
164      * Sets the degree of transparency
165      * @param alpha 1.0 means fully opaqe and 0.0 means fully transparent
166      */
setAlpha(@loatRangefrom=0.0, to=1.0) float alpha)167     public void setAlpha(@FloatRange(from=0.0, to=1.0) float alpha) {
168         mAlpha = alpha;
169     }
170 
171     /**
172      * Sets the current Transform's clip rect
173      * @hide
174      */
setClipRect(Rect r)175     public void setClipRect(Rect r) {
176         setClipRect(r.left, r.top, r.right, r.bottom);
177     }
178 
179     /**
180      * Sets the current Transform's clip rect
181      * @hide
182      */
setClipRect(int l, int t, int r, int b)183     public void setClipRect(int l, int t, int r, int b) {
184         mClipRect.set(l, t, r, b);
185         mHasClipRect = true;
186     }
187 
188     /**
189      * Returns the current Transform's clip rect
190      * @hide
191      */
getClipRect()192     public Rect getClipRect() {
193         return mClipRect;
194     }
195 
196     /**
197      * Returns whether the current Transform's clip rect is set
198      * @hide
199      */
hasClipRect()200     public boolean hasClipRect() {
201         return mHasClipRect;
202     }
203 
204     /**
205      * @return The degree of transparency
206      */
getAlpha()207     public float getAlpha() {
208         return mAlpha;
209     }
210 
211     @Override
toString()212     public String toString() {
213         StringBuilder sb = new StringBuilder(64);
214         sb.append("Transformation");
215         toShortString(sb);
216         return sb.toString();
217     }
218 
219     /**
220      * Return a string representation of the transformation in a compact form.
221      */
toShortString()222     public String toShortString() {
223         StringBuilder sb = new StringBuilder(64);
224         toShortString(sb);
225         return sb.toString();
226     }
227 
228     /**
229      * @hide
230      */
toShortString(StringBuilder sb)231     public void toShortString(StringBuilder sb) {
232         sb.append("{alpha="); sb.append(mAlpha);
233         sb.append(" matrix="); mMatrix.toShortString(sb);
234         sb.append('}');
235     }
236 
237     /**
238      * Print short string, to optimize dumping.
239      * @hide
240      */
printShortString(PrintWriter pw)241     public void printShortString(PrintWriter pw) {
242         pw.print("{alpha="); pw.print(mAlpha);
243         pw.print(" matrix=");
244         mMatrix.printShortString(pw);
245         pw.print('}');
246     }
247 }
248