| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License") {} |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.graphics.drawable; |
| |
| import com.android.ide.common.rendering.api.LayoutLog; |
| import com.android.internal.view.animation.NativeInterpolatorFactoryHelper_Delegate; |
| import com.android.layoutlib.bridge.Bridge; |
| import com.android.layoutlib.bridge.impl.DelegateManager; |
| import com.android.tools.layoutlib.annotations.LayoutlibDelegate; |
| |
| import android.animation.Animator; |
| import android.animation.AnimatorSet; |
| import android.animation.ObjectAnimator; |
| import android.animation.PropertyValuesHolder; |
| import android.annotation.NonNull; |
| import android.annotation.Nullable; |
| import android.graphics.drawable.AnimatedVectorDrawable.VectorDrawableAnimatorRT; |
| import android.graphics.drawable.VectorDrawable_Delegate.VFullPath_Delegate; |
| import android.graphics.drawable.VectorDrawable_Delegate.VGroup_Delegate; |
| import android.graphics.drawable.VectorDrawable_Delegate.VNativeObject; |
| import android.graphics.drawable.VectorDrawable_Delegate.VPathRenderer_Delegate; |
| |
| import java.util.ArrayList; |
| import java.util.function.Consumer; |
| |
| /** |
| * Delegate used to provide new implementation of a select few methods of {@link |
| * AnimatedVectorDrawable} |
| * <p> |
| * Through the layoutlib_create tool, the original methods of AnimatedVectorDrawable have been |
| * replaced by calls to methods of the same name in this delegate class. |
| */ |
| @SuppressWarnings("unused") |
| public class AnimatedVectorDrawable_Delegate { |
| private static DelegateManager<AnimatorSetHolder> sAnimatorSets = new |
| DelegateManager<>(AnimatorSetHolder.class); |
| private static DelegateManager<PropertySetter> sHolders = new |
| DelegateManager<>(PropertySetter.class); |
| |
| |
| @LayoutlibDelegate |
| /*package*/ static long nCreateAnimatorSet() { |
| return sAnimatorSets.addNewDelegate(new AnimatorSetHolder()); |
| } |
| |
| @LayoutlibDelegate |
| /*package*/ static void nSetVectorDrawableTarget(long animatorPtr, long vectorDrawablePtr) { |
| // TODO: implement |
| } |
| @LayoutlibDelegate |
| /*package*/ static void nAddAnimator(long setPtr, long propertyValuesHolder, |
| long nativeInterpolator, long startDelay, long duration, int repeatCount, |
| int repeatMode) { |
| PropertySetter holder = sHolders.getDelegate(propertyValuesHolder); |
| if (holder == null || holder.getValues() == null) { |
| return; |
| } |
| |
| ObjectAnimator animator = new ObjectAnimator(); |
| animator.setValues(holder.getValues()); |
| animator.setInterpolator( |
| NativeInterpolatorFactoryHelper_Delegate.getDelegate(nativeInterpolator)); |
| animator.setStartDelay(startDelay); |
| animator.setDuration(duration); |
| animator.setRepeatCount(repeatCount); |
| animator.setRepeatMode(repeatMode); |
| animator.setTarget(holder); |
| animator.setPropertyName(holder.getValues().getPropertyName()); |
| |
| AnimatorSetHolder set = sAnimatorSets.getDelegate(setPtr); |
| assert set != null; |
| set.addAnimator(animator); |
| } |
| |
| @LayoutlibDelegate |
| /*package*/ static long nCreateGroupPropertyHolder(long nativePtr, int propertyId, |
| float startValue, float endValue) { |
| VGroup_Delegate group = VNativeObject.getDelegate(nativePtr); |
| Consumer<Float> setter = group.getPropertySetter(propertyId); |
| |
| return sHolders.addNewDelegate(FloatPropertySetter.of(setter, startValue, |
| endValue)); |
| } |
| |
| @LayoutlibDelegate |
| /*package*/ static long nCreatePathDataPropertyHolder(long nativePtr, long startValuePtr, |
| long endValuePtr) { |
| Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED, "AnimatedVectorDrawable path " + |
| "animations are not supported.", null, null); |
| return 0; |
| } |
| |
| @LayoutlibDelegate |
| /*package*/ static long nCreatePathColorPropertyHolder(long nativePtr, int propertyId, |
| int startValue, int endValue) { |
| VFullPath_Delegate path = VNativeObject.getDelegate(nativePtr); |
| Consumer<Integer> setter = path.getIntPropertySetter(propertyId); |
| |
| return sHolders.addNewDelegate(IntPropertySetter.of(setter, startValue, |
| endValue)); |
| } |
| |
| @LayoutlibDelegate |
| /*package*/ static long nCreatePathPropertyHolder(long nativePtr, int propertyId, |
| float startValue, float endValue) { |
| VFullPath_Delegate path = VNativeObject.getDelegate(nativePtr); |
| Consumer<Float> setter = path.getFloatPropertySetter(propertyId); |
| |
| return sHolders.addNewDelegate(FloatPropertySetter.of(setter, startValue, |
| endValue)); |
| } |
| |
| @LayoutlibDelegate |
| /*package*/ static long nCreateRootAlphaPropertyHolder(long nativePtr, float startValue, |
| float endValue) { |
| VPathRenderer_Delegate renderer = VNativeObject.getDelegate(nativePtr); |
| |
| return sHolders.addNewDelegate(FloatPropertySetter.of(renderer::setRootAlpha, |
| startValue, |
| endValue)); |
| } |
| |
| @LayoutlibDelegate |
| /*package*/ static void nSetPropertyHolderData(long nativePtr, float[] data, int length) { |
| PropertySetter setter = sHolders.getDelegate(nativePtr); |
| assert setter != null; |
| |
| setter.setValues(data); |
| } |
| |
| @LayoutlibDelegate |
| /*package*/ static void nSetPropertyHolderData(long nativePtr, int[] data, int length) { |
| PropertySetter setter = sHolders.getDelegate(nativePtr); |
| assert setter != null; |
| |
| setter.setValues(data); |
| } |
| |
| @LayoutlibDelegate |
| /*package*/ static void nStart(long animatorSetPtr, VectorDrawableAnimatorRT set, int id) { |
| AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr); |
| assert animatorSet != null; |
| |
| animatorSet.start(); |
| } |
| |
| @LayoutlibDelegate |
| /*package*/ static void nReverse(long animatorSetPtr, VectorDrawableAnimatorRT set, int id) { |
| AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr); |
| assert animatorSet != null; |
| |
| animatorSet.reverse(); |
| } |
| |
| @LayoutlibDelegate |
| /*package*/ static void nEnd(long animatorSetPtr) { |
| AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr); |
| assert animatorSet != null; |
| |
| animatorSet.end(); |
| } |
| |
| @LayoutlibDelegate |
| /*package*/ static void nReset(long animatorSetPtr) { |
| AnimatorSetHolder animatorSet = sAnimatorSets.getDelegate(animatorSetPtr); |
| assert animatorSet != null; |
| |
| animatorSet.end(); |
| animatorSet.start(); |
| } |
| |
| private static class AnimatorSetHolder { |
| private ArrayList<Animator> mAnimators = new ArrayList<>(); |
| private AnimatorSet mAnimatorSet = null; |
| |
| private void addAnimator(@NonNull Animator animator) { |
| mAnimators.add(animator); |
| } |
| |
| private void ensureAnimatorSet() { |
| if (mAnimatorSet == null) { |
| mAnimatorSet = new AnimatorSet(); |
| mAnimatorSet.playTogether(mAnimators); |
| } |
| } |
| |
| private void start() { |
| ensureAnimatorSet(); |
| |
| mAnimatorSet.start(); |
| } |
| |
| private void end() { |
| mAnimatorSet.end(); |
| } |
| |
| private void reset() { |
| end(); |
| start(); |
| } |
| |
| private void reverse() { |
| mAnimatorSet.reverse(); |
| } |
| } |
| |
| /** |
| * Class that allows setting a value and holds the range of values for the given property. |
| * |
| * @param <T> the type of the property |
| */ |
| private static class PropertySetter<T> { |
| final Consumer<T> mValueSetter; |
| private PropertyValuesHolder mValues; |
| |
| private PropertySetter(@NonNull Consumer<T> valueSetter) { |
| mValueSetter = valueSetter; |
| } |
| |
| /** |
| * Method to set an {@link Integer} value for this property. The default implementation of |
| * this method doesn't do anything. This method is accessed via reflection by the |
| * PropertyValuesHolder. |
| */ |
| public void setIntValue(Integer value) { |
| } |
| |
| /** |
| * Method to set an {@link Integer} value for this property. The default implementation of |
| * this method doesn't do anything. This method is accessed via reflection by the |
| * PropertyValuesHolder. |
| */ |
| public void setFloatValue(Float value) { |
| } |
| |
| void setValues(float... values) { |
| mValues = PropertyValuesHolder.ofFloat("floatValue", values); |
| } |
| |
| @Nullable |
| PropertyValuesHolder getValues() { |
| return mValues; |
| } |
| |
| void setValues(int... values) { |
| mValues = PropertyValuesHolder.ofInt("intValue", values); |
| } |
| } |
| |
| private static class IntPropertySetter extends PropertySetter<Integer> { |
| private IntPropertySetter(Consumer<Integer> valueSetter) { |
| super(valueSetter); |
| } |
| |
| private static PropertySetter of(Consumer<Integer> valueSetter, int... values) { |
| PropertySetter setter = new IntPropertySetter(valueSetter); |
| setter.setValues(values); |
| |
| return setter; |
| } |
| |
| public void setIntValue(Integer value) { |
| mValueSetter.accept(value); |
| } |
| } |
| |
| private static class FloatPropertySetter extends PropertySetter<Float> { |
| private FloatPropertySetter(Consumer<Float> valueSetter) { |
| super(valueSetter); |
| } |
| |
| private static PropertySetter of(Consumer<Float> valueSetter, float... values) { |
| PropertySetter setter = new FloatPropertySetter(valueSetter); |
| setter.setValues(values); |
| |
| return setter; |
| } |
| |
| public void setFloatValue(Float value) { |
| mValueSetter.accept(value); |
| } |
| |
| } |
| } |