1 /*
2  * Copyright (C) 2014 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.graphics.Rect;
22 import android.util.AttributeSet;
23 
24 /**
25  * An animation that controls the clip of an object. See the
26  * {@link android.view.animation full package} description for details and
27  * sample code.
28  *
29  * @hide
30  */
31 public class ClipRectAnimation extends Animation {
32     protected final Rect mFromRect = new Rect();
33     protected final Rect mToRect = new Rect();
34 
35     private int mFromLeftType = ABSOLUTE;
36     private int mFromTopType = ABSOLUTE;
37     private int mFromRightType = ABSOLUTE;
38     private int mFromBottomType = ABSOLUTE;
39 
40     private int mToLeftType = ABSOLUTE;
41     private int mToTopType = ABSOLUTE;
42     private int mToRightType = ABSOLUTE;
43     private int mToBottomType = ABSOLUTE;
44 
45     private float mFromLeftValue;
46     private float mFromTopValue;
47     private float mFromRightValue;
48     private float mFromBottomValue;
49 
50     private float mToLeftValue;
51     private float mToTopValue;
52     private float mToRightValue;
53     private float mToBottomValue;
54 
55     /**
56      * Constructor used when a ClipRectAnimation is loaded from a resource.
57      *
58      * @param context Application context to use
59      * @param attrs Attribute set from which to read values
60      */
ClipRectAnimation(Context context, AttributeSet attrs)61     public ClipRectAnimation(Context context, AttributeSet attrs) {
62         super(context, attrs);
63 
64         TypedArray a = context.obtainStyledAttributes(attrs,
65                 com.android.internal.R.styleable.ClipRectAnimation);
66 
67         Description d = Description.parseValue(a.peekValue(
68                 com.android.internal.R.styleable.ClipRectAnimation_fromLeft), context);
69         mFromLeftType = d.type;
70         mFromLeftValue = d.value;
71 
72         d = Description.parseValue(a.peekValue(
73                 com.android.internal.R.styleable.ClipRectAnimation_fromTop), context);
74         mFromTopType = d.type;
75         mFromTopValue = d.value;
76 
77         d = Description.parseValue(a.peekValue(
78                 com.android.internal.R.styleable.ClipRectAnimation_fromRight), context);
79         mFromRightType = d.type;
80         mFromRightValue = d.value;
81 
82         d = Description.parseValue(a.peekValue(
83                 com.android.internal.R.styleable.ClipRectAnimation_fromBottom), context);
84         mFromBottomType = d.type;
85         mFromBottomValue = d.value;
86 
87 
88         d = Description.parseValue(a.peekValue(
89                 com.android.internal.R.styleable.ClipRectAnimation_toLeft), context);
90         mToLeftType = d.type;
91         mToLeftValue = d.value;
92 
93         d = Description.parseValue(a.peekValue(
94                 com.android.internal.R.styleable.ClipRectAnimation_toTop), context);
95         mToTopType = d.type;
96         mToTopValue = d.value;
97 
98         d = Description.parseValue(a.peekValue(
99                 com.android.internal.R.styleable.ClipRectAnimation_toRight), context);
100         mToRightType = d.type;
101         mToRightValue = d.value;
102 
103         d = Description.parseValue(a.peekValue(
104                 com.android.internal.R.styleable.ClipRectAnimation_toBottom), context);
105         mToBottomType = d.type;
106         mToBottomValue = d.value;
107 
108         a.recycle();
109     }
110 
111     /**
112      * Constructor to use when building a ClipRectAnimation from code
113      *
114      * @param fromClip the clip rect to animate from
115      * @param toClip the clip rect to animate to
116      */
ClipRectAnimation(Rect fromClip, Rect toClip)117     public ClipRectAnimation(Rect fromClip, Rect toClip) {
118         if (fromClip == null || toClip == null) {
119             throw new RuntimeException("Expected non-null animation clip rects");
120         }
121         mFromLeftValue = fromClip.left;
122         mFromTopValue = fromClip.top;
123         mFromRightValue= fromClip.right;
124         mFromBottomValue = fromClip.bottom;
125 
126         mToLeftValue = toClip.left;
127         mToTopValue = toClip.top;
128         mToRightValue= toClip.right;
129         mToBottomValue = toClip.bottom;
130     }
131 
132     /**
133      * Constructor to use when building a ClipRectAnimation from code
134      */
ClipRectAnimation(int fromL, int fromT, int fromR, int fromB, int toL, int toT, int toR, int toB)135     public ClipRectAnimation(int fromL, int fromT, int fromR, int fromB,
136             int toL, int toT, int toR, int toB) {
137         this(new Rect(fromL, fromT, fromR, fromB), new Rect(toL, toT, toR, toB));
138     }
139 
140     @Override
applyTransformation(float it, Transformation tr)141     protected void applyTransformation(float it, Transformation tr) {
142         int l = mFromRect.left + (int) ((mToRect.left - mFromRect.left) * it);
143         int t = mFromRect.top + (int) ((mToRect.top - mFromRect.top) * it);
144         int r = mFromRect.right + (int) ((mToRect.right - mFromRect.right) * it);
145         int b = mFromRect.bottom + (int) ((mToRect.bottom - mFromRect.bottom) * it);
146         tr.setClipRect(l, t, r, b);
147     }
148 
149     @Override
willChangeTransformationMatrix()150     public boolean willChangeTransformationMatrix() {
151         return false;
152     }
153 
154     @Override
initialize(int width, int height, int parentWidth, int parentHeight)155     public void initialize(int width, int height, int parentWidth, int parentHeight) {
156         super.initialize(width, height, parentWidth, parentHeight);
157         mFromRect.set((int) resolveSize(mFromLeftType, mFromLeftValue, width, parentWidth),
158                 (int) resolveSize(mFromTopType, mFromTopValue, height, parentHeight),
159                 (int) resolveSize(mFromRightType, mFromRightValue, width, parentWidth),
160                 (int) resolveSize(mFromBottomType, mFromBottomValue, height, parentHeight));
161         mToRect.set((int) resolveSize(mToLeftType, mToLeftValue, width, parentWidth),
162                 (int) resolveSize(mToTopType, mToTopValue, height, parentHeight),
163                 (int) resolveSize(mToRightType, mToRightValue, width, parentWidth),
164                 (int) resolveSize(mToBottomType, mToBottomValue, height, parentHeight));
165     }
166 }
167