067d0494ee784a49001d43ec0662a5a471a3cd4d
[pub/Android/ownCloud.git] /
1 package com.actionbarsherlock.internal.nineoldandroids.view.animation;
2
3 import java.lang.ref.WeakReference;
4 import java.util.WeakHashMap;
5 import android.graphics.Matrix;
6 import android.graphics.RectF;
7 import android.os.Build;
8 import android.util.FloatMath;
9 import android.view.View;
10 import android.view.animation.Animation;
11 import android.view.animation.Transformation;
12
13 public final class AnimatorProxy extends Animation {
14 public static final boolean NEEDS_PROXY = Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB;
15
16 private static final WeakHashMap<View, AnimatorProxy> PROXIES =
17 new WeakHashMap<View, AnimatorProxy>();
18
19 public static AnimatorProxy wrap(View view) {
20 AnimatorProxy proxy = PROXIES.get(view);
21 if (proxy == null) {
22 proxy = new AnimatorProxy(view);
23 PROXIES.put(view, proxy);
24 }
25 return proxy;
26 }
27
28 private final WeakReference<View> mView;
29
30 private float mAlpha = 1;
31 private float mScaleX = 1;
32 private float mScaleY = 1;
33 private float mTranslationX;
34 private float mTranslationY;
35
36 private final RectF mBefore = new RectF();
37 private final RectF mAfter = new RectF();
38 private final Matrix mTempMatrix = new Matrix();
39
40 private AnimatorProxy(View view) {
41 setDuration(0); //perform transformation immediately
42 setFillAfter(true); //persist transformation beyond duration
43 view.setAnimation(this);
44 mView = new WeakReference<View>(view);
45 }
46
47 public float getAlpha() {
48 return mAlpha;
49 }
50 public void setAlpha(float alpha) {
51 if (mAlpha != alpha) {
52 mAlpha = alpha;
53 View view = mView.get();
54 if (view != null) {
55 view.invalidate();
56 }
57 }
58 }
59 public float getScaleX() {
60 return mScaleX;
61 }
62 public void setScaleX(float scaleX) {
63 if (mScaleX != scaleX) {
64 prepareForUpdate();
65 mScaleX = scaleX;
66 invalidateAfterUpdate();
67 }
68 }
69 public float getScaleY() {
70 return mScaleY;
71 }
72 public void setScaleY(float scaleY) {
73 if (mScaleY != scaleY) {
74 prepareForUpdate();
75 mScaleY = scaleY;
76 invalidateAfterUpdate();
77 }
78 }
79 public int getScrollX() {
80 View view = mView.get();
81 if (view == null) {
82 return 0;
83 }
84 return view.getScrollX();
85 }
86 public void setScrollX(int value) {
87 View view = mView.get();
88 if (view != null) {
89 view.scrollTo(value, view.getScrollY());
90 }
91 }
92 public int getScrollY() {
93 View view = mView.get();
94 if (view == null) {
95 return 0;
96 }
97 return view.getScrollY();
98 }
99 public void setScrollY(int value) {
100 View view = mView.get();
101 if (view != null) {
102 view.scrollTo(view.getScrollY(), value);
103 }
104 }
105
106 public float getTranslationX() {
107 return mTranslationX;
108 }
109 public void setTranslationX(float translationX) {
110 if (mTranslationX != translationX) {
111 prepareForUpdate();
112 mTranslationX = translationX;
113 invalidateAfterUpdate();
114 }
115 }
116 public float getTranslationY() {
117 return mTranslationY;
118 }
119 public void setTranslationY(float translationY) {
120 if (mTranslationY != translationY) {
121 prepareForUpdate();
122 mTranslationY = translationY;
123 invalidateAfterUpdate();
124 }
125 }
126
127 private void prepareForUpdate() {
128 View view = mView.get();
129 if (view != null) {
130 computeRect(mBefore, view);
131 }
132 }
133 private void invalidateAfterUpdate() {
134 View view = mView.get();
135 if (view == null) {
136 return;
137 }
138 View parent = (View)view.getParent();
139 if (parent == null) {
140 return;
141 }
142
143 view.setAnimation(this);
144
145 final RectF after = mAfter;
146 computeRect(after, view);
147 after.union(mBefore);
148
149 parent.invalidate(
150 (int) FloatMath.floor(after.left),
151 (int) FloatMath.floor(after.top),
152 (int) FloatMath.ceil(after.right),
153 (int) FloatMath.ceil(after.bottom));
154 }
155
156 private void computeRect(final RectF r, View view) {
157 // compute current rectangle according to matrix transformation
158 final float w = view.getWidth();
159 final float h = view.getHeight();
160
161 // use a rectangle at 0,0 to make sure we don't run into issues with scaling
162 r.set(0, 0, w, h);
163
164 final Matrix m = mTempMatrix;
165 m.reset();
166 transformMatrix(m, view);
167 mTempMatrix.mapRect(r);
168
169 r.offset(view.getLeft(), view.getTop());
170
171 // Straighten coords if rotations flipped them
172 if (r.right < r.left) {
173 final float f = r.right;
174 r.right = r.left;
175 r.left = f;
176 }
177 if (r.bottom < r.top) {
178 final float f = r.top;
179 r.top = r.bottom;
180 r.bottom = f;
181 }
182 }
183
184 private void transformMatrix(Matrix m, View view) {
185 final float w = view.getWidth();
186 final float h = view.getHeight();
187
188 final float sX = mScaleX;
189 final float sY = mScaleY;
190 if ((sX != 1.0f) || (sY != 1.0f)) {
191 final float deltaSX = ((sX * w) - w) / 2f;
192 final float deltaSY = ((sY * h) - h) / 2f;
193 m.postScale(sX, sY);
194 m.postTranslate(-deltaSX, -deltaSY);
195 }
196 m.postTranslate(mTranslationX, mTranslationY);
197 }
198
199 @Override
200 protected void applyTransformation(float interpolatedTime, Transformation t) {
201 View view = mView.get();
202 if (view != null) {
203 t.setAlpha(mAlpha);
204 transformMatrix(t.getMatrix(), view);
205 }
206 }
207
208 @Override
209 public void reset() {
210 /* Do nothing. */
211 }
212 }