diff --git a/.gitignore b/.gitignore index aa724b7..28a82e3 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ .externalNativeBuild .cxx local.properties +/.kotlin diff --git a/.idea/artifacts/app.xml b/.idea/artifacts/app.xml new file mode 100644 index 0000000..ed2bb0f --- /dev/null +++ b/.idea/artifacts/app.xml @@ -0,0 +1,8 @@ + + + $PROJECT_DIR$/app/build/libs + + + + + \ No newline at end of file diff --git a/.idea/artifacts/app_desktop.xml b/.idea/artifacts/app_desktop.xml new file mode 100644 index 0000000..ff875ba --- /dev/null +++ b/.idea/artifacts/app_desktop.xml @@ -0,0 +1,8 @@ + + + $PROJECT_DIR$/app/build/libs + + + + + \ No newline at end of file diff --git a/.idea/artifacts/app_js.xml b/.idea/artifacts/app_js.xml new file mode 100644 index 0000000..93a033e --- /dev/null +++ b/.idea/artifacts/app_js.xml @@ -0,0 +1,8 @@ + + + $PROJECT_DIR$/app/build/libs + + + + + \ No newline at end of file diff --git a/.idea/artifacts/app_wasm_js.xml b/.idea/artifacts/app_wasm_js.xml new file mode 100644 index 0000000..b7affd0 --- /dev/null +++ b/.idea/artifacts/app_wasm_js.xml @@ -0,0 +1,8 @@ + + + $PROJECT_DIR$/app/build/libs + + + + + \ No newline at end of file diff --git a/.idea/artifacts/backdrop.xml b/.idea/artifacts/backdrop.xml new file mode 100644 index 0000000..6508176 --- /dev/null +++ b/.idea/artifacts/backdrop.xml @@ -0,0 +1,8 @@ + + + $PROJECT_DIR$/backdrop/build/libs + + + + + \ No newline at end of file diff --git a/.idea/artifacts/backdrop_desktop.xml b/.idea/artifacts/backdrop_desktop.xml new file mode 100644 index 0000000..59e3ee8 --- /dev/null +++ b/.idea/artifacts/backdrop_desktop.xml @@ -0,0 +1,8 @@ + + + $PROJECT_DIR$/backdrop/build/libs + + + + + \ No newline at end of file diff --git a/.idea/artifacts/backdrop_js.xml b/.idea/artifacts/backdrop_js.xml new file mode 100644 index 0000000..a9eda81 --- /dev/null +++ b/.idea/artifacts/backdrop_js.xml @@ -0,0 +1,8 @@ + + + $PROJECT_DIR$/backdrop/build/libs + + + + + \ No newline at end of file diff --git a/.idea/artifacts/backdrop_wasm_js.xml b/.idea/artifacts/backdrop_wasm_js.xml new file mode 100644 index 0000000..342a789 --- /dev/null +++ b/.idea/artifacts/backdrop_wasm_js.xml @@ -0,0 +1,8 @@ + + + $PROJECT_DIR$/backdrop/build/libs + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 73902b3..04ba6ce 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -9,8 +9,9 @@ diff --git a/README.md b/README.md index 1cf42fc..cd8733f 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# Android Liquid Glass (Backdrop) +# Liquid Glass (Backdrop) ![frontPhoto](artworks/banner.jpg) -A customizable Liquid Glass effect library for Jetpack Compose. +A customizable Liquid Glass effect library for Compose Multiplatform. ## Docs @@ -15,17 +15,13 @@ A customizable Liquid Glass effect library for Jetpack Compose. The library does not include any high-level components; you will need to create your own. Below are some example components: -- [LiquidButton](/catalog/src/main/java/com/kyant/backdrop/catalog/components/LiquidButton.kt) -- [LiquidToggle](/catalog/src/main/java/com/kyant/backdrop/catalog/components/LiquidToggle.kt) -- [LiquidSlider](/catalog/src/main/java/com/kyant/backdrop/catalog/components/LiquidSlider.kt) -- [LiquidBottomTabs](/catalog/src/main/java/com/kyant/backdrop/catalog/components/LiquidBottomTabs.kt) +- [LiquidButton](/androidApp/src/main/java/com/kyant/backdrop/catalog/components/LiquidButton.kt) +- [LiquidToggle](/androidApp/src/main/java/com/kyant/backdrop/catalog/components/LiquidToggle.kt) +- [LiquidSlider](/androidApp/src/main/java/com/kyant/backdrop/catalog/components/LiquidSlider.kt) +- [LiquidBottomTabs](/androidApp/src/main/java/com/kyant/backdrop/catalog/components/LiquidBottomTabs.kt) -## Demos +## Demo -- [Backdrop Catalog](./catalog/release/catalog-release.apk) +- [Backdrop Catalog](./androidApp/release/catalog-release.apk) ![Screenshots of Backdrop Catalog](artworks/catalog_app.jpg) - -- **(Deprecated)** [Liquid Glass Playground](./app/release/app-release.apk) (Android 13+) - -Screenshots of Liquid Glass Playground diff --git a/catalog/.gitignore b/androidApp/.gitignore similarity index 100% rename from catalog/.gitignore rename to androidApp/.gitignore diff --git a/catalog/build.gradle.kts b/androidApp/build.gradle.kts similarity index 86% rename from catalog/build.gradle.kts rename to androidApp/build.gradle.kts index c1de45f..e1e46f0 100644 --- a/catalog/build.gradle.kts +++ b/androidApp/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + plugins { alias(libs.plugins.android.application) alias(libs.plugins.kotlin.compose) @@ -57,8 +59,8 @@ android { } kotlin { - jvmToolchain(21) compilerOptions { + jvmTarget = JvmTarget.JVM_11 freeCompilerArgs.addAll( "-Xlambdas=class" ) @@ -68,10 +70,10 @@ kotlin { dependencies { implementation(libs.androidx.core.ktx) implementation(libs.androidx.activity.compose) - implementation(libs.androidx.compose.foundation) - implementation(libs.androidx.compose.ui) - implementation(libs.androidx.compose.ui.graphics) - implementation(libs.androidx.compose.material.ripple) + implementation(libs.compose.foundation) + implementation(libs.compose.ui) + implementation(libs.compose.ui.graphics) + implementation(libs.compose.material.ripple) implementation(libs.kyant.shapes) implementation(project(":backdrop")) } diff --git a/catalog/proguard-rules.pro b/androidApp/proguard-rules.pro similarity index 100% rename from catalog/proguard-rules.pro rename to androidApp/proguard-rules.pro diff --git a/catalog/release/baselineProfiles/0/catalog-release.dm b/androidApp/release/baselineProfiles/0/catalog-release.dm similarity index 100% rename from catalog/release/baselineProfiles/0/catalog-release.dm rename to androidApp/release/baselineProfiles/0/catalog-release.dm diff --git a/catalog/release/baselineProfiles/1/catalog-release.dm b/androidApp/release/baselineProfiles/1/catalog-release.dm similarity index 100% rename from catalog/release/baselineProfiles/1/catalog-release.dm rename to androidApp/release/baselineProfiles/1/catalog-release.dm diff --git a/catalog/release/catalog-release.apk b/androidApp/release/catalog-release.apk similarity index 100% rename from catalog/release/catalog-release.apk rename to androidApp/release/catalog-release.apk diff --git a/catalog/release/output-metadata.json b/androidApp/release/output-metadata.json similarity index 100% rename from catalog/release/output-metadata.json rename to androidApp/release/output-metadata.json diff --git a/catalog/src/main/AndroidManifest.xml b/androidApp/src/main/AndroidManifest.xml similarity index 100% rename from catalog/src/main/AndroidManifest.xml rename to androidApp/src/main/AndroidManifest.xml diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/BackdropDemoScaffold.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/BackdropDemoScaffold.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/BackdropDemoScaffold.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/BackdropDemoScaffold.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/Block.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/Block.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/Block.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/Block.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/CatalogDestination.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/CatalogDestination.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/CatalogDestination.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/CatalogDestination.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/MainActivity.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/MainActivity.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/MainActivity.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/MainActivity.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/MainContent.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/MainContent.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/MainContent.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/MainContent.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/Ripple.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/Ripple.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/Ripple.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/Ripple.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/components/LiquidBottomTab.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/components/LiquidBottomTab.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/components/LiquidBottomTab.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/components/LiquidBottomTab.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/components/LiquidBottomTabs.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/components/LiquidBottomTabs.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/components/LiquidBottomTabs.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/components/LiquidBottomTabs.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/components/LiquidButton.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/components/LiquidButton.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/components/LiquidButton.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/components/LiquidButton.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/components/LiquidSlider.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/components/LiquidSlider.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/components/LiquidSlider.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/components/LiquidSlider.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/components/LiquidToggle.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/components/LiquidToggle.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/components/LiquidToggle.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/components/LiquidToggle.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/destinations/AdaptiveLuminanceGlassContent.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/AdaptiveLuminanceGlassContent.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/destinations/AdaptiveLuminanceGlassContent.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/AdaptiveLuminanceGlassContent.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/destinations/BottomTabsContent.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/BottomTabsContent.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/destinations/BottomTabsContent.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/BottomTabsContent.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/destinations/ButtonsContent.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/ButtonsContent.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/destinations/ButtonsContent.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/ButtonsContent.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/destinations/ControlCenterContent.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/ControlCenterContent.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/destinations/ControlCenterContent.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/ControlCenterContent.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/destinations/DialogContent.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/DialogContent.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/destinations/DialogContent.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/DialogContent.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/destinations/GlassPlaygroundContent.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/GlassPlaygroundContent.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/destinations/GlassPlaygroundContent.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/GlassPlaygroundContent.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/destinations/HomeContent.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/HomeContent.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/destinations/HomeContent.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/HomeContent.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/destinations/LazyScrollContainerContent.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/LazyScrollContainerContent.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/destinations/LazyScrollContainerContent.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/LazyScrollContainerContent.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/destinations/LockScreenContent.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/LockScreenContent.kt similarity index 97% rename from catalog/src/main/java/com/kyant/backdrop/catalog/destinations/LockScreenContent.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/LockScreenContent.kt index f157db9..b7f2334 100644 --- a/catalog/src/main/java/com/kyant/backdrop/catalog/destinations/LockScreenContent.kt +++ b/androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/LockScreenContent.kt @@ -26,7 +26,7 @@ import com.kyant.backdrop.catalog.utils.rememberSdfShader import com.kyant.backdrop.drawPlainBackdrop import com.kyant.backdrop.effects.blur import com.kyant.backdrop.effects.colorControls -import com.kyant.shapes.Capsule +import com.kyant.shapes.Rectangle @Composable fun LockScreenContent() { @@ -56,7 +56,7 @@ fun LockScreenContent() { .draggable2D(rememberDraggable2DState { delta -> offset += delta }) .drawPlainBackdrop( backdrop = backdrop, - shape = { Capsule }, + shape = { Rectangle }, effects = { colorControls(brightness = -0.1f, contrast = 0.75f, saturation = 1.5f) blur(2f.dp.toPx()) diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/destinations/MagnifierContent.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/MagnifierContent.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/destinations/MagnifierContent.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/MagnifierContent.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/destinations/ProgressiveBlurContent.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/ProgressiveBlurContent.kt similarity index 69% rename from catalog/src/main/java/com/kyant/backdrop/catalog/destinations/ProgressiveBlurContent.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/ProgressiveBlurContent.kt index 48e157e..92d2ad4 100644 --- a/catalog/src/main/java/com/kyant/backdrop/catalog/destinations/ProgressiveBlurContent.kt +++ b/androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/ProgressiveBlurContent.kt @@ -1,7 +1,5 @@ package com.kyant.backdrop.catalog.destinations -import android.graphics.RenderEffect -import android.os.Build import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -14,14 +12,13 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.RectangleShape -import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.kyant.backdrop.catalog.BackdropDemoScaffold import com.kyant.backdrop.drawPlainBackdrop import com.kyant.backdrop.effects.blur -import com.kyant.backdrop.effects.effect +import com.kyant.backdrop.effects.runtimeShaderEffect @Composable fun ProgressiveBlurContent() { @@ -41,12 +38,9 @@ fun ProgressiveBlurContent() { shape = { RectangleShape }, effects = { blur(4f.dp.toPx()) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - effect( - RenderEffect.createRuntimeShaderEffect( - obtainRuntimeShader( - "AlphaMask", - """ + runtimeShaderEffect( + "AlphaMask", + """ uniform shader content; uniform float2 size; @@ -57,15 +51,12 @@ half4 main(float2 coord) { float blurAlpha = smoothstep(size.y, size.y * 0.5, coord.y); float tintAlpha = smoothstep(size.y, size.y * 0.5, coord.y); return mix(content.eval(coord) * blurAlpha, tint * tintAlpha, tintIntensity); -}""" - ).apply { - setFloatUniform("size", size.width, size.height) - setColorUniform("tint", tintColor.toArgb()) - setFloatUniform("tintIntensity", 0.8f) - }, - "content" - ) - ) +}""", + "content" + ) { + setFloatUniform("size", size.width, size.height) + setColorUniform("tint", tintColor) + setFloatUniform("tintIntensity", 0.8f) } } ) diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/destinations/ScrollContainerContent.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/ScrollContainerContent.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/destinations/ScrollContainerContent.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/ScrollContainerContent.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/destinations/SliderContent.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/SliderContent.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/destinations/SliderContent.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/SliderContent.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/destinations/ToggleContent.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/ToggleContent.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/destinations/ToggleContent.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/destinations/ToggleContent.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/utils/DampedDragAnimation.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/utils/DampedDragAnimation.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/utils/DampedDragAnimation.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/utils/DampedDragAnimation.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/utils/DragGestureInspector.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/utils/DragGestureInspector.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/utils/DragGestureInspector.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/utils/DragGestureInspector.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/utils/InteractiveHighlight.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/utils/InteractiveHighlight.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/utils/InteractiveHighlight.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/utils/InteractiveHighlight.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/utils/LoremIpsum.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/utils/LoremIpsum.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/utils/LoremIpsum.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/utils/LoremIpsum.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/utils/ProgressConverter.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/utils/ProgressConverter.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/utils/ProgressConverter.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/utils/ProgressConverter.kt diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/utils/SdfShader.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/utils/SdfShader.kt similarity index 80% rename from catalog/src/main/java/com/kyant/backdrop/catalog/utils/SdfShader.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/utils/SdfShader.kt index b5f38ee..153b197 100644 --- a/catalog/src/main/java/com/kyant/backdrop/catalog/utils/SdfShader.kt +++ b/androidApp/src/main/java/com/kyant/backdrop/catalog/utils/SdfShader.kt @@ -2,7 +2,6 @@ package com.kyant.backdrop.catalog.utils import android.graphics.Bitmap import android.graphics.BitmapShader -import android.graphics.RenderEffect import android.graphics.Shader import android.graphics.drawable.BitmapDrawable import android.os.Build @@ -14,7 +13,8 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalResources import androidx.compose.ui.unit.dp import com.kyant.backdrop.BackdropEffectScope -import com.kyant.backdrop.effects.effect +import com.kyant.backdrop.asAndroidRuntimeShader +import com.kyant.backdrop.effects.runtimeShaderEffect import org.intellij.lang.annotations.Language @Composable @@ -39,15 +39,17 @@ class SdfShader(val sdfBitmap: Bitmap) { lightAngle: Float = 45f ) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - val shader = - obtainRuntimeShader("SdfShader", createSdfShaderString()).apply { - setInputBuffer("sdfTex", sdfTexture) - setFloatUniform("size", size.width, size.height) - setFloatUniform("sdfTexSize", sdfBitmap.width.toFloat(), sdfBitmap.height.toFloat()) - setFloatUniform("refractionHeight", refractionHeight) - setFloatUniform("lightAngle", lightAngle) - } - effect(RenderEffect.createRuntimeShaderEffect(shader, "content")) + runtimeShaderEffect( + "SdfShader", + createSdfShaderString(), + "content" + ) { + asAndroidRuntimeShader().setInputBuffer("sdfTex", sdfTexture) + setFloatUniform("size", size.width, size.height) + setFloatUniform("sdfTexSize", sdfBitmap.width.toFloat(), sdfBitmap.height.toFloat()) + setFloatUniform("refractionHeight", refractionHeight) + setFloatUniform("lightAngle", lightAngle) + } } } } diff --git a/catalog/src/main/java/com/kyant/backdrop/catalog/utils/UISensor.kt b/androidApp/src/main/java/com/kyant/backdrop/catalog/utils/UISensor.kt similarity index 100% rename from catalog/src/main/java/com/kyant/backdrop/catalog/utils/UISensor.kt rename to androidApp/src/main/java/com/kyant/backdrop/catalog/utils/UISensor.kt diff --git a/catalog/src/main/res/drawable-v24/ic_launcher_foreground.xml b/androidApp/src/main/res/drawable-v24/ic_launcher_foreground.xml similarity index 100% rename from catalog/src/main/res/drawable-v24/ic_launcher_foreground.xml rename to androidApp/src/main/res/drawable-v24/ic_launcher_foreground.xml diff --git a/catalog/src/main/res/drawable/flight_40px.xml b/androidApp/src/main/res/drawable/flight_40px.xml similarity index 100% rename from catalog/src/main/res/drawable/flight_40px.xml rename to androidApp/src/main/res/drawable/flight_40px.xml diff --git a/catalog/src/main/res/drawable/flower.jpg b/androidApp/src/main/res/drawable/flower.jpg similarity index 100% rename from catalog/src/main/res/drawable/flower.jpg rename to androidApp/src/main/res/drawable/flower.jpg diff --git a/catalog/src/main/res/drawable/ic_launcher_background.xml b/androidApp/src/main/res/drawable/ic_launcher_background.xml similarity index 100% rename from catalog/src/main/res/drawable/ic_launcher_background.xml rename to androidApp/src/main/res/drawable/ic_launcher_background.xml diff --git a/catalog/src/main/res/drawable/instagram_logo.xml b/androidApp/src/main/res/drawable/instagram_logo.xml similarity index 100% rename from catalog/src/main/res/drawable/instagram_logo.xml rename to androidApp/src/main/res/drawable/instagram_logo.xml diff --git a/catalog/src/main/res/drawable/sdf.webp b/androidApp/src/main/res/drawable/sdf.webp similarity index 100% rename from catalog/src/main/res/drawable/sdf.webp rename to androidApp/src/main/res/drawable/sdf.webp diff --git a/catalog/src/main/res/drawable/system_home_screen_light.webp b/androidApp/src/main/res/drawable/system_home_screen_light.webp similarity index 100% rename from catalog/src/main/res/drawable/system_home_screen_light.webp rename to androidApp/src/main/res/drawable/system_home_screen_light.webp diff --git a/catalog/src/main/res/drawable/wallpaper_light.webp b/androidApp/src/main/res/drawable/wallpaper_light.webp similarity index 100% rename from catalog/src/main/res/drawable/wallpaper_light.webp rename to androidApp/src/main/res/drawable/wallpaper_light.webp diff --git a/catalog/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml similarity index 100% rename from catalog/src/main/res/mipmap-anydpi-v26/ic_launcher.xml rename to androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher.xml diff --git a/catalog/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml similarity index 100% rename from catalog/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml rename to androidApp/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml diff --git a/catalog/src/main/res/mipmap-hdpi/ic_launcher.webp b/androidApp/src/main/res/mipmap-hdpi/ic_launcher.webp similarity index 100% rename from catalog/src/main/res/mipmap-hdpi/ic_launcher.webp rename to androidApp/src/main/res/mipmap-hdpi/ic_launcher.webp diff --git a/catalog/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/androidApp/src/main/res/mipmap-hdpi/ic_launcher_round.webp similarity index 100% rename from catalog/src/main/res/mipmap-hdpi/ic_launcher_round.webp rename to androidApp/src/main/res/mipmap-hdpi/ic_launcher_round.webp diff --git a/catalog/src/main/res/mipmap-mdpi/ic_launcher.webp b/androidApp/src/main/res/mipmap-mdpi/ic_launcher.webp similarity index 100% rename from catalog/src/main/res/mipmap-mdpi/ic_launcher.webp rename to androidApp/src/main/res/mipmap-mdpi/ic_launcher.webp diff --git a/catalog/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/androidApp/src/main/res/mipmap-mdpi/ic_launcher_round.webp similarity index 100% rename from catalog/src/main/res/mipmap-mdpi/ic_launcher_round.webp rename to androidApp/src/main/res/mipmap-mdpi/ic_launcher_round.webp diff --git a/catalog/src/main/res/mipmap-xhdpi/ic_launcher.webp b/androidApp/src/main/res/mipmap-xhdpi/ic_launcher.webp similarity index 100% rename from catalog/src/main/res/mipmap-xhdpi/ic_launcher.webp rename to androidApp/src/main/res/mipmap-xhdpi/ic_launcher.webp diff --git a/catalog/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/androidApp/src/main/res/mipmap-xhdpi/ic_launcher_round.webp similarity index 100% rename from catalog/src/main/res/mipmap-xhdpi/ic_launcher_round.webp rename to androidApp/src/main/res/mipmap-xhdpi/ic_launcher_round.webp diff --git a/catalog/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/androidApp/src/main/res/mipmap-xxhdpi/ic_launcher.webp similarity index 100% rename from catalog/src/main/res/mipmap-xxhdpi/ic_launcher.webp rename to androidApp/src/main/res/mipmap-xxhdpi/ic_launcher.webp diff --git a/catalog/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/androidApp/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp similarity index 100% rename from catalog/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp rename to androidApp/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp diff --git a/catalog/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/androidApp/src/main/res/mipmap-xxxhdpi/ic_launcher.webp similarity index 100% rename from catalog/src/main/res/mipmap-xxxhdpi/ic_launcher.webp rename to androidApp/src/main/res/mipmap-xxxhdpi/ic_launcher.webp diff --git a/catalog/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/androidApp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp similarity index 100% rename from catalog/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp rename to androidApp/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp diff --git a/catalog/src/main/res/values-night/themes.xml b/androidApp/src/main/res/values-night/themes.xml similarity index 100% rename from catalog/src/main/res/values-night/themes.xml rename to androidApp/src/main/res/values-night/themes.xml diff --git a/catalog/src/main/res/values/strings.xml b/androidApp/src/main/res/values/strings.xml similarity index 100% rename from catalog/src/main/res/values/strings.xml rename to androidApp/src/main/res/values/strings.xml diff --git a/catalog/src/main/res/values/themes.xml b/androidApp/src/main/res/values/themes.xml similarity index 100% rename from catalog/src/main/res/values/themes.xml rename to androidApp/src/main/res/values/themes.xml diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 0000000..6119f54 --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,96 @@ +import org.jetbrains.compose.desktop.application.dsl.TargetFormat +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +plugins { + alias(libs.plugins.android.multiplatform.library) + alias(libs.plugins.kotlin.multiplatform) + alias(libs.plugins.kotlin.compose) + alias(libs.plugins.jetbrains.compose) +} + +kotlin { + androidLibrary { + compileSdk = 36 + namespace = "com.kyant.backdrop.catalog" + compilerOptions { + jvmTarget = JvmTarget.JVM_11 + } + } + + jvm("desktop") + + js(IR) { + browser() + } + wasmJs { + browser() + } + + macosArm64() + iosArm64("iosArm64") + iosSimulatorArm64("iosSimulatorArm64") + + sourceSets { + val commonMain by getting { + dependencies { + implementation(libs.compose.foundation) + implementation(libs.compose.ui) + implementation(libs.compose.ui.graphics) + implementation(libs.compose.material.ripple) + implementation(libs.kyant.shapes) + implementation(project(":backdrop")) + } + } + + val skikoMain by creating { + dependsOn(commonMain) + } + + val desktopMain by getting { + dependsOn(skikoMain) + dependencies { + implementation(compose.desktop.currentOs) + } + } + + val macosArm64Main by getting { + dependsOn(skikoMain) + } + + val iosMain by creating { + dependsOn(skikoMain) + } + + val iosArm64Main by getting { + dependsOn(iosMain) + } + + val iosSimulatorArm64Main by getting { + dependsOn(iosMain) + } + + val jsMain by getting { + dependsOn(skikoMain) + } + + val wasmJsMain by getting { + dependsOn(skikoMain) + } + + all { + languageSettings.enableLanguageFeature("ContextParameters") + } + } +} + +compose.desktop { + application { + mainClass = "com.kyant.backdrop.catalog.MainKt" + + nativeDistributions { + targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) + packageName = "com.kyant.backdrop.catalog" + packageVersion = "1.0.0" + } + } +} diff --git a/app/release/app-release.apk b/app/release/app-release.apk deleted file mode 100644 index 3911184..0000000 Binary files a/app/release/app-release.apk and /dev/null differ diff --git a/app/src/commonMain/kotlin/com/kyant/backdrop/catalog/MainContent.kt b/app/src/commonMain/kotlin/com/kyant/backdrop/catalog/MainContent.kt new file mode 100644 index 0000000..0bc3362 --- /dev/null +++ b/app/src/commonMain/kotlin/com/kyant/backdrop/catalog/MainContent.kt @@ -0,0 +1,73 @@ +package com.kyant.backdrop.catalog + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.text.BasicText +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.kyant.backdrop.backdrops.layerBackdrop +import com.kyant.backdrop.backdrops.rememberLayerBackdrop +import com.kyant.backdrop.drawBackdrop +import com.kyant.backdrop.effects.blur +import com.kyant.backdrop.effects.colorControls +import com.kyant.backdrop.effects.lens +import com.kyant.shapes.RoundedRectangle + +@Composable +fun MainContent() { + Box( + Modifier + .fillMaxSize(), + contentAlignment = Alignment.Center + ) { + val backdrop = rememberLayerBackdrop() + + Box( + Modifier + .layerBackdrop(backdrop) + .drawBehind { + drawRect( + Brush.sweepGradient( + listOf( + Color(0xFFFF6D6D), + Color(0xFFFFD86D), + Color(0xFF6DFF8E), + Color(0xFF6DE1FF), + Color(0xFFFF6D6D), + ) + ) + ) + drawRect(Color.Black.copy(alpha = 0.5f)) + } + .fillMaxSize(), + contentAlignment = Alignment.Center + ) { + BasicText( + "This is the content behind the backdrop!", + style = TextStyle(fontSize = 20f.sp) + ) + } + + Box( + Modifier + .drawBackdrop( + backdrop, + { RoundedRectangle(32f.dp) }, + { + colorControls(brightness = 0.2f, contrast = 1.5f, saturation = 1.5f) + blur(1f.dp.toPx()) + lens(32f.dp.toPx(), 64f.dp.toPx()) + } + ) + .size(256f.dp) + ) + } +} diff --git a/app/src/desktopMain/kotlin/com/kyant/backdrop/catalog/Main.kt b/app/src/desktopMain/kotlin/com/kyant/backdrop/catalog/Main.kt new file mode 100644 index 0000000..4906cc7 --- /dev/null +++ b/app/src/desktopMain/kotlin/com/kyant/backdrop/catalog/Main.kt @@ -0,0 +1,17 @@ +package com.kyant.backdrop.catalog + +import androidx.compose.ui.Alignment +import androidx.compose.ui.window.Window +import androidx.compose.ui.window.WindowPosition +import androidx.compose.ui.window.application +import androidx.compose.ui.window.rememberWindowState + +fun main() = application { + Window( + onCloseRequest = ::exitApplication, + state = rememberWindowState(position = WindowPosition.Aligned(Alignment.Center)), + title = "Backdrop Catalog", + ) { + MainContent() + } +} diff --git a/backdrop/build.gradle.kts b/backdrop/build.gradle.kts index 4ae073d..ee03a36 100644 --- a/backdrop/build.gradle.kts +++ b/backdrop/build.gradle.kts @@ -1,57 +1,93 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + plugins { - alias(libs.plugins.android.library) + alias(libs.plugins.android.multiplatform.library) + alias(libs.plugins.kotlin.multiplatform) alias(libs.plugins.kotlin.compose) + alias(libs.plugins.jetbrains.compose) id("com.vanniktech.maven.publish") } -android { - namespace = "com.kyant.backdrop" - compileSdk { - version = release(36) - } - buildToolsVersion = "36.1.0" - - defaultConfig { - minSdk = 21 - consumerProguardFiles("consumer-rules.pro") - } - - buildTypes { - release { - isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") +kotlin { + androidLibrary { + compileSdk = 36 + namespace = "com.kyant.backdrop" + compilerOptions { + jvmTarget = JvmTarget.JVM_11 } } - buildFeatures { - compose = true - } -} -kotlin { - jvmToolchain(21) - compilerOptions { - freeCompilerArgs.addAll( - "-Xcontext-parameters" - ) - } -} + jvm("desktop") -dependencies { - implementation(libs.androidx.compose.foundation) - implementation(libs.androidx.compose.ui) - implementation(libs.androidx.compose.ui.graphics) - implementation(libs.kyant.shapes) + js(IR) { + browser() + } + wasmJs { + browser() + } + + macosArm64() + iosArm64("iosArm64") + iosSimulatorArm64("iosSimulatorArm64") + + sourceSets { + val commonMain by getting { + dependencies { + implementation(libs.compose.foundation) + implementation(libs.compose.ui) + implementation(libs.compose.ui.graphics) + implementation(libs.kyant.shapes) + implementation("org.jetbrains:annotations:26.0.2-1") + } + } + + val skikoMain by creating { + dependsOn(commonMain) + } + + val desktopMain by getting { + dependsOn(skikoMain) + } + + val macosArm64Main by getting { + dependsOn(skikoMain) + } + + val iosMain by creating { + dependsOn(skikoMain) + } + + val iosArm64Main by getting { + dependsOn(iosMain) + } + + val iosSimulatorArm64Main by getting { + dependsOn(iosMain) + } + + val jsMain by getting { + dependsOn(skikoMain) + } + + val wasmJsMain by getting { + dependsOn(skikoMain) + } + + all { + languageSettings.enableLanguageFeature("ContextParameters") + } + } } mavenPublishing { publishToMavenCentral() signAllPublications() - coordinates("io.github.kyant0", "backdrop", "1.0.5") + coordinates("io.github.kyant0", "backdrop", "2.0.0-alpha01") pom { name.set("Backdrop") - description.set("Jetpack Compose blur and Liquid Glass effects") + description.set("Compose Multiplatform Liquid Glass effects") inceptionYear.set("2025") url.set("https://github.com/Kyant0/AndroidLiquidGlass") licenses { diff --git a/backdrop/src/androidMain/kotlin/com/kyant/backdrop/RuntimeShader.kt b/backdrop/src/androidMain/kotlin/com/kyant/backdrop/RuntimeShader.kt new file mode 100644 index 0000000..17b0a91 --- /dev/null +++ b/backdrop/src/androidMain/kotlin/com/kyant/backdrop/RuntimeShader.kt @@ -0,0 +1,65 @@ +package com.kyant.backdrop + +import android.os.Build +import androidx.annotation.RequiresApi +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb +import org.intellij.lang.annotations.Language + +@RequiresApi(Build.VERSION_CODES.TIRAMISU) +actual fun RuntimeShader(@Language("AGSL") shaderString: String): RuntimeShader { + val shader = android.graphics.RuntimeShader(shaderString) + return AndroidRuntimeShader(shader) +} + +fun RuntimeShader.asAndroidRuntimeShader(): android.graphics.RuntimeShader { + return (this as AndroidRuntimeShader).shader +} + +@RequiresApi(Build.VERSION_CODES.TIRAMISU) +internal class AndroidRuntimeShader(val shader: android.graphics.RuntimeShader) : RuntimeShader { + + override fun setFloatUniform(name: String, value: Float) { + shader.setFloatUniform(name, value) + } + + override fun setFloatUniform(name: String, value1: Float, value2: Float) { + shader.setFloatUniform(name, value1, value2) + } + + override fun setFloatUniform(name: String, value1: Float, value2: Float, value3: Float) { + shader.setFloatUniform(name, value1, value2, value3) + } + + override fun setFloatUniform(name: String, value1: Float, value2: Float, value3: Float, value4: Float) { + shader.setFloatUniform(name, value1, value2, value3, value4) + } + + override fun setFloatUniform(name: String, values: FloatArray) { + shader.setFloatUniform(name, values) + } + + override fun setIntUniform(name: String, value: Int) { + shader.setIntUniform(name, value) + } + + override fun setIntUniform(name: String, value1: Int, value2: Int) { + shader.setIntUniform(name, value1, value2) + } + + override fun setIntUniform(name: String, value1: Int, value2: Int, value3: Int) { + shader.setIntUniform(name, value1, value2, value3) + } + + override fun setIntUniform(name: String, value1: Int, value2: Int, value3: Int, value4: Int) { + shader.setIntUniform(name, value1, value2, value3, value4) + } + + override fun setIntUniform(name: String, values: IntArray) { + shader.setIntUniform(name, values) + } + + override fun setColorUniform(name: String, color: Color) { + shader.setColorUniform(name, color.toArgb()) + } +} diff --git a/backdrop/src/androidMain/kotlin/com/kyant/backdrop/internal/Paint.kt b/backdrop/src/androidMain/kotlin/com/kyant/backdrop/internal/Paint.kt new file mode 100644 index 0000000..081428b --- /dev/null +++ b/backdrop/src/androidMain/kotlin/com/kyant/backdrop/internal/Paint.kt @@ -0,0 +1,16 @@ +package com.kyant.backdrop.internal + +import android.graphics.BlurMaskFilter +import androidx.compose.ui.graphics.Paint +import com.kyant.backdrop.RuntimeShader +import com.kyant.backdrop.asAndroidRuntimeShader + +internal actual fun Paint.blur(radius: Float) { + this.asFrameworkPaint().maskFilter = + if (radius > 0f) BlurMaskFilter(radius, BlurMaskFilter.Blur.NORMAL) + else null +} + +internal actual fun Paint.setRuntimeShader(runtimeShader: RuntimeShader?) { + this.asFrameworkPaint().shader = runtimeShader?.asAndroidRuntimeShader() +} diff --git a/backdrop/src/androidMain/kotlin/com/kyant/backdrop/internal/PlatformCapabilities.kt b/backdrop/src/androidMain/kotlin/com/kyant/backdrop/internal/PlatformCapabilities.kt new file mode 100644 index 0000000..12afcae --- /dev/null +++ b/backdrop/src/androidMain/kotlin/com/kyant/backdrop/internal/PlatformCapabilities.kt @@ -0,0 +1,7 @@ +package com.kyant.backdrop.internal + +import android.os.Build + +internal actual fun isRenderEffectSupported(): Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.S + +internal actual fun isRuntimeShaderSupported(): Boolean = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU diff --git a/backdrop/src/androidMain/kotlin/com/kyant/backdrop/internal/RenderEffect.kt b/backdrop/src/androidMain/kotlin/com/kyant/backdrop/internal/RenderEffect.kt new file mode 100644 index 0000000..22048e9 --- /dev/null +++ b/backdrop/src/androidMain/kotlin/com/kyant/backdrop/internal/RenderEffect.kt @@ -0,0 +1,50 @@ +package com.kyant.backdrop.internal + +import android.os.Build +import androidx.annotation.RequiresApi +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.graphics.RenderEffect +import androidx.compose.ui.graphics.asAndroidColorFilter +import androidx.compose.ui.graphics.asComposeRenderEffect +import com.kyant.backdrop.RuntimeShader +import com.kyant.backdrop.asAndroidRuntimeShader + +@RequiresApi(Build.VERSION_CODES.S) +internal actual fun RenderEffect?.chain(other: RenderEffect): RenderEffect { + return if (this != null) { + android.graphics.RenderEffect.createChainEffect( + other.asAndroidRenderEffect(), + this.asAndroidRenderEffect() + ).asComposeRenderEffect() + } else { + other + } +} + +@RequiresApi(Build.VERSION_CODES.TIRAMISU) +internal actual fun RuntimeShaderEffect( + runtimeShader: RuntimeShader, + uniformShaderName: String +): RenderEffect { + return android.graphics.RenderEffect.createRuntimeShaderEffect( + runtimeShader.asAndroidRuntimeShader(), + uniformShaderName + ).asComposeRenderEffect() +} + +@RequiresApi(Build.VERSION_CODES.S) +internal actual fun ColorFilterEffect( + renderEffect: RenderEffect?, + colorFilter: ColorFilter +): RenderEffect { + return if (renderEffect != null) { + android.graphics.RenderEffect.createColorFilterEffect( + colorFilter.asAndroidColorFilter(), + renderEffect.asAndroidRenderEffect() + ).asComposeRenderEffect() + } else { + android.graphics.RenderEffect.createColorFilterEffect( + colorFilter.asAndroidColorFilter(), + ).asComposeRenderEffect() + } +} diff --git a/backdrop/src/main/java/com/kyant/backdrop/Backdrop.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/Backdrop.kt similarity index 100% rename from backdrop/src/main/java/com/kyant/backdrop/Backdrop.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/Backdrop.kt diff --git a/backdrop/src/main/java/com/kyant/backdrop/BackdropEffectScope.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/BackdropEffectScope.kt similarity index 91% rename from backdrop/src/main/java/com/kyant/backdrop/BackdropEffectScope.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/BackdropEffectScope.kt index a271d45..dc42af3 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/BackdropEffectScope.kt +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/BackdropEffectScope.kt @@ -1,10 +1,7 @@ package com.kyant.backdrop -import android.graphics.RenderEffect -import android.graphics.RuntimeShader -import android.os.Build -import androidx.annotation.RequiresApi import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.RenderEffect import androidx.compose.ui.graphics.Shape import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.unit.Density @@ -34,7 +31,6 @@ internal abstract class BackdropEffectScopeImpl : BackdropEffectScope, RuntimeSh private val runtimeShaderCache = RuntimeShaderCacheImpl() - @RequiresApi(Build.VERSION_CODES.TIRAMISU) override fun obtainRuntimeShader(key: String, string: String): RuntimeShader { return runtimeShaderCache.obtainRuntimeShader(key, string) } diff --git a/backdrop/src/main/java/com/kyant/backdrop/DrawBackdropModifier.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/DrawBackdropModifier.kt similarity index 97% rename from backdrop/src/main/java/com/kyant/backdrop/DrawBackdropModifier.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/DrawBackdropModifier.kt index e970c24..f757129 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/DrawBackdropModifier.kt +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/DrawBackdropModifier.kt @@ -1,6 +1,5 @@ package com.kyant.backdrop -import android.os.Build import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf @@ -9,7 +8,6 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.GraphicsLayerScope import androidx.compose.ui.graphics.Shape -import androidx.compose.ui.graphics.asComposeRenderEffect import androidx.compose.ui.graphics.drawscope.ContentDrawScope import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.graphics.graphicsLayer @@ -33,6 +31,9 @@ import androidx.compose.ui.unit.IntSize import com.kyant.backdrop.backdrops.LayerBackdrop import com.kyant.backdrop.highlight.Highlight import com.kyant.backdrop.highlight.HighlightElement +import com.kyant.backdrop.internal.ShapeProvider +import com.kyant.backdrop.internal.isRenderEffectSupported +import com.kyant.backdrop.internal.recordLayer import com.kyant.backdrop.shadow.InnerShadow import com.kyant.backdrop.shadow.InnerShadowElement import com.kyant.backdrop.shadow.Shadow @@ -357,11 +358,11 @@ private class DrawBackdropNode( } private fun updateEffects() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - effectScope.apply(effects) - graphicsLayer?.renderEffect = effectScope.renderEffect?.asComposeRenderEffect() - padding = effectScope.padding - } + if (!isRenderEffectSupported()) return + + effectScope.apply(effects) + graphicsLayer?.renderEffect = effectScope.renderEffect + padding = effectScope.padding } override fun onAttach() { diff --git a/backdrop/src/commonMain/kotlin/com/kyant/backdrop/RuntimeShader.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/RuntimeShader.kt new file mode 100644 index 0000000..7085c6e --- /dev/null +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/RuntimeShader.kt @@ -0,0 +1,23 @@ +package com.kyant.backdrop + +import androidx.compose.ui.graphics.Color +import org.intellij.lang.annotations.Language + +expect fun RuntimeShader(@Language("AGSL") shaderString: String): RuntimeShader + +interface RuntimeShader { + + fun setFloatUniform(name: String, value: Float) + fun setFloatUniform(name: String, value1: Float, value2: Float) + fun setFloatUniform(name: String, value1: Float, value2: Float, value3: Float) + fun setFloatUniform(name: String, value1: Float, value2: Float, value3: Float, value4: Float) + fun setFloatUniform(name: String, values: FloatArray) + + fun setIntUniform(name: String, value: Int) + fun setIntUniform(name: String, value1: Int, value2: Int) + fun setIntUniform(name: String, value1: Int, value2: Int, value3: Int) + fun setIntUniform(name: String, value1: Int, value2: Int, value3: Int, value4: Int) + fun setIntUniform(name: String, values: IntArray) + + fun setColorUniform(name: String, color: Color) +} diff --git a/backdrop/src/main/java/com/kyant/backdrop/RuntimeShaderCache.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/RuntimeShaderCache.kt similarity index 60% rename from backdrop/src/main/java/com/kyant/backdrop/RuntimeShaderCache.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/RuntimeShaderCache.kt index f4a953b..f7067c1 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/RuntimeShaderCache.kt +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/RuntimeShaderCache.kt @@ -1,24 +1,16 @@ package com.kyant.backdrop -import android.graphics.RuntimeShader -import android.os.Build -import androidx.annotation.RequiresApi import org.intellij.lang.annotations.Language sealed interface RuntimeShaderCache { - @RequiresApi(Build.VERSION_CODES.TIRAMISU) - fun obtainRuntimeShader( - key: String, - @Language("AGSL") string: String - ): RuntimeShader + fun obtainRuntimeShader(key: String, @Language("AGSL") string: String): RuntimeShader } internal class RuntimeShaderCacheImpl : RuntimeShaderCache { private val runtimeShaders = mutableMapOf() - @RequiresApi(Build.VERSION_CODES.TIRAMISU) override fun obtainRuntimeShader(key: String, string: String): RuntimeShader { return runtimeShaders.getOrPut(key) { RuntimeShader(string) } } diff --git a/backdrop/src/main/java/com/kyant/backdrop/backdrops/Backdrop.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/backdrops/Backdrop.kt similarity index 100% rename from backdrop/src/main/java/com/kyant/backdrop/backdrops/Backdrop.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/backdrops/Backdrop.kt diff --git a/backdrop/src/main/java/com/kyant/backdrop/backdrops/CanvasBackdrop.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/backdrops/CanvasBackdrop.kt similarity index 100% rename from backdrop/src/main/java/com/kyant/backdrop/backdrops/CanvasBackdrop.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/backdrops/CanvasBackdrop.kt diff --git a/backdrop/src/main/java/com/kyant/backdrop/backdrops/CombinedBackdrop.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/backdrops/CombinedBackdrop.kt similarity index 100% rename from backdrop/src/main/java/com/kyant/backdrop/backdrops/CombinedBackdrop.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/backdrops/CombinedBackdrop.kt diff --git a/backdrop/src/main/java/com/kyant/backdrop/backdrops/EmptyBackdrop.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/backdrops/EmptyBackdrop.kt similarity index 100% rename from backdrop/src/main/java/com/kyant/backdrop/backdrops/EmptyBackdrop.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/backdrops/EmptyBackdrop.kt diff --git a/backdrop/src/main/java/com/kyant/backdrop/backdrops/LayerBackdrop.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/backdrops/LayerBackdrop.kt similarity index 98% rename from backdrop/src/main/java/com/kyant/backdrop/backdrops/LayerBackdrop.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/backdrops/LayerBackdrop.kt index 7e15110..787f532 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/backdrops/LayerBackdrop.kt +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/backdrops/LayerBackdrop.kt @@ -17,7 +17,7 @@ import androidx.compose.ui.layout.LayoutCoordinates import androidx.compose.ui.layout.positionInWindow import androidx.compose.ui.unit.Density import com.kyant.backdrop.Backdrop -import com.kyant.backdrop.InverseLayerScope +import com.kyant.backdrop.internal.InverseLayerScope private val DefaultOnDraw: ContentDrawScope.() -> Unit = { drawContent() } diff --git a/backdrop/src/main/java/com/kyant/backdrop/backdrops/LayerBackdropModifier.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/backdrops/LayerBackdropModifier.kt similarity index 97% rename from backdrop/src/main/java/com/kyant/backdrop/backdrops/LayerBackdropModifier.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/backdrops/LayerBackdropModifier.kt index a0251cf..a38e9a8 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/backdrops/LayerBackdropModifier.kt +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/backdrops/LayerBackdropModifier.kt @@ -8,7 +8,7 @@ import androidx.compose.ui.node.GlobalPositionAwareModifierNode import androidx.compose.ui.node.ModifierNodeElement import androidx.compose.ui.node.invalidateDraw import androidx.compose.ui.platform.InspectorInfo -import com.kyant.backdrop.recordLayer +import com.kyant.backdrop.internal.recordLayer fun Modifier.layerBackdrop(backdrop: LayerBackdrop): Modifier = this then LayerBackdropElement(backdrop) diff --git a/backdrop/src/commonMain/kotlin/com/kyant/backdrop/effects/Blur.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/effects/Blur.kt new file mode 100644 index 0000000..5b3d2c2 --- /dev/null +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/effects/Blur.kt @@ -0,0 +1,29 @@ +package com.kyant.backdrop.effects + +import androidx.annotation.FloatRange +import androidx.compose.ui.graphics.BlurEffect +import androidx.compose.ui.graphics.TileMode +import com.kyant.backdrop.BackdropEffectScope +import com.kyant.backdrop.internal.isRenderEffectSupported + +fun BackdropEffectScope.blur( + @FloatRange(from = 0.0) radius: Float, + edgeTreatment: TileMode = TileMode.Clamp +) { + if (!isRenderEffectSupported()) return + if (radius <= 0f) return + + if (edgeTreatment != TileMode.Clamp || renderEffect != null) { + if (radius > padding) { + padding = radius + } + } + + renderEffect = + BlurEffect( + renderEffect, + radius, + radius, + edgeTreatment + ) +} diff --git a/backdrop/src/main/java/com/kyant/backdrop/effects/ColorFilter.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/effects/ColorFilter.kt similarity index 52% rename from backdrop/src/main/java/com/kyant/backdrop/effects/ColorFilter.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/effects/ColorFilter.kt index 57595ee..6ea34df 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/effects/ColorFilter.kt +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/effects/ColorFilter.kt @@ -1,30 +1,17 @@ package com.kyant.backdrop.effects -import android.graphics.ColorFilter -import android.graphics.ColorMatrix -import android.graphics.ColorMatrixColorFilter -import android.graphics.RenderEffect -import android.os.Build import androidx.annotation.FloatRange -import androidx.compose.ui.graphics.asAndroidColorFilter +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.graphics.ColorMatrix +import androidx.compose.ui.graphics.ColorMatrixColorFilter import com.kyant.backdrop.BackdropEffectScope -import com.kyant.backdrop.GammaAdjustmentShaderString -import kotlin.math.pow +import com.kyant.backdrop.internal.ColorFilterEffect +import com.kyant.backdrop.internal.isRenderEffectSupported fun BackdropEffectScope.colorFilter(colorFilter: ColorFilter) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return + if (!isRenderEffectSupported()) return - val currentEffect = renderEffect - renderEffect = - if (currentEffect != null) { - RenderEffect.createColorFilterEffect(colorFilter, currentEffect) - } else { - RenderEffect.createColorFilterEffect(colorFilter) - } -} - -fun BackdropEffectScope.colorFilter(colorFilter: androidx.compose.ui.graphics.ColorFilter) { - colorFilter(colorFilter.asAndroidColorFilter()) + renderEffect = ColorFilterEffect(renderEffect, colorFilter) } fun BackdropEffectScope.opacity(@FloatRange(from = 0.0, to = 1.0) alpha: Float) { @@ -51,32 +38,10 @@ fun BackdropEffectScope.colorControls( colorFilter(colorControlsColorFilter(brightness, contrast, saturation)) } -fun BackdropEffectScope.vibrancy() { - colorFilter(VibrantColorFilter) -} - private val VibrantColorFilter = colorControlsColorFilter(saturation = 1.5f) -fun BackdropEffectScope.exposureAdjustment(ev: Float) { - val scale = 2f.pow(ev / 2.2f) - val colorMatrix = ColorMatrix( - floatArrayOf( - scale, 0f, 0f, 0f, 0f, - 0f, scale, 0f, 0f, 0f, - 0f, 0f, scale, 0f, 0f, - 0f, 0f, 0f, 1f, 0f - ) - ) - colorFilter(ColorMatrixColorFilter(colorMatrix)) -} - -fun BackdropEffectScope.gammaAdjustment(power: Float) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) return - - val shader = obtainRuntimeShader("GammaAdjustment", GammaAdjustmentShaderString).apply { - setFloatUniform("power", power) - } - effect(RenderEffect.createRuntimeShaderEffect(shader, "content")) +fun BackdropEffectScope.vibrancy() { + colorFilter(VibrantColorFilter) } private fun colorControlsColorFilter( diff --git a/backdrop/src/main/java/com/kyant/backdrop/effects/Lens.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/effects/Lens.kt similarity index 90% rename from backdrop/src/main/java/com/kyant/backdrop/effects/Lens.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/effects/Lens.kt index f4a4ef7..217901b 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/effects/Lens.kt +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/effects/Lens.kt @@ -1,15 +1,15 @@ package com.kyant.backdrop.effects -import android.graphics.RenderEffect -import android.os.Build import androidx.annotation.FloatRange import androidx.compose.foundation.shape.CornerBasedShape import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.util.fastCoerceAtLeast import androidx.compose.ui.util.fastCoerceAtMost import com.kyant.backdrop.BackdropEffectScope -import com.kyant.backdrop.RoundedRectRefractionShaderString -import com.kyant.backdrop.RoundedRectRefractionWithDispersionShaderString +import com.kyant.backdrop.internal.RoundedRectRefractionShaderString +import com.kyant.backdrop.internal.RoundedRectRefractionWithDispersionShaderString +import com.kyant.backdrop.internal.RuntimeShaderEffect +import com.kyant.backdrop.internal.isRuntimeShaderSupported import com.kyant.shapes.RoundedRectangularShape fun BackdropEffectScope.lens( @@ -18,7 +18,7 @@ fun BackdropEffectScope.lens( depthEffect: Boolean = false, chromaticAberration: Boolean = false ) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU) return + if (!isRuntimeShaderSupported()) return if (refractionHeight <= 0f || refractionAmount <= 0f) return if (padding > 0f) { @@ -51,7 +51,7 @@ fun BackdropEffectScope.lens( setFloatUniform("chromaticAberration", 1f) } } - RenderEffect.createRuntimeShaderEffect(shader, "content") + RuntimeShaderEffect(shader, "content") } else { throwUnsupportedSDFException() } diff --git a/backdrop/src/commonMain/kotlin/com/kyant/backdrop/effects/RenderEffect.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/effects/RenderEffect.kt new file mode 100644 index 0000000..df46441 --- /dev/null +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/effects/RenderEffect.kt @@ -0,0 +1,34 @@ +package com.kyant.backdrop.effects + +import androidx.compose.ui.graphics.RenderEffect +import com.kyant.backdrop.BackdropEffectScope +import com.kyant.backdrop.RuntimeShader +import com.kyant.backdrop.internal.RuntimeShaderEffect +import com.kyant.backdrop.internal.chain +import com.kyant.backdrop.internal.isRenderEffectSupported +import com.kyant.backdrop.internal.isRuntimeShaderSupported +import org.intellij.lang.annotations.Language +import kotlin.contracts.ExperimentalContracts + +fun BackdropEffectScope.effect(effect: RenderEffect) { + if (!isRenderEffectSupported()) return + + renderEffect = renderEffect.chain(effect) +} + +@OptIn(ExperimentalContracts::class) +fun BackdropEffectScope.runtimeShaderEffect( + key: String, + @Language("AGSL") shaderString: String, + uniformShaderName: String, + block: RuntimeShader.() -> Unit +) { + if (!isRuntimeShaderSupported()) return + + val effect = + RuntimeShaderEffect( + runtimeShader = obtainRuntimeShader(key, shaderString).apply(block), + uniformShaderName = uniformShaderName + ) + renderEffect = renderEffect.chain(effect) +} diff --git a/backdrop/src/main/java/com/kyant/backdrop/highlight/Highlight.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/highlight/Highlight.kt similarity index 100% rename from backdrop/src/main/java/com/kyant/backdrop/highlight/Highlight.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/highlight/Highlight.kt diff --git a/backdrop/src/main/java/com/kyant/backdrop/highlight/HighlightModifier.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/highlight/HighlightModifier.kt similarity index 85% rename from backdrop/src/main/java/com/kyant/backdrop/highlight/HighlightModifier.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/highlight/HighlightModifier.kt index fdd66fa..0ecda10 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/highlight/HighlightModifier.kt +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/highlight/HighlightModifier.kt @@ -1,7 +1,5 @@ package com.kyant.backdrop.highlight -import android.graphics.BlurMaskFilter -import android.os.Build import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Outline import androidx.compose.ui.graphics.Paint @@ -22,8 +20,11 @@ import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.IntSize import androidx.compose.ui.util.fastCoerceAtMost import com.kyant.backdrop.RuntimeShaderCacheImpl -import com.kyant.backdrop.ShapeProvider -import com.kyant.backdrop.clipOutline +import com.kyant.backdrop.internal.ShapeProvider +import com.kyant.backdrop.internal.blur +import com.kyant.backdrop.internal.clipOutline +import com.kyant.backdrop.internal.isRuntimeShaderSupported +import com.kyant.backdrop.internal.setRuntimeShader import kotlin.math.ceil internal class HighlightElement( @@ -149,22 +150,17 @@ internal class HighlightNode( private fun DrawScope.configurePaint(highlight: Highlight) { paint.color = highlight.style.color - paint.strokeWidth = - ceil(highlight.width.toPx().fastCoerceAtMost(size.minDimension / 2f)) * 2f - val blurRadius = highlight.blurRadius.toPx() - paint.asFrameworkPaint().maskFilter = - if (blurRadius > 0f) { - BlurMaskFilter(blurRadius, BlurMaskFilter.Blur.NORMAL) - } else { - null - } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - paint.shader = with(highlight.style) { - createShader( - shape = shapeProvider.shape, - runtimeShaderCache = runtimeShaderCache - ) - } + paint.strokeWidth = ceil(highlight.width.toPx().fastCoerceAtMost(size.minDimension / 2f)) * 2f + paint.blur(highlight.blurRadius.toPx()) + if (isRuntimeShaderSupported()) { + val shader = + with(highlight.style) { + createShader( + shape = shapeProvider.shape, + runtimeShaderCache = runtimeShaderCache + ) + } + paint.setRuntimeShader(shader) } } } diff --git a/backdrop/src/main/java/com/kyant/backdrop/highlight/HighlightStyle.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/highlight/HighlightStyle.kt similarity index 78% rename from backdrop/src/main/java/com/kyant/backdrop/highlight/HighlightStyle.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/highlight/HighlightStyle.kt index 8b7934d..16ceb9a 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/highlight/HighlightStyle.kt +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/highlight/HighlightStyle.kt @@ -1,22 +1,20 @@ package com.kyant.backdrop.highlight -import android.os.Build import androidx.annotation.FloatRange -import androidx.annotation.RequiresApi import androidx.compose.foundation.shape.CornerBasedShape import androidx.compose.runtime.Immutable import androidx.compose.runtime.Stable import androidx.compose.ui.graphics.BlendMode import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Shader import androidx.compose.ui.graphics.Shape import androidx.compose.ui.graphics.drawscope.DrawScope -import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.unit.LayoutDirection import androidx.compose.ui.util.fastCoerceAtMost -import com.kyant.backdrop.AmbientHighlightShaderString -import com.kyant.backdrop.DefaultHighlightShaderString +import com.kyant.backdrop.RuntimeShader import com.kyant.backdrop.RuntimeShaderCache +import com.kyant.backdrop.internal.AmbientHighlightShaderString +import com.kyant.backdrop.internal.DefaultHighlightShaderString +import com.kyant.backdrop.internal.isRuntimeShaderSupported import kotlin.math.PI @Immutable @@ -26,11 +24,10 @@ interface HighlightStyle { val blendMode: BlendMode - @RequiresApi(Build.VERSION_CODES.S) fun DrawScope.createShader( shape: Shape, runtimeShaderCache: RuntimeShaderCache - ): Shader? + ): RuntimeShader? @Immutable data class Plain( @@ -38,11 +35,10 @@ interface HighlightStyle { override val blendMode: BlendMode = BlendMode.Plus ) : HighlightStyle { - @RequiresApi(Build.VERSION_CODES.S) override fun DrawScope.createShader( shape: Shape, runtimeShaderCache: RuntimeShaderCache - ): Shader? = null + ): RuntimeShader? = null } @Immutable @@ -53,33 +49,18 @@ interface HighlightStyle { @param:FloatRange(from = 0.0) val falloff: Float = 1f ) : HighlightStyle { - @Deprecated( - "Use the constructor with color parameter instead.", - ReplaceWith("HighlightStyle.Default(color = Color.White.copy(alpha = intensity), angle = angle, falloff = falloff)") - ) - constructor( - intensity: Float, - angle: Float = 45f, - falloff: Float = 1f - ) : this( - color = Color.White.copy(alpha = intensity), - angle = angle, - falloff = falloff - ) - - @RequiresApi(Build.VERSION_CODES.S) override fun DrawScope.createShader( shape: Shape, runtimeShaderCache: RuntimeShaderCache - ): Shader? { - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + ): RuntimeShader? { + return if (isRuntimeShaderSupported()) { runtimeShaderCache.obtainRuntimeShader( "Default", DefaultHighlightShaderString ).apply { setFloatUniform("size", size.width, size.height) setFloatUniform("cornerRadii", getCornerRadii(shape)) - setColorUniform("color", color.copy(alpha = 1f).toArgb()) + setColorUniform("color", color.copy(alpha = 1f)) setFloatUniform("angle", angle * (PI / 180f).toFloat()) setFloatUniform("falloff", falloff) } @@ -98,12 +79,11 @@ interface HighlightStyle { override val blendMode: BlendMode = DrawScope.DefaultBlendMode - @RequiresApi(Build.VERSION_CODES.S) override fun DrawScope.createShader( shape: Shape, runtimeShaderCache: RuntimeShaderCache - ): Shader? { - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + ): RuntimeShader? { + return if (isRuntimeShaderSupported()) { runtimeShaderCache.obtainRuntimeShader( "Ambient", AmbientHighlightShaderString diff --git a/backdrop/src/main/java/com/kyant/backdrop/InverseLayerScope.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/InverseLayerScope.kt similarity index 99% rename from backdrop/src/main/java/com/kyant/backdrop/InverseLayerScope.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/InverseLayerScope.kt index 25941d0..f6827ff 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/InverseLayerScope.kt +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/InverseLayerScope.kt @@ -1,4 +1,4 @@ -package com.kyant.backdrop +package com.kyant.backdrop.internal import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Size diff --git a/backdrop/src/main/java/com/kyant/backdrop/LayerRecorder.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/LayerRecorder.kt similarity index 95% rename from backdrop/src/main/java/com/kyant/backdrop/LayerRecorder.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/LayerRecorder.kt index 82623b0..6876c11 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/LayerRecorder.kt +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/LayerRecorder.kt @@ -1,4 +1,4 @@ -package com.kyant.backdrop +package com.kyant.backdrop.internal import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.graphics.layer.GraphicsLayer diff --git a/backdrop/src/main/java/com/kyant/backdrop/Outline.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/Outline.kt similarity index 93% rename from backdrop/src/main/java/com/kyant/backdrop/Outline.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/Outline.kt index 9220e46..1a55526 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/Outline.kt +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/Outline.kt @@ -1,4 +1,4 @@ -package com.kyant.backdrop +package com.kyant.backdrop.internal import androidx.compose.ui.graphics.Canvas import androidx.compose.ui.graphics.Outline diff --git a/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/Paint.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/Paint.kt new file mode 100644 index 0000000..8274d69 --- /dev/null +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/Paint.kt @@ -0,0 +1,8 @@ +package com.kyant.backdrop.internal + +import androidx.compose.ui.graphics.Paint +import com.kyant.backdrop.RuntimeShader + +internal expect fun Paint.blur(radius: Float) + +internal expect fun Paint.setRuntimeShader(runtimeShader: RuntimeShader?) diff --git a/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/Platform.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/Platform.kt new file mode 100644 index 0000000..a2b48e8 --- /dev/null +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/Platform.kt @@ -0,0 +1,5 @@ +package com.kyant.backdrop.internal + +internal expect fun isRenderEffectSupported(): Boolean + +internal expect fun isRuntimeShaderSupported(): Boolean diff --git a/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/RenderEffect.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/RenderEffect.kt new file mode 100644 index 0000000..2e94022 --- /dev/null +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/RenderEffect.kt @@ -0,0 +1,17 @@ +package com.kyant.backdrop.internal + +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.graphics.RenderEffect +import com.kyant.backdrop.RuntimeShader + +internal expect fun RenderEffect?.chain(other: RenderEffect): RenderEffect + +internal expect fun RuntimeShaderEffect( + runtimeShader: RuntimeShader, + uniformShaderName: String +): RenderEffect + +internal expect fun ColorFilterEffect( + renderEffect: RenderEffect? = null, + colorFilter: ColorFilter +): RenderEffect diff --git a/backdrop/src/main/java/com/kyant/backdrop/Shaders.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/Shaders.kt similarity index 94% rename from backdrop/src/main/java/com/kyant/backdrop/Shaders.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/Shaders.kt index 73fdcfe..a96e900 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/Shaders.kt +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/Shaders.kt @@ -14,7 +14,7 @@ limitations under the License. */ -package com.kyant.backdrop +package com.kyant.backdrop.internal import org.intellij.lang.annotations.Language @@ -202,17 +202,3 @@ half4 main(float2 coord) { float t = step(0.0, d); return half4(t, t, t, 1.0) * intensity; }""" - -@Language("AGSL") -internal const val GammaAdjustmentShaderString = """ -uniform shader content; - -uniform float power; - -half4 main(float2 coord) { - half4 color = content.eval(coord); - color.r = pow(color.r, power); - color.g = pow(color.g, power); - color.b = pow(color.b, power); - return color; -}""" diff --git a/backdrop/src/main/java/com/kyant/backdrop/ShapeProvider.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/ShapeProvider.kt similarity index 97% rename from backdrop/src/main/java/com/kyant/backdrop/ShapeProvider.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/ShapeProvider.kt index c79a776..7728916 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/ShapeProvider.kt +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/internal/ShapeProvider.kt @@ -1,4 +1,4 @@ -package com.kyant.backdrop +package com.kyant.backdrop.internal import androidx.compose.runtime.Immutable import androidx.compose.ui.geometry.Size diff --git a/backdrop/src/main/java/com/kyant/backdrop/shadow/InnerShadow.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/shadow/InnerShadow.kt similarity index 100% rename from backdrop/src/main/java/com/kyant/backdrop/shadow/InnerShadow.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/shadow/InnerShadow.kt diff --git a/backdrop/src/main/java/com/kyant/backdrop/shadow/InnerShadowModifier.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/shadow/InnerShadowModifier.kt similarity index 92% rename from backdrop/src/main/java/com/kyant/backdrop/shadow/InnerShadowModifier.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/shadow/InnerShadowModifier.kt index 4c65d28..d20e678 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/shadow/InnerShadowModifier.kt +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/shadow/InnerShadowModifier.kt @@ -1,6 +1,5 @@ package com.kyant.backdrop.shadow -import android.os.Build import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.BlendMode import androidx.compose.ui.graphics.BlurEffect @@ -20,8 +19,9 @@ import androidx.compose.ui.node.invalidateDraw import androidx.compose.ui.node.requireGraphicsContext import androidx.compose.ui.platform.InspectorInfo import androidx.compose.ui.unit.Density -import com.kyant.backdrop.ShapeProvider -import com.kyant.backdrop.clipOutline +import com.kyant.backdrop.internal.ShapeProvider +import com.kyant.backdrop.internal.clipOutline +import com.kyant.backdrop.internal.isRenderEffectSupported internal class InnerShadowElement( val shapeProvider: ShapeProvider, @@ -78,7 +78,7 @@ internal class InnerShadowNode( override fun ContentDrawScope.draw() { drawContent() - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return + if (!isRenderEffectSupported()) return val shadow = shadow() ?: return @@ -151,14 +151,6 @@ internal class InnerShadowNode( private fun DrawScope.configurePaint(shadow: InnerShadow) { paint.color = shadow.color } - - private fun DrawScope.drawMaskedShadow(outline: Outline, layer: GraphicsLayer) { - val canvas = drawContext.canvas - canvas.save() - canvas.clipOutline(outline, clipPath) - drawLayer(layer) - canvas.restore() - } } private val ShadowMaskPaint = Paint().apply { diff --git a/backdrop/src/main/java/com/kyant/backdrop/shadow/Shadow.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/shadow/Shadow.kt similarity index 100% rename from backdrop/src/main/java/com/kyant/backdrop/shadow/Shadow.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/shadow/Shadow.kt diff --git a/backdrop/src/main/java/com/kyant/backdrop/shadow/ShadowModifier.kt b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/shadow/ShadowModifier.kt similarity index 92% rename from backdrop/src/main/java/com/kyant/backdrop/shadow/ShadowModifier.kt rename to backdrop/src/commonMain/kotlin/com/kyant/backdrop/shadow/ShadowModifier.kt index 1d810dd..cd4b6e3 100644 --- a/backdrop/src/main/java/com/kyant/backdrop/shadow/ShadowModifier.kt +++ b/backdrop/src/commonMain/kotlin/com/kyant/backdrop/shadow/ShadowModifier.kt @@ -1,6 +1,5 @@ package com.kyant.backdrop.shadow -import android.graphics.BlurMaskFilter import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.BlendMode import androidx.compose.ui.graphics.Paint @@ -18,7 +17,8 @@ import androidx.compose.ui.node.requireGraphicsContext import androidx.compose.ui.platform.InspectorInfo import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.IntSize -import com.kyant.backdrop.ShapeProvider +import com.kyant.backdrop.internal.ShapeProvider +import com.kyant.backdrop.internal.blur import kotlin.math.ceil internal class ShadowElement( @@ -128,13 +128,7 @@ internal class ShadowNode( private fun DrawScope.configurePaint(shadow: Shadow) { paint.color = shadow.color - val blurRadius = shadow.radius.toPx() - paint.asFrameworkPaint().maskFilter = - if (blurRadius > 0f) { - BlurMaskFilter(blurRadius, BlurMaskFilter.Blur.NORMAL) - } else { - null - } + paint.blur(shadow.radius.toPx()) } } diff --git a/backdrop/src/main/AndroidManifest.xml b/backdrop/src/main/AndroidManifest.xml deleted file mode 100644 index a5918e6..0000000 --- a/backdrop/src/main/AndroidManifest.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/backdrop/src/main/java/com/kyant/backdrop/effects/Blur.kt b/backdrop/src/main/java/com/kyant/backdrop/effects/Blur.kt deleted file mode 100644 index d3599f3..0000000 --- a/backdrop/src/main/java/com/kyant/backdrop/effects/Blur.kt +++ /dev/null @@ -1,39 +0,0 @@ -package com.kyant.backdrop.effects - -import android.graphics.RenderEffect -import android.os.Build -import androidx.annotation.FloatRange -import androidx.compose.ui.graphics.TileMode -import androidx.compose.ui.graphics.toAndroidTileMode -import com.kyant.backdrop.BackdropEffectScope - -fun BackdropEffectScope.blur( - @FloatRange(from = 0.0) radius: Float, - edgeTreatment: TileMode = TileMode.Clamp -) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return - if (radius <= 0f) return - - if (edgeTreatment != TileMode.Clamp || renderEffect != null) { - if (radius > padding) { - padding = radius - } - } - - val currentEffect = renderEffect - renderEffect = - if (currentEffect != null) { - RenderEffect.createBlurEffect( - radius, - radius, - currentEffect, - edgeTreatment.toAndroidTileMode() - ) - } else { - RenderEffect.createBlurEffect( - radius, - radius, - edgeTreatment.toAndroidTileMode() - ) - } -} diff --git a/backdrop/src/main/java/com/kyant/backdrop/effects/RenderEffect.kt b/backdrop/src/main/java/com/kyant/backdrop/effects/RenderEffect.kt deleted file mode 100644 index bccbb90..0000000 --- a/backdrop/src/main/java/com/kyant/backdrop/effects/RenderEffect.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.kyant.backdrop.effects - -import android.graphics.RenderEffect -import android.os.Build -import com.kyant.backdrop.BackdropEffectScope - -fun BackdropEffectScope.effect(effect: RenderEffect) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return - - val currentEffect = renderEffect - renderEffect = - if (currentEffect != null) { - RenderEffect.createChainEffect(effect, currentEffect) - } else { - effect - } -} - -fun BackdropEffectScope.effect(effect: androidx.compose.ui.graphics.RenderEffect) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) return - - effect(effect.asAndroidRenderEffect()) -} diff --git a/backdrop/src/skikoMain/kotlin/com/kyant/backdrop/RuntimeShader.kt b/backdrop/src/skikoMain/kotlin/com/kyant/backdrop/RuntimeShader.kt new file mode 100644 index 0000000..5f06639 --- /dev/null +++ b/backdrop/src/skikoMain/kotlin/com/kyant/backdrop/RuntimeShader.kt @@ -0,0 +1,64 @@ +package com.kyant.backdrop + +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.colorspace.ColorSpaces +import org.intellij.lang.annotations.Language +import org.jetbrains.skia.RuntimeEffect +import org.jetbrains.skia.RuntimeShaderBuilder + +actual fun RuntimeShader(@Language("AGSL") shaderString: String): RuntimeShader { + val shader = RuntimeShaderBuilder(RuntimeEffect.makeForShader(shaderString)) + return SkikoRuntimeShader(shader) +} + +fun RuntimeShader.asSkikoRuntimeShader(): RuntimeShaderBuilder { + return (this as SkikoRuntimeShader).shader +} + +internal class SkikoRuntimeShader(val shader: RuntimeShaderBuilder) : RuntimeShader { + + override fun setFloatUniform(name: String, value: Float) { + shader.uniform(name, value) + } + + override fun setFloatUniform(name: String, value1: Float, value2: Float) { + shader.uniform(name, value1, value2) + } + + override fun setFloatUniform(name: String, value1: Float, value2: Float, value3: Float) { + shader.uniform(name, value1, value2, value3) + } + + override fun setFloatUniform(name: String, value1: Float, value2: Float, value3: Float, value4: Float) { + shader.uniform(name, value1, value2, value3, value4) + } + + override fun setFloatUniform(name: String, values: FloatArray) { + shader.uniform(name, values) + } + + override fun setIntUniform(name: String, value: Int) { + shader.uniform(name, value) + } + + override fun setIntUniform(name: String, value1: Int, value2: Int) { + shader.uniform(name, value1, value2) + } + + override fun setIntUniform(name: String, value1: Int, value2: Int, value3: Int) { + shader.uniform(name, value1, value2, value3) + } + + override fun setIntUniform(name: String, value1: Int, value2: Int, value3: Int, value4: Int) { + shader.uniform(name, value1, value2, value3, value4) + } + + override fun setIntUniform(name: String, values: IntArray) { + throw UnsupportedOperationException("Setting int array uniforms is not supported on Skia RuntimeShader.") + } + + override fun setColorUniform(name: String, color: Color) { + val srgb = color.convert(ColorSpaces.Srgb) + shader.uniform(name, srgb.red, srgb.green, srgb.blue, srgb.alpha) + } +} diff --git a/backdrop/src/skikoMain/kotlin/com/kyant/backdrop/internal/Paint.kt b/backdrop/src/skikoMain/kotlin/com/kyant/backdrop/internal/Paint.kt new file mode 100644 index 0000000..8b1b3e9 --- /dev/null +++ b/backdrop/src/skikoMain/kotlin/com/kyant/backdrop/internal/Paint.kt @@ -0,0 +1,17 @@ +package com.kyant.backdrop.internal + +import androidx.compose.ui.graphics.Paint +import com.kyant.backdrop.RuntimeShader +import com.kyant.backdrop.asSkikoRuntimeShader +import org.jetbrains.skia.FilterBlurMode +import org.jetbrains.skia.MaskFilter + +internal actual fun Paint.blur(radius: Float) { + this.asFrameworkPaint().maskFilter = + if (radius > 0f) MaskFilter.makeBlur(FilterBlurMode.NORMAL, radius) + else null +} + +internal actual fun Paint.setRuntimeShader(runtimeShader: RuntimeShader?) { + this.asFrameworkPaint().shader = runtimeShader?.asSkikoRuntimeShader()?.makeShader() +} diff --git a/backdrop/src/skikoMain/kotlin/com/kyant/backdrop/internal/PlatformCapabilities.kt b/backdrop/src/skikoMain/kotlin/com/kyant/backdrop/internal/PlatformCapabilities.kt new file mode 100644 index 0000000..fe10b51 --- /dev/null +++ b/backdrop/src/skikoMain/kotlin/com/kyant/backdrop/internal/PlatformCapabilities.kt @@ -0,0 +1,5 @@ +package com.kyant.backdrop.internal + +internal actual fun isRenderEffectSupported(): Boolean = true + +internal actual fun isRuntimeShaderSupported(): Boolean = true diff --git a/backdrop/src/skikoMain/kotlin/com/kyant/backdrop/internal/RenderEffect.kt b/backdrop/src/skikoMain/kotlin/com/kyant/backdrop/internal/RenderEffect.kt new file mode 100644 index 0000000..3a43d52 --- /dev/null +++ b/backdrop/src/skikoMain/kotlin/com/kyant/backdrop/internal/RenderEffect.kt @@ -0,0 +1,42 @@ +package com.kyant.backdrop.internal + +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.graphics.RenderEffect +import androidx.compose.ui.graphics.asComposeRenderEffect +import androidx.compose.ui.graphics.asSkiaColorFilter +import com.kyant.backdrop.RuntimeShader +import com.kyant.backdrop.asSkikoRuntimeShader +import org.jetbrains.skia.ImageFilter + +internal actual fun RenderEffect?.chain(other: RenderEffect): RenderEffect { + return if (this != null) { + ImageFilter.makeCompose( + other.asSkiaImageFilter(), + this.asSkiaImageFilter() + ).asComposeRenderEffect() + } else { + other + } +} + +internal actual fun RuntimeShaderEffect( + runtimeShader: RuntimeShader, + uniformShaderName: String +): RenderEffect { + return ImageFilter.makeRuntimeShader( + runtimeShader.asSkikoRuntimeShader(), + uniformShaderName, + null + ).asComposeRenderEffect() +} + +internal actual fun ColorFilterEffect( + renderEffect: RenderEffect?, + colorFilter: ColorFilter +): RenderEffect { + return ImageFilter.makeColorFilter( + colorFilter.asSkiaColorFilter(), + renderEffect?.asSkiaImageFilter(), + null + ).asComposeRenderEffect() +} diff --git a/build.gradle.kts b/build.gradle.kts index b765df2..8b94c5e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,9 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - alias(libs.plugins.android.application) apply false - alias(libs.plugins.android.library) apply false + alias(libs.plugins.kotlin.multiplatform) apply false alias(libs.plugins.kotlin.compose) apply false + alias(libs.plugins.android.application) apply false + alias(libs.plugins.android.multiplatform.library) apply false + alias(libs.plugins.jetbrains.compose) apply false id("com.vanniktech.maven.publish") version "0.36.0" apply false } diff --git a/gradle.properties b/gradle.properties index 38d51de..dcad3d2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -28,3 +28,4 @@ org.gradle.caching=true # (Note that some plugins may not yet be compatible with the configuration cache.) # https://docs.gradle.org/current/userguide/configuration_cache.html org.gradle.configuration-cache=true +org.jetbrains.compose.experimental.macos.enabled=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fc99182..73919b7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,19 +4,21 @@ kotlin = "2.3.0" activity = "1.12.2" core = "1.17.0" -compose = "1.10.1" -kyantShapes = "1.0.0" +compose = "1.10.0" +kyantShapes = "1.0.4" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "core" } androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activity" } -androidx-compose-foundation = { group = "androidx.compose.foundation", name = "foundation", version.ref = "compose" } -androidx-compose-ui = { group = "androidx.compose.ui", name = "ui", version.ref = "compose" } -androidx-compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics", version.ref = "compose" } -androidx-compose-material-ripple = { group = "androidx.compose.material", name = "material-ripple", version.ref = "compose" } +compose-foundation = { group = "org.jetbrains.compose.foundation", name = "foundation", version.ref = "compose" } +compose-ui = { group = "org.jetbrains.compose.ui", name = "ui", version.ref = "compose" } +compose-ui-graphics = { group = "org.jetbrains.compose.ui", name = "ui-graphics", version.ref = "compose" } +compose-material-ripple = { group = "org.jetbrains.compose.material", name = "material-ripple", version.ref = "compose" } kyant-shapes = { group = "io.github.kyant0", name = "shapes", version.ref = "kyantShapes" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } -android-library = { id = "com.android.library", version.ref = "agp" } +android-multiplatform-library = { id = "com.android.kotlin.multiplatform.library", version.ref = "agp" } +kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } +jetbrains-compose = { id = "org.jetbrains.compose", version.ref = "compose" } diff --git a/settings.gradle.kts b/settings.gradle.kts index 3f107f1..60e1bee 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -24,4 +24,5 @@ dependencyResolutionManagement { rootProject.name = "Glass" include(":backdrop") -include(":catalog") +include(":app") +include(":androidApp")