From b69227ed08687eadf391c2582ae382cccbbe1c96 Mon Sep 17 00:00:00 2001 From: Martmists Date: Tue, 7 Nov 2023 13:43:52 +0100 Subject: [PATCH] Support multiplatform Signed-off-by: Martmists --- build.gradle | 1 + .../com/skydoves/orbital/Configuration.kt | 2 +- .../com/skydoves/orbital/Dependencies.kt | 10 +-- orbital/build.gradle | 61 ------------------ orbital/build.gradle.kts | 62 +++++++++++++++++++ .../{main => androidMain}/AndroidManifest.xml | 0 .../{main => androidMain}/baseline-prof.txt | 0 .../com/skydoves/orbital/AnimateMovement.kt | 12 ++-- .../orbital/AnimateSharedElementTransition.kt | 14 +++-- .../skydoves/orbital/AnimateTransformation.kt | 0 .../com/skydoves/orbital/DeferredAnimation.kt | 0 .../kotlin/com/skydoves/orbital/Orbital.kt | 22 ++++--- .../com/skydoves/orbital/OrbitalScope.kt | 7 ++- .../com/skydoves/orbital/RememberMovables.kt | 0 14 files changed, 106 insertions(+), 85 deletions(-) delete mode 100644 orbital/build.gradle create mode 100644 orbital/build.gradle.kts rename orbital/src/{main => androidMain}/AndroidManifest.xml (100%) rename orbital/src/{main => androidMain}/baseline-prof.txt (100%) rename orbital/src/{main => commonMain}/kotlin/com/skydoves/orbital/AnimateMovement.kt (90%) rename orbital/src/{main => commonMain}/kotlin/com/skydoves/orbital/AnimateSharedElementTransition.kt (91%) rename orbital/src/{main => commonMain}/kotlin/com/skydoves/orbital/AnimateTransformation.kt (100%) rename orbital/src/{main => commonMain}/kotlin/com/skydoves/orbital/DeferredAnimation.kt (100%) rename orbital/src/{main => commonMain}/kotlin/com/skydoves/orbital/Orbital.kt (89%) rename orbital/src/{main => commonMain}/kotlin/com/skydoves/orbital/OrbitalScope.kt (75%) rename orbital/src/{main => commonMain}/kotlin/com/skydoves/orbital/RememberMovables.kt (100%) diff --git a/build.gradle b/build.gradle index fe1a852..24102af 100644 --- a/build.gradle +++ b/build.gradle @@ -17,6 +17,7 @@ buildscript { classpath Dependencies.dokka classpath Dependencies.kotlinBinaryValidator classpath Dependencies.hiltPlugin + classpath Dependencies.composePlugin } } diff --git a/buildSrc/src/main/kotlin/com/skydoves/orbital/Configuration.kt b/buildSrc/src/main/kotlin/com/skydoves/orbital/Configuration.kt index cb019b1..9f2752f 100644 --- a/buildSrc/src/main/kotlin/com/skydoves/orbital/Configuration.kt +++ b/buildSrc/src/main/kotlin/com/skydoves/orbital/Configuration.kt @@ -1,7 +1,7 @@ package com.skydoves.orbital object Configuration { - const val compileSdk = 33 + const val compileSdk = 34 const val targetSdk = 33 const val minSdk = 21 const val majorVersion = 0 diff --git a/buildSrc/src/main/kotlin/com/skydoves/orbital/Dependencies.kt b/buildSrc/src/main/kotlin/com/skydoves/orbital/Dependencies.kt index f366af9..a07fa50 100644 --- a/buildSrc/src/main/kotlin/com/skydoves/orbital/Dependencies.kt +++ b/buildSrc/src/main/kotlin/com/skydoves/orbital/Dependencies.kt @@ -4,12 +4,12 @@ object Versions { internal const val ANDROID_GRADLE_PLUGIN = "7.4.1" internal const val ANDROID_GRADLE_SPOTLESS = "6.7.0" internal const val GRADLE_NEXUS_PUBLISH_PLUGIN = "1.3.0" - internal const val KOTLIN = "1.8.10" - internal const val KOTLIN_GRADLE_DOKKA = "1.8.10" + internal const val KOTLIN = "1.9.10" + internal const val KOTLIN_GRADLE_DOKKA = "1.9.10" internal const val KOTLIN_BINARY_VALIDATOR = "0.13.0" - internal const val COMPOSE = "1.3.1" - internal const val COMPOSE_COMPILER = "1.4.4" + internal const val COMPOSE = "1.5.3" + const val COMPOSE_COMPILER = "1.5.3" internal const val COROUTINES = "1.6.4" internal const val RULES = "1.4.0" @@ -39,6 +39,8 @@ object Dependencies { "com.diffplug.spotless:spotless-plugin-gradle:${Versions.ANDROID_GRADLE_SPOTLESS}" const val dokka = "org.jetbrains.dokka:dokka-gradle-plugin:${Versions.KOTLIN_GRADLE_DOKKA}" const val hiltPlugin = "com.google.dagger:hilt-android-gradle-plugin:${Versions.HILT}" + const val composePlugin = + "org.jetbrains.compose:compose-gradle-plugin:${Versions.COMPOSE_COMPILER}" const val kotlinBinaryValidator = "org.jetbrains.kotlinx:binary-compatibility-validator:${Versions.KOTLIN_BINARY_VALIDATOR}" diff --git a/orbital/build.gradle b/orbital/build.gradle deleted file mode 100644 index 1201063..0000000 --- a/orbital/build.gradle +++ /dev/null @@ -1,61 +0,0 @@ -import com.skydoves.orbital.Configuration -import com.skydoves.orbital.Dependencies -import com.skydoves.orbital.Versions - -plugins { - id 'com.android.library' - id 'org.jetbrains.kotlin.android' - id 'org.jetbrains.dokka' - id 'binary-compatibility-validator' -} - -ext { - PUBLISH_GROUP_ID = Configuration.artifactGroup - PUBLISH_ARTIFACT_ID = 'orbital' - PUBLISH_VERSION = rootVersionName -} - -apply from: "${rootDir}/scripts/publish-module.gradle" - -android { - compileSdkVersion Configuration.compileSdk - defaultConfig { - minSdkVersion Configuration.minSdk - targetSdkVersion Configuration.targetSdk - } - - buildFeatures { - compose true - buildConfig false - } - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - - composeOptions { - kotlinCompilerExtensionVersion Versions.COMPOSE_COMPILER - } - - kotlinOptions { - jvmTarget = '1.8' - } - - lintOptions { - abortOnError false - } -} - -tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { - kotlinOptions.freeCompilerArgs += [ - "-Xexplicit-api=strict", - "-Xopt-in=androidx.compose.ui.ExperimentalComposeUiApi" - ] -} - -dependencies { - implementation Dependencies.composeUI - implementation Dependencies.composeRuntime - implementation Dependencies.composeMaterial -} diff --git a/orbital/build.gradle.kts b/orbital/build.gradle.kts new file mode 100644 index 0000000..96127ff --- /dev/null +++ b/orbital/build.gradle.kts @@ -0,0 +1,62 @@ +import com.skydoves.orbital.Configuration +import com.skydoves.orbital.Dependencies +import com.skydoves.orbital.Versions + +plugins { + id("com.android.library") + kotlin("multiplatform") + id("org.jetbrains.compose") + id("org.jetbrains.dokka") + id("binary-compatibility-validator") +} + +kotlin { + androidTarget() + jvm() + + sourceSets { + val commonMain by getting { + dependencies { + implementation(compose.ui) + implementation(compose.animation) + } + } + } +} + + +android { + compileSdk = Configuration.compileSdk + defaultConfig { + minSdk = Configuration.minSdk + targetSdk = Configuration.targetSdk + } + + buildFeatures { + compose = true + buildConfig = false + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + composeOptions { + kotlinCompilerExtensionVersion = Versions.COMPOSE_COMPILER + } + + lint { + abortOnError = false + } +} + +tasks.withType { + kotlinOptions { + jvmTarget = "1.8" + freeCompilerArgs += listOf( + "-Xexplicit-api=strict", + "-Xopt-in=androidx.compose.ui.ExperimentalComposeUiApi" + ) + } +} diff --git a/orbital/src/main/AndroidManifest.xml b/orbital/src/androidMain/AndroidManifest.xml similarity index 100% rename from orbital/src/main/AndroidManifest.xml rename to orbital/src/androidMain/AndroidManifest.xml diff --git a/orbital/src/main/baseline-prof.txt b/orbital/src/androidMain/baseline-prof.txt similarity index 100% rename from orbital/src/main/baseline-prof.txt rename to orbital/src/androidMain/baseline-prof.txt diff --git a/orbital/src/main/kotlin/com/skydoves/orbital/AnimateMovement.kt b/orbital/src/commonMain/kotlin/com/skydoves/orbital/AnimateMovement.kt similarity index 90% rename from orbital/src/main/kotlin/com/skydoves/orbital/AnimateMovement.kt rename to orbital/src/commonMain/kotlin/com/skydoves/orbital/AnimateMovement.kt index adaac6c..014abef 100644 --- a/orbital/src/main/kotlin/com/skydoves/orbital/AnimateMovement.kt +++ b/orbital/src/commonMain/kotlin/com/skydoves/orbital/AnimateMovement.kt @@ -25,9 +25,12 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue +import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.composed import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.layout.intermediateLayout +import androidx.compose.ui.layout.onPlaced import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.round @@ -39,6 +42,7 @@ import androidx.compose.ui.unit.round * * @param animationSpec An [FiniteAnimationSpec] which has [IntOffset] as a generic type. */ +@OptIn(ExperimentalComposeUiApi::class) public fun Modifier.animateMovement( orbitalScope: OrbitalScope, animationSpec: FiniteAnimationSpec = spring( @@ -53,14 +57,14 @@ public fun Modifier.animateMovement( } with(orbitalScope) { this@composed - .onPlaced { lookaheadScopeCoordinates, layoutCoordinates -> + .onPlaced { layoutCoordinates -> // This block of code has the LookaheadCoordinates of the LookaheadLayout // as the first parameter, and the coordinates of this modifier as the second // parameter. // localLookaheadPositionOf returns the *target* position of this // modifier in the LookaheadLayout's local coordinates. - val targetOffset = lookaheadScopeCoordinates + val targetOffset = layoutCoordinates.parentLayoutCoordinates!! .localLookaheadPositionOf( layoutCoordinates ) @@ -69,7 +73,7 @@ public fun Modifier.animateMovement( // localPositionOf returns the *current* position of this // modifier in the LookaheadLayout's local coordinates. - placementOffset = lookaheadScopeCoordinates + placementOffset = layoutCoordinates.parentLayoutCoordinates!! .localPositionOf( layoutCoordinates, Offset.Zero ) @@ -79,7 +83,7 @@ public fun Modifier.animateMovement( // intermediateLayout is expected to produce intermediate stages of a layout // transform. When the measure block is invoked after lookahead pass, the lookahead // size of the child will be accessible as a parameter to the measure block. - .intermediateLayout { measurable, constraints, _ -> + .intermediateLayout { measurable, constraints -> val placeable = measurable.measure(constraints) layout(placeable.width, placeable.height) { // offsetAnimation will animate the target position whenever it changes. diff --git a/orbital/src/main/kotlin/com/skydoves/orbital/AnimateSharedElementTransition.kt b/orbital/src/commonMain/kotlin/com/skydoves/orbital/AnimateSharedElementTransition.kt similarity index 91% rename from orbital/src/main/kotlin/com/skydoves/orbital/AnimateSharedElementTransition.kt rename to orbital/src/commonMain/kotlin/com/skydoves/orbital/AnimateSharedElementTransition.kt index 40b7c9c..0163d8c 100644 --- a/orbital/src/main/kotlin/com/skydoves/orbital/AnimateSharedElementTransition.kt +++ b/orbital/src/commonMain/kotlin/com/skydoves/orbital/AnimateSharedElementTransition.kt @@ -25,9 +25,12 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue +import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.composed import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.layout.intermediateLayout +import androidx.compose.ui.layout.onPlaced import androidx.compose.ui.unit.Constraints import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.IntSize @@ -40,6 +43,7 @@ import androidx.compose.ui.unit.round * @param movementSpec An [FiniteAnimationSpec] which has [IntOffset] as a generic type. * @param transformSpec An [FiniteAnimationSpec] which has [IntSize] as a generic type. */ +@OptIn(ExperimentalComposeUiApi::class) public fun Modifier.animateSharedElementTransition( orbitalScope: OrbitalScope, movementSpec: FiniteAnimationSpec = spring( @@ -66,7 +70,7 @@ public fun Modifier.animateSharedElementTransition( // child will be accessible as a parameter to the measure block. with(orbitalScope) { this@composed - .intermediateLayout { measurable, constraints, lookaheadSize -> + .intermediateLayout { measurable, constraints -> val (width, height) = sizeAnimation.value ?: lookaheadSize measurable .measure(constraints) @@ -76,14 +80,14 @@ public fun Modifier.animateSharedElementTransition( } } } - .onPlaced { lookaheadScopeCoordinates, layoutCoordinates -> + .onPlaced { layoutCoordinates -> // This block of code has the LookaheadCoordinates of the LookaheadLayout // as the first parameter, and the coordinates of this modifier as the second // parameter. // localLookaheadPositionOf returns the *target* position of this // modifier in the LookaheadLayout's local coordinates. - val targetOffset = lookaheadScopeCoordinates + val targetOffset = layoutCoordinates.parentLayoutCoordinates!! .localLookaheadPositionOf( layoutCoordinates ) @@ -92,13 +96,13 @@ public fun Modifier.animateSharedElementTransition( // localPositionOf returns the *current* position of this // modifier in the LookaheadLayout's local coordinates. - placementOffset = lookaheadScopeCoordinates + placementOffset = layoutCoordinates.parentLayoutCoordinates!! .localPositionOf( layoutCoordinates, Offset.Zero ) .round() } - .intermediateLayout { measurable, _, lookaheadSize -> + .intermediateLayout { measurable, _ -> // When layout changes, the lookahead pass will calculate a new final size for the // child modifier. This lookahead size can be used to animate the size // change, such that the animation starts from the current size and gradually diff --git a/orbital/src/main/kotlin/com/skydoves/orbital/AnimateTransformation.kt b/orbital/src/commonMain/kotlin/com/skydoves/orbital/AnimateTransformation.kt similarity index 100% rename from orbital/src/main/kotlin/com/skydoves/orbital/AnimateTransformation.kt rename to orbital/src/commonMain/kotlin/com/skydoves/orbital/AnimateTransformation.kt diff --git a/orbital/src/main/kotlin/com/skydoves/orbital/DeferredAnimation.kt b/orbital/src/commonMain/kotlin/com/skydoves/orbital/DeferredAnimation.kt similarity index 100% rename from orbital/src/main/kotlin/com/skydoves/orbital/DeferredAnimation.kt rename to orbital/src/commonMain/kotlin/com/skydoves/orbital/DeferredAnimation.kt diff --git a/orbital/src/main/kotlin/com/skydoves/orbital/Orbital.kt b/orbital/src/commonMain/kotlin/com/skydoves/orbital/Orbital.kt similarity index 89% rename from orbital/src/main/kotlin/com/skydoves/orbital/Orbital.kt rename to orbital/src/commonMain/kotlin/com/skydoves/orbital/Orbital.kt index c669a3a..8d2d510 100644 --- a/orbital/src/main/kotlin/com/skydoves/orbital/Orbital.kt +++ b/orbital/src/commonMain/kotlin/com/skydoves/orbital/Orbital.kt @@ -18,8 +18,11 @@ package com.skydoves.orbital import androidx.compose.runtime.Composable import androidx.compose.runtime.remember +import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.Layout import androidx.compose.ui.layout.LookaheadLayout +import androidx.compose.ui.layout.LookaheadScope import androidx.compose.ui.layout.MeasurePolicy import java.lang.Integer.max @@ -32,20 +35,23 @@ import java.lang.Integer.max * @param measurePolicy The function that defines the measurement and layout. * @param content A Composable that receives [OrbitalScope]. */ +@OptIn(ExperimentalComposeUiApi::class) @Composable public fun Orbital( modifier: Modifier = Modifier, measurePolicy: MeasurePolicy = internalMeasurePolicy, content: @Composable OrbitalScope.() -> Unit ) { - LookaheadLayout( - content = { - val orbitalScope = remember { OrbitalScope(this) } - orbitalScope.content() - }, - modifier = modifier, - measurePolicy = measurePolicy - ) + LookaheadScope { + Layout( + content = { + val orbitalScope = remember { OrbitalScope(this) } + orbitalScope.content() + }, + modifier = modifier, + measurePolicy = measurePolicy + ) + } } /** diff --git a/orbital/src/main/kotlin/com/skydoves/orbital/OrbitalScope.kt b/orbital/src/commonMain/kotlin/com/skydoves/orbital/OrbitalScope.kt similarity index 75% rename from orbital/src/main/kotlin/com/skydoves/orbital/OrbitalScope.kt rename to orbital/src/commonMain/kotlin/com/skydoves/orbital/OrbitalScope.kt index f030630..f8e8325 100644 --- a/orbital/src/main/kotlin/com/skydoves/orbital/OrbitalScope.kt +++ b/orbital/src/commonMain/kotlin/com/skydoves/orbital/OrbitalScope.kt @@ -16,10 +16,13 @@ package com.skydoves.orbital +import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.layout.LookaheadLayoutScope +import androidx.compose.ui.layout.LookaheadScope /** * OrbitalScope is a scope that wraps [LookaheadLayoutScope] to apply animations. */ -public class OrbitalScope internal constructor(lookaheadLayoutScope: LookaheadLayoutScope) : - LookaheadLayoutScope by lookaheadLayoutScope +@OptIn(ExperimentalComposeUiApi::class) +public class OrbitalScope internal constructor(lookaheadScope: LookaheadScope) : + LookaheadScope by lookaheadScope diff --git a/orbital/src/main/kotlin/com/skydoves/orbital/RememberMovables.kt b/orbital/src/commonMain/kotlin/com/skydoves/orbital/RememberMovables.kt similarity index 100% rename from orbital/src/main/kotlin/com/skydoves/orbital/RememberMovables.kt rename to orbital/src/commonMain/kotlin/com/skydoves/orbital/RememberMovables.kt