From 5b9b2d270dd9c507176d2980c2da4eeab5852c99 Mon Sep 17 00:00:00 2001 From: Femi Date: Wed, 28 Feb 2024 15:10:46 +0100 Subject: [PATCH 1/3] Added DCLClock Added DSL clock faces for time and complications --- app-watch/src/main/AndroidManifest.xml | 1 + .../dslclock/DSLClockComplication.kt | 355 ++++++++++++++++++ .../watchfaces/dslclock/DSLClockTime.kt | 195 ++++++++++ 3 files changed, 551 insertions(+) create mode 100644 shared/src/main/kotlin/watchfaces/dslclock/DSLClockComplication.kt create mode 100644 shared/src/main/kotlin/watchfaces/dslclock/DSLClockTime.kt diff --git a/app-watch/src/main/AndroidManifest.xml b/app-watch/src/main/AndroidManifest.xml index a6d858c..27f6d73 100644 --- a/app-watch/src/main/AndroidManifest.xml +++ b/app-watch/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ + + when (isAmbient) { + true -> sensorManager.unregisterListener(heartRateListener) + false -> { + sensorManager.registerListener( + heartRateListener, + sensor, + SensorManager.SENSOR_DELAY_NORMAL + ) + } + } + + } + + + @OptIn(InternalComposeOClockApi::class) + val measurer = LocalTextMeasurerWithoutCache.current + + val textLayoutResult by remember { + derivedStateOf { + measurer.measure( + "heart rate = $hr bps", + style + ) + } + } + + OClockCanvas { + rotate(degrees = 0f) { + drawText( + brush = style.brush ?: SolidColor(style.color), + textLayoutResult = textLayoutResult, + topLeft = Offset( + x = 120f, + y = center.y - (textLayoutResult.size.height / 2f) + ) + ) + } + } + +} + + +@Composable +private fun Steps(style: TextStyle) { + + var steps by remember { mutableIntStateOf(-1) } + + @OptIn(InternalComposeOClockApi::class) + val measurer = LocalTextMeasurerWithoutCache.current + + val textLayoutResult by remember { + derivedStateOf { + measurer.measure( + "steps = $steps", + style + ) + } + } + + OClockCanvas { + rotate(degrees = 0f) { + drawText( + brush = style.brush ?: SolidColor(style.color), + textLayoutResult = textLayoutResult, + topLeft = Offset( + x = 120f, + y = size.height - (center.y * 0.8f) - (textLayoutResult.size.height / 2f) + ) + ) + } + } + +} + + +@Composable +private fun Weather(style: TextStyle) { + + val weather = "no idea" + + @OptIn(InternalComposeOClockApi::class) + val measurer = LocalTextMeasurerWithoutCache.current + + val textLayoutResult by remember { + derivedStateOf { + measurer.measure( + "weather = $weather", + style + ) + } + } + + OClockCanvas { + rotate(degrees = 0f) { + drawText( + brush = style.brush ?: SolidColor(style.color), + textLayoutResult = textLayoutResult, + topLeft = Offset( + x = 120f, + y = size.height - (center.y * 0.6f) - (textLayoutResult.size.height / 2f) + ) + ) + } + } + +} + + +@Composable +private fun CloseParentheses(style: TextStyle) { + @OptIn(InternalComposeOClockApi::class) + val measurer = LocalTextMeasurerWithoutCache.current + + val textLayoutResult by remember { + derivedStateOf { + measurer.measure( + "}", + style + ) + } + } + + OClockCanvas { + rotate(degrees = 0f) { + drawText( + brush = style.brush ?: SolidColor(style.color), + textLayoutResult = textLayoutResult, + topLeft = Offset( + x = 60f, + y = size.height - (center.y * 0.4f) - (textLayoutResult.size.height / 2f) + ) + ) + } + } +} + +private val kotlinDarkBg = Color(0xFF101010) + +@WatchFacePreview +@Composable +private fun KotlinComplicationDSLClockPreview( + @PreviewParameter(WearPreviewSizesProvider::class) size: Dp, +) = WatchFacePreview(size) { + DSLClockComplication() +} diff --git a/shared/src/main/kotlin/watchfaces/dslclock/DSLClockTime.kt b/shared/src/main/kotlin/watchfaces/dslclock/DSLClockTime.kt new file mode 100644 index 0000000..c5570c5 --- /dev/null +++ b/shared/src/main/kotlin/watchfaces/dslclock/DSLClockTime.kt @@ -0,0 +1,195 @@ +package org.splitties.compose.oclock.sample.watchfaces.dslclock + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.drawText +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.sp +import org.splitties.compose.oclock.CurrentTime +import org.splitties.compose.oclock.LocalIsAmbient +import org.splitties.compose.oclock.LocalTextMeasurerWithoutCache +import org.splitties.compose.oclock.LocalTime +import org.splitties.compose.oclock.OClockCanvas +import org.splitties.compose.oclock.internal.InternalComposeOClockApi +import org.splitties.compose.oclock.sample.WatchFacePreview +import org.splitties.compose.oclock.sample.WearPreviewSizesProvider +import org.splitties.compose.oclock.sample.extensions.rotate + +@Composable +fun DSLClockTime() { + + val style = remember { + TextStyle( + color = Color.White, + fontFamily = FontFamily.Monospace, + fontSize = 15.sp, + ) + } + + Background() + TimeAndOpenParentheses(style) + Hours(style) + Minutes(style) + Seconds(style) + CloseParentheses(style) + +} + + +@Composable +private fun Background() { + val isAmbient by LocalIsAmbient.current + OClockCanvas { + if (isAmbient.not()) drawCircle(kotlinDarkBg) + } +} + +@Composable +private fun TimeAndOpenParentheses(style: TextStyle) { + + @OptIn(InternalComposeOClockApi::class) + val measurer = LocalTextMeasurerWithoutCache.current + + val textLayoutResult by remember { + derivedStateOf { + measurer.measure( + "time {", + style + ) + } + } + + OClockCanvas { + rotate(degrees = 0f) { + drawText( + brush = style.brush ?: SolidColor(style.color), + textLayoutResult = textLayoutResult, + topLeft = Offset(x = 60f, y = (center.y * 0.55f) - (textLayoutResult.size.height / 2f)) + ) + } + } +} + +@Composable +private fun Hours(style: TextStyle) { + + DSLTimeValue( + style = style, + timeType = TimeParamType.Hour, + ) +} + + +@Composable +private fun Minutes(style: TextStyle) { + + DSLTimeValue( + style = style, + timeType = TimeParamType.Minute, + ) +} + +@Composable +private fun Seconds(style: TextStyle) { + + DSLTimeValue( + style = style, + timeType = TimeParamType.Second, + ) +} + + +@Composable +private fun CloseParentheses(style: TextStyle) { + @OptIn(InternalComposeOClockApi::class) + val measurer = LocalTextMeasurerWithoutCache.current + + val textLayoutResult by remember { + derivedStateOf { + measurer.measure( + "}", + style + ) + } + } + + OClockCanvas { + rotate(degrees = 0f) { + drawText( + brush = style.brush ?: SolidColor(style.color), + textLayoutResult = textLayoutResult, + topLeft = Offset(x = 60f, y = size.height - (center.y * 0.55f) - (textLayoutResult.size.height / 2f)) + ) + } + } +} + + +@Composable +private fun DSLTimeValue( + style: TextStyle, + timeType: TimeParamType, +) { + val time = LocalTime.current + + @OptIn(InternalComposeOClockApi::class) + val measurer = LocalTextMeasurerWithoutCache.current + + val textLayoutResult by remember { + derivedStateOf { + val timeInt = timeType.paramValue(time) + measurer.measure( + "${timeType.paramName} = $timeInt", + style + ) + } + } + + OClockCanvas { + rotate(degrees = 0f) { + val offset = when (timeType) { + TimeParamType.Hour -> Offset(x = 140f, y = (center.y * 0.8f) - (textLayoutResult.size.height / 2f)) + TimeParamType.Minute -> Offset(x = 140f, y = center.y - (textLayoutResult.size.height / 2f)) + TimeParamType.Second -> Offset(x = 140f, y = size.height - (center.y * 0.8f) - (textLayoutResult.size.height / 2f)) + } + drawText( + brush = style.brush ?: SolidColor(style.color), + textLayoutResult = textLayoutResult, + topLeft = offset + ) + } + } +} + + +enum class TimeParamType(val paramName: String) { + Hour("hours") { + override fun paramValue(current: CurrentTime): Int = current.hours + }, + Minute("minutes") { + override fun paramValue(current: CurrentTime): Int = current.minutes + }, + Second("seconds") { + override fun paramValue(current: CurrentTime): Int = current.seconds + }; + + abstract fun paramValue(current: CurrentTime): Int +} + +private val kotlinDarkBg = Color(0xFF101010) + +@WatchFacePreview +@Composable +private fun KotlinTimeDSLClockPreview( + @PreviewParameter(WearPreviewSizesProvider::class) size: Dp, +) = WatchFacePreview(size) { + DSLClockTime() +} From 1c87e789fc367221bf81eaed4ad6d0b0353df4b7 Mon Sep 17 00:00:00 2001 From: Femi Date: Sun, 10 Mar 2024 22:19:05 +0100 Subject: [PATCH 2/3] Removed SensorEventListener from heart rate data --- app-watch/src/main/AndroidManifest.xml | 1 - .../dslclock/DSLClockComplication.kt | 44 ++----------------- 2 files changed, 3 insertions(+), 42 deletions(-) diff --git a/app-watch/src/main/AndroidManifest.xml b/app-watch/src/main/AndroidManifest.xml index 27f6d73..a6d858c 100644 --- a/app-watch/src/main/AndroidManifest.xml +++ b/app-watch/src/main/AndroidManifest.xml @@ -4,7 +4,6 @@ - - when (isAmbient) { - true -> sensorManager.unregisterListener(heartRateListener) - false -> { - sensorManager.registerListener( - heartRateListener, - sensor, - SensorManager.SENSOR_DELAY_NORMAL - ) - } - } - - } + var hr by remember { mutableIntStateOf(-1) } @OptIn(InternalComposeOClockApi::class) @@ -286,7 +248,7 @@ private fun Steps(style: TextStyle) { @Composable private fun Weather(style: TextStyle) { - val weather = "no idea" + val weather = "" @OptIn(InternalComposeOClockApi::class) val measurer = LocalTextMeasurerWithoutCache.current From 3b19ac4e761f651009324e350c6a540bd6965b81 Mon Sep 17 00:00:00 2001 From: Femi Date: Sun, 10 Mar 2024 23:34:32 +0100 Subject: [PATCH 3/3] Removed heart rate and bug fixes - Removed Heart rate from complications face - Removed unused rotation from various OClockCanvas - Changed date format to "yyyy/MM/dd" for shorter length - Removed hardcoded offset values - Kept battery BroadcastReceiver in a DisposableEffect --- .../dslclock/DSLClockComplication.kt | 193 +++++++----------- .../watchfaces/dslclock/DSLClockTime.kt | 81 ++++---- 2 files changed, 114 insertions(+), 160 deletions(-) diff --git a/shared/src/main/kotlin/watchfaces/dslclock/DSLClockComplication.kt b/shared/src/main/kotlin/watchfaces/dslclock/DSLClockComplication.kt index 55acc63..efb391d 100644 --- a/shared/src/main/kotlin/watchfaces/dslclock/DSLClockComplication.kt +++ b/shared/src/main/kotlin/watchfaces/dslclock/DSLClockComplication.kt @@ -6,10 +6,10 @@ import android.content.Intent import android.content.IntentFilter import android.os.BatteryManager import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.mutableLongStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.geometry.Offset @@ -28,7 +28,6 @@ import org.splitties.compose.oclock.OClockCanvas import org.splitties.compose.oclock.internal.InternalComposeOClockApi import org.splitties.compose.oclock.sample.WatchFacePreview import org.splitties.compose.oclock.sample.WearPreviewSizesProvider -import org.splitties.compose.oclock.sample.extensions.rotate import java.time.LocalDate import java.time.format.DateTimeFormatter @@ -36,7 +35,7 @@ import java.time.format.DateTimeFormatter @Composable fun DSLClockComplication() { - val style = remember { + val textStyle = remember { TextStyle( color = Color.White, fontFamily = FontFamily.Monospace, @@ -45,13 +44,12 @@ fun DSLClockComplication() { } Background() - TimeAndOpenParentheses(style) - Date(style) - Battery(style) - HeartRate(style) - Steps(style) - Weather(style) - CloseParentheses(style) + TimeAndOpenParentheses(textStyle) + Date(textStyle) + Battery(textStyle) + Steps(textStyle) + Weather(textStyle) + CloseParentheses(textStyle) } @@ -65,7 +63,7 @@ private fun Background() { } @Composable -private fun TimeAndOpenParentheses(style: TextStyle) { +private fun TimeAndOpenParentheses(textStyle: TextStyle) { @OptIn(InternalComposeOClockApi::class) val measurer = LocalTextMeasurerWithoutCache.current @@ -73,31 +71,29 @@ private fun TimeAndOpenParentheses(style: TextStyle) { val textLayoutResult by remember { derivedStateOf { measurer.measure( - "complications {", - style + "comp {", + textStyle ) } } OClockCanvas { - rotate(degrees = 0f) { - drawText( - brush = style.brush ?: SolidColor(style.color), - textLayoutResult = textLayoutResult, - topLeft = Offset( - x = 60f, - y = (center.y * 0.4f) - (textLayoutResult.size.height / 2f) - ) + drawText( + brush = textStyle.brush ?: SolidColor(textStyle.color), + textLayoutResult = textLayoutResult, + topLeft = Offset( + x = center.x * 0.23f, + y = (center.y * 0.45f) - (textLayoutResult.size.height / 2f) ) - } + ) } } @Composable -private fun Date(style: TextStyle) { +private fun Date(textStyle: TextStyle) { - val formatter = DateTimeFormatter.ofPattern("MMM dd, yyyy") + val formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd") val date = LocalDate.now().format(formatter) @OptIn(InternalComposeOClockApi::class) @@ -107,113 +103,84 @@ private fun Date(style: TextStyle) { derivedStateOf { measurer.measure( "date = $date", - style + textStyle ) } } OClockCanvas { - rotate(degrees = 0f) { - drawText( - brush = style.brush ?: SolidColor(style.color), - textLayoutResult = textLayoutResult, - topLeft = Offset( - x = 120f, - y = (center.y * 0.6f) - (textLayoutResult.size.height / 2f) - ) + drawText( + brush = textStyle.brush ?: SolidColor(textStyle.color), + textLayoutResult = textLayoutResult, + topLeft = Offset( + x = center.x * 0.4f, + y = (center.y * 0.7f) - (textLayoutResult.size.height / 2f) ) - } + ) } } @Composable -private fun Battery(style: TextStyle) { +private fun Battery(textStyle: TextStyle) { val context: Context = LocalContext.current var batteryLevel by remember { mutableIntStateOf(0) } - val iFilter = IntentFilter(Intent.ACTION_BATTERY_CHANGED) - val batteryStatus = context.registerReceiver(null, iFilter) + DisposableEffect(true) { + val iFilter = IntentFilter(Intent.ACTION_BATTERY_CHANGED) + val batteryStatus = context.registerReceiver(null, iFilter) - batteryLevel = batteryStatus?.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) ?: -1 + batteryLevel = batteryStatus?.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) ?: -1 - context.registerReceiver( - object : BroadcastReceiver() { + val batteryListener = object : BroadcastReceiver() { override fun onReceive(ctxt: Context, intent: Intent) { try { batteryLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) } catch (_: IllegalStateException) { } } - }, - IntentFilter(Intent.ACTION_BATTERY_CHANGED)) - - @OptIn(InternalComposeOClockApi::class) - val measurer = LocalTextMeasurerWithoutCache.current - - val textLayoutResult by remember { - derivedStateOf { - measurer.measure( - "battery = $batteryLevel / 100", - style - ) } - } - OClockCanvas { - rotate(degrees = 0f) { - drawText( - brush = style.brush ?: SolidColor(style.color), - textLayoutResult = textLayoutResult, - topLeft = Offset( - x = 120f, - y = (center.y * 0.8f) - (textLayoutResult.size.height / 2f) - ) - ) + context.registerReceiver( + batteryListener, + IntentFilter(Intent.ACTION_BATTERY_CHANGED) + ) + + onDispose { + context.unregisterReceiver(batteryListener) } } -} - - -@Composable -private fun HeartRate(style: TextStyle) { - - var hr by remember { mutableIntStateOf(-1) } - - @OptIn(InternalComposeOClockApi::class) val measurer = LocalTextMeasurerWithoutCache.current val textLayoutResult by remember { derivedStateOf { measurer.measure( - "heart rate = $hr bps", - style + "battery = $batteryLevel / 100", + textStyle ) } } OClockCanvas { - rotate(degrees = 0f) { - drawText( - brush = style.brush ?: SolidColor(style.color), - textLayoutResult = textLayoutResult, - topLeft = Offset( - x = 120f, - y = center.y - (textLayoutResult.size.height / 2f) - ) + drawText( + brush = textStyle.brush ?: SolidColor(textStyle.color), + textLayoutResult = textLayoutResult, + topLeft = Offset( + x = center.x * 0.4f, + y = (center.y * 0.9f) - (textLayoutResult.size.height / 2f) ) - } + ) } } @Composable -private fun Steps(style: TextStyle) { +private fun Steps(textStyle: TextStyle) { var steps by remember { mutableIntStateOf(-1) } @@ -224,29 +191,27 @@ private fun Steps(style: TextStyle) { derivedStateOf { measurer.measure( "steps = $steps", - style + textStyle ) } } OClockCanvas { - rotate(degrees = 0f) { - drawText( - brush = style.brush ?: SolidColor(style.color), - textLayoutResult = textLayoutResult, - topLeft = Offset( - x = 120f, - y = size.height - (center.y * 0.8f) - (textLayoutResult.size.height / 2f) - ) + drawText( + brush = textStyle.brush ?: SolidColor(textStyle.color), + textLayoutResult = textLayoutResult, + topLeft = Offset( + x = center.x * 0.4f, + y = size.height - (center.y * 0.9f) - (textLayoutResult.size.height / 2f) ) - } + ) } } @Composable -private fun Weather(style: TextStyle) { +private fun Weather(textStyle: TextStyle) { val weather = "" @@ -257,29 +222,27 @@ private fun Weather(style: TextStyle) { derivedStateOf { measurer.measure( "weather = $weather", - style + textStyle ) } } OClockCanvas { - rotate(degrees = 0f) { - drawText( - brush = style.brush ?: SolidColor(style.color), - textLayoutResult = textLayoutResult, - topLeft = Offset( - x = 120f, - y = size.height - (center.y * 0.6f) - (textLayoutResult.size.height / 2f) - ) + drawText( + brush = textStyle.brush ?: SolidColor(textStyle.color), + textLayoutResult = textLayoutResult, + topLeft = Offset( + x = center.x * 0.4f, + y = size.height - (center.y * 0.7f) - (textLayoutResult.size.height / 2f) ) - } + ) } } @Composable -private fun CloseParentheses(style: TextStyle) { +private fun CloseParentheses(textStyle: TextStyle) { @OptIn(InternalComposeOClockApi::class) val measurer = LocalTextMeasurerWithoutCache.current @@ -287,22 +250,20 @@ private fun CloseParentheses(style: TextStyle) { derivedStateOf { measurer.measure( "}", - style + textStyle ) } } OClockCanvas { - rotate(degrees = 0f) { - drawText( - brush = style.brush ?: SolidColor(style.color), - textLayoutResult = textLayoutResult, - topLeft = Offset( - x = 60f, - y = size.height - (center.y * 0.4f) - (textLayoutResult.size.height / 2f) - ) + drawText( + brush = textStyle.brush ?: SolidColor(textStyle.color), + textLayoutResult = textLayoutResult, + topLeft = Offset( + x = center.x * 0.3f, + y = size.height - (center.y * 0.45f) - (textLayoutResult.size.height / 2f) ) - } + ) } } diff --git a/shared/src/main/kotlin/watchfaces/dslclock/DSLClockTime.kt b/shared/src/main/kotlin/watchfaces/dslclock/DSLClockTime.kt index c5570c5..31fcfef 100644 --- a/shared/src/main/kotlin/watchfaces/dslclock/DSLClockTime.kt +++ b/shared/src/main/kotlin/watchfaces/dslclock/DSLClockTime.kt @@ -21,12 +21,11 @@ import org.splitties.compose.oclock.OClockCanvas import org.splitties.compose.oclock.internal.InternalComposeOClockApi import org.splitties.compose.oclock.sample.WatchFacePreview import org.splitties.compose.oclock.sample.WearPreviewSizesProvider -import org.splitties.compose.oclock.sample.extensions.rotate @Composable fun DSLClockTime() { - val style = remember { + val textStyle = remember { TextStyle( color = Color.White, fontFamily = FontFamily.Monospace, @@ -35,11 +34,11 @@ fun DSLClockTime() { } Background() - TimeAndOpenParentheses(style) - Hours(style) - Minutes(style) - Seconds(style) - CloseParentheses(style) + TimeAndOpenParentheses(textStyle) + Hours(textStyle) + Minutes(textStyle) + Seconds(textStyle) + CloseParentheses(textStyle) } @@ -53,7 +52,7 @@ private fun Background() { } @Composable -private fun TimeAndOpenParentheses(style: TextStyle) { +private fun TimeAndOpenParentheses(textStyle: TextStyle) { @OptIn(InternalComposeOClockApi::class) val measurer = LocalTextMeasurerWithoutCache.current @@ -62,53 +61,51 @@ private fun TimeAndOpenParentheses(style: TextStyle) { derivedStateOf { measurer.measure( "time {", - style + textStyle ) } } OClockCanvas { - rotate(degrees = 0f) { - drawText( - brush = style.brush ?: SolidColor(style.color), - textLayoutResult = textLayoutResult, - topLeft = Offset(x = 60f, y = (center.y * 0.55f) - (textLayoutResult.size.height / 2f)) - ) - } + drawText( + brush = textStyle.brush ?: SolidColor(textStyle.color), + textLayoutResult = textLayoutResult, + topLeft = Offset(x = center.x * 0.25f, y = (center.y * 0.55f) - (textLayoutResult.size.height / 2f)) + ) } } @Composable -private fun Hours(style: TextStyle) { +private fun Hours(textStyle: TextStyle) { DSLTimeValue( - style = style, + textStyle = textStyle, timeType = TimeParamType.Hour, ) } @Composable -private fun Minutes(style: TextStyle) { +private fun Minutes(textStyle: TextStyle) { DSLTimeValue( - style = style, + textStyle = textStyle, timeType = TimeParamType.Minute, ) } @Composable -private fun Seconds(style: TextStyle) { +private fun Seconds(textStyle: TextStyle) { DSLTimeValue( - style = style, + textStyle = textStyle, timeType = TimeParamType.Second, ) } @Composable -private fun CloseParentheses(style: TextStyle) { +private fun CloseParentheses(textStyle: TextStyle) { @OptIn(InternalComposeOClockApi::class) val measurer = LocalTextMeasurerWithoutCache.current @@ -116,26 +113,24 @@ private fun CloseParentheses(style: TextStyle) { derivedStateOf { measurer.measure( "}", - style + textStyle ) } } OClockCanvas { - rotate(degrees = 0f) { - drawText( - brush = style.brush ?: SolidColor(style.color), - textLayoutResult = textLayoutResult, - topLeft = Offset(x = 60f, y = size.height - (center.y * 0.55f) - (textLayoutResult.size.height / 2f)) - ) - } + drawText( + brush = textStyle.brush ?: SolidColor(textStyle.color), + textLayoutResult = textLayoutResult, + topLeft = Offset(x = center.x * 0.25f, y = size.height - (center.y * 0.55f) - (textLayoutResult.size.height / 2f)) + ) } } @Composable private fun DSLTimeValue( - style: TextStyle, + textStyle: TextStyle, timeType: TimeParamType, ) { val time = LocalTime.current @@ -148,24 +143,22 @@ private fun DSLTimeValue( val timeInt = timeType.paramValue(time) measurer.measure( "${timeType.paramName} = $timeInt", - style + textStyle ) } } OClockCanvas { - rotate(degrees = 0f) { - val offset = when (timeType) { - TimeParamType.Hour -> Offset(x = 140f, y = (center.y * 0.8f) - (textLayoutResult.size.height / 2f)) - TimeParamType.Minute -> Offset(x = 140f, y = center.y - (textLayoutResult.size.height / 2f)) - TimeParamType.Second -> Offset(x = 140f, y = size.height - (center.y * 0.8f) - (textLayoutResult.size.height / 2f)) - } - drawText( - brush = style.brush ?: SolidColor(style.color), - textLayoutResult = textLayoutResult, - topLeft = offset - ) + val offset = when (timeType) { + TimeParamType.Hour -> Offset(x = center.x * 0.55f, y = (center.y * 0.8f) - (textLayoutResult.size.height / 2f)) + TimeParamType.Minute -> Offset(x = center.x * 0.55f, y = center.y - (textLayoutResult.size.height / 2f)) + TimeParamType.Second -> Offset(x = center.x * 0.55f, y = size.height - (center.y * 0.8f) - (textLayoutResult.size.height / 2f)) } + drawText( + brush = textStyle.brush ?: SolidColor(textStyle.color), + textLayoutResult = textLayoutResult, + topLeft = offset + ) } }