Home | History | Annotate | Download | only in drawable
      1 /*
      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 
     17 package android.graphics.drawable;
     18 
     19 import com.android.ide.common.rendering.api.LayoutLog;
     20 import com.android.internal.view.animation.NativeInterpolatorFactoryHelper_Delegate;
     21 import com.android.layoutlib.bridge.Bridge;
     22 import com.android.layoutlib.bridge.impl.DelegateManager;
     23 import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
     24 
     25 import android.animation.Animator;
     26 import android.animation.AnimatorSet;
     27 import android.animation.ObjectAnimator;
     28 import android.animation.PropertyValuesHolder;
     29 import android.annotation.NonNull;
     30 import android.annotation.Nullable;
     31 import android.graphics.drawable.AnimatedVectorDrawable.VectorDrawableAnimatorRT;
     32 import android.graphics.drawable.VectorDrawable_Delegate.VFullPath_Delegate;
     33 import android.graphics.drawable.VectorDrawable_Delegate.VGroup_Delegate;
     34 import android.graphics.drawable.VectorDrawable_Delegate.VNativeObject;
     35 import android.graphics.drawable.VectorDrawable_Delegate.VPathRenderer_Delegate;
     36 
     37 import java.util.ArrayList;
     38 import 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")
     48 public 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
     61     /*package*/ static void nSetVectorDrawableTarget(long animatorPtr, long vectorDrawablePtr) {
     62         // TODO: implement
     63     }
     64     @LayoutlibDelegate
     65     /*package*/ static void nAddAnimator(long setPtr, long propertyValuesHolder,
     66             long nativeInterpolator, long startDelay, long duration, int repeatCount,
     67             int repeatMode) {
     68         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(
     76                 NativeInterpolatorFactoryHelper_Delegate.getDelegate(nativeInterpolator));
     77         animator.setStartDelay(startDelay);
     78         animator.setDuration(duration);
     79         animator.setRepeatCount(repeatCount);
     80         animator.setRepeatMode(repeatMode);
     81         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
    146     /*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
    154     /*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 }
    299