91 lines
3.4 KiB
Kotlin
91 lines
3.4 KiB
Kotlin
/**
|
|
* @file StepCounterUiController.kt
|
|
* @brief Rendering for the live step-counter card and hold-to-reset gesture indicator.
|
|
*/
|
|
package com.example.jnicpp.bowling
|
|
|
|
import android.content.Context
|
|
import android.view.View
|
|
import android.widget.TextView
|
|
import com.example.jnicpp.R
|
|
import com.google.android.material.progressindicator.CircularProgressIndicator
|
|
|
|
/**
|
|
* @brief Owns rendering for [BowlingCameraActivity]'s step-counter card and
|
|
* hold-to-reset gesture indicator, so the Activity's job stays
|
|
* limited to wiring [CameraViewModel] state into this controller
|
|
* rather than holding view-rendering logic itself.
|
|
*
|
|
* @param context Used only for string resource lookups.
|
|
* @param cardStepCounter The step-counter card container view.
|
|
* @param textStepCountBig The large step-count number TextView.
|
|
* @param layoutResetHint The hold-to-reset hint row container view.
|
|
* @param progressHandRaise The circular hold-progress indicator.
|
|
* @param textResetHint The hold-to-reset hint text.
|
|
*/
|
|
class StepCounterUiController(
|
|
private val context: Context,
|
|
private val cardStepCounter: View,
|
|
private val textStepCountBig: TextView,
|
|
private val layoutResetHint: View,
|
|
private val progressHandRaise: CircularProgressIndicator,
|
|
private val textResetHint: TextView
|
|
) {
|
|
// Last step count rendered, so pulse() in renderStepCount only plays
|
|
// when a new step actually pushed the count up, not on every
|
|
// stepEvents emission -- a reset back to zero shouldn't visually "pop".
|
|
private var lastRenderedStepCount = 0
|
|
|
|
/**
|
|
* @brief Shows or hides the step counter and reset-hint views together.
|
|
* @param visible true to reveal both (recording in progress), false to hide them.
|
|
*/
|
|
fun setVisible(visible: Boolean) {
|
|
val visibility = if (visible) View.VISIBLE else View.GONE
|
|
cardStepCounter.visibility = visibility
|
|
layoutResetHint.visibility = visibility
|
|
}
|
|
|
|
/** @brief Clears pulse-tracking state; call whenever a new recording starts. */
|
|
fun resetTracking() {
|
|
lastRenderedStepCount = 0
|
|
}
|
|
|
|
/**
|
|
* @brief Renders the current step count, pulsing the card if a new step was just confirmed.
|
|
* @param stepCount Total steps counted so far in the current attempt.
|
|
*/
|
|
fun renderStepCount(stepCount: Int) {
|
|
textStepCountBig.text = stepCount.toString()
|
|
if (stepCount > lastRenderedStepCount) {
|
|
pulse()
|
|
}
|
|
lastRenderedStepCount = stepCount
|
|
}
|
|
|
|
/**
|
|
* @brief Reflects the hold-to-reset gesture's progress onto the
|
|
* circular indicator and hint text.
|
|
* @param progress Current hold progress, from 0 (not raised) to 1 (reset just fired).
|
|
*/
|
|
fun renderHandRaiseProgress(progress: Float) {
|
|
progressHandRaise.progress = (progress * 100).toInt()
|
|
textResetHint.text = if (progress <= 0f) {
|
|
context.getString(R.string.reset_hint_idle)
|
|
} else {
|
|
context.getString(R.string.reset_hint_holding, (progress * 100).toInt())
|
|
}
|
|
}
|
|
|
|
/** @brief Briefly scales the step counter up and back down, drawing the eye to a newly confirmed step. */
|
|
private fun pulse() {
|
|
cardStepCounter.animate()
|
|
.scaleX(1.15f).scaleY(1.15f)
|
|
.setDuration(80)
|
|
.withEndAction {
|
|
cardStepCounter.animate().scaleX(1f).scaleY(1f).setDuration(120).start()
|
|
}
|
|
.start()
|
|
}
|
|
}
|