Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d973f9da authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Use standard touch path for drawable state" into rvc-dev am: e7794e69 am: 5e884e3f

Change-Id: I25a0ab61761fb6a60c5870928daf36ba28966fe0
parents 0077c40c 5e884e3f
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -16,7 +16,5 @@
  -->
<com.android.systemui.media.IlluminationDrawable
    xmlns:systemui="http://schemas.android.com/apk/res-auto"
    systemui:rippleMinSize="30dp"
    systemui:rippleMaxSize="135dp"
    systemui:highlight="15"
    systemui:cornerRadius="?android:attr/dialogCornerRadius" />
 No newline at end of file
+20 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2020 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.
  -->
<com.android.systemui.media.LightSourceDrawable
    xmlns:systemui="http://schemas.android.com/apk/res-auto"
    systemui:rippleMinSize="25dp"
    systemui:rippleMaxSize="135dp" />
 No newline at end of file
+2 −1
Original line number Diff line number Diff line
@@ -94,7 +94,8 @@
        android:id="@+id/media_seamless"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="@*android:drawable/media_seamless_background"
        android:foreground="@*android:drawable/media_seamless_background"
        android:background="@drawable/qs_media_light_source"
        android:orientation="horizontal"
        android:forceHasOverlappingRendering="false"
        android:paddingLeft="12dp"
+1 −1
Original line number Diff line number Diff line
@@ -623,7 +623,7 @@
    </style>

    <style name="MediaPlayer.Button" parent="@android:style/Widget.Material.Button.Borderless.Small">
        <item name="android:background">@null</item>
        <item name="android:background">@drawable/qs_media_light_source</item>
        <item name="android:tint">@android:color/white</item>
        <item name="android:stateListAnimator">@anim/media_button_state_list_animator</item>
    </style>
+33 −148
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.systemui.media

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
import android.animation.ValueAnimator
import android.content.res.ColorStateList
import android.content.res.Resources
@@ -10,16 +25,12 @@ import android.content.res.TypedArray
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.ColorFilter
import android.graphics.Outline
import android.graphics.Paint
import android.graphics.PixelFormat
import android.graphics.RadialGradient
import android.graphics.Rect
import android.graphics.Shader
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.util.MathUtils
import android.util.MathUtils.lerp
import android.view.MotionEvent
import android.view.View
import androidx.annotation.Keep
import com.android.internal.graphics.ColorUtils
@@ -29,20 +40,6 @@ import com.android.systemui.R
import org.xmlpull.v1.XmlPullParser

private const val BACKGROUND_ANIM_DURATION = 370L
private const val RIPPLE_ANIM_DURATION = 800L
private const val RIPPLE_DOWN_PROGRESS = 0.05f
private const val RIPPLE_CANCEL_DURATION = 200L
private val GRADIENT_STOPS = floatArrayOf(0.2f, 1f)

private data class RippleData(
    var x: Float,
    var y: Float,
    var alpha: Float,
    var progress: Float,
    var minSize: Float,
    var maxSize: Float,
    var highlight: Float
)

/**
 * Drawable that can draw an animated gradient when tapped.
@@ -53,9 +50,10 @@ class IlluminationDrawable : Drawable() {
    private var themeAttrs: IntArray? = null
    private var cornerRadius = 0f
    private var highlightColor = Color.TRANSPARENT
    private val rippleData = RippleData(0f, 0f, 0f, 0f, 0f, 0f, 0f)
    private var tmpHsl = floatArrayOf(0f, 0f, 0f)
    private var paint = Paint()
    private var highlight = 0f
    private val lightSources = arrayListOf<LightSourceDrawable>()

    private var backgroundColor = Color.TRANSPARENT
    set(value) {
@@ -66,70 +64,20 @@ class IlluminationDrawable : Drawable() {
        animateBackground()
    }

    /**
     * Draw a small highlight under the finger before expanding (or cancelling) it.
     */
    private var pressed: Boolean = false
        set(value) {
            if (value == field) {
                return
            }
            field = value

            if (value) {
                rippleAnimation?.cancel()
                rippleData.alpha = 1f
                rippleData.progress = RIPPLE_DOWN_PROGRESS
            } else {
                rippleAnimation?.cancel()
                rippleAnimation = ValueAnimator.ofFloat(rippleData.alpha, 0f).apply {
                    duration = RIPPLE_CANCEL_DURATION
                    interpolator = Interpolators.LINEAR_OUT_SLOW_IN
                    addUpdateListener {
                        rippleData.alpha = it.animatedValue as Float
                        invalidateSelf()
                    }
                    addListener(object : AnimatorListenerAdapter() {
                        var cancelled = false
                        override fun onAnimationCancel(animation: Animator?) {
                            cancelled = true;
                        }

                        override fun onAnimationEnd(animation: Animator?) {
                            if (cancelled) {
                                return
                            }
                            rippleData.progress = 0f
                            rippleData.alpha = 0f
                            rippleAnimation = null
                            invalidateSelf()
                        }
                    })
                    start()
                }
            }
            invalidateSelf()
        }

    private var rippleAnimation: Animator? = null
    private var backgroundAnimation: ValueAnimator? = null

    /**
     * Draw background and gradient.
     */
    override fun draw(canvas: Canvas) {
        paint.shader = if (rippleData.progress > 0) {
            val radius = lerp(rippleData.minSize, rippleData.maxSize, rippleData.progress)
            val centerColor = blendARGB(paint.color, highlightColor, rippleData.alpha)
            RadialGradient(rippleData.x, rippleData.y, radius, intArrayOf(centerColor, paint.color),
                    GRADIENT_STOPS, Shader.TileMode.CLAMP)
        } else {
            null
        }
        canvas.drawRoundRect(0f, 0f, bounds.width().toFloat(), bounds.height().toFloat(),
                cornerRadius, cornerRadius, paint)
    }

    override fun getOutline(outline: Outline) {
        outline.setRoundRect(bounds, cornerRadius)
    }

    override fun getOpacity(): Int {
        return PixelFormat.TRANSPARENT
    }
@@ -151,14 +99,8 @@ class IlluminationDrawable : Drawable() {
            cornerRadius = a.getDimension(R.styleable.IlluminationDrawable_cornerRadius,
                    cornerRadius)
        }
        if (a.hasValue(R.styleable.IlluminationDrawable_rippleMinSize)) {
            rippleData.minSize = a.getDimension(R.styleable.IlluminationDrawable_rippleMinSize, 0f)
        }
        if (a.hasValue(R.styleable.IlluminationDrawable_rippleMaxSize)) {
            rippleData.maxSize = a.getDimension(R.styleable.IlluminationDrawable_rippleMaxSize, 0f)
        }
        if (a.hasValue(R.styleable.IlluminationDrawable_highlight)) {
            rippleData.highlight = a.getInteger(R.styleable.IlluminationDrawable_highlight, 0) /
            highlight = a.getInteger(R.styleable.IlluminationDrawable_highlight, 0) /
                    100f
        }
    }
@@ -192,10 +134,10 @@ class IlluminationDrawable : Drawable() {
    private fun animateBackground() {
        ColorUtils.colorToHSL(backgroundColor, tmpHsl)
        val L = tmpHsl[2]
        tmpHsl[2] = MathUtils.constrain(if (L < 1f - rippleData.highlight) {
            L + rippleData.highlight
        tmpHsl[2] = MathUtils.constrain(if (L < 1f - highlight) {
            L + highlight
        } else {
            L - rippleData.highlight
            L - highlight
        }, 0f, 1f)

        val initialBackground = paint.color
@@ -210,6 +152,7 @@ class IlluminationDrawable : Drawable() {
                val progress = it.animatedValue as Float
                paint.color = blendARGB(initialBackground, backgroundColor, progress)
                highlightColor = blendARGB(initialHighlight, finalHighlight, progress)
                lightSources.forEach { it.highlightColor = highlightColor }
                invalidateSelf()
            }
            addListener(object : AnimatorListenerAdapter() {
@@ -226,69 +169,11 @@ class IlluminationDrawable : Drawable() {
        backgroundColor = tint!!.defaultColor
    }

    /**
     * Draws an animated ripple that expands fading away.
     */
    private fun illuminate() {
        rippleData.alpha = 1f
        invalidateSelf()

        rippleAnimation?.cancel()
        rippleAnimation = AnimatorSet().apply {
            playTogether(ValueAnimator.ofFloat(1f, 0f).apply {
                startDelay = 133
                duration = RIPPLE_ANIM_DURATION - startDelay
                interpolator = Interpolators.LINEAR_OUT_SLOW_IN
                addUpdateListener {
                    rippleData.alpha = it.animatedValue as Float
                    invalidateSelf()
                }
            }, ValueAnimator.ofFloat(rippleData.progress, 1f).apply {
                duration = RIPPLE_ANIM_DURATION
                interpolator = Interpolators.LINEAR_OUT_SLOW_IN
                addUpdateListener {
                    rippleData.progress = it.animatedValue as Float
                    invalidateSelf()
                }
            })
            addListener(object : AnimatorListenerAdapter() {
                override fun onAnimationEnd(animation: Animator?) {
                    rippleData.progress = 0f
                    rippleAnimation = null
                    invalidateSelf()
                }
            })
            start()
        }
    }

    /**
     * Setup touch events on a view such as tapping it would trigger effects on this drawable.
     * @param target View receiving touched.
     * @param container View that holds this drawable.
     */
    fun setupTouch(target: View, container: View) {
        val containerRect = Rect()
        target.setOnTouchListener { view: View, event: MotionEvent ->
            container.getGlobalVisibleRect(containerRect)
            rippleData.x = event.rawX - containerRect.left
            rippleData.y = event.rawY - containerRect.top

            when (event.action) {
                MotionEvent.ACTION_DOWN -> {
                    pressed = true
                }
                MotionEvent.ACTION_MOVE -> {
                    invalidateSelf()
                }
                MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                    pressed = false
                    if (event.action == MotionEvent.ACTION_UP) {
                        illuminate()
                    }
                }
            }
            false
    fun registerLightSource(lightSource: View) {
        if (lightSource.background is LightSourceDrawable) {
            lightSources.add(lightSource.background as LightSourceDrawable)
        } else if (lightSource.foreground is LightSourceDrawable) {
            lightSources.add(lightSource.foreground as LightSourceDrawable)
        }
    }
}
 No newline at end of file
Loading