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