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

Commit e3c16460 authored by Hawkwood's avatar Hawkwood
Browse files

Precompute clock view max size, and provide to sysui for layout

Some lockscreen layout decisions (like smartspace date/weather to the
right of the small clock) will be better served by knowing the maximum
size the clock could be at any time, than it's current size since that
can change depending on the current time. This provides that so that
we can make those decisions consistently for a given clock.

Bug: 428993607
Test: Manually checked clock layout
Flag: com.android.systemui.shared.clock_reactive_variants
Change-Id: I9a49425db6a2db689b8c9dff91367113c2860108
parent 3fc01416
Loading
Loading
Loading
Loading
+37 −13
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import com.android.systemui.plugins.clocks.ClockAxisStyle
import com.android.systemui.plugins.clocks.ClockViewIds
import com.android.systemui.plugins.clocks.VPoint
import com.android.systemui.plugins.clocks.VPointF
import com.android.systemui.plugins.clocks.VPointF.Companion.max
import com.android.systemui.plugins.clocks.VPointF.Companion.size
import com.android.systemui.plugins.clocks.VRectF
import com.android.systemui.shared.Flags.ambientAod
@@ -107,11 +108,13 @@ abstract class DigitalClockTextView(
    }

    var onViewBoundsChanged: ((VRectF) -> Unit)? = null
    var maxSingleDigitHeight = -1f
    var maxSingleDigitWidth = -1f
    var onViewMaxSizeChanged: ((VPointF) -> Unit)? = null
    var digitTranslateAnimator: DigitTranslateAnimator? = null
    var aodFontSizePx = -1f

    var maxSingleDigitSize = VPointF(-1f)
        private set

    // Store the font size when there's no height constraint as a reference when adjusting font size
    private var lastUnconstrainedTextSize = Float.MAX_VALUE
    // Calculated by height of styled text view / text size
@@ -120,6 +123,10 @@ abstract class DigitalClockTextView(

    private val initThread = Thread.currentThread()

    // Maximum size this view will be at any time, but in its current rendering configuration
    var maxSize = VPointF(-1f)
        private set

    // textBounds is the size of text in LS, which only measures current text in lockscreen style
    var textBounds = VRectF.ZERO
    // prevTextBounds and targetTextBounds are to deal with dozing animation between LS and AOD
@@ -212,7 +219,7 @@ abstract class DigitalClockTextView(
        )

        measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
        recomputeMaxSingleDigitSizes()
        recomputeMaxTextSize()
        requestLayout()
        invalidate()
    }
@@ -552,7 +559,7 @@ abstract class DigitalClockTextView(
        lockScreenPaint.strokeWidth = textBorderWidth
        measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
        setInterpolatorPaint()
        recomputeMaxSingleDigitSizes()
        recomputeMaxTextSize()
        invalidate()
    }

@@ -567,30 +574,47 @@ abstract class DigitalClockTextView(
            lockScreenPaint.textSize = textSize
            updateTextBounds()
        }

        if (!constrainedByHeight) {
            val lastUnconstrainedHeight = textBounds.height + lockScreenPaint.strokeWidth * 2
            fontSizeAdjustFactor = lastUnconstrainedHeight / lastUnconstrainedTextSize
        }

        lockScreenPaint.strokeWidth = textBorderWidth
        recomputeMaxSingleDigitSizes()
        recomputeMaxTextSize()

        if (this::textAnimator.isInitialized) {
            textAnimator.setTextStyle(TextAnimator.Style(textSize = lockScreenPaint.textSize))
        }
    }

    private fun recomputeMaxSingleDigitSizes() {
        maxSingleDigitHeight = 0f
        maxSingleDigitWidth = 0f
    /** Measures a maximal piece of text so that layout decisions can be consistent. */
    private fun recomputeMaxTextSize() {
        maxSingleDigitSize = VPointF(-1)

        for (i in 0..9) {
            val rectForCalculate = lockScreenPaint.getTextBounds("$i")
            maxSingleDigitHeight = max(maxSingleDigitHeight, rectForCalculate.height)
            maxSingleDigitWidth = max(maxSingleDigitWidth, rectForCalculate.width)
        }
        maxSingleDigitWidth += 2 * lockScreenPaint.strokeWidth
        maxSingleDigitHeight += 2 * lockScreenPaint.strokeWidth
            val digitBounds = lockScreenPaint.getTextBounds("$i")
            maxSingleDigitSize = max(maxSingleDigitSize, digitBounds.size)
        }
        maxSingleDigitSize += 2 * lockScreenPaint.strokeWidth

        maxSize =
            when (id) {
                // Single digit values have already been computed
                ClockViewIds.HOUR_FIRST_DIGIT,
                ClockViewIds.HOUR_SECOND_DIGIT,
                ClockViewIds.MINUTE_FIRST_DIGIT,
                ClockViewIds.MINUTE_SECOND_DIGIT -> maxSingleDigitSize
                // Digit pairs should measure 00 as 88 is not a valid hour or minute pair
                ClockViewIds.HOUR_DIGIT_PAIR,
                ClockViewIds.MINUTE_DIGIT_PAIR -> lockScreenPaint.getTextBounds("00").size
                // Full format includes the colon. This overmeasures a bit for 12hr configurations.
                ClockViewIds.TIME_FULL_FORMAT -> lockScreenPaint.getTextBounds("00:00").size
                // DATE_FORMAT is difficult, and shouldn't be necessary
                else -> VPointF(-1)
            }

        onViewMaxSizeChanged?.let { it(maxSize) }
    }

    /** Called without animation, can be used to set the initial state of animator */
+4 −1
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import com.android.systemui.plugins.clocks.ClockPickerConfig
import com.android.systemui.plugins.clocks.ClockProvider
import com.android.systemui.plugins.clocks.ClockProviderPlugin
import com.android.systemui.plugins.clocks.ClockSettings
import com.android.systemui.plugins.clocks.VPointF
import com.android.systemui.plugins.clocks.VRectF
import com.android.systemui.util.ThreadAssert
import java.io.PrintWriter
@@ -313,7 +314,9 @@ open class ClockRegistry(
        val onComplete = endChangeTrace?.also { endChangeTrace = null } ?: return
        clock.eventListeners.attach(
            object : ClockEventListener {
                override fun onBoundsChanged(bounds: VRectF) {}
                override fun onBoundsChanged(current: VRectF) {}

                override fun onMaxSizeChanged(maxSize: VPointF, isLargeClock: Boolean) {}

                override fun onChangeComplete() = onComplete()
            }
+6 −0
Original line number Diff line number Diff line
@@ -113,6 +113,9 @@ class FlexClockController(
    override fun initialize(isDarkTheme: Boolean, dozeFraction: Float, foldFraction: Float) {
        smallClock.run {
            layerController.onViewBoundsChanged = { eventListeners.fire { onBoundsChanged(it) } }
            layerController.onViewMaxSizeChanged = {
                eventListeners.fire { onMaxSizeChanged(it, isLargeClock = false) }
            }
            events.onThemeChanged(theme.copy(isDarkTheme = isDarkTheme))
            animations.onFontAxesChanged(clockCtx.settings.axes)
            animations.doze(dozeFraction)
@@ -122,6 +125,9 @@ class FlexClockController(

        largeClock.run {
            layerController.onViewBoundsChanged = { eventListeners.fire { onBoundsChanged(it) } }
            layerController.onViewMaxSizeChanged = {
                eventListeners.fire { onMaxSizeChanged(it, isLargeClock = true) }
            }
            events.onThemeChanged(theme.copy(isDarkTheme = isDarkTheme))
            animations.onFontAxesChanged(clockCtx.settings.axes)
            animations.doze(dozeFraction)
+2 −0
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import com.android.systemui.plugins.clocks.ClockPositionAnimationArgs
import com.android.systemui.plugins.clocks.ClockViewIds
import com.android.systemui.plugins.clocks.ThemeConfig
import com.android.systemui.plugins.clocks.TimeFormatKind
import com.android.systemui.plugins.clocks.VPointF
import com.android.systemui.plugins.clocks.VRectF
import com.android.systemui.plugins.clocks.WeatherData
import com.android.systemui.plugins.clocks.ZenData
@@ -66,6 +67,7 @@ interface FlexClockViewController {
    val config: ClockFaceConfig

    var onViewBoundsChanged: ((VRectF) -> Unit)?
    var onViewMaxSizeChanged: ((VPointF) -> Unit)?
}

class FlexClockFaceController(
+1 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ open class FlexClockTextViewController(
    private val logger = Logger(clockCtx.messageBuffer, TAG)
    private val timespec = DigitalTimespecHandler(layerCfg.timespec, layerCfg.timeFormatter!!)
    override var onViewBoundsChanged by view::onViewBoundsChanged
    override var onViewMaxSizeChanged by view::onViewMaxSizeChanged

    override val config = ClockFaceConfig()
    var dozeState: DefaultClockController.AnimationState? = null
Loading