Merge "Fix Squiggly line inconsistency." into tm-qpr-dev am: 43c7da8e6e

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19951015

Change-Id: I2200683d207458dc6d7f376958d8e18ead50d06e
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Hawkwood Glazier
2022-09-16 17:36:47 +00:00
committed by Automerger Merge Worker

View File

@@ -60,6 +60,8 @@ class SquigglyProgress : Drawable() {
linePaint.strokeWidth = value linePaint.strokeWidth = value
} }
// Enables a transition region where the amplitude
// of the wave is reduced linearly across it.
var transitionEnabled = true var transitionEnabled = true
set(value) { set(value) {
field = value field = value
@@ -116,44 +118,40 @@ class SquigglyProgress : Drawable() {
} }
val progress = level / 10_000f val progress = level / 10_000f
val totalProgressPx = bounds.width() * progress val totalWidth = bounds.width().toFloat()
val waveProgressPx = bounds.width() * ( val totalProgressPx = totalWidth * progress
val waveProgressPx = totalWidth * (
if (!transitionEnabled || progress > matchedWaveEndpoint) progress else if (!transitionEnabled || progress > matchedWaveEndpoint) progress else
lerp(minWaveEndpoint, matchedWaveEndpoint, lerpInv(0f, matchedWaveEndpoint, progress))) lerp(minWaveEndpoint, matchedWaveEndpoint, lerpInv(0f, matchedWaveEndpoint, progress)))
// Build Wiggly Path // Build Wiggly Path
val waveStart = -phaseOffset val waveStart = -phaseOffset - waveLength / 2f
val waveEnd = waveProgressPx val waveEnd = if (transitionEnabled) totalWidth else waveProgressPx
val transitionLength = if (transitionEnabled) transitionPeriods * waveLength else 0.01f
// helper function, computes amplitude for wave segment // helper function, computes amplitude for wave segment
val computeAmplitude: (Float, Float) -> Float = { x, sign -> val computeAmplitude: (Float, Float) -> Float = { x, sign ->
sign * heightFraction * lineAmplitude * if (transitionEnabled) {
lerpInvSat(waveEnd, waveEnd - transitionLength, x) val length = transitionPeriods * waveLength
val coeff = lerpInvSat(
waveProgressPx + length / 2f,
waveProgressPx - length / 2f,
x)
sign * heightFraction * lineAmplitude * coeff
} else {
sign * heightFraction * lineAmplitude
}
} }
var currentX = waveEnd // Reset path object to the start
var waveSign = if (phaseOffset < waveLength / 2) 1f else -1f
path.rewind() path.rewind()
path.moveTo(waveStart, 0f)
// Draw flat line from end to wave endpoint // Build the wave, incrementing by half the wavelength each time
path.moveTo(bounds.width().toFloat(), 0f) var currentX = waveStart
path.lineTo(waveEnd, 0f) var waveSign = 1f
// First wave has shortened wavelength
// approx quarter wave gets us to first wave peak
// shouldn't be big enough to notice it's not a sin wave
currentX -= phaseOffset % (waveLength / 2)
val controlRatio = 0.25f
var currentAmp = computeAmplitude(currentX, waveSign) var currentAmp = computeAmplitude(currentX, waveSign)
path.cubicTo( val dist = waveLength / 2f
waveEnd, currentAmp * controlRatio, while (currentX < waveEnd) {
lerp(currentX, waveEnd, controlRatio), currentAmp,
currentX, currentAmp)
// Other waves have full wavelength
val dist = -1 * waveLength / 2f
while (currentX > waveStart) {
waveSign = -waveSign waveSign = -waveSign
val nextX = currentX + dist val nextX = currentX + dist
val midX = currentX + dist / 2 val midX = currentX + dist / 2
@@ -166,34 +164,35 @@ class SquigglyProgress : Drawable() {
currentX = nextX currentX = nextX
} }
// Draw path; clip to progress position // translate to the start position of the progress bar for all draw commands
val clipTop = lineAmplitude + strokeWidth
canvas.save() canvas.save()
canvas.translate(bounds.left.toFloat(), bounds.centerY().toFloat()) canvas.translate(bounds.left.toFloat(), bounds.centerY().toFloat())
canvas.clipRect(
0f, // Draw path up to progress position
-lineAmplitude - strokeWidth, canvas.save()
totalProgressPx, canvas.clipRect(0f, -1f * clipTop, totalProgressPx, clipTop)
lineAmplitude + strokeWidth)
canvas.drawPath(path, wavePaint) canvas.drawPath(path, wavePaint)
canvas.restore() canvas.restore()
// Draw path; clip between progression position & far edge if (transitionEnabled) {
canvas.save() // If there's a smooth transition, we draw the rest of the
canvas.translate(bounds.left.toFloat(), bounds.centerY().toFloat()) // path in a different color (using different clip params)
canvas.clipRect( canvas.save()
totalProgressPx, canvas.clipRect(totalProgressPx, -1f * clipTop, totalWidth, clipTop)
-lineAmplitude - strokeWidth, canvas.drawPath(path, linePaint)
bounds.width().toFloat(), canvas.restore()
lineAmplitude + strokeWidth) } else {
canvas.drawPath(path, linePaint) // No transition, just draw a flat line to the end of the region.
canvas.restore() // The discontinuity is hidden by the progress bar thumb shape.
canvas.drawLine(totalProgressPx, 0f, totalWidth, 0f, linePaint)
}
// Draw round line cap at the beginning of the wave // Draw round line cap at the beginning of the wave
val startAmp = cos(abs(waveEnd - phaseOffset) / waveLength * TWO_PI) val startAmp = cos(abs(waveStart) / waveLength * TWO_PI)
canvas.drawPoint( canvas.drawPoint(0f, startAmp * lineAmplitude * heightFraction, wavePaint)
bounds.left.toFloat(),
bounds.centerY() + startAmp * lineAmplitude * heightFraction, canvas.restore()
wavePaint)
} }
override fun getOpacity(): Int { override fun getOpacity(): Int {
@@ -233,4 +232,4 @@ class SquigglyProgress : Drawable() {
linePaint.color = ColorUtils.setAlphaComponent(tintColor, linePaint.color = ColorUtils.setAlphaComponent(tintColor,
(DISABLED_ALPHA * (alpha / 255f)).toInt()) (DISABLED_ALPHA * (alpha / 255f)).toInt())
} }
} }