From 9eeb7b31dec9efd156b439ea490a8dbe79cb7083 Mon Sep 17 00:00:00 2001 From: Louis CAD Date: Fri, 21 Jun 2024 01:38:47 +0200 Subject: [PATCH] Update Kotlin, Compose, and Compose O'Clock --- app-phone/build.gradle.kts | 3 -- app-watch/build.gradle.kts | 3 -- convention-plugins/build.gradle.kts | 1 + convention-plugins/settings.gradle.kts | 2 +- .../src/main/kotlin/android-app.gradle.kts | 6 +-- gradle/libs.versions.toml | 2 +- settings.gradle.kts | 2 +- shared/build.gradle.kts | 8 +-- .../src/main/kotlin/ComposeOClockWatermark.kt | 2 +- shared/src/main/kotlin/WatchFacePreview.kt | 16 +++++- .../PixelWatchStyleComplication.kt | 2 + .../elements/CirclePatterns.kt | 1 + .../elements/PatternsPreviews.kt | 1 + .../experiments/KotlinLogoExperiments.kt | 6 +-- .../experiments/TextOnPathExperiments.kt | 4 +- shared/src/main/kotlin/elements/MyPath.kt | 4 +- .../main/kotlin/elements/SinusoidalCrown.kt | 18 +++---- .../src/main/kotlin/extensions/DrawScope.kt | 29 +--------- shared/src/main/kotlin/extensions/Path.kt | 4 +- .../kotlin/extensions/SizeDependentState.kt | 53 ++++++++++++++++--- .../kotlin/watchfaces/BasicAnalogClock.kt | 5 +- .../main/kotlin/watchfaces/ComposeFanClock.kt | 5 +- .../main/kotlin/watchfaces/KotlinFanClock.kt | 5 +- .../kotlin/watchfaces/WatchFaceSwitcher.kt | 4 +- .../kotlin/watchfaces/hansie/HansieClock.kt | 2 +- versions.properties | 18 +++---- 26 files changed, 111 insertions(+), 95 deletions(-) diff --git a/app-phone/build.gradle.kts b/app-phone/build.gradle.kts index 144f5af..23b6753 100644 --- a/app-phone/build.gradle.kts +++ b/app-phone/build.gradle.kts @@ -25,7 +25,6 @@ dependencies { AndroidX.compose.material3() AndroidX.compose.ui.toolingPreview() AndroidX.activity.compose() - platform(AndroidX.compose.bom) AndroidX.compose.ui() AndroidX.compose.ui.graphics() AndroidX.compose.ui.toolingPreview() @@ -38,11 +37,9 @@ dependencies { androidTestImplementation { AndroidX.test.ext.junit() AndroidX.test.espresso.core() - platform(AndroidX.compose.bom) AndroidX.compose.ui.testJunit4() } debugImplementation { - platform(AndroidX.compose.bom) AndroidX.compose.ui.tooling() AndroidX.compose.ui.testManifest() } diff --git a/app-watch/build.gradle.kts b/app-watch/build.gradle.kts index d909881..8fe0c63 100644 --- a/app-watch/build.gradle.kts +++ b/app-watch/build.gradle.kts @@ -24,7 +24,6 @@ dependencies { libs.compose.oclock.watchface.renderer() AndroidX.wear.watchFace.editor() - platform(AndroidX.compose.bom) AndroidX.wear.compose.material() AndroidX.wear.compose.foundation() AndroidX.activity.compose() @@ -34,11 +33,9 @@ dependencies { Splitties.toast() } androidTestImplementation { - platform(AndroidX.compose.bom) AndroidX.compose.ui.testJunit4() } debugImplementation { - platform(AndroidX.compose.bom) AndroidX.compose.ui.tooling() AndroidX.compose.ui.testManifest() } diff --git a/convention-plugins/build.gradle.kts b/convention-plugins/build.gradle.kts index 300a1cc..b5f2f7d 100644 --- a/convention-plugins/build.gradle.kts +++ b/convention-plugins/build.gradle.kts @@ -15,6 +15,7 @@ dependencies { implementation { Android.tools.build.gradlePlugin() Kotlin.gradlePlugin() + plugin("org.jetbrains.kotlin.plugin.compose", "_")() Google.playServicesGradlePlugin() Firebase.crashlyticsGradlePlugin() plugin("de.fayard.refreshVersions", "_")() diff --git a/convention-plugins/settings.gradle.kts b/convention-plugins/settings.gradle.kts index 7fb2b66..8e9cf3a 100644 --- a/convention-plugins/settings.gradle.kts +++ b/convention-plugins/settings.gradle.kts @@ -6,7 +6,7 @@ pluginManagement { } plugins { id("org.splitties.dependencies-dsl") version "0.1.0" - id("de.fayard.refreshVersions") version "0.60.4" + id("de.fayard.refreshVersions") version "0.60.5" } } diff --git a/convention-plugins/src/main/kotlin/android-app.gradle.kts b/convention-plugins/src/main/kotlin/android-app.gradle.kts index b5a040b..90f0b2c 100644 --- a/convention-plugins/src/main/kotlin/android-app.gradle.kts +++ b/convention-plugins/src/main/kotlin/android-app.gradle.kts @@ -1,9 +1,9 @@ -import de.fayard.refreshVersions.core.versionFor import java.io.FileNotFoundException plugins { kotlin("android") id("com.android.application") + kotlin("plugin.compose") } android { @@ -60,7 +60,6 @@ android { } } kotlinOptions { - freeCompilerArgs += "-opt-in=splitties.experimental.ExperimentalSplittiesApi" jvmTarget = "1.8" freeCompilerArgs += "-Xcontext-receivers" } @@ -69,9 +68,6 @@ android { targetCompatibility = JavaVersion.VERSION_1_8 } buildFeatures.compose = true - composeOptions { - kotlinCompilerExtensionVersion = versionFor(AndroidX.compose.compiler) - } packagingOptions.resources { excludes += setOf( "META-INF/ASL2.0", diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2974a9b..497f298 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,7 +3,7 @@ roborazzi = { id = "io.github.takahirom.roborazzi", version.ref = "roborazzi" } [versions] -composeOClock = "0.1.0-SNAPSHOT" +composeOClock = "0.2.0-SNAPSHOT" roborazzi = "1.10.1" [libraries] diff --git a/settings.gradle.kts b/settings.gradle.kts index 25dceae..1a0e073 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -14,7 +14,7 @@ pluginManagement { } plugins { - id("de.fayard.refreshVersions") version "0.60.4" + id("de.fayard.refreshVersions") version "0.60.5" id("org.splitties.settings-include-dsl") version "0.2.6" id("org.splitties.dependencies-dsl") version "0.2.0" id("org.splitties.version-sync") version "0.2.6" diff --git a/shared/build.gradle.kts b/shared/build.gradle.kts index 5176fb7..1702902 100644 --- a/shared/build.gradle.kts +++ b/shared/build.gradle.kts @@ -1,9 +1,8 @@ @file:Suppress("UnstableApiUsage") -import de.fayard.refreshVersions.core.versionFor - plugins { id("android-lib") + kotlin("plugin.compose") alias(libs.plugins.roborazzi) } @@ -19,9 +18,6 @@ android { compose = true buildConfig = true } - composeOptions { - kotlinCompilerExtensionVersion = versionFor(AndroidX.compose.compiler) - } compileOptions { isCoreLibraryDesugaringEnabled = true } @@ -38,8 +34,8 @@ dependencies { libs.compose.oclock.core() Google.android.playServices.wearOS() - platform(AndroidX.compose.bom) AndroidX.compose.ui() + AndroidX.compose.ui.graphics() AndroidX.compose.ui.toolingPreview() AndroidX.compose.ui.text.googleFonts() diff --git a/shared/src/main/kotlin/ComposeOClockWatermark.kt b/shared/src/main/kotlin/ComposeOClockWatermark.kt index 8e1e7cd..89bf1a1 100644 --- a/shared/src/main/kotlin/ComposeOClockWatermark.kt +++ b/shared/src/main/kotlin/ComposeOClockWatermark.kt @@ -101,7 +101,7 @@ fun ComposeOClockWatermark(finalBrush: Brush) { @WatchFacePreview @Composable private fun ComposeOClockWatermarkPreview( - @PreviewParameter(WearPreviewSizesProvider::class) size: Dp + @PreviewParameter(WearPreviewSizes::class) size: Dp ) = WatchFacePreview(size) { ComposeOClockWatermark(SolidColor(Color.Magenta)) } diff --git a/shared/src/main/kotlin/WatchFacePreview.kt b/shared/src/main/kotlin/WatchFacePreview.kt index 650b6c7..2d468fe 100644 --- a/shared/src/main/kotlin/WatchFacePreview.kt +++ b/shared/src/main/kotlin/WatchFacePreview.kt @@ -24,15 +24,23 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import androidx.wear.watchface.complications.data.ComplicationData import kotlinx.coroutines.flow.* +import org.splitties.compose.oclock.ExperimentalComposeOClockApi import org.splitties.compose.oclock.OClockRootCanvas +import org.splitties.compose.oclock.PreviewTime -class WearPreviewSizesProvider : PreviewParameterProvider { +class WearPreviewSizes : PreviewParameterProvider { override val values: Sequence = sequenceOf( WatchFacePreview.Size.small, WatchFacePreview.Size.large ) } +class WearSmallest : PreviewParameterProvider { + override val values: Sequence = sequenceOf( + WatchFacePreview.Size.small + ) +} + /** * Example usage: * @@ -40,7 +48,7 @@ class WearPreviewSizesProvider : PreviewParameterProvider { * @WatchFacePreview * @Composable * private fun MyFunClockPreview( - * @PreviewParameter(WearPreviewSizesProvider::class) size: Dp + * @PreviewParameter(WearPreviewSizes::class) size: Dp * ) = WatchFacePreview(size) { * MyFunClock() * } @@ -57,6 +65,8 @@ annotation class WatchFacePreview { @Composable fun WatchFacePreview( size: Dp, + @OptIn(ExperimentalComposeOClockApi::class) + previewTime: PreviewTime.Config = PreviewTime.rememberConfig(), content: @Composable (complicationData: Map>) -> Unit ) { val spacing = 8.dp @@ -80,11 +90,13 @@ fun WatchFacePreview( val modifier = Modifier.requiredSize(size).clip(CircleShape) OClockRootCanvas( modifier = modifier, + previewTime = previewTime, isAmbientFlow = isAmbientFlow ) { content(it) } AnimatedVisibility(touched.not()) { OClockRootCanvas( modifier = modifier, + previewTime = previewTime, isAmbientFlow = remember { MutableStateFlow(true) } ) { content(it) } } diff --git a/shared/src/main/kotlin/cleanthisbeforerelease/complications/PixelWatchStyleComplication.kt b/shared/src/main/kotlin/cleanthisbeforerelease/complications/PixelWatchStyleComplication.kt index 20da976..8500e4c 100644 --- a/shared/src/main/kotlin/cleanthisbeforerelease/complications/PixelWatchStyleComplication.kt +++ b/shared/src/main/kotlin/cleanthisbeforerelease/complications/PixelWatchStyleComplication.kt @@ -3,6 +3,7 @@ package org.splitties.compose.oclock.sample.cleanthisbeforerelease.complications import android.app.PendingIntent import android.os.Build import androidx.compose.runtime.Composable +import androidx.compose.runtime.NoLiveLiterals import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.graphics.BlendMode @@ -31,6 +32,7 @@ import org.splitties.compose.oclock.complications.rememberDrawableAsState import org.splitties.compose.oclock.complications.rememberMeasuredAsState import org.splitties.compose.oclock.sample.extensions.topCenterAsTopLeft +@NoLiveLiterals // Because compilation fails otherwise. TODO: Report issue @Composable fun PixelWatchStyleComplication( complicationDataFlow: StateFlow, diff --git a/shared/src/main/kotlin/cleanthisbeforerelease/elements/CirclePatterns.kt b/shared/src/main/kotlin/cleanthisbeforerelease/elements/CirclePatterns.kt index a9285ee..71b1005 100644 --- a/shared/src/main/kotlin/cleanthisbeforerelease/elements/CirclePatterns.kt +++ b/shared/src/main/kotlin/cleanthisbeforerelease/elements/CirclePatterns.kt @@ -4,6 +4,7 @@ import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.graphics.drawscope.rotate import androidx.compose.ui.unit.dp import org.splitties.compose.oclock.sample.extensions.drawOval import org.splitties.compose.oclock.sample.extensions.rotate diff --git a/shared/src/main/kotlin/cleanthisbeforerelease/elements/PatternsPreviews.kt b/shared/src/main/kotlin/cleanthisbeforerelease/elements/PatternsPreviews.kt index ccb0516..74faf9b 100644 --- a/shared/src/main/kotlin/cleanthisbeforerelease/elements/PatternsPreviews.kt +++ b/shared/src/main/kotlin/cleanthisbeforerelease/elements/PatternsPreviews.kt @@ -3,6 +3,7 @@ package org.splitties.compose.oclock.sample.cleanthisbeforerelease.elements import androidx.compose.runtime.Composable import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.drawscope.rotate import androidx.compose.ui.unit.dp import androidx.wear.compose.ui.tooling.preview.WearPreviewSmallRound import org.splitties.compose.oclock.OClockCanvas diff --git a/shared/src/main/kotlin/cleanthisbeforerelease/experiments/KotlinLogoExperiments.kt b/shared/src/main/kotlin/cleanthisbeforerelease/experiments/KotlinLogoExperiments.kt index adada5c..9160d8f 100644 --- a/shared/src/main/kotlin/cleanthisbeforerelease/experiments/KotlinLogoExperiments.kt +++ b/shared/src/main/kotlin/cleanthisbeforerelease/experiments/KotlinLogoExperiments.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.graphics.StrokeJoin import androidx.compose.ui.graphics.drawscope.Fill import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.graphics.drawscope.rotate import androidx.compose.ui.unit.dp import org.splitties.compose.oclock.LocalIsAmbient import org.splitties.compose.oclock.OClockCanvas @@ -26,9 +27,8 @@ import org.splitties.compose.oclock.sample.extensions.lineTo import org.splitties.compose.oclock.sample.extensions.moveTo import org.splitties.compose.oclock.sample.extensions.offsetBy import org.splitties.compose.oclock.sample.extensions.plus -import org.splitties.compose.oclock.sample.extensions.quadraticBezierTo +import org.splitties.compose.oclock.sample.extensions.quadraticTo import org.splitties.compose.oclock.sample.extensions.rememberStateWithSize -import org.splitties.compose.oclock.sample.extensions.rotate import org.splitties.compose.oclock.sample.extensions.rotateAround import kotlin.math.sqrt @@ -158,7 +158,7 @@ private fun Path.setToStarX( moveTo(topMiddle) for (i in 1..count) { val target = topMiddle.rotateAround(pivot = center, degrees = 360f * i / count) - quadraticBezierTo(center, target) + quadraticTo(center, target) } close() } diff --git a/shared/src/main/kotlin/cleanthisbeforerelease/experiments/TextOnPathExperiments.kt b/shared/src/main/kotlin/cleanthisbeforerelease/experiments/TextOnPathExperiments.kt index 48fe0ed..843ea16 100644 --- a/shared/src/main/kotlin/cleanthisbeforerelease/experiments/TextOnPathExperiments.kt +++ b/shared/src/main/kotlin/cleanthisbeforerelease/experiments/TextOnPathExperiments.kt @@ -32,7 +32,7 @@ import androidx.compose.ui.util.fastForEachIndexed import org.splitties.compose.oclock.LocalIsAmbient import org.splitties.compose.oclock.OClockCanvas import org.splitties.compose.oclock.sample.WatchFacePreview -import org.splitties.compose.oclock.sample.WearPreviewSizesProvider +import org.splitties.compose.oclock.sample.WearPreviewSizes import org.splitties.compose.oclock.sample.extensions.centerAsTopLeft import org.splitties.compose.oclock.sample.extensions.drawTextOnPath import org.splitties.compose.oclock.sample.extensions.rememberStateWithSize @@ -173,7 +173,7 @@ fun TextOnPathExperiment(finalBrush: Brush) { @WatchFacePreview @Composable private fun TextOnPathExperimentPreview( - @PreviewParameter(WearPreviewSizesProvider::class) size: Dp + @PreviewParameter(WearPreviewSizes::class) size: Dp ) = WatchFacePreview(size) { TextOnPathExperiment(finalBrush = SolidColor(Color.Magenta)) } diff --git a/shared/src/main/kotlin/elements/MyPath.kt b/shared/src/main/kotlin/elements/MyPath.kt index 58ce9a5..b9e8c8d 100644 --- a/shared/src/main/kotlin/elements/MyPath.kt +++ b/shared/src/main/kotlin/elements/MyPath.kt @@ -11,7 +11,7 @@ import org.splitties.compose.oclock.sample.extensions.lineTo import org.splitties.compose.oclock.sample.extensions.moveTo import org.splitties.compose.oclock.sample.extensions.offsetBy import org.splitties.compose.oclock.sample.extensions.plus -import org.splitties.compose.oclock.sample.extensions.quadraticBezierTo +import org.splitties.compose.oclock.sample.extensions.quadraticTo import org.splitties.compose.oclock.sample.extensions.rotateAround import kotlin.math.sqrt @@ -34,7 +34,7 @@ fun Path.setToStarX( moveTo(topMiddle) for (i in 1..count) { val target = topMiddle.rotateAround(pivot = center, degrees = 360f * i / count) - quadraticBezierTo(center, target) + quadraticTo(center, target) } close() } diff --git a/shared/src/main/kotlin/elements/SinusoidalCrown.kt b/shared/src/main/kotlin/elements/SinusoidalCrown.kt index 351f014..0a5be30 100644 --- a/shared/src/main/kotlin/elements/SinusoidalCrown.kt +++ b/shared/src/main/kotlin/elements/SinusoidalCrown.kt @@ -22,20 +22,20 @@ import org.splitties.compose.oclock.LocalIsAmbient import org.splitties.compose.oclock.LocalTime import org.splitties.compose.oclock.OClockCanvas import org.splitties.compose.oclock.sample.WatchFacePreview -import org.splitties.compose.oclock.sample.WearPreviewSizesProvider +import org.splitties.compose.oclock.sample.WearPreviewSizes import org.splitties.compose.oclock.sample.elements.vectors.rememberComposeMultiplatformVectorPainter import org.splitties.compose.oclock.sample.elements.vectors.rememberWearOsLogoVectorPainter import org.splitties.compose.oclock.sample.extensions.centerAsTopLeft import org.splitties.compose.oclock.sample.extensions.drawPainter import org.splitties.compose.oclock.sample.extensions.moveTo -import org.splitties.compose.oclock.sample.extensions.quadraticBezierTo +import org.splitties.compose.oclock.sample.extensions.quadraticTo import org.splitties.compose.oclock.sample.extensions.rememberStateWithSize import org.splitties.compose.oclock.sample.extensions.rotateAround @WatchFacePreview @Composable fun SinusoidalCrownPreview( - @PreviewParameter(WearPreviewSizesProvider::class) size: Dp + @PreviewParameter(WearPreviewSizes::class) size: Dp ) = WatchFacePreview(size) { val time = LocalTime.current SinusoidalCrown(getRatio = { time.minutesWithSeconds / 60f }) @@ -111,11 +111,11 @@ private fun Path.setToSineWaveLike(size: Size) { for (i in 1..count) { val ratio = i.toFloat() / count val anglePeriod = 360f / count - quadraticBezierTo( + quadraticTo( p1 = start.copy(y = 0f).rotateAround(center, anglePeriod * (i - .75f)), p2 = start.rotateAround(pivot = center, degrees = anglePeriod * (i - .5f)) ) - quadraticBezierTo( + quadraticTo( p1 = start.copy(y = amplitude).rotateAround(center, anglePeriod * (i - .25f)), p2 = start.rotateAround(pivot = center, degrees = anglePeriod * (i)) ) @@ -132,13 +132,13 @@ private fun Path.setToDecoration(size: Size) { val ratio = i.toFloat() / count val topForward = start.rotateAround(pivot = size.center, degrees = 360f * ratio) val bottomForward = start.copy(y = amplitude).rotateAround(size.center, 360f * ratio) - quadraticBezierTo( + quadraticTo( p1 = topForward, p2 = bottomForward ) val p3 = bottomForward.rotateAround(pivot = size.center, degrees = 360f / count / 2f) val p4 = topForward.rotateAround(pivot = size.center, degrees = 360f / count / 2f) - quadraticBezierTo( + quadraticTo( p3, p4 ) } @@ -156,13 +156,13 @@ private fun Path.setToAccidentalArt1(size: Size) { val anglePeriod = 360f / count val topForward = start.rotateAround(pivot = center, degrees = 360f * ratio) val bottomForward = start.copy(y = amplitude).rotateAround(size.center, 360f * ratio) - quadraticBezierTo( + quadraticTo( p1 = topForward, p2 = start.rotateAround(center, anglePeriod) ) val p3 = bottomForward.rotateAround(pivot = size.center, degrees = 360f / count / 2f) val p4 = topForward.rotateAround(pivot = size.center, degrees = 360f / count / 2f) - quadraticBezierTo( + quadraticTo( p3, p4 ) } diff --git a/shared/src/main/kotlin/extensions/DrawScope.kt b/shared/src/main/kotlin/extensions/DrawScope.kt index 0e1e14e..b26ebce 100644 --- a/shared/src/main/kotlin/extensions/DrawScope.kt +++ b/shared/src/main/kotlin/extensions/DrawScope.kt @@ -13,8 +13,9 @@ import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.asAndroidPath import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.graphics.drawscope.DrawStyle -import androidx.compose.ui.graphics.drawscope.DrawTransform import androidx.compose.ui.graphics.drawscope.Fill +import androidx.compose.ui.graphics.drawscope.translate +import androidx.compose.ui.graphics.drawscope.withTransform import androidx.compose.ui.graphics.nativeCanvas import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.text.style.TextAlign @@ -169,32 +170,6 @@ private fun TextAlign.toPaintAlign(layoutDirection: LayoutDirection): Paint.Alig else -> TextAlign.Start.toPaintAlign(layoutDirection) } -//TODO: Remove when https://issuetracker.google.com/issues/318384666 is fixed. -inline fun DrawScope.rotate( - degrees: Float, - pivot: Offset = center, - block: DrawScope.() -> Unit -) = withTransform({ rotate(degrees, pivot) }, block) - -//TODO: Remove when https://issuetracker.google.com/issues/318384666 is fixed. -inline fun DrawScope.withTransform( - transformBlock: DrawTransform.() -> Unit, - drawBlock: DrawScope.() -> Unit -) = with(drawContext) { - // Transformation can include inset calls which change the drawing area - // so cache the previous size before the transformation is done - // and reset it afterwards - val previousSize = size - canvas.save() - try { - transformBlock(transform) - drawBlock() - } finally { - canvas.restore() - size = previousSize - } -} - fun DrawScope.drawDrawable( drawable: Drawable, topLeft: Offset = Offset.Zero, diff --git a/shared/src/main/kotlin/extensions/Path.kt b/shared/src/main/kotlin/extensions/Path.kt index ac48961..104837b 100644 --- a/shared/src/main/kotlin/extensions/Path.kt +++ b/shared/src/main/kotlin/extensions/Path.kt @@ -13,10 +13,10 @@ inline fun Path.lineTo(position: Offset) { lineTo(x = position.x, y = position.y) } -inline fun Path.quadraticBezierTo( +inline fun Path.quadraticTo( p1: Offset, p2: Offset -) = quadraticBezierTo( +) = quadraticTo( x1 = p1.x, y1 = p1.y, x2 = p2.x, diff --git a/shared/src/main/kotlin/extensions/SizeDependentState.kt b/shared/src/main/kotlin/extensions/SizeDependentState.kt index 046ce4a..1893b1c 100644 --- a/shared/src/main/kotlin/extensions/SizeDependentState.kt +++ b/shared/src/main/kotlin/extensions/SizeDependentState.kt @@ -1,13 +1,18 @@ package org.splitties.compose.oclock.sample.extensions import androidx.compose.runtime.Composable +import androidx.compose.runtime.SnapshotMutationPolicy import androidx.compose.runtime.Stable +import androidx.compose.runtime.cache +import androidx.compose.runtime.currentComposer import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.neverEqualPolicy import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.runtime.structuralEqualityPolicy import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Size import androidx.compose.ui.geometry.center @@ -15,6 +20,26 @@ import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.unit.Density import kotlin.reflect.KProperty +@Composable fun T.rememberAsStateWithSize( + key1: Any? = Unit, + key2: Any? = Unit, + key3: Any? = Unit, + calculation: SizeDependentState.Scope.(T) -> Unit +): SizeDependentState = currentComposer.let { + val t = this + it.cache( + it.changed(value = key1) or + it.changed(value = key2) or + it.changed(value = key3) or + it.changed(value = calculation) + ) { + SizeDependentState( + calculation = { calculation(t);t }, + policy = neverEqualPolicy() + ) + } +} + @Composable fun rememberStateWithSize( calculation: SizeDependentState.Scope.() -> T @@ -55,7 +80,10 @@ fun rememberStateWithSize( } @Stable -class SizeDependentState(private val calculation: Scope.() -> T) { +class SizeDependentState( + private val calculation: Scope.() -> T, + policy: SnapshotMutationPolicy = structuralEqualityPolicy() +) { interface Scope : Density { val size: Size @@ -68,14 +96,23 @@ class SizeDependentState(private val calculation: Scope.() -> T) { context (DrawScope) operator fun getValue(thisRef: Nothing?, property: KProperty<*>?): T = get() + context (DrawScope, Scope) + operator fun getValue(thisRef: Nothing?, property: KProperty<*>?): T = get() + + context (Scope) + fun provideDelegate(thisRef: Nothing?, property: KProperty<*>?): SizeDependentState { + return this + } + context (DrawScope) fun provideDelegate(thisRef: Nothing?, property: KProperty<*>?): SizeDependentState { - get() // Ensure it's activated if it's declared + get() // Ensure it's activated if declared, in case side-effects are needed at draw time. return this } - context (Scope) + context (DrawScope, Scope) fun provideDelegate(thisRef: Nothing?, property: KProperty<*>?): SizeDependentState { + get() // Ensure it's activated if declared, in case side-effects are needed at draw time. return this } @@ -85,9 +122,15 @@ class SizeDependentState(private val calculation: Scope.() -> T) { context (Scope) fun get(): T = get(size, density, fontScale) + context (DrawScope) + private fun getDrawScopeOnly(): T = get(size, density, fontScale) + context (DrawScope) fun get(): T = get(size, density, fontScale) + context (DrawScope, Scope) + fun get(): T = getDrawScopeOnly() + private fun get(size: Size, density: Float, fontScale: Float): T { scope.also { it.size = size @@ -97,9 +140,7 @@ class SizeDependentState(private val calculation: Scope.() -> T) { return value } - private val state by lazy { derivedStateOf { calculation(scope) } } - - private val value by state + private val value by derivedStateOf(policy = policy) { calculation(scope) } private val scope = object : Scope { override var density: Float by mutableFloatStateOf(1f) diff --git a/shared/src/main/kotlin/watchfaces/BasicAnalogClock.kt b/shared/src/main/kotlin/watchfaces/BasicAnalogClock.kt index 2a99d83..d7a956e 100644 --- a/shared/src/main/kotlin/watchfaces/BasicAnalogClock.kt +++ b/shared/src/main/kotlin/watchfaces/BasicAnalogClock.kt @@ -10,6 +10,7 @@ import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.graphics.drawscope.Fill import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.graphics.drawscope.rotate import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp @@ -18,7 +19,7 @@ import org.splitties.compose.oclock.LocalTime import org.splitties.compose.oclock.OClockCanvas import org.splitties.compose.oclock.sample.ComposeOClockWatermark import org.splitties.compose.oclock.sample.WatchFacePreview -import org.splitties.compose.oclock.sample.WearPreviewSizesProvider +import org.splitties.compose.oclock.sample.WearPreviewSizes import org.splitties.compose.oclock.sample.elements.clockHand import org.splitties.compose.oclock.sample.extensions.rotate @@ -135,7 +136,7 @@ private val kotlinLogoColors = listOf( @WatchFacePreview @Composable private fun BasicAnalogClockPreview( - @PreviewParameter(WearPreviewSizesProvider::class) size: Dp + @PreviewParameter(WearPreviewSizes::class) size: Dp ) = WatchFacePreview(size) { BasicAnalogClock() } diff --git a/shared/src/main/kotlin/watchfaces/ComposeFanClock.kt b/shared/src/main/kotlin/watchfaces/ComposeFanClock.kt index 0800db7..7678b6e 100644 --- a/shared/src/main/kotlin/watchfaces/ComposeFanClock.kt +++ b/shared/src/main/kotlin/watchfaces/ComposeFanClock.kt @@ -17,6 +17,7 @@ import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.graphics.StrokeJoin import androidx.compose.ui.graphics.drawscope.Fill import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.graphics.drawscope.rotate import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.Dp @@ -26,7 +27,7 @@ import org.splitties.compose.oclock.LocalIsAmbient import org.splitties.compose.oclock.LocalTime import org.splitties.compose.oclock.OClockCanvas import org.splitties.compose.oclock.sample.WatchFacePreview -import org.splitties.compose.oclock.sample.WearPreviewSizesProvider +import org.splitties.compose.oclock.sample.WearPreviewSizes import org.splitties.compose.oclock.sample.elements.SinusoidalCrown import org.splitties.compose.oclock.sample.elements.clockHand import org.splitties.compose.oclock.sample.elements.setToHeart @@ -239,7 +240,7 @@ private fun HeartHourPips() { @WatchFacePreview @Composable private fun ComposeFanClockPreview( - @PreviewParameter(WearPreviewSizesProvider::class) size: Dp + @PreviewParameter(WearPreviewSizes::class) size: Dp ) = WatchFacePreview(size) { ComposeFanClock() } diff --git a/shared/src/main/kotlin/watchfaces/KotlinFanClock.kt b/shared/src/main/kotlin/watchfaces/KotlinFanClock.kt index e1d5a35..2f2d034 100644 --- a/shared/src/main/kotlin/watchfaces/KotlinFanClock.kt +++ b/shared/src/main/kotlin/watchfaces/KotlinFanClock.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.graphics.StrokeJoin import androidx.compose.ui.graphics.drawscope.DrawStyle import androidx.compose.ui.graphics.drawscope.Fill import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.graphics.drawscope.rotate import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp @@ -23,7 +24,7 @@ import org.splitties.compose.oclock.LocalTime import org.splitties.compose.oclock.OClockCanvas import org.splitties.compose.oclock.sample.ComposeOClockWatermark import org.splitties.compose.oclock.sample.WatchFacePreview -import org.splitties.compose.oclock.sample.WearPreviewSizesProvider +import org.splitties.compose.oclock.sample.WearPreviewSizes import org.splitties.compose.oclock.sample.elements.clockHand import org.splitties.compose.oclock.sample.elements.setToHeart import org.splitties.compose.oclock.sample.elements.setToKotlinLogo @@ -209,7 +210,7 @@ private val kotlinLogoColors = listOf( @WatchFacePreview @Composable private fun KotlinFanClockPreview( - @PreviewParameter(WearPreviewSizesProvider::class) size: Dp + @PreviewParameter(WearPreviewSizes::class) size: Dp ) = WatchFacePreview(size) { KotlinFanClock() } diff --git a/shared/src/main/kotlin/watchfaces/WatchFaceSwitcher.kt b/shared/src/main/kotlin/watchfaces/WatchFaceSwitcher.kt index 0bf2d1c..4e42bf6 100644 --- a/shared/src/main/kotlin/watchfaces/WatchFaceSwitcher.kt +++ b/shared/src/main/kotlin/watchfaces/WatchFaceSwitcher.kt @@ -11,7 +11,7 @@ import androidx.compose.ui.unit.dp import org.splitties.compose.oclock.OClockCanvas import org.splitties.compose.oclock.TapEvent import org.splitties.compose.oclock.sample.WatchFacePreview -import org.splitties.compose.oclock.sample.WearPreviewSizesProvider +import org.splitties.compose.oclock.sample.WearPreviewSizes @Composable fun WatchFaceSwitcher() { @@ -45,7 +45,7 @@ fun WatchFaceSwitcher() { @WatchFacePreview @Composable private fun WatchFaceSwitcherPreview( - @PreviewParameter(WearPreviewSizesProvider::class) size: Dp + @PreviewParameter(WearPreviewSizes::class) size: Dp ) = WatchFacePreview(size) { WatchFaceSwitcher() } diff --git a/shared/src/main/kotlin/watchfaces/hansie/HansieClock.kt b/shared/src/main/kotlin/watchfaces/hansie/HansieClock.kt index 71c65c8..8e73d45 100644 --- a/shared/src/main/kotlin/watchfaces/hansie/HansieClock.kt +++ b/shared/src/main/kotlin/watchfaces/hansie/HansieClock.kt @@ -9,6 +9,7 @@ import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.BlendMode import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.graphics.drawscope.rotate import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.drawText @@ -23,7 +24,6 @@ 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.extensions.rotate import java.util.Locale @Suppress("DEPRECATION") diff --git a/versions.properties b/versions.properties index e5db9f6..a501d24 100644 --- a/versions.properties +++ b/versions.properties @@ -1,5 +1,5 @@ #### Dependencies and Plugin versions with their available updates. -#### Generated by `./gradlew refreshVersions` version 0.60.4 +#### Generated by `./gradlew refreshVersions` version 0.60.5 #### #### Don't manually edit or split the comments that start with four hashtags (####), #### they will be overwritten by refreshVersions. @@ -7,9 +7,9 @@ #### suppress inspection "SpellCheckingInspection" for whole file #### suppress inspection "UnusedProperty" for whole file -plugin.android=8.2.0 +plugin.android=8.5.0 -plugin.de.fayard.refreshVersions=0.60.4 +plugin.de.fayard.refreshVersions=0.60.5 plugin.org.splitties.dependencies-dsl=0.2.0 @@ -19,10 +19,6 @@ version.androidx.activity=1.8.2 ## # available=1.9.0-alpha01 ## # available=1.9.0-alpha02 -version.androidx.compose=2023.10.01 - -version.androidx.compose.compiler=1.5.8 - version.androidx.compose.foundation=1.6.0 ## # available=1.7.0-alpha01 @@ -43,11 +39,9 @@ version.androidx.compose.material3=1.1.2 ## # available=1.2.0-beta02 ## # available=1.2.0-rc01 -version.androidx.compose.runtime=1.6.0 -## # available=1.7.0-alpha01 +version.androidx.compose.runtime=1.7.0-beta03 -version.androidx.compose.ui=1.6.0 -## # available=1.7.0-alpha01 +version.androidx.compose.ui=1.7.0-beta03 version.androidx.core=1.12.0 ## # available=1.13.0-alpha01 @@ -94,7 +88,7 @@ version.google.android.play-services-wearable=18.1.0 version.junit.junit=4.13.2 -version.kotlin=1.9.22 +version.kotlin=2.0.0 version.robolectric=4.11.1