blob: 5ad1ddae7fe418f40f23dd7e5e412a90116275be [file] [log] [blame]
Diego Perezee552062016-03-03 09:58:02 +00001/*
2 * Copyright (C) 2016 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.graphics.drawable;
18
19import com.android.ide.common.rendering.api.LayoutLog;
Diego Perezee552062016-03-03 09:58:02 +000020import com.android.layoutlib.bridge.Bridge;
21import com.android.layoutlib.bridge.impl.DelegateManager;
22import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
23
24import android.animation.Animator;
25import android.animation.AnimatorSet;
26import android.animation.ObjectAnimator;
27import android.animation.PropertyValuesHolder;
28import android.annotation.NonNull;
29import android.annotation.Nullable;
Jerome Gaillard39adcde2020-02-17 16:15:33 +000030import android.graphics.animation.NativeInterpolatorFactory_Delegate;
Diego Perezee552062016-03-03 09:58:02 +000031import android.graphics.drawable.AnimatedVectorDrawable.VectorDrawableAnimatorRT;
32import android.graphics.drawable.VectorDrawable_Delegate.VFullPath_Delegate;
33import android.graphics.drawable.VectorDrawable_Delegate.VGroup_Delegate;
34import android.graphics.drawable.VectorDrawable_Delegate.VNativeObject;
35import android.graphics.drawable.VectorDrawable_Delegate.VPathRenderer_Delegate;
36
37import java.util.ArrayList;
38import java.util.function.Consumer;
39
40/**
41 * Delegate used to provide new implementation of a select few methods of {@link
42 * AnimatedVectorDrawable}
43 * <p>
44 * Through the layoutlib_create tool, the original methods of AnimatedVectorDrawable have been
45 * replaced by calls to methods of the same name in this delegate class.
46 */
47@SuppressWarnings("unused")
48public class AnimatedVectorDrawable_Delegate {
49 private static DelegateManager<AnimatorSetHolder> sAnimatorSets = new
50 DelegateManager<>(AnimatorSetHolder.class);
51 private static DelegateManager<PropertySetter> sHolders = new
52 DelegateManager<>(PropertySetter.class);
53
54
55 @LayoutlibDelegate
56 /*package*/ static long nCreateAnimatorSet() {
57 return sAnimatorSets.addNewDelegate(new AnimatorSetHolder());
58 }
59
60 @LayoutlibDelegate
Jerome Gaillard989f4cb2016-11-24 21:51:22 +000061 /*package*/ static void nSetVectorDrawableTarget(long animatorPtr, long vectorDrawablePtr) {
62 // TODO: implement
63 }
64 @LayoutlibDelegate
Diego Perezee552062016-03-03 09:58:02 +000065 /*package*/ static void nAddAnimator(long setPtr, long propertyValuesHolder,
Jerome Gaillard989f4cb2016-11-24 21:51:22 +000066 long nativeInterpolator, long startDelay, long duration, int repeatCount,
67 int repeatMode) {
Diego Perezee552062016-03-03 09:58:02 +000068 PropertySetter holder = sHolders.getDelegate(propertyValuesHolder);
69 if (holder == null || holder.getValues() == null) {
70 return;
71 }
72
73 ObjectAnimator animator = new ObjectAnimator();
74 animator.setValues(holder.getValues());
75 animator.setInterpolator(
Jerome Gaillard39adcde2020-02-17 16:15:33 +000076 NativeInterpolatorFactory_Delegate.getDelegate(nativeInterpolator));
Diego Perezee552062016-03-03 09:58:02 +000077 animator.setStartDelay(startDelay);
78 animator.setDuration(duration);
79 animator.setRepeatCount(repeatCount);
Jerome Gaillard989f4cb2016-11-24 21:51:22 +000080 animator.setRepeatMode(repeatMode);
Diego Perezee552062016-03-03 09:58:02 +000081 animator.setTarget(holder);
82 animator.setPropertyName(holder.getValues().getPropertyName());
83
84 AnimatorSetHolder set = sAnimatorSets.getDelegate(setPtr);
85 assert set != null;
86 set.addAnimator(animator);
87 }
88
89 @LayoutlibDelegate
90 /*package*/ static long nCreateGroupPropertyHolder(long nativePtr, int propertyId,
91 float startValue, float endValue) {
92 VGroup_Delegate group = VNativeObject.getDelegate(nativePtr);
93 Consumer<Float> setter = group.getPropertySetter(propertyId);
94
95 return sHolders.addNewDelegate(FloatPropertySetter.of(setter, startValue,
96 endValue));
97 }
98
99 @LayoutlibDelegate
100 /*package*/ static long nCreatePathDataPropertyHolder(long nativePtr, long startValuePtr,
101 long endValuePtr) {
102 Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, "AnimatedVectorDrawable path " +
103 "animations are not supported.", null, null);
104 return 0;
105 }
106
107 @LayoutlibDelegate
108 /*package*/ static long nCreatePathColorPropertyHolder(long nativePtr, int propertyId,
109 int startValue, int endValue) {
110 VFullPath_Delegate path = VNativeObject.getDelegate(nativePtr);
111 Consumer<Integer> setter = path.getIntPropertySetter(propertyId);
112
113 return sHolders.addNewDelegate(IntPropertySetter.of(setter, startValue,
114 endValue));
115 }
116
117 @LayoutlibDelegate
118 /*package*/ static long nCreatePathPropertyHolder(long nativePtr, int propertyId,
119 float startValue, float endValue) {
120 VFullPath_Delegate path = VNativeObject.getDelegate(nativePtr);
121 Consumer<Float> setter = path.getFloatPropertySetter(propertyId);
122
123 return sHolders.addNewDelegate(FloatPropertySetter.of(setter, startValue,
124 endValue));
125 }
126
127 @LayoutlibDelegate
128 /*package*/ static long nCreateRootAlphaPropertyHolder(long nativePtr, float startValue,
129 float endValue) {
130 VPathRenderer_Delegate renderer = VNativeObject.getDelegate(nativePtr);
131
132 return sHolders.addNewDelegate(FloatPropertySetter.of(renderer::setRootAlpha,
133 startValue,
134 endValue));
135 }
136
137 @LayoutlibDelegate
138 /*package*/ static void nSetPropertyHolderData(long nativePtr, float[] data, int length) {
139 PropertySetter setter = sHolders.getDelegate(nativePtr);
140 assert setter != null;
141
142 setter.setValues(data);
143 }
144
145 @LayoutlibDelegate
Jerome Gaillard989f4cb2016-11-24 21:51:22 +0000146 /*package*/ static void nSetPropertyHolderData(long nativePtr, int[] data, int length) {
147 PropertySetter setter = sHolders.getDelegate(nativePtr);
148 assert setter != null;
149
150 setter.setValues(data);
151 }
152
153 @LayoutlibDelegate
Diego Perezee552062016-03-03 09:58:02 +0000154 /*package*/ static void nStart(long animatorSetPtr, VectorDrawableAnimatorRT set, int id) {
155 AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
156 assert animatorSet != null;
157
158 animatorSet.start();
159 }
160
161 @LayoutlibDelegate
162 /*package*/ static void nReverse(long animatorSetPtr, VectorDrawableAnimatorRT set, int id) {
163 AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
164 assert animatorSet != null;
165
166 animatorSet.reverse();
167 }
168
169 @LayoutlibDelegate
170 /*package*/ static void nEnd(long animatorSetPtr) {
171 AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
172 assert animatorSet != null;
173
174 animatorSet.end();
175 }
176
177 @LayoutlibDelegate
178 /*package*/ static void nReset(long animatorSetPtr) {
179 AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr);
180 assert animatorSet != null;
181
182 animatorSet.end();
183 animatorSet.start();
184 }
185
186 private static class AnimatorSetHolder {
187 private ArrayList<Animator> mAnimators = new ArrayList<>();
188 private AnimatorSet mAnimatorSet = null;
189
190 private void addAnimator(@NonNull Animator animator) {
191 mAnimators.add(animator);
192 }
193
194 private void ensureAnimatorSet() {
195 if (mAnimatorSet == null) {
196 mAnimatorSet = new AnimatorSet();
197 mAnimatorSet.playTogether(mAnimators);
198 }
199 }
200
201 private void start() {
202 ensureAnimatorSet();
203
204 mAnimatorSet.start();
205 }
206
207 private void end() {
208 mAnimatorSet.end();
209 }
210
211 private void reset() {
212 end();
213 start();
214 }
215
216 private void reverse() {
217 mAnimatorSet.reverse();
218 }
219 }
220
221 /**
222 * Class that allows setting a value and holds the range of values for the given property.
223 *
224 * @param <T> the type of the property
225 */
226 private static class PropertySetter<T> {
227 final Consumer<T> mValueSetter;
228 private PropertyValuesHolder mValues;
229
230 private PropertySetter(@NonNull Consumer<T> valueSetter) {
231 mValueSetter = valueSetter;
232 }
233
234 /**
235 * Method to set an {@link Integer} value for this property. The default implementation of
236 * this method doesn't do anything. This method is accessed via reflection by the
237 * PropertyValuesHolder.
238 */
239 public void setIntValue(Integer value) {
240 }
241
242 /**
243 * Method to set an {@link Integer} value for this property. The default implementation of
244 * this method doesn't do anything. This method is accessed via reflection by the
245 * PropertyValuesHolder.
246 */
247 public void setFloatValue(Float value) {
248 }
249
250 void setValues(float... values) {
251 mValues = PropertyValuesHolder.ofFloat("floatValue", values);
252 }
253
254 @Nullable
255 PropertyValuesHolder getValues() {
256 return mValues;
257 }
258
259 void setValues(int... values) {
260 mValues = PropertyValuesHolder.ofInt("intValue", values);
261 }
262 }
263
264 private static class IntPropertySetter extends PropertySetter<Integer> {
265 private IntPropertySetter(Consumer<Integer> valueSetter) {
266 super(valueSetter);
267 }
268
269 private static PropertySetter of(Consumer<Integer> valueSetter, int... values) {
270 PropertySetter setter = new IntPropertySetter(valueSetter);
271 setter.setValues(values);
272
273 return setter;
274 }
275
276 public void setIntValue(Integer value) {
277 mValueSetter.accept(value);
278 }
279 }
280
281 private static class FloatPropertySetter extends PropertySetter<Float> {
282 private FloatPropertySetter(Consumer<Float> valueSetter) {
283 super(valueSetter);
284 }
285
286 private static PropertySetter of(Consumer<Float> valueSetter, float... values) {
287 PropertySetter setter = new FloatPropertySetter(valueSetter);
288 setter.setValues(values);
289
290 return setter;
291 }
292
293 public void setFloatValue(Float value) {
294 mValueSetter.accept(value);
295 }
296
297 }
298}