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

Commit 98d5501c authored by Brad Hinegardner's avatar Brad Hinegardner
Browse files

Migrate Burmese support to FlexClockView

Changes detailed:
1. Adjust large clock to be vertically centered on BASELINE
2. Calculate the bottom location of each textview using descent, ascent
3. Made this extensible, so if more languages are wanted that don't have
   "mono" vertically-spaced numerals, we can just add them to
   `nonMonoVerticalNumericLineSpacingLanguages` and they will be
   rendered properly, assuming the font has support for them.
4. Remove the need for "magic numbers" which is different from the prior
   implementation
4. Remove allocation in onDraw

Bug: 364674467
Test: manual
Flag: com.android.systemui.clock_reactive_variants
Change-Id: I6b33997cd8a1481398293ddd7e28e7197ce9930a
parent b6af45d6
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -139,7 +139,7 @@ class DefaultClockProvider(
                                    alignment =
                                        DigitalAlignment(
                                            HorizontalAlignment.CENTER,
                                            VerticalAlignment.CENTER,
                                            VerticalAlignment.BASELINE,
                                        ),
                                    dateTimeFormat = "hh",
                                ),
@@ -158,7 +158,7 @@ class DefaultClockProvider(
                                    alignment =
                                        DigitalAlignment(
                                            HorizontalAlignment.CENTER,
                                            VerticalAlignment.CENTER,
                                            VerticalAlignment.BASELINE,
                                        ),
                                    dateTimeFormat = "hh",
                                ),
@@ -177,7 +177,7 @@ class DefaultClockProvider(
                                    alignment =
                                        DigitalAlignment(
                                            HorizontalAlignment.CENTER,
                                            VerticalAlignment.CENTER,
                                            VerticalAlignment.BASELINE,
                                        ),
                                    dateTimeFormat = "mm",
                                ),
@@ -196,7 +196,7 @@ class DefaultClockProvider(
                                    alignment =
                                        DigitalAlignment(
                                            HorizontalAlignment.CENTER,
                                            VerticalAlignment.CENTER,
                                            VerticalAlignment.BASELINE,
                                        ),
                                    dateTimeFormat = "mm",
                                ),
+45 −6
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.shared.clocks.view
import android.content.Context
import android.graphics.Canvas
import android.graphics.Point
import android.icu.text.NumberFormat
import android.util.MathUtils.constrainedMap
import android.view.View
import android.view.ViewGroup
@@ -28,6 +29,7 @@ import com.android.systemui.customization.R
import com.android.systemui.log.core.MessageBuffer
import com.android.systemui.shared.clocks.AssetLoader
import com.android.systemui.shared.clocks.DigitTranslateAnimator
import java.util.Locale
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min
@@ -37,10 +39,14 @@ fun clamp(value: Float, minVal: Float, maxVal: Float): Float = max(min(value, ma
class FlexClockView(context: Context, val assets: AssetLoader, messageBuffer: MessageBuffer) :
    DigitalClockFaceView(context, messageBuffer) {
    override var digitalClockTextViewMap = mutableMapOf<Int, SimpleDigitalClockTextView>()
    val digitLeftTopMap = mutableMapOf<Int, Point>()
    var maxSingleDigitSize = Point(-1, -1)
    val lockscreenTranslate = Point(0, 0)
    var aodTranslate = Point(0, 0)
    private val digitLeftTopMap = mutableMapOf<Int, Point>()

    private var maxSingleDigitSize = Point(-1, -1)
    private val lockscreenTranslate = Point(0, 0)
    private var aodTranslate = Point(0, 0)

    // Does the current language have mono vertical size when displaying numerals
    private var isMonoVerticalNumericLineSpacing = true

    init {
        setWillNotDraw(false)
@@ -49,6 +55,7 @@ class FlexClockView(context: Context, val assets: AssetLoader, messageBuffer: Me
                ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT,
            )
        updateLocale(Locale.getDefault())
    }

    private val digitOffsets = mutableMapOf<Int, Float>()
@@ -61,12 +68,19 @@ class FlexClockView(context: Context, val assets: AssetLoader, messageBuffer: Me

    protected override fun calculateSize(widthMeasureSpec: Int, heightMeasureSpec: Int): Point {
        maxSingleDigitSize = Point(-1, -1)
        val bottomLocation: (textView: SimpleDigitalClockTextView) -> Int = { textView ->
            if (isMonoVerticalNumericLineSpacing) {
                maxSingleDigitSize.y
            } else {
                (textView.paint.fontMetrics.descent - textView.paint.fontMetrics.ascent).toInt()
            }
        }

        digitalClockTextViewMap.forEach { (_, textView) ->
            textView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
            maxSingleDigitSize.x = max(maxSingleDigitSize.x, textView.measuredWidth)
            maxSingleDigitSize.y = max(maxSingleDigitSize.y, textView.measuredHeight)
            maxSingleDigitSize.y = max(bottomLocation(textView), textView.measuredHeight)
        }
        val textView = digitalClockTextViewMap[R.id.HOUR_FIRST_DIGIT]!!
        aodTranslate = Point(0, 0)
        return Point(
            ((maxSingleDigitSize.x + abs(aodTranslate.x)) * 2),
@@ -106,6 +120,11 @@ class FlexClockView(context: Context, val assets: AssetLoader, messageBuffer: Me
        }
    }

    override fun onLocaleChanged(locale: Locale) {
        updateLocale(locale)
        requestLayout()
    }

    override fun animateDoze(isDozing: Boolean, isAnimated: Boolean) {
        dozeControlState.animateDoze = {
            super.animateDoze(isDozing, isAnimated)
@@ -166,6 +185,18 @@ class FlexClockView(context: Context, val assets: AssetLoader, messageBuffer: Me
        }
    }

    private fun updateLocale(locale: Locale) {
        isMonoVerticalNumericLineSpacing =
            !NON_MONO_VERTICAL_NUMERIC_LINE_SPACING_LANGUAGES.any {
                val newLocaleNumberFormat =
                    NumberFormat.getInstance(locale).format(FORMAT_NUMBER.toLong())
                val nonMonoVerticalNumericLineSpaceNumberFormat =
                    NumberFormat.getInstance(Locale.forLanguageTag(it))
                        .format(FORMAT_NUMBER.toLong())
                newLocaleNumberFormat == nonMonoVerticalNumericLineSpaceNumberFormat
            }
    }

    /**
     * Offsets the textViews of the clock for the step clock animation.
     *
@@ -264,10 +295,18 @@ class FlexClockView(context: Context, val assets: AssetLoader, messageBuffer: Me
        // Constants for the animation
        private val MOVE_INTERPOLATOR = Interpolators.EMPHASIZED

        private const val FORMAT_NUMBER = 1234567890

        // 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)

        // Add language tags below that do not have vertically mono spaced numerals
        private val NON_MONO_VERTICAL_NUMERIC_LINE_SPACING_LANGUAGES =
            setOf(
                "my", // Burmese
            )

        // Use the sign of targetTranslation to control the direction of digit translation
        fun updateDirectionalTargetTranslate(id: Int, targetTranslation: Point): Point {
            val outPoint = Point(targetTranslation)
+9 −5
Original line number Diff line number Diff line
@@ -117,7 +117,7 @@ open class SimpleDigitalClockTextView(
        }
    }

    override var verticalAlignment: VerticalAlignment = VerticalAlignment.CENTER
    override var verticalAlignment: VerticalAlignment = VerticalAlignment.BASELINE
    override var horizontalAlignment: HorizontalAlignment = HorizontalAlignment.LEFT
    override var isAnimationEnabled = true
    override var dozeFraction: Float = 0F
@@ -258,7 +258,7 @@ open class SimpleDigitalClockTextView(
                -translation.y.toFloat(),
                (-translation.x + measuredWidth).toFloat(),
                (-translation.y + measuredHeight).toFloat(),
                Paint().also { it.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OUT) },
                PORTER_DUFF_XFER_MODE_PAINT,
            )
            canvas.restore()
            canvas.restore()
@@ -403,7 +403,7 @@ open class SimpleDigitalClockTextView(

    // translation of reference point of text
    // used for translation when calling textInterpolator
    fun getLocalTranslation(): Point {
    private fun getLocalTranslation(): Point {
        val viewHeight = if (isVertical) measuredWidth else measuredHeight
        val interpolatedTextBounds = updateInterpolatedTextBounds()
        val localTranslation = Point(0, 0)
@@ -429,7 +429,9 @@ open class SimpleDigitalClockTextView(
                        correctedBaseline
            }
            VerticalAlignment.BASELINE -> {
                localTranslation.y = -lockScreenPaint.strokeWidth.toInt()
                // account for max bottom distance of font, so clock doesn't collide with elements
                localTranslation.y =
                    -lockScreenPaint.strokeWidth.toInt() - paint.fontMetrics.descent.toInt()
            }
        }

@@ -550,7 +552,9 @@ open class SimpleDigitalClockTextView(
    }

    companion object {
        val AOD_STROKE_WIDTH = "2dp"
        private val PORTER_DUFF_XFER_MODE_PAINT =
            Paint().also { it.xfermode = PorterDuffXfermode(PorterDuff.Mode.DST_OUT) }

        val AOD_COLOR = Color.WHITE
        val OPTICAL_SIZE_AXIS = ClockFontAxisSetting("opsz", 144f)
        val DEFAULT_LS_VARIATION =