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