From 8a9a824cd5641d214906a20a2a9372e62e9f3fb8 Mon Sep 17 00:00:00 2001 From: Diego Perez Date: Thu, 3 Mar 2016 09:58:02 +0000 Subject: [PATCH] Animated vector drawable support Change-Id: Iefd41d95503bb4f3b26020a519636a63d3da799b --- .../AnimatedVectorDrawable_Delegate.java | 284 ++++++++++++++++++ ...ble_VectorDrawableAnimatorRT_Delegate.java | 28 ++ .../drawable/VectorDrawable_Delegate.java | 180 +++++++---- ...iveInterpolatorFactoryHelper_Delegate.java | 128 ++++++++ .../tools/layoutlib/create/CreateInfo.java | 3 + 5 files changed, 561 insertions(+), 62 deletions(-) create mode 100644 tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java create mode 100644 tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate.java create mode 100644 tools/layoutlib/bridge/src/com/android/internal/view/animation/NativeInterpolatorFactoryHelper_Delegate.java diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java new file mode 100644 index 0000000000000..200fe3b1d1923 --- /dev/null +++ b/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java @@ -0,0 +1,284 @@ +/* + * 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} + *

+ * 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 sAnimatorSets = new + DelegateManager<>(AnimatorSetHolder.class); + private static DelegateManager sHolders = new + DelegateManager<>(PropertySetter.class); + + + @LayoutlibDelegate + /*package*/ static long nCreateAnimatorSet() { + return sAnimatorSets.addNewDelegate(new AnimatorSetHolder()); + } + + @LayoutlibDelegate + /*package*/ static void nAddAnimator(long setPtr, long propertyValuesHolder, + long nativeInterpolator, long startDelay, long duration, int repeatCount) { + 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.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 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 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 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 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 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 the type of the property + */ + private static class PropertySetter { + final Consumer mValueSetter; + private PropertyValuesHolder mValues; + + private PropertySetter(@NonNull Consumer 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 { + private IntPropertySetter(Consumer valueSetter) { + super(valueSetter); + } + + private static PropertySetter of(Consumer 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 { + private FloatPropertySetter(Consumer valueSetter) { + super(valueSetter); + } + + private static PropertySetter of(Consumer valueSetter, float... values) { + PropertySetter setter = new FloatPropertySetter(valueSetter); + setter.setValues(values); + + return setter; + } + + public void setFloatValue(Float value) { + mValueSetter.accept(value); + } + + } +} diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate.java new file mode 100644 index 0000000000000..3d78931a152cf --- /dev/null +++ b/tools/layoutlib/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate.java @@ -0,0 +1,28 @@ +/* + * 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.tools.layoutlib.annotations.LayoutlibDelegate; + +import android.graphics.drawable.AnimatedVectorDrawable.VectorDrawableAnimatorRT; + +public class AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate { + @LayoutlibDelegate + /*package*/ static boolean useLastSeenTarget(VectorDrawableAnimatorRT thisDrawableAnimator) { + return true; + } +} diff --git a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java index 22d15e148ba4f..e7250b69d1f6d 100644 --- a/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java @@ -20,6 +20,7 @@ import com.android.internal.R; import com.android.layoutlib.bridge.impl.DelegateManager; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; +import android.annotation.NonNull; import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.TypedArray; @@ -45,6 +46,7 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.FloatBuffer; import java.util.ArrayList; +import java.util.function.Consumer; import static android.graphics.Canvas.CLIP_SAVE_FLAG; import static android.graphics.Canvas.MATRIX_SAVE_FLAG; @@ -69,14 +71,6 @@ public class VectorDrawable_Delegate { private static final DelegateManager sPathManager = new DelegateManager<>(VNativeObject.class); - private static T getDelegate(long nativePtr) { - //noinspection unchecked - T object = (T) sPathManager.getDelegate(nativePtr); - assert object != null; - - return object; - } - /** * Obtains styled attributes from the theme, if available, or unstyled resources if the theme is * null. @@ -98,21 +92,21 @@ public class VectorDrawable_Delegate { @LayoutlibDelegate static long nCreateRenderer(long rootGroupPtr) { - VGroup_Delegate rootGroup = getDelegate(rootGroupPtr); + VGroup_Delegate rootGroup = VNativeObject.getDelegate(rootGroupPtr); return sPathManager.addNewDelegate(new VPathRenderer_Delegate(rootGroup)); } @LayoutlibDelegate static void nSetRendererViewportSize(long rendererPtr, float viewportWidth, float viewportHeight) { - VPathRenderer_Delegate nativePathRenderer = getDelegate(rendererPtr); + VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr); nativePathRenderer.mViewportWidth = viewportWidth; nativePathRenderer.mViewportHeight = viewportHeight; } @LayoutlibDelegate static boolean nSetRootAlpha(long rendererPtr, float alpha) { - VPathRenderer_Delegate nativePathRenderer = getDelegate(rendererPtr); + VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr); nativePathRenderer.setRootAlpha(alpha); return true; @@ -120,7 +114,7 @@ public class VectorDrawable_Delegate { @LayoutlibDelegate static float nGetRootAlpha(long rendererPtr) { - VPathRenderer_Delegate nativePathRenderer = getDelegate(rendererPtr); + VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr); return nativePathRenderer.getRootAlpha(); } @@ -133,8 +127,7 @@ public class VectorDrawable_Delegate { @LayoutlibDelegate static void nDraw(long rendererPtr, long canvasWrapperPtr, long colorFilterPtr, Rect bounds, boolean needsMirroring, boolean canReuseCache) { - VPathRenderer_Delegate nativePathRenderer = - getDelegate(rendererPtr); + VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr); nativePathRenderer.draw(canvasWrapperPtr, colorFilterPtr, bounds.width(), bounds.height()); } @@ -146,7 +139,7 @@ public class VectorDrawable_Delegate { @LayoutlibDelegate static long nCreateFullPath(long nativeFullPathPtr) { - VFullPath_Delegate original = getDelegate(nativeFullPathPtr); + VFullPath_Delegate original = VNativeObject.getDelegate(nativeFullPathPtr); return sPathManager.addNewDelegate(new VFullPath_Delegate(original)); } @@ -154,7 +147,7 @@ public class VectorDrawable_Delegate { @LayoutlibDelegate static boolean nGetFullPathProperties(long pathPtr, byte[] propertiesData, int length) { - VFullPath_Delegate path = getDelegate(pathPtr); + VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr); ByteBuffer properties = ByteBuffer.wrap(propertiesData); properties.order(ByteOrder.nativeOrder()); @@ -181,7 +174,7 @@ public class VectorDrawable_Delegate { int strokeColor, float strokeAlpha, int fillColor, float fillAlpha, float trimPathStart, float trimPathEnd, float trimPathOffset, float strokeMiterLimit, int strokeLineCap, int strokeLineJoin) { - VFullPath_Delegate path = getDelegate(pathPtr); + VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr); path.setStrokeWidth(strokeWidth); path.setStrokeColor(strokeColor); @@ -213,7 +206,7 @@ public class VectorDrawable_Delegate { @LayoutlibDelegate static long nCreateClipPath(long clipPathPtr) { - VClipPath_Delegate original = getDelegate(clipPathPtr); + VClipPath_Delegate original = VNativeObject.getDelegate(clipPathPtr); return sPathManager.addNewDelegate(new VClipPath_Delegate(original)); } @@ -224,21 +217,21 @@ public class VectorDrawable_Delegate { @LayoutlibDelegate static long nCreateGroup(long groupPtr) { - VGroup_Delegate original = getDelegate(groupPtr); + VGroup_Delegate original = VNativeObject.getDelegate(groupPtr); return sPathManager.addNewDelegate( new VGroup_Delegate(original, new ArrayMap())); } @LayoutlibDelegate static void nSetName(long nodePtr, String name) { - VNativeObject group = getDelegate(nodePtr); + VNativeObject group = VNativeObject.getDelegate(nodePtr); group.setName(name); } @LayoutlibDelegate static boolean nGetGroupProperties(long groupPtr, float[] propertiesData, int length) { - VGroup_Delegate group = getDelegate(groupPtr); + VGroup_Delegate group = VNativeObject.getDelegate(groupPtr); FloatBuffer properties = FloatBuffer.wrap(propertiesData); @@ -255,7 +248,7 @@ public class VectorDrawable_Delegate { @LayoutlibDelegate static void nUpdateGroupProperties(long groupPtr, float rotate, float pivotX, float pivotY, float scaleX, float scaleY, float translateX, float translateY) { - VGroup_Delegate group = getDelegate(groupPtr); + VGroup_Delegate group = VNativeObject.getDelegate(groupPtr); group.setRotation(rotate); group.setPivotX(pivotX); @@ -268,13 +261,13 @@ public class VectorDrawable_Delegate { @LayoutlibDelegate static void nAddChild(long groupPtr, long nodePtr) { - VGroup_Delegate group = getDelegate(groupPtr); - group.mChildren.add(getDelegate(nodePtr)); + VGroup_Delegate group = VNativeObject.getDelegate(groupPtr); + group.mChildren.add(VNativeObject.getDelegate(nodePtr)); } @LayoutlibDelegate static void nSetPathString(long pathPtr, String pathString, int length) { - VPath_Delegate path = getDelegate(pathPtr); + VPath_Delegate path = VNativeObject.getDelegate(pathPtr); path.setPathData(PathParser_Delegate.createNodesFromPathData(pathString)); } @@ -287,187 +280,187 @@ public class VectorDrawable_Delegate { // Setters and getters during animation. @LayoutlibDelegate static float nGetRotation(long groupPtr) { - VGroup_Delegate group = getDelegate(groupPtr); + VGroup_Delegate group = VNativeObject.getDelegate(groupPtr); return group.getRotation(); } @LayoutlibDelegate static void nSetRotation(long groupPtr, float rotation) { - VGroup_Delegate group = getDelegate(groupPtr); + VGroup_Delegate group = VNativeObject.getDelegate(groupPtr); group.setRotation(rotation); } @LayoutlibDelegate static float nGetPivotX(long groupPtr) { - VGroup_Delegate group = getDelegate(groupPtr); + VGroup_Delegate group = VNativeObject.getDelegate(groupPtr); return group.getPivotX(); } @LayoutlibDelegate static void nSetPivotX(long groupPtr, float pivotX) { - VGroup_Delegate group = getDelegate(groupPtr); + VGroup_Delegate group = VNativeObject.getDelegate(groupPtr); group.setPivotX(pivotX); } @LayoutlibDelegate static float nGetPivotY(long groupPtr) { - VGroup_Delegate group = getDelegate(groupPtr); + VGroup_Delegate group = VNativeObject.getDelegate(groupPtr); return group.getPivotY(); } @LayoutlibDelegate static void nSetPivotY(long groupPtr, float pivotY) { - VGroup_Delegate group = getDelegate(groupPtr); + VGroup_Delegate group = VNativeObject.getDelegate(groupPtr); group.setPivotY(pivotY); } @LayoutlibDelegate static float nGetScaleX(long groupPtr) { - VGroup_Delegate group = getDelegate(groupPtr); + VGroup_Delegate group = VNativeObject.getDelegate(groupPtr); return group.getScaleX(); } @LayoutlibDelegate static void nSetScaleX(long groupPtr, float scaleX) { - VGroup_Delegate group = getDelegate(groupPtr); + VGroup_Delegate group = VNativeObject.getDelegate(groupPtr); group.setScaleX(scaleX); } @LayoutlibDelegate static float nGetScaleY(long groupPtr) { - VGroup_Delegate group = getDelegate(groupPtr); + VGroup_Delegate group = VNativeObject.getDelegate(groupPtr); return group.getScaleY(); } @LayoutlibDelegate static void nSetScaleY(long groupPtr, float scaleY) { - VGroup_Delegate group = getDelegate(groupPtr); + VGroup_Delegate group = VNativeObject.getDelegate(groupPtr); group.setScaleY(scaleY); } @LayoutlibDelegate static float nGetTranslateX(long groupPtr) { - VGroup_Delegate group = getDelegate(groupPtr); + VGroup_Delegate group = VNativeObject.getDelegate(groupPtr); return group.getTranslateX(); } @LayoutlibDelegate static void nSetTranslateX(long groupPtr, float translateX) { - VGroup_Delegate group = getDelegate(groupPtr); + VGroup_Delegate group = VNativeObject.getDelegate(groupPtr); group.setTranslateX(translateX); } @LayoutlibDelegate static float nGetTranslateY(long groupPtr) { - VGroup_Delegate group = getDelegate(groupPtr); + VGroup_Delegate group = VNativeObject.getDelegate(groupPtr); return group.getTranslateY(); } @LayoutlibDelegate static void nSetTranslateY(long groupPtr, float translateY) { - VGroup_Delegate group = getDelegate(groupPtr); + VGroup_Delegate group = VNativeObject.getDelegate(groupPtr); group.setTranslateY(translateY); } @LayoutlibDelegate static void nSetPathData(long pathPtr, long pathDataPtr) { - VPath_Delegate path = getDelegate(pathPtr); + VPath_Delegate path = VNativeObject.getDelegate(pathPtr); path.setPathData(PathParser_Delegate.getDelegate(pathDataPtr).getPathDataNodes()); } @LayoutlibDelegate static float nGetStrokeWidth(long pathPtr) { - VFullPath_Delegate path = getDelegate(pathPtr); + VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr); return path.getStrokeWidth(); } @LayoutlibDelegate static void nSetStrokeWidth(long pathPtr, float width) { - VFullPath_Delegate path = getDelegate(pathPtr); + VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr); path.setStrokeWidth(width); } @LayoutlibDelegate static int nGetStrokeColor(long pathPtr) { - VFullPath_Delegate path = getDelegate(pathPtr); + VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr); return path.getStrokeColor(); } @LayoutlibDelegate static void nSetStrokeColor(long pathPtr, int strokeColor) { - VFullPath_Delegate path = getDelegate(pathPtr); + VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr); path.setStrokeColor(strokeColor); } @LayoutlibDelegate static float nGetStrokeAlpha(long pathPtr) { - VFullPath_Delegate path = getDelegate(pathPtr); + VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr); return path.getStrokeAlpha(); } @LayoutlibDelegate static void nSetStrokeAlpha(long pathPtr, float alpha) { - VFullPath_Delegate path = getDelegate(pathPtr); + VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr); path.setStrokeAlpha(alpha); } @LayoutlibDelegate static int nGetFillColor(long pathPtr) { - VFullPath_Delegate path = getDelegate(pathPtr); + VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr); return path.getFillColor(); } @LayoutlibDelegate static void nSetFillColor(long pathPtr, int fillColor) { - VFullPath_Delegate path = getDelegate(pathPtr); + VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr); path.setFillColor(fillColor); } @LayoutlibDelegate static float nGetFillAlpha(long pathPtr) { - VFullPath_Delegate path = getDelegate(pathPtr); + VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr); return path.getFillAlpha(); } @LayoutlibDelegate static void nSetFillAlpha(long pathPtr, float fillAlpha) { - VFullPath_Delegate path = getDelegate(pathPtr); + VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr); path.setFillAlpha(fillAlpha); } @LayoutlibDelegate static float nGetTrimPathStart(long pathPtr) { - VFullPath_Delegate path = getDelegate(pathPtr); + VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr); return path.getTrimPathStart(); } @LayoutlibDelegate static void nSetTrimPathStart(long pathPtr, float trimPathStart) { - VFullPath_Delegate path = getDelegate(pathPtr); + VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr); path.setTrimPathStart(trimPathStart); } @LayoutlibDelegate static float nGetTrimPathEnd(long pathPtr) { - VFullPath_Delegate path = getDelegate(pathPtr); + VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr); return path.getTrimPathEnd(); } @LayoutlibDelegate static void nSetTrimPathEnd(long pathPtr, float trimPathEnd) { - VFullPath_Delegate path = getDelegate(pathPtr); + VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr); path.setTrimPathEnd(trimPathEnd); } @LayoutlibDelegate static float nGetTrimPathOffset(long pathPtr) { - VFullPath_Delegate path = getDelegate(pathPtr); + VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr); return path.getTrimPathOffset(); } @LayoutlibDelegate static void nSetTrimPathOffset(long pathPtr, float trimPathOffset) { - VFullPath_Delegate path = getDelegate(pathPtr); + VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr); path.setTrimPathOffset(trimPathOffset); } @@ -479,7 +472,16 @@ public class VectorDrawable_Delegate { * not need it * */ - private interface VNativeObject { + interface VNativeObject { + @NonNull + static T getDelegate(long nativePtr) { + //noinspection unchecked + T vNativeObject = (T) sPathManager.getDelegate(nativePtr); + + assert vNativeObject != null; + return vNativeObject; + } + void setName(String name); } @@ -520,7 +522,7 @@ public class VectorDrawable_Delegate { } } - private static class VFullPath_Delegate extends VPath_Delegate { + static class VFullPath_Delegate extends VPath_Delegate { // These constants need to be kept in sync with their values in VectorDrawable.VFullPath private static final int STROKE_WIDTH_INDEX = 0; private static final int STROKE_COLOR_INDEX = 1; @@ -542,6 +544,38 @@ public class VectorDrawable_Delegate { private static final int LINEJOIN_ROUND = 1; private static final int LINEJOIN_BEVEL = 2; + @NonNull + public Consumer getFloatPropertySetter(int propertyIdx) { + switch (propertyIdx) { + case STROKE_ALPHA_INDEX: + return this::setStrokeAlpha; + case FILL_ALPHA_INDEX: + return this::setFillAlpha; + case TRIM_PATH_START_INDEX: + return this::setTrimPathStart; + case TRIM_PATH_END_INDEX: + return this::setTrimPathEnd; + case TRIM_PATH_OFFSET_INDEX: + return this::setTrimPathOffset; + } + + throw new IllegalArgumentException("Invalid VFullPath_Delegate property index " + + propertyIdx); + } + + @NonNull + public Consumer getIntPropertySetter(int propertyIdx) { + switch (propertyIdx) { + case STROKE_COLOR_INDEX: + return this::setStrokeColor; + case FILL_COLOR_INDEX: + return this::setFillColor; + } + + throw new IllegalArgumentException("Invalid VFullPath_Delegate property index " + + propertyIdx); + } + ///////////////////////////////////////////////////// // Variables below need to be copied (deep copy if applicable) for mutation. @@ -646,7 +680,7 @@ public class VectorDrawable_Delegate { return mStrokeColor; } - private void setStrokeColor(int strokeColor) { + private void setStrokeColor(int strokeColor) { mStrokeColor = strokeColor; } @@ -715,7 +749,7 @@ public class VectorDrawable_Delegate { } } - private static class VGroup_Delegate implements VNativeObject { + static class VGroup_Delegate implements VNativeObject { // This constants need to be kept in sync with their definitions in VectorDrawable.Group private static final int ROTATE_INDEX = 0; private static final int PIVOT_X_INDEX = 1; @@ -725,6 +759,28 @@ public class VectorDrawable_Delegate { private static final int TRANSLATE_X_INDEX = 5; private static final int TRANSLATE_Y_INDEX = 6; + public Consumer getPropertySetter(int propertyIdx) { + switch (propertyIdx) { + case ROTATE_INDEX: + return this::setRotation; + case PIVOT_X_INDEX: + return this::setPivotX; + case PIVOT_Y_INDEX: + return this::setPivotY; + case SCALE_X_INDEX: + return this::setScaleX; + case SCALE_Y_INDEX: + return this::setScaleY; + case TRANSLATE_X_INDEX: + return this::setTranslateX; + case TRANSLATE_Y_INDEX: + return this::setTranslateY; + } + + throw new IllegalArgumentException("Invalid VGroup_Delegate property index " + + propertyIdx); + } + ///////////////////////////////////////////////////// // Variables below need to be copied (deep copy if applicable) for mutation. final ArrayList mChildren = new ArrayList<>(); @@ -923,7 +979,7 @@ public class VectorDrawable_Delegate { } } - private static class VPathRenderer_Delegate implements VNativeObject { + static class VPathRenderer_Delegate implements VNativeObject { /* Right now the internal data structure is organized as a tree. * Each node can be a group node, or a path. * A group node can have groups or paths as children, but a path node has @@ -959,7 +1015,7 @@ public class VectorDrawable_Delegate { return mRootAlpha; } - private void setRootAlpha(float alpha) { + void setRootAlpha(float alpha) { mRootAlpha = alpha; } diff --git a/tools/layoutlib/bridge/src/com/android/internal/view/animation/NativeInterpolatorFactoryHelper_Delegate.java b/tools/layoutlib/bridge/src/com/android/internal/view/animation/NativeInterpolatorFactoryHelper_Delegate.java new file mode 100644 index 0000000000000..0f39e8042883f --- /dev/null +++ b/tools/layoutlib/bridge/src/com/android/internal/view/animation/NativeInterpolatorFactoryHelper_Delegate.java @@ -0,0 +1,128 @@ +/* + * 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 com.android.internal.view.animation; + +import com.android.layoutlib.bridge.impl.DelegateManager; +import com.android.tools.layoutlib.annotations.LayoutlibDelegate; + +import android.util.MathUtils; +import android.view.animation.AccelerateDecelerateInterpolator; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.AnticipateInterpolator; +import android.view.animation.AnticipateOvershootInterpolator; +import android.view.animation.BaseInterpolator; +import android.view.animation.BounceInterpolator; +import android.view.animation.CycleInterpolator; +import android.view.animation.DecelerateInterpolator; +import android.view.animation.Interpolator; +import android.view.animation.LinearInterpolator; +import android.view.animation.OvershootInterpolator; + +/** + * Delegate used to provide new implementation of a select few methods of {@link + * NativeInterpolatorFactoryHelper} + *

+ * Through the layoutlib_create tool, the original methods of NativeInterpolatorFactoryHelper have + * been replaced by calls to methods of the same name in this delegate class. + */ +@SuppressWarnings("unused") +public class NativeInterpolatorFactoryHelper_Delegate { + private static final DelegateManager sManager = new DelegateManager<> + (Interpolator.class); + + public static Interpolator getDelegate(long nativePtr) { + return sManager.getDelegate(nativePtr); + } + + @LayoutlibDelegate + /*package*/ static long createAccelerateDecelerateInterpolator() { + return sManager.addNewDelegate(new AccelerateDecelerateInterpolator()); + } + + @LayoutlibDelegate + /*package*/ static long createAccelerateInterpolator(float factor) { + return sManager.addNewDelegate(new AccelerateInterpolator(factor)); + } + + @LayoutlibDelegate + /*package*/ static long createAnticipateInterpolator(float tension) { + return sManager.addNewDelegate(new AnticipateInterpolator(tension)); + } + + @LayoutlibDelegate + /*package*/ static long createAnticipateOvershootInterpolator(float tension) { + return sManager.addNewDelegate(new AnticipateOvershootInterpolator(tension)); + } + + @LayoutlibDelegate + /*package*/ static long createBounceInterpolator() { + return sManager.addNewDelegate(new BounceInterpolator()); + } + + @LayoutlibDelegate + /*package*/ static long createCycleInterpolator(float cycles) { + return sManager.addNewDelegate(new CycleInterpolator(cycles)); + } + + @LayoutlibDelegate + /*package*/ static long createDecelerateInterpolator(float factor) { + return sManager.addNewDelegate(new DecelerateInterpolator(factor)); + } + + @LayoutlibDelegate + /*package*/ static long createLinearInterpolator() { + return sManager.addNewDelegate(new LinearInterpolator()); + } + + @LayoutlibDelegate + /*package*/ static long createOvershootInterpolator(float tension) { + return sManager.addNewDelegate(new OvershootInterpolator(tension)); + } + + private static class LutInterpolator extends BaseInterpolator { + private final float[] mValues; + private final int mSize; + + private LutInterpolator(float[] values) { + mValues = values; + mSize = mValues.length; + } + + @Override + public float getInterpolation(float input) { + float lutpos = input * mSize; + if (lutpos >= (mSize - 1)) { + return mValues[mSize - 1]; + } + + int ipart = (int) lutpos; + float weight = lutpos - ipart; + + int i1 = ipart; + int i2 = Math.min(i1 + 1, mSize - 1); + + assert i1 >= 0 && i2 >= 0 : "Negatives in the interpolation"; + + return MathUtils.lerp(mValues[i1], mValues[i2], weight); + } + } + + @LayoutlibDelegate + /*package*/ static long createLutInterpolator(float[] values) { + return sManager.addNewDelegate(new LutInterpolator(values)); + } +} diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java index 8c3bd2f40b53b..351be83c563ce 100644 --- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java +++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java @@ -164,6 +164,7 @@ public final class CreateInfo implements ICreateInfo { "android.content.res.TypedArray#obtain", "android.graphics.BitmapFactory#finishDecode", "android.graphics.BitmapFactory#setDensityFromOptions", + "android.graphics.drawable.AnimatedVectorDrawable$VectorDrawableAnimatorRT#useLastSeenTarget", "android.graphics.drawable.GradientDrawable#buildRing", "android.graphics.Typeface#getSystemFontConfigLocation", "android.graphics.Typeface#makeFamilyFromParsed", @@ -269,6 +270,7 @@ public final class CreateInfo implements ICreateInfo { "android.graphics.SweepGradient", "android.graphics.Typeface", "android.graphics.Xfermode", + "android.graphics.drawable.AnimatedVectorDrawable", "android.graphics.drawable.VectorDrawable", "android.os.SystemClock", "android.os.SystemProperties", @@ -276,6 +278,7 @@ public final class CreateInfo implements ICreateInfo { "android.text.StaticLayout", "android.util.PathParser", "android.view.Display", + "com.android.internal.view.animation.NativeInterpolatorFactoryHelper", "libcore.icu.ICU", };