Merge "Make sparkle color and alpha customizable" into sc-dev

This commit is contained in:
Lucas Dupin
2021-04-19 21:32:28 +00:00
committed by Android (Google) Code Review
10 changed files with 61 additions and 60 deletions

View File

@@ -592,6 +592,7 @@ package android {
field public static final int editTextStyle = 16842862; // 0x101006e
field @Deprecated public static final int editable = 16843115; // 0x101016b
field public static final int editorExtras = 16843300; // 0x1010224
field public static final int effectColor;
field public static final int elegantTextHeight = 16843869; // 0x101045d
field public static final int elevation = 16843840; // 0x1010440
field public static final int ellipsize = 16842923; // 0x10100ab
@@ -16791,8 +16792,10 @@ package android.graphics.drawable {
public class RippleDrawable extends android.graphics.drawable.LayerDrawable {
ctor public RippleDrawable(@NonNull android.content.res.ColorStateList, @Nullable android.graphics.drawable.Drawable, @Nullable android.graphics.drawable.Drawable);
method @NonNull public android.content.res.ColorStateList getEffectColor();
method public int getRadius();
method public void setColor(android.content.res.ColorStateList);
method public void setColor(@NonNull android.content.res.ColorStateList);
method public void setEffectColor(@NonNull android.content.res.ColorStateList);
method public void setRadius(int);
field public static final int RADIUS_AUTO = -1; // 0xffffffff
}

View File

@@ -15,8 +15,7 @@
-->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight"
android:rippleStyle="?attr/rippleStyle">
android:color="?attr/colorControlHighlight">
<item android:id="@id/mask"
android:drawable="@drawable/btn_default_mtrl_shape" />
</ripple>

View File

@@ -19,8 +19,7 @@
android:insetTop="@dimen/button_inset_vertical_material"
android:insetRight="@dimen/button_inset_horizontal_material"
android:insetBottom="@dimen/button_inset_vertical_material">
<ripple android:color="?attr/colorControlHighlight"
android:rippleStyle="?attr/rippleStyle">
<ripple android:color="?attr/colorControlHighlight">
<item>
<shape android:shape="rectangle"
android:tint="@color/btn_colored_background_material">

View File

@@ -15,7 +15,6 @@
-->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="?attr/colorControlHighlight"
android:rippleStyle="?attr/rippleStyle">
android:color="?attr/colorControlHighlight">
<item android:drawable="@drawable/btn_default_mtrl_shape" />
</ripple>

View File

@@ -21,8 +21,7 @@
android:insetBottom="@dimen/button_inset_vertical_material">
<layer-list android:paddingMode="stack">
<item>
<ripple android:color="?attr/colorControlHighlight"
android:rippleStyle="?attr/rippleStyle">
<ripple android:color="?attr/colorControlHighlight">
<item>
<shape android:shape="rectangle"
android:tint="?attr/colorButtonNormal">

View File

@@ -1176,6 +1176,9 @@
<!-- Alternative color applied to surfaces on top of colorBackground. @hide -->
<attr name="colorSurfaceHeader" format="color" />
<!-- Color applied to effects. -->
<attr name="effectColor" format="color" />
<!-- The type of the edge effect. The default is glow. -->
<attr name="edgeEffectType">
<!-- Use a colored glow at the edge. -->
@@ -6540,13 +6543,8 @@
<!-- The radius of the ripple when fully expanded. By default, the
radius is computed based on the size of the ripple's container. -->
<attr name="radius" />
<!-- The style of the ripple drawable is solid by default -->
<attr name="rippleStyle">
<!-- Solid is the default style -->
<enum name="solid" value="0" />
<!-- Patterned style-->
<enum name="patterned" value="1" />
</attr>
<!-- Secondary color of the ripple effect. -->
<attr name="effectColor" />
</declare-styleable>
<declare-styleable name="ScaleDrawable">

View File

@@ -3099,6 +3099,7 @@
<!-- @hide @SystemApi -->
<public name="throttleDurationMillis" />
<public name="showInInputMethodPicker" />
<public name="effectColor" />
</staging-public-group>
<staging-public-group type="drawable" first-id="0x010800b5">

View File

@@ -234,9 +234,6 @@ easier.
<item name="textColorTertiary">@color/text_color_tertiary_device_default_dark</item>
<item name="colorForeground">@color/foreground_device_default_dark</item>
<item name="colorForegroundInverse">@color/foreground_device_default_light</item>
<!-- Ripple style-->
<item name="rippleStyle">solid</item>
</style>
<style name="Theme.DeviceDefault" parent="Theme.DeviceDefaultBase" />

View File

@@ -150,6 +150,7 @@ public class RippleDrawable extends LayerDrawable {
/** The maximum number of ripples supported. */
private static final int MAX_RIPPLES = 10;
private static final LinearInterpolator LINEAR_INTERPOLATOR = new LinearInterpolator();
private static final int DEFAULT_EFFECT_COLOR = 0x80ffffff;
/** Temporary flag for teamfood. **/
private static final boolean FORCE_PATTERNED_STYLE = true;
@@ -465,11 +466,36 @@ public class RippleDrawable extends LayerDrawable {
*
* @attr ref android.R.styleable#RippleDrawable_color
*/
public void setColor(ColorStateList color) {
public void setColor(@NonNull ColorStateList color) {
if (color == null) {
throw new IllegalArgumentException("color cannot be null");
}
mState.mColor = color;
invalidateSelf(false);
}
/**
* Sets the ripple effect color.
*
* @param color Ripple color as a color state list.
*
* @attr ref android.R.styleable#RippleDrawable_effectColor
*/
public void setEffectColor(@NonNull ColorStateList color) {
if (color == null) {
throw new IllegalArgumentException("color cannot be null");
}
mState.mEffectColor = color;
invalidateSelf(false);
}
/**
* @return The ripple effect color as a color state list.
*/
public @NonNull ColorStateList getEffectColor() {
return mState.mEffectColor;
}
/**
* Sets the radius in pixels of the fully expanded ripple.
*
@@ -561,13 +587,14 @@ public class RippleDrawable extends LayerDrawable {
mState.mColor = color;
}
final ColorStateList effectColor =
a.getColorStateList(R.styleable.RippleDrawable_effectColor);
if (effectColor != null) {
mState.mEffectColor = effectColor;
}
mState.mMaxRadius = a.getDimensionPixelSize(
R.styleable.RippleDrawable_radius, mState.mMaxRadius);
if (!FORCE_PATTERNED_STYLE) {
mState.mRippleStyle = a.getInteger(R.styleable.RippleDrawable_rippleStyle,
mState.mRippleStyle);
}
}
private void verifyRequiredAttributes(@NonNull TypedArray a) throws XmlPullParserException {
@@ -933,10 +960,11 @@ public class RippleDrawable extends LayerDrawable {
float radius = getComputedRadius();
RippleAnimationSession.AnimationProperties<Float, Paint> properties;
RippleShader shader = new RippleShader();
int color = mMaskColorFilter == null
final int color = mMaskColorFilter == null
? mState.mColor.getColorForState(getState(), Color.BLACK)
: mMaskColorFilter.getColor();
shader.setColor(color);
final int effectColor = mState.mEffectColor.getColorForState(getState(), Color.MAGENTA);
shader.setColor(color, effectColor);
shader.setOrigin(cx, cy);
shader.setTouch(x, y);
shader.setResolution(w, h, mState.mDensity);
@@ -1257,33 +1285,6 @@ public class RippleDrawable extends LayerDrawable {
return this;
}
/**
* Sets the visual style of the ripple.
*
* @see #STYLE_SOLID
* @see #STYLE_PATTERNED
*
* @param style The style of the ripple
* @hide
*/
public void setRippleStyle(@RippleStyle int style) throws IllegalArgumentException {
if (style == STYLE_SOLID || style == STYLE_PATTERNED) {
mState.mRippleStyle = style;
} else {
throw new IllegalArgumentException("Invalid style value " + style);
}
}
/**
* Get the current ripple style
* @return Ripple style
* @hide
*/
public @RippleStyle int getRippleStyle() {
return mState.mRippleStyle;
}
@Override
RippleState createConstantState(LayerState state, Resources res) {
return new RippleState(state, this, res);
@@ -1293,6 +1294,7 @@ public class RippleDrawable extends LayerDrawable {
int[] mTouchThemeAttrs;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
ColorStateList mColor = ColorStateList.valueOf(Color.MAGENTA);
ColorStateList mEffectColor = ColorStateList.valueOf(DEFAULT_EFFECT_COLOR);
int mMaxRadius = RADIUS_AUTO;
int mRippleStyle = FORCE_PATTERNED_STYLE ? STYLE_PATTERNED : STYLE_SOLID;
@@ -1305,6 +1307,7 @@ public class RippleDrawable extends LayerDrawable {
mColor = origs.mColor;
mMaxRadius = origs.mMaxRadius;
mRippleStyle = origs.mRippleStyle;
mEffectColor = origs.mEffectColor;
if (origs.mDensity != mDensity) {
applyDensityScaling(orig.mDensity, mDensity);

View File

@@ -39,6 +39,7 @@ final class RippleShader extends RuntimeShader {
+ "uniform vec2 in_tRotation2;\n"
+ "uniform vec2 in_tRotation3;\n"
+ "uniform vec4 in_color;\n"
+ "uniform vec4 in_sparkleColor;\n"
+ "uniform shader in_shader;\n";
private static final String SHADER_LIB =
"float triangleNoise(vec2 n) {\n"
@@ -48,7 +49,6 @@ final class RippleShader extends RuntimeShader {
+ " return fract(xy * 95.4307) + fract(xy * 75.04961) - 1.0;\n"
+ "}"
+ "const float PI = 3.1415926535897932384626;\n"
+ "const float SPARKLE_OPACITY = 0.75;\n"
+ "\n"
+ "float sparkles(vec2 uv, float t) {\n"
+ " float n = triangleNoise(uv);\n"
@@ -60,7 +60,7 @@ final class RippleShader extends RuntimeShader {
+ " o *= abs(sin(PI * o * (t + 0.55 * i)));\n"
+ " s += o;\n"
+ " }\n"
+ " return saturate(s) * SPARKLE_OPACITY;\n"
+ " return saturate(s) * in_sparkleColor.a;\n"
+ "}\n"
+ "float softCircle(vec2 uv, vec2 xy, float radius, float blur) {\n"
+ " float blurHalf = blur * 0.5;\n"
@@ -116,7 +116,7 @@ final class RippleShader extends RuntimeShader {
+ " vec4 circle = in_color * (softCircle(p, center, in_maxRadius "
+ " * scaleIn, 0.2) * fade);\n"
+ " float mask = in_hasMask == 1. ? sample(in_shader).a > 0. ? 1. : 0. : 1.;\n"
+ " return mix(circle, vec4(sparkle), sparkle) * mask;\n"
+ " return mix(circle, in_sparkleColor, sparkle) * mask;\n"
+ "}";
private static final String SHADER = SHADER_UNIFORMS + SHADER_LIB + SHADER_MAIN;
private static final double PI_ROTATE_RIGHT = Math.PI * 0.0078125;
@@ -200,10 +200,13 @@ final class RippleShader extends RuntimeShader {
/**
* Color of the circle that's under the sparkles. Sparkles will always be white.
*/
public void setColor(@ColorInt int colorIn) {
Color color = Color.valueOf(colorIn);
this.setUniform("in_color", new float[] {color.red(),
public void setColor(@ColorInt int colorInt, @ColorInt int sparkleColorInt) {
Color color = Color.valueOf(colorInt);
Color sparkleColor = Color.valueOf(sparkleColorInt);
setUniform("in_color", new float[] {color.red(),
color.green(), color.blue(), color.alpha()});
setUniform("in_sparkleColor", new float[] {sparkleColor.red(),
sparkleColor.green(), sparkleColor.blue(), sparkleColor.alpha()});
}
public void setResolution(float w, float h, int density) {