Skip to content

Commit

Permalink
Merge pull request #391 from skydoves/kmp/landscapist-palette
Browse files Browse the repository at this point in the history
Support landscapist-palette for KMP
  • Loading branch information
skydoves authored Dec 31, 2023
2 parents 6061636 + 083f6b6 commit 9c59e33
Show file tree
Hide file tree
Showing 15 changed files with 101 additions and 45 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ android {
compileSdk = Configuration.compileSdk
defaultConfig {
applicationId = "com.github.skydoves.landscapistdemo"
minSdk = Configuration.minSdk
minSdk = Configuration.minSdk24
targetSdk = Configuration.targetSdk
versionCode = Configuration.versionCode
versionName = Configuration.versionName
Expand Down
2 changes: 1 addition & 1 deletion benchmark-landscapist-app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ android {
compileSdk = Configuration.compileSdk
defaultConfig {
applicationId = "com.skydoves.benchmark.landscapist.app"
minSdk = 24
minSdk = Configuration.minSdk24
targetSdk = Configuration.targetSdk
versionCode = Configuration.versionCode
versionName = Configuration.versionName
Expand Down
2 changes: 1 addition & 1 deletion benchmark-landscapist/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ android {
compileSdk = Configuration.compileSdk

defaultConfig {
minSdk = 24
minSdk = Configuration.minSdk24
targetSdk = Configuration.targetSdk
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ object Configuration {
const val compileSdk = 34
const val targetSdk = 34
const val minSdk = 21
const val minSdk24 = 24
const val majorVersion = 2
const val minorVersion = 2
const val patchVersion = 13
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ kotlinx-coroutines-android = { group = "org.jetbrains.kotlinx", name = "kotlinx-
kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "kotlinxCoroutines" }
hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
hilt-compiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hilt" }
palette = { group = "androidx.palette", name = "palette-ktx", version.ref = "palette" }
palette = { group = "com.kmpalette", name = "kmpalette-core", version.ref = "palette" }
glide = { group = "com.github.bumptech.glide", name = "glide", version.ref = "glide" }
fresco = { group = "com.facebook.fresco", name = "fresco", version.ref = "fresco" }
fresco-okhttp3 = { group = "com.facebook.fresco", name = "imagepipeline-okhttp3", version.ref = "fresco" }
Expand Down
25 changes: 25 additions & 0 deletions landscapist-palette/api/android/landscapist-palette.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
public abstract interface class com/skydoves/landscapist/palette/PaletteBuilderInterceptor {
public abstract fun intercept (Landroidx/palette/graphics/Palette$Builder;)Landroidx/palette/graphics/Palette$Builder;
}

public abstract interface class com/skydoves/landscapist/palette/PaletteLoadedListener {
public abstract fun onPaletteLoaded (Landroidx/palette/graphics/Palette;)V
}

public final class com/skydoves/landscapist/palette/PalettePlugin : com/skydoves/landscapist/plugins/ImagePlugin$SuccessStatePlugin {
public static final field $stable I
public fun <init> ()V
public fun <init> (Ljava/lang/Object;ZLcom/skydoves/landscapist/palette/PaletteBuilderInterceptor;Lcom/skydoves/landscapist/palette/PaletteLoadedListener;)V
public synthetic fun <init> (Ljava/lang/Object;ZLcom/skydoves/landscapist/palette/PaletteBuilderInterceptor;Lcom/skydoves/landscapist/palette/PaletteLoadedListener;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun compose (Landroidx/compose/ui/Modifier;Ljava/lang/Object;Lcom/skydoves/landscapist/ImageOptions;Landroidx/compose/ui/graphics/ImageBitmap;Landroidx/compose/runtime/Composer;I)Lcom/skydoves/landscapist/plugins/ImagePlugin;
public final fun copy (Ljava/lang/Object;ZLcom/skydoves/landscapist/palette/PaletteBuilderInterceptor;Lcom/skydoves/landscapist/palette/PaletteLoadedListener;)Lcom/skydoves/landscapist/palette/PalettePlugin;
public static synthetic fun copy$default (Lcom/skydoves/landscapist/palette/PalettePlugin;Ljava/lang/Object;ZLcom/skydoves/landscapist/palette/PaletteBuilderInterceptor;Lcom/skydoves/landscapist/palette/PaletteLoadedListener;ILjava/lang/Object;)Lcom/skydoves/landscapist/palette/PalettePlugin;
public fun equals (Ljava/lang/Object;)Z
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class com/skydoves/landscapist/palette/RememberPaletteStateKt {
public static final fun rememberPaletteState (Landroidx/palette/graphics/Palette;Landroidx/compose/runtime/SnapshotMutationPolicy;Landroidx/compose/runtime/Composer;II)Landroidx/compose/runtime/MutableState;
}

25 changes: 25 additions & 0 deletions landscapist-palette/api/desktop/landscapist-palette.api
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
public abstract interface class com/skydoves/landscapist/palette/PaletteBuilderInterceptor {
public abstract fun intercept (Landroidx/palette/graphics/Palette$Builder;)Landroidx/palette/graphics/Palette$Builder;
}

public abstract interface class com/skydoves/landscapist/palette/PaletteLoadedListener {
public abstract fun onPaletteLoaded (Landroidx/palette/graphics/Palette;)V
}

public final class com/skydoves/landscapist/palette/PalettePlugin : com/skydoves/landscapist/plugins/ImagePlugin$SuccessStatePlugin {
public static final field $stable I
public fun <init> ()V
public fun <init> (Ljava/lang/Object;ZLcom/skydoves/landscapist/palette/PaletteBuilderInterceptor;Lcom/skydoves/landscapist/palette/PaletteLoadedListener;)V
public synthetic fun <init> (Ljava/lang/Object;ZLcom/skydoves/landscapist/palette/PaletteBuilderInterceptor;Lcom/skydoves/landscapist/palette/PaletteLoadedListener;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun compose (Landroidx/compose/ui/Modifier;Ljava/lang/Object;Lcom/skydoves/landscapist/ImageOptions;Landroidx/compose/ui/graphics/ImageBitmap;Landroidx/compose/runtime/Composer;I)Lcom/skydoves/landscapist/plugins/ImagePlugin;
public final fun copy (Ljava/lang/Object;ZLcom/skydoves/landscapist/palette/PaletteBuilderInterceptor;Lcom/skydoves/landscapist/palette/PaletteLoadedListener;)Lcom/skydoves/landscapist/palette/PalettePlugin;
public static synthetic fun copy$default (Lcom/skydoves/landscapist/palette/PalettePlugin;Ljava/lang/Object;ZLcom/skydoves/landscapist/palette/PaletteBuilderInterceptor;Lcom/skydoves/landscapist/palette/PaletteLoadedListener;ILjava/lang/Object;)Lcom/skydoves/landscapist/palette/PalettePlugin;
public fun equals (Ljava/lang/Object;)Z
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class com/skydoves/landscapist/palette/RememberPaletteStateKt {
public static final fun rememberPaletteState (Landroidx/palette/graphics/Palette;Landroidx/compose/runtime/SnapshotMutationPolicy;Landroidx/compose/runtime/Composer;II)Landroidx/compose/runtime/MutableState;
}

48 changes: 32 additions & 16 deletions landscapist-palette/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import com.github.skydoves.landscapist.Configuration

plugins {
id("landscapist.library.compose")
id("landscapist.library.compose.multiplatform")
id("landscapist.spotless")
}

Expand All @@ -35,12 +35,32 @@ mavenPublishing {
}
}

kotlin {
sourceSets {
all {
languageSettings.optIn("kotlin.RequiresOptIn")
languageSettings.optIn("kotlinx.coroutines.ExperimentalCoroutinesApi")
languageSettings.optIn("com.skydoves.landscapist.InternalLandscapistApi")
}
val commonMain by getting {
dependencies {
api(project(":landscapist"))
api(libs.palette)

implementation(compose.ui)
implementation(compose.runtime)
implementation(compose.foundation)
}
}
}
}

android {
namespace = "com.skydoves.landscapist.palette"
compileSdk = Configuration.compileSdk

defaultConfig {
minSdk = Configuration.minSdk
minSdk = Configuration.minSdk24
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
}
Expand All @@ -52,18 +72,14 @@ baselineProfile {
}
}

dependencies {
api(project(":landscapist"))
api(libs.palette)

implementation(libs.androidx.core.ktx)
implementation(libs.androidx.compose.ui)
implementation(libs.androidx.compose.runtime)
implementation(libs.androidx.compose.foundation)

androidTestImplementation(libs.androidx.test.rules)
androidTestImplementation(libs.androidx.test.runner)
androidTestImplementation(libs.androidx.test.junit)
androidTestImplementation(libs.androidx.compose.ui)
androidTestImplementation(libs.androidx.compose.ui.test)
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs += listOf(
"-Xexplicit-api=strict",
"-opt-in=kotlin.RequiresOptIn",
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-opt-in=com.skydoves.landscapist.InternalLandscapistApi",
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@
*/
package com.skydoves.landscapist.palette

import android.graphics.Bitmap
import android.util.LruCache
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.graphics.ImageBitmap
import androidx.palette.graphics.Palette
import com.kmpalette.rememberPaletteState

/**
* BitmapPalette is a [Palette] generator for extracting major (theme) colors
Expand All @@ -28,7 +30,7 @@ import androidx.palette.graphics.Palette
* @param interceptor A custom interceptor before generating colors.
* @param paletteLoadedListener A listener for listening to the loaded palette.
*/
internal class BitmapPalette constructor(
internal class BitmapPalette(
private var imageModel: Any? = null,
private val useCache: Boolean = true,
private val interceptor: PaletteBuilderInterceptor? = null,
Expand All @@ -39,29 +41,17 @@ internal class BitmapPalette constructor(
this.imageModel = imageModel
}

fun generate(bitmap: Bitmap?) {
val target = bitmap ?: return
val model = imageModel ?: return
if (useCache) {
val palette = cache.get(model)
@Composable
fun generate(bitmap: ImageBitmap) {
val cacheSize = if (useCache) 5 else 0
val paletteState = rememberPaletteState(cacheSize = cacheSize)
LaunchedEffect(bitmap) {
paletteState.generate(bitmap)
val palette = paletteState.palette

if (palette != null) {
paletteLoadedListener?.onPaletteLoaded(palette)
return
}
}
val builder = interceptor?.intercept(Palette.Builder(target))
?: Palette.Builder(target)
builder.generate async@{
val palette: Palette = it ?: return@async
if (useCache) {
cache.put(model, palette)
}
paletteLoadedListener?.onPaletteLoaded(palette)
}
}

internal companion object {
internal val cache: LruCache<Any, Palette?>
by lazy(LazyThreadSafetyMode.NONE) { LruCache(20) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asAndroidBitmap
import com.skydoves.landscapist.ImageOptions
import com.skydoves.landscapist.plugins.ImagePlugin

Expand Down Expand Up @@ -56,7 +55,7 @@ public data class PalettePlugin(
apply {
imageBitmap?.let {
bitmapPalette.applyImageModel(this.imageModel ?: imageModel)
bitmapPalette.generate(it.asAndroidBitmap())
bitmapPalette.generate(it)
}
}
}

0 comments on commit 9c59e33

Please sign in to comment.