Merge "Change BridgeResources to Resources_Delegate" into nyc-dev
diff --git a/.idea/runConfigurations/Create.xml b/.idea/runConfigurations/Create.xml
index fb798b6..536a23f 100644
--- a/.idea/runConfigurations/Create.xml
+++ b/.idea/runConfigurations/Create.xml
@@ -3,7 +3,7 @@
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<option name="MAIN_CLASS_NAME" value="com.android.tools.layoutlib.create.Main" />
<option name="VM_PARAMETERS" value="-ea" />
- <option name="PROGRAM_PARAMETERS" value="out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar out/target/common/obj/JAVA_LIBRARIES/core-libart_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/icu4j-icudata-jarjar_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/icu4j-icutzdata-jarjar_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/javalib.jar" />
+ <option name="PROGRAM_PARAMETERS" value="out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar out/target/common/obj/JAVA_LIBRARIES/core-libart_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar out/host/common/obj/JAVA_LIBRARIES/icu4j-icudata-host-jarjar_intermediates/classes-jarjar.jar out/host/common/obj/JAVA_LIBRARIES/icu4j-icutzdata-host-jarjar_intermediates/classes-jarjar.jar out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/javalib.jar" />
<option name="WORKING_DIRECTORY" value="file://$PROJECT_DIR$/../../../../" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" value="" />
diff --git a/bridge/src/android/content/res/BridgeTypedArray.java b/bridge/src/android/content/res/BridgeTypedArray.java
index b5eafb2..d0e431a 100644
--- a/bridge/src/android/content/res/BridgeTypedArray.java
+++ b/bridge/src/android/content/res/BridgeTypedArray.java
@@ -25,14 +25,9 @@
import com.android.internal.util.XmlUtils;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
-import com.android.layoutlib.bridge.impl.ParserFactory;
import com.android.layoutlib.bridge.impl.ResourceHelper;
import com.android.resources.ResourceType;
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
import android.annotation.Nullable;
import android.content.res.Resources.NotFoundException;
import android.content.res.Resources.Theme;
@@ -42,7 +37,6 @@
import android.view.LayoutInflater_Delegate;
import android.view.ViewGroup.LayoutParams;
-import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
@@ -306,76 +300,21 @@
}
@Override
- public ComplexColor getComplexColor(int index) {
- // TODO: Support GradientColor
- return getColorStateList(index);
- }
-
- /**
- * Retrieve the ColorStateList for the attribute at <var>index</var>.
- * The value may be either a single solid color or a reference to
- * a color or complex {@link android.content.res.ColorStateList} description.
- *
- * @param index Index of attribute to retrieve.
- *
- * @return ColorStateList for the attribute, or null if not defined.
- */
- @Override
public ColorStateList getColorStateList(int index) {
if (!hasValue(index)) {
return null;
}
- ResourceValue resValue = mResourceData[index];
- String value = resValue.getValue();
+ return ResourceHelper.getColorStateList(mResourceData[index], mContext);
+ }
- if (value == null) {
+ @Override
+ public ComplexColor getComplexColor(int index) {
+ if (!hasValue(index)) {
return null;
}
-
- try {
- // Get the state list file content from callback to parse PSI file
- XmlPullParser parser = mContext.getLayoutlibCallback().getXmlFileParser(value);
- if (parser == null) {
- // If used with a version of Android Studio that does not implement getXmlFileParser
- // fall back to reading the file from disk
- File f = new File(value);
- if (f.isFile()) {
- parser = ParserFactory.create(f);
- }
- }
- if (parser != null) {
- BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
- parser, mContext, resValue.isFramework());
- try {
- return ColorStateList.createFromXml(mContext.getResources(), blockParser,
- mContext.getTheme());
- } finally {
- blockParser.ensurePopped();
- }
- }
- } catch (XmlPullParserException e) {
- Bridge.getLog().error(LayoutLog.TAG_BROKEN,
- "Failed to configure parser for " + value, e, null);
- return null;
- } catch (Exception e) {
- // this is an error and not warning since the file existence is checked before
- // attempting to parse it.
- Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
- "Failed to parse file " + value, e, null);
-
- return null;
- }
-
- try {
- int color = ResourceHelper.getColor(value);
- return ColorStateList.valueOf(color);
- } catch (NumberFormatException e) {
- Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, e.getMessage(), e, null);
- }
-
- return null;
+ return ResourceHelper.getComplexColor(mResourceData[index], mContext);
}
/**
diff --git a/bridge/src/android/content/res/ComplexColor_Accessor.java b/bridge/src/android/content/res/ComplexColor_Accessor.java
new file mode 100644
index 0000000..09c0260
--- /dev/null
+++ b/bridge/src/android/content/res/ComplexColor_Accessor.java
@@ -0,0 +1,46 @@
+/*
+ * 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.content.res;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.res.Resources.Theme;
+import android.util.AttributeSet;
+
+import java.io.IOException;
+
+/**
+ * Class that provides access to the {@link GradientColor#createFromXmlInner(Resources,
+ * XmlPullParser, AttributeSet, Theme)} and {@link ColorStateList#createFromXmlInner(Resources,
+ * XmlPullParser, AttributeSet, Theme)} methods
+ */
+public class ComplexColor_Accessor {
+ public static GradientColor createGradientColorFromXmlInner(@NonNull Resources r,
+ @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme)
+ throws IOException, XmlPullParserException {
+ return GradientColor.createFromXmlInner(r, parser, attrs, theme);
+ }
+
+ public static ColorStateList createColorStateListFromXmlInner(@NonNull Resources r,
+ @NonNull XmlPullParser parser, @NonNull AttributeSet attrs, @Nullable Theme theme)
+ throws IOException, XmlPullParserException {
+ return ColorStateList.createFromXmlInner(r, parser, attrs, theme);
+ }
+}
diff --git a/bridge/src/android/graphics/Paint_Delegate.java b/bridge/src/android/graphics/Paint_Delegate.java
index 839c182..33296e1 100644
--- a/bridge/src/android/graphics/Paint_Delegate.java
+++ b/bridge/src/android/graphics/Paint_Delegate.java
@@ -227,6 +227,10 @@
mColorFilter = ColorFilter_Delegate.getDelegate(colorFilterPtr);
}
+ public void setShader(long shaderPtr) {
+ mShader = Shader_Delegate.getDelegate(shaderPtr);
+ }
+
/**
* Returns the {@link Shader} delegate or null if none have been set
*
diff --git a/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java b/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_Delegate.java
new file mode 100644
index 0000000..200fe3b
--- /dev/null
+++ b/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}
+ * <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 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<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 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);
+ }
+
+ }
+}
diff --git a/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate.java b/bridge/src/android/graphics/drawable/AnimatedVectorDrawable_VectorDrawableAnimatorRT_Delegate.java
new file mode 100644
index 0000000..3d78931
--- /dev/null
+++ b/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/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java b/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
index eef8235..6e3aa40 100644
--- a/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
+++ b/bridge/src/android/graphics/drawable/VectorDrawable_Delegate.java
@@ -19,6 +19,7 @@
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;
@@ -44,6 +45,7 @@
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;
@@ -68,14 +70,6 @@
private static final DelegateManager<VNativeObject> sPathManager =
new DelegateManager<>(VNativeObject.class);
- private static <T> 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.
@@ -97,21 +91,21 @@
@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;
@@ -119,7 +113,7 @@
@LayoutlibDelegate
static float nGetRootAlpha(long rendererPtr) {
- VPathRenderer_Delegate nativePathRenderer = getDelegate(rendererPtr);
+ VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr);
return nativePathRenderer.getRootAlpha();
}
@@ -132,8 +126,7 @@
@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);
Canvas_Delegate.native_save(canvasWrapperPtr, MATRIX_SAVE_FLAG | CLIP_SAVE_FLAG);
Canvas_Delegate.native_translate(canvasWrapperPtr, bounds.left, bounds.top);
@@ -159,7 +152,7 @@
@LayoutlibDelegate
static long nCreateFullPath(long nativeFullPathPtr) {
- VFullPath_Delegate original = getDelegate(nativeFullPathPtr);
+ VFullPath_Delegate original = VNativeObject.getDelegate(nativeFullPathPtr);
return sPathManager.addNewDelegate(new VFullPath_Delegate(original));
}
@@ -167,7 +160,7 @@
@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());
@@ -194,7 +187,7 @@
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);
@@ -211,12 +204,16 @@
@LayoutlibDelegate
static void nUpdateFullPathFillGradient(long pathPtr, long fillGradientPtr) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+ path.setFillGradient(fillGradientPtr);
}
@LayoutlibDelegate
static void nUpdateFullPathStrokeGradient(long pathPtr, long strokeGradientPtr) {
+ VFullPath_Delegate path = getDelegate(pathPtr);
+ path.setStrokeGradient(strokeGradientPtr);
}
@LayoutlibDelegate
@@ -226,7 +223,7 @@
@LayoutlibDelegate
static long nCreateClipPath(long clipPathPtr) {
- VClipPath_Delegate original = getDelegate(clipPathPtr);
+ VClipPath_Delegate original = VNativeObject.getDelegate(clipPathPtr);
return sPathManager.addNewDelegate(new VClipPath_Delegate(original));
}
@@ -237,21 +234,21 @@
@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<String, Object>()));
}
@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);
@@ -268,7 +265,7 @@
@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);
@@ -281,13 +278,13 @@
@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));
}
@@ -300,187 +297,187 @@
// 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);
}
@@ -492,7 +489,16 @@
* not need it
* </ol>
*/
- private interface VNativeObject {
+ interface VNativeObject {
+ @NonNull
+ static <T> T getDelegate(long nativePtr) {
+ //noinspection unchecked
+ T vNativeObject = (T) sPathManager.getDelegate(nativePtr);
+
+ assert vNativeObject != null;
+ return vNativeObject;
+ }
+
void setName(String name);
}
@@ -511,7 +517,7 @@
}
}
- 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;
@@ -533,6 +539,38 @@
private static final int LINEJOIN_ROUND = 1;
private static final int LINEJOIN_BEVEL = 2;
+ @NonNull
+ public Consumer<Float> 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<Integer> 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.
@@ -540,6 +578,8 @@
float mStrokeWidth = 0;
int mFillColor = Color.TRANSPARENT;
+ long mStrokeGradient = 0;
+ long mFillGradient = 0;
float mStrokeAlpha = 1.0f;
float mFillAlpha = 1.0f;
float mTrimPathStart = 0;
@@ -569,6 +609,9 @@
mStrokeLineCap = copy.mStrokeLineCap;
mStrokeLineJoin = copy.mStrokeLineJoin;
mStrokeMiterlimit = copy.mStrokeMiterlimit;
+
+ mStrokeGradient = copy.mStrokeGradient;
+ mFillGradient = copy.mFillGradient;
}
private int getStrokeLineCap() {
@@ -637,7 +680,7 @@
return mStrokeColor;
}
- private void setStrokeColor(int strokeColor) {
+ private void setStrokeColor(int strokeColor) {
mStrokeColor = strokeColor;
}
@@ -704,9 +747,17 @@
private float getStrokeMiterlimit() {
return mStrokeMiterlimit;
}
+
+ private void setStrokeGradient(long gradientPtr) {
+ mStrokeGradient = gradientPtr;
+ }
+
+ private void setFillGradient(long gradientPtr) {
+ mFillGradient = gradientPtr;
+ }
}
- 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;
@@ -716,6 +767,28 @@
private static final int TRANSLATE_X_INDEX = 5;
private static final int TRANSLATE_Y_INDEX = 6;
+ public Consumer<Float> 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<Object> mChildren = new ArrayList<>();
@@ -914,7 +987,7 @@
}
}
- 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
@@ -950,7 +1023,7 @@
return mRootAlpha;
}
- private void setRootAlpha(float alpha) {
+ void setRootAlpha(float alpha) {
mRootAlpha = alpha;
}
@@ -1046,11 +1119,11 @@
final Paint fillPaint = mFillPaint;
fillPaint.setColor(applyAlpha(fullPath.mFillColor, fullPath.mFillAlpha));
Paint_Delegate fillPaintDelegate = Paint_Delegate.getDelegate(fillPaint
- .getNativeInstance
- ());
+ .getNativeInstance());
// mFillPaint can not be null at this point so we will have a delegate
assert fillPaintDelegate != null;
fillPaintDelegate.setColorFilter(filterPtr);
+ fillPaintDelegate.setShader(fullPath.mFillGradient);
Canvas_Delegate.native_drawPath(canvasPtr, mRenderPath.mNativePath, fillPaint
.getNativeInstance());
}
@@ -1080,6 +1153,7 @@
strokePaintDelegate.setColorFilter(filterPtr);
final float finalStrokeScale = minScale * matrixScale;
strokePaint.setStrokeWidth(fullPath.mStrokeWidth * finalStrokeScale);
+ strokePaintDelegate.setShader(fullPath.mStrokeGradient);
Canvas_Delegate.native_drawPath(canvasPtr, mRenderPath.mNativePath, strokePaint
.getNativeInstance());
}
diff --git a/bridge/src/com/android/internal/view/animation/NativeInterpolatorFactoryHelper_Delegate.java b/bridge/src/com/android/internal/view/animation/NativeInterpolatorFactoryHelper_Delegate.java
new file mode 100644
index 0000000..0f39e80
--- /dev/null
+++ b/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}
+ * <p>
+ * 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<Interpolator> 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/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
index c72eeb1..494b3d2 100644
--- a/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
+++ b/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
@@ -33,7 +33,11 @@
import org.xmlpull.v1.XmlPullParserException;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.res.ColorStateList;
+import android.content.res.ComplexColor;
+import android.content.res.ComplexColor_Accessor;
+import android.content.res.GradientColor;
import android.content.res.Resources.Theme;
import android.graphics.Bitmap;
import android.graphics.Bitmap_Delegate;
@@ -47,6 +51,7 @@
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
@@ -119,54 +124,128 @@
throw new NumberFormatException();
}
- public static ColorStateList getColorStateList(ResourceValue resValue, BridgeContext context) {
+ /**
+ * Returns a {@link ComplexColor} from the given {@link ResourceValue}
+ *
+ * @param resValue the value containing a color value or a file path to a complex color
+ * definition
+ * @param context the current context
+ * @param theme the theme to use when resolving the complex color
+ * @param allowGradients when false, only {@link ColorStateList} will be returned. If a {@link
+ * GradientColor} is found, null will be returned.
+ */
+ @Nullable
+ private static ComplexColor getInternalComplexColor(@NonNull ResourceValue resValue,
+ @NonNull BridgeContext context, @Nullable Theme theme, boolean allowGradients) {
String value = resValue.getValue();
- if (value != null && !RenderResources.REFERENCE_NULL.equals(value)) {
- // first check if the value is a file (xml most likely)
+ if (value == null || RenderResources.REFERENCE_NULL.equals(value)) {
+ return null;
+ }
+
+ // first check if the value is a file (xml most likely)
+ XmlPullParser parser = context.getLayoutlibCallback().getXmlFileParser(value);
+ if (parser == null) {
File f = new File(value);
if (f.isFile()) {
+ // let the framework inflate the color from the XML file, by
+ // providing an XmlPullParser
try {
- // let the framework inflate the ColorStateList from the XML file, by
- // providing an XmlPullParser
- XmlPullParser parser = ParserFactory.create(f);
-
- BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
- parser, context, resValue.isFramework());
- try {
- return ColorStateList.createFromXml(context.getResources(), blockParser);
- } finally {
- blockParser.ensurePopped();
- }
- } catch (XmlPullParserException e) {
- Bridge.getLog().error(LayoutLog.TAG_BROKEN,
- "Failed to configure parser for " + value, e, null /*data*/);
- // we'll return null below.
- } catch (Exception e) {
- // this is an error and not warning since the file existence is
- // checked before attempting to parse it.
+ parser = ParserFactory.create(f);
+ } catch (XmlPullParserException | FileNotFoundException e) {
Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
"Failed to parse file " + value, e, null /*data*/);
-
- return null;
- }
- } else {
- // try to load the color state list from an int
- try {
- int color = ResourceHelper.getColor(value);
- return ColorStateList.valueOf(color);
- } catch (NumberFormatException e) {
- Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
- "Failed to convert " + value + " into a ColorStateList", e,
- null /*data*/);
- return null;
}
}
}
+ if (parser != null) {
+ try {
+ BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
+ parser, context, resValue.isFramework());
+ try {
+ // Advance the parser to the first element so we can detect if it's a
+ // color list or a gradient color
+ int type;
+ //noinspection StatementWithEmptyBody
+ while ((type = blockParser.next()) != XmlPullParser.START_TAG
+ && type != XmlPullParser.END_DOCUMENT) {
+ // Seek parser to start tag.
+ }
+
+ if (type != XmlPullParser.START_TAG) {
+ throw new XmlPullParserException("No start tag found");
+ }
+
+ final String name = blockParser.getName();
+ if (allowGradients && "gradient".equals(name)) {
+ return ComplexColor_Accessor.createGradientColorFromXmlInner(
+ context.getResources(),
+ blockParser, blockParser,
+ theme);
+ } else if ("selector".equals(name)) {
+ return ComplexColor_Accessor.createColorStateListFromXmlInner(
+ context.getResources(),
+ blockParser, blockParser,
+ theme);
+ }
+ } finally {
+ blockParser.ensurePopped();
+ }
+ } catch (XmlPullParserException e) {
+ Bridge.getLog().error(LayoutLog.TAG_BROKEN,
+ "Failed to configure parser for " + value, e, null /*data*/);
+ // we'll return null below.
+ } catch (Exception e) {
+ // this is an error and not warning since the file existence is
+ // checked before attempting to parse it.
+ Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
+ "Failed to parse file " + value, e, null /*data*/);
+
+ return null;
+ }
+ } else {
+ // try to load the color state list from an int
+ try {
+ int color = getColor(value);
+ return ColorStateList.valueOf(color);
+ } catch (NumberFormatException e) {
+ Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
+ "Failed to convert " + value + " into a ColorStateList", e,
+ null /*data*/);
+ }
+ }
+
return null;
}
/**
+ * Returns a {@link ColorStateList} from the given {@link ResourceValue}
+ *
+ * @param resValue the value containing a color value or a file path to a complex color
+ * definition
+ * @param context the current context
+ */
+ @Nullable
+ public static ColorStateList getColorStateList(@NonNull ResourceValue resValue,
+ @NonNull BridgeContext context) {
+ return (ColorStateList) getInternalComplexColor(resValue, context, context.getTheme(),
+ false);
+ }
+
+ /**
+ * Returns a {@link ComplexColor} from the given {@link ResourceValue}
+ *
+ * @param resValue the value containing a color value or a file path to a complex color
+ * definition
+ * @param context the current context
+ */
+ @Nullable
+ public static ComplexColor getComplexColor(@NonNull ResourceValue resValue,
+ @NonNull BridgeContext context) {
+ return getInternalComplexColor(resValue, context, context.getTheme(), true);
+ }
+
+ /**
* Returns a drawable from the given value.
* @param value The value that contains a path to a 9 patch, a bitmap or a xml based drawable,
* or an hexadecimal color
diff --git a/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png b/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png
index 72b87ab..47cb042 100644
--- a/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png
+++ b/bridge/tests/res/testApp/MyApplication/golden/vector_drawable.png
Binary files differ
diff --git a/bridge/tests/res/testApp/MyApplication/src/main/res/color/gradient.xml b/bridge/tests/res/testApp/MyApplication/src/main/res/color/gradient.xml
new file mode 100644
index 0000000..fc0afa6
--- /dev/null
+++ b/bridge/tests/res/testApp/MyApplication/src/main/res/color/gradient.xml
@@ -0,0 +1,24 @@
+<!--
+ ~ 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.
+ -->
+
+
+<gradient xmlns:android="http://schemas.android.com/apk/res/android"
+ android:startX="10"
+ android:startY="10"
+ android:endX="50"
+ android:endY="50"
+ android:startColor="#ffff0000"
+ android:endColor="#ff00ff00" />
diff --git a/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/multi_path.xml b/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/multi_path.xml
index ffc70dc..5c19b08 100644
--- a/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/multi_path.xml
+++ b/bridge/tests/res/testApp/MyApplication/src/main/res/drawable/multi_path.xml
@@ -53,6 +53,16 @@
android:trimPathStart="0.2"
android:trimPathEnd="0.8"
/>
+
+ <!--
+ Draw a line with gradient stroke color
+ -->
+ <path
+ android:strokeWidth="1"
+ android:strokeColor="#FF00FF"
+ android:fillColor="@color/gradient"
+ android:pathData="M-20,-20 l0, 10 l10, 0 l0, -10 l-10,0 "
+ />
</group>
</vector>
\ No newline at end of file
diff --git a/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 3f12df5..bd37665 100644
--- a/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -189,6 +189,7 @@
"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",
@@ -294,6 +295,7 @@
"android.graphics.SweepGradient",
"android.graphics.Typeface",
"android.graphics.Xfermode",
+ "android.graphics.drawable.AnimatedVectorDrawable",
"android.graphics.drawable.VectorDrawable",
"android.os.SystemClock",
"android.os.SystemProperties",
@@ -301,6 +303,7 @@
"android.text.StaticLayout",
"android.util.PathParser",
"android.view.Display",
+ "com.android.internal.view.animation.NativeInterpolatorFactoryHelper",
"libcore.icu.ICU",
};