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

Commit b5106269 authored by Hawkwood Glazier's avatar Hawkwood Glazier Committed by Android (Google) Code Review
Browse files

Merge "Translate digits on AOD to not be quite so wide" into main

parents 3b0411e2 552c1df2
Loading
Loading
Loading
Loading
+5 −16
Original line number Diff line number Diff line
@@ -55,31 +55,20 @@ class ComposedDigitalLayerController(private val clockCtx: ClockContext) :
        val layerCfg =
            LayerConfig(
                style = FontTextStyle(lineHeight = 147.25f),
                timespec = DigitalTimespec.DIGIT_PAIR,
                alignment = DigitalAlignment(HorizontalAlignment.CENTER, VerticalAlignment.CENTER),
                aodStyle =
                    FontTextStyle(
                        transitionInterpolator = Interpolators.EMPHASIZED,
                        transitionDuration = 750,
                    ),
                alignment =
                    DigitalAlignment(HorizontalAlignment.CENTER, VerticalAlignment.BASELINE),

                // Placeholders
                timespec = DigitalTimespec.TIME_FULL_FORMAT,
                // Placeholder
                dateTimeFormat = "hh:mm",
            )

        createController(
            layerCfg.copy(timespec = DigitalTimespec.FIRST_DIGIT, dateTimeFormat = "hh")
        )
        createController(
            layerCfg.copy(timespec = DigitalTimespec.SECOND_DIGIT, dateTimeFormat = "hh")
        )
        createController(
            layerCfg.copy(timespec = DigitalTimespec.FIRST_DIGIT, dateTimeFormat = "mm")
        )
        createController(
            layerCfg.copy(timespec = DigitalTimespec.SECOND_DIGIT, dateTimeFormat = "mm")
        )
        createController(layerCfg.copy(dateTimeFormat = "hh"))
        createController(layerCfg.copy(dateTimeFormat = "mm"))
    }

    private fun refreshTime() {
+2 −16
Original line number Diff line number Diff line
@@ -148,21 +148,6 @@ class FlexClockFaceController(clockCtx: ClockContext, private val isLargeClock:
         * keyguard_large_clock_top_margin from default clock
         */
        override fun onTargetRegionChanged(targetRegion: Rect?) {
            // When a clock needs to be aligned with screen, like weather clock
            // it needs to offset back the translation of keyguard_large_clock_top_margin
            if (isLargeClock && (view as FlexClockView).isAlignedWithScreen()) {
                val topMargin = keyguardLargeClockTopMargin
                targetRegion?.let {
                    val (_, yDiff) = computeLayoutDiff(view, it, isLargeClock)
                    // In LS, we use yDiff to counter translate
                    // the translation of KeyguardLargeClockTopMargin
                    // With the targetRegion passed from picker,
                    // we will have yDiff = 0, no translation is needed for weather clock
                    if (yDiff.toInt() != 0) view.translationY = yDiff - topMargin / 2
                }
                return
            }

            var maxWidth = 0f
            var maxHeight = 0f

@@ -231,7 +216,7 @@ class FlexClockFaceController(clockCtx: ClockContext, private val isLargeClock:
            }

            override fun onPickerCarouselSwiping(swipingFraction: Float) {
                if (isLargeClock && !(view as FlexClockView).isAlignedWithScreen()) {
                if (isLargeClock) {
                    view.translationY = keyguardLargeClockTopMargin / 2F * swipingFraction
                }
                layerController.animations.onPickerCarouselSwiping(swipingFraction)
@@ -251,6 +236,7 @@ class FlexClockFaceController(clockCtx: ClockContext, private val isLargeClock:

    companion object {
        val SMALL_CLOCK_MAX_WDTH = 120f

        val SMALL_LAYER_CONFIG =
            LayerConfig(
                timespec = DigitalTimespec.TIME_FULL_FORMAT,
+25 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ data class FontTextStyle(

enum class DigitalTimespec {
    TIME_FULL_FORMAT,
    DIGIT_PAIR,
    FIRST_DIGIT,
    SECOND_DIGIT,
}
@@ -121,6 +122,28 @@ open class SimpleDigitalHandLayerController(
        }
    }

    private fun applyLayout() {
        // TODO: Remove NO-OP
        if (view.layoutParams is RelativeLayout.LayoutParams) {
            val lp = view.layoutParams as RelativeLayout.LayoutParams
            lp.addRule(RelativeLayout.TEXT_ALIGNMENT_CENTER)
            when (view.id) {
                R.id.HOUR_DIGIT_PAIR -> {
                    lp.addRule(RelativeLayout.CENTER_VERTICAL)
                    lp.addRule(RelativeLayout.ALIGN_PARENT_START)
                }
                R.id.MINUTE_DIGIT_PAIR -> {
                    lp.addRule(RelativeLayout.CENTER_VERTICAL)
                    lp.addRule(RelativeLayout.END_OF, R.id.HOUR_DIGIT_PAIR)
                }
                else -> {
                    throw Exception("cannot apply two pairs layout to view ${view.id}")
                }
            }
            view.layoutParams = lp
        }
    }

    override val events =
        object : ClockEvents {
            override var isReactiveTouchInteractionEnabled = false
@@ -155,6 +178,7 @@ open class SimpleDigitalHandLayerController(
    override val animations =
        object : ClockAnimations {
            override fun enter() {
                applyLayout()
                refreshTime()
            }

@@ -170,6 +194,7 @@ open class SimpleDigitalHandLayerController(
            }

            override fun fold(fraction: Float) {
                applyLayout()
                refreshTime()
            }

+5 −8
Original line number Diff line number Diff line
@@ -106,19 +106,16 @@ class DigitalTimespecHandler(
        )
    }

    private fun getSingleDigit(): String {
        val isFirstDigit = timespec == DigitalTimespec.FIRST_DIGIT
    private fun getSingleDigit(offset: Int): String {
        val text = dateFormat.format(cal.time).toString()
        return text.substring(
            if (isFirstDigit) 0 else text.length - 1,
            if (isFirstDigit) text.length - 1 else text.length,
        )
        return text.substring(offset, offset + 1)
    }

    fun getDigitString(): String {
        return when (timespec) {
            DigitalTimespec.FIRST_DIGIT,
            DigitalTimespec.SECOND_DIGIT -> getSingleDigit()
            DigitalTimespec.FIRST_DIGIT -> getSingleDigit(0)
            DigitalTimespec.SECOND_DIGIT -> getSingleDigit(1)
            DigitalTimespec.DIGIT_PAIR -> dateFormat.format(cal.time).toString()
            DigitalTimespec.TIME_FULL_FORMAT -> dateFormat.format(cal.time).toString()
        }
    }
+34 −25
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ class FlexClockView(clockCtx: ClockContext) : FrameLayout(clockCtx.context) {

    protected fun calculateSize(widthMeasureSpec: Int, heightMeasureSpec: Int): Point? {
        maxSingleDigitSize = Point(-1, -1)
        val bottomLocation: (textView: SimpleDigitalClockTextView) -> Int = { textView ->
        val viewHeight: (textView: SimpleDigitalClockTextView) -> Int = { textView ->
            if (isMonoVerticalNumericLineSpacing) {
                maxSingleDigitSize.y
            } else {
@@ -98,9 +98,15 @@ class FlexClockView(clockCtx: ClockContext) : FrameLayout(clockCtx.context) {
        digitalClockTextViewMap.forEach { (_, textView) ->
            textView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
            maxSingleDigitSize.x = max(maxSingleDigitSize.x, textView.measuredWidth)
            maxSingleDigitSize.y = max(bottomLocation(textView), textView.measuredHeight)
            maxSingleDigitSize.y = max(viewHeight(textView), textView.measuredHeight)
        }
        aodTranslate = Point(0, 0)
        // TODO(b/364680879): Cleanup
        /*
        aodTranslate = Point(
            (maxSingleDigitSize.x * AOD_HORIZONTAL_TRANSLATE_RATIO).toInt(),
            (maxSingleDigitSize.y * AOD_VERTICAL_TRANSLATE_RATIO).toInt())
        */
        return Point(
            ((maxSingleDigitSize.x + abs(aodTranslate.x)) * 2),
            ((maxSingleDigitSize.y + abs(aodTranslate.y)) * 2),
@@ -112,6 +118,10 @@ class FlexClockView(clockCtx: ClockContext) : FrameLayout(clockCtx.context) {
        digitLeftTopMap[R.id.HOUR_SECOND_DIGIT] = Point(maxSingleDigitSize.x, 0)
        digitLeftTopMap[R.id.MINUTE_FIRST_DIGIT] = Point(0, maxSingleDigitSize.y)
        digitLeftTopMap[R.id.MINUTE_SECOND_DIGIT] = Point(maxSingleDigitSize)
        digitLeftTopMap[R.id.HOUR_DIGIT_PAIR] = Point(maxSingleDigitSize.x / 2, 0)
        // Add a small vertical buffer for the second digit pair
        digitLeftTopMap[R.id.MINUTE_DIGIT_PAIR] =
            Point(maxSingleDigitSize.x / 2, (maxSingleDigitSize.y * 1.05f).toInt())
        digitLeftTopMap.forEach { (_, point) ->
            point.x += abs(aodTranslate.x)
            point.y += abs(aodTranslate.y)
@@ -179,9 +189,9 @@ class FlexClockView(clockCtx: ClockContext) : FrameLayout(clockCtx.context) {
            // save canvas location in anticipation of restoration later
            canvas.save()
            val xTranslateAmount =
                digitOffsets.getOrDefault(id, 0f) + digitLeftTopMap[id]!!.x.toFloat()
                digitOffsets.getOrDefault(id, 0f) + (digitLeftTopMap[id]?.x?.toFloat() ?: 0f)
            // move canvas to location that the textView would like
            canvas.translate(xTranslateAmount, digitLeftTopMap[id]!!.y.toFloat())
            canvas.translate(xTranslateAmount, digitLeftTopMap[id]?.y?.toFloat() ?: 0f)
            // draw the textView at the location of the canvas above
            textView.draw(canvas)
            // reset the canvas location back to 0 without drawing
@@ -189,8 +199,6 @@ class FlexClockView(clockCtx: ClockContext) : FrameLayout(clockCtx.context) {
        }
    }

    fun isAlignedWithScreen(): Boolean = false

    fun onLocaleChanged(locale: Locale) {
        updateLocale(locale)
        requestLayout()
@@ -302,23 +310,17 @@ class FlexClockView(clockCtx: ClockContext) : FrameLayout(clockCtx.context) {
        clockMoveDirection: Int,
        moveFraction: Float,
    ) {
        // TODO(b/393577936): The step animation isn't correct with the two pairs approach
        val isMovingToCenter = if (isLayoutRtl) clockMoveDirection < 0 else clockMoveDirection > 0
        // The sign of moveAmountDeltaForDigit is already set here
        // we can interpret (left - clockStartLeft) as (destinationPosition - originPosition)
        // so we no longer need to multiply direct sign to moveAmountDeltaForDigit
        val currentMoveAmount = left - clockStartLeft
        for (i in 0 until NUM_DIGITS) {
            val mapIndexToId =
                when (i) {
                    0 -> R.id.HOUR_FIRST_DIGIT
                    1 -> R.id.HOUR_SECOND_DIGIT
                    2 -> R.id.MINUTE_FIRST_DIGIT
                    3 -> R.id.MINUTE_SECOND_DIGIT
                    else -> -1
                }
        var index = 0
        digitalClockTextViewMap.forEach { id, _ ->
            val digitFraction =
                getDigitFraction(
                    digit = i,
                    digit = index++,
                    isMovingToCenter = isMovingToCenter,
                    fraction = moveFraction,
                )
@@ -326,7 +328,7 @@ class FlexClockView(clockCtx: ClockContext) : FrameLayout(clockCtx.context) {
            val moveAmountForDigit = currentMoveAmount * digitFraction
            var moveAmountDeltaForDigit = moveAmountForDigit - currentMoveAmount
            if (isMovingToCenter && moveAmountForDigit < 0) moveAmountDeltaForDigit *= -1
            digitOffsets[mapIndexToId] = moveAmountDeltaForDigit
            digitOffsets[id] = moveAmountDeltaForDigit
            invalidate()
        }
    }
@@ -347,7 +349,8 @@ class FlexClockView(clockCtx: ClockContext) : FrameLayout(clockCtx.context) {
                /* rangeMin= */ 0.0f,
                /* rangeMax= */ 1.0f,
                /* valueMin= */ digitInitialDelay,
                /* valueMax= */ digitInitialDelay + AVAILABLE_ANIMATION_TIME,
                /* valueMax= */ digitInitialDelay +
                    availableAnimationTime(digitalClockTextViewMap.size),
                /* value= */ fraction,
            )
        )
@@ -357,12 +360,8 @@ class FlexClockView(clockCtx: ClockContext) : FrameLayout(clockCtx.context) {
        val AOD_TRANSITION_DURATION = 750L
        val CHARGING_TRANSITION_DURATION = 300L

        // Calculate the positions of all of the digits...
        // Offset each digit by, say, 0.1
        // This means that each digit needs to move over a slice of "fractions", i.e. digit 0 should
        // move from 0.0 - 0.7, digit 1 from 0.1 - 0.8, digit 2 from 0.2 - 0.9, and digit 3
        // from 0.3 - 1.0.
        private const val NUM_DIGITS = 4
        val AOD_HORIZONTAL_TRANSLATE_RATIO = -0.15F
        val AOD_VERTICAL_TRANSLATE_RATIO = 0.075F

        // Delays. Each digit's animation should have a slight delay, so we get a nice
        // "stepping" effect. When moving right, the second digit of the hour should move first.
@@ -387,7 +386,9 @@ class FlexClockView(clockCtx: ClockContext) : FrameLayout(clockCtx.context) {

        // Total available transition time for each digit, taking into account the step. If step is
        // 0.1, then digit 0 would animate over 0.0 - 0.7, making availableTime 0.7.
        private const val AVAILABLE_ANIMATION_TIME = 1.0f - MOVE_DIGIT_STEP * (NUM_DIGITS - 1)
        private fun availableAnimationTime(numDigits: Int): Float {
            return 1.0f - MOVE_DIGIT_STEP * (numDigits.toFloat() - 1)
        }

        // Add language tags below that do not have vertically mono spaced numerals
        private val NON_MONO_VERTICAL_NUMERIC_LINE_SPACING_LANGUAGES =
@@ -415,6 +416,14 @@ class FlexClockView(clockCtx: ClockContext) : FrameLayout(clockCtx.context) {
                    outPoint.x *= 1
                    outPoint.y *= 1
                }
                R.id.HOUR_DIGIT_PAIR -> {
                    outPoint.x *= -1
                    outPoint.y *= -1
                }
                R.id.MINUTE_DIGIT_PAIR -> {
                    outPoint.x *= -1
                    outPoint.y *= 1
                }
            }
            return outPoint
        }
Loading