Skip to content

Commit 0c35513

Browse files
authored
Chore: Add demo for new PainterLoader (#75)
1 parent a4d91c1 commit 0c35513

File tree

12 files changed

+173
-25
lines changed

12 files changed

+173
-25
lines changed

README.md

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,10 @@ kotlin {
122122

123123
To see the generated KDocs, visit [docs.kmpalette.com](https://docs.kmpalette.com/)
124124

125-
In order to use this library you first must have a `ImageBitmap` object. You can get this from using
126-
one of the [sources](#sources) or by using a library that creates one for you.
125+
In order to use this library you first must have a `ImageBitmap` or a `Painter` object.
126+
127+
To get an `ImageBitmap` you can use one of the [sources](#sources) or by using a library that
128+
creates one for you.
127129

128130
Since this library is a port of
129131
the [`androidx.palette`](https://developer.android.com/jetpack/androidx/releases/palette) library,
@@ -164,6 +166,21 @@ fun SomeComposable(bitmap: ImageBitmap) {
164166
}
165167
```
166168

169+
You can also use a `Painter` object by specifying the `DominantColorState.loader` parameter:
170+
171+
```kotlin
172+
@Composable
173+
fun SomeComposable(painter: Painter) {
174+
val loader = rememberPainterLoader()
175+
val dominantColorState = rememberDominantColorState(loader = loader)
176+
LaunchedEffect(painter) {
177+
dominantColorState.updateFrom(painter)
178+
}
179+
180+
// ...
181+
}
182+
```
183+
167184
Since the generation of the dominant color is an asynchronous operation that can fail, you can track
168185
the results of the operation using the `DominantColorState.result` object.
169186

@@ -190,6 +207,8 @@ If you want a whole color palette instead of just a dominate color, you can use
190207
the `rememberPaletteState` composeable. This will provide a `Palette` object which contains a few
191208
different color `Swatch`s, each have their own color and _onColor_.
192209

210+
Using an `ImageBitmap`:
211+
193212
```kotlin
194213
fun SomeComposable(bitmap: ImageBitmap) {
195214
val paletteState = rememberPaletteState()
@@ -211,6 +230,20 @@ fun SomeComposable(bitmap: ImageBitmap) {
211230
}
212231
```
213232

233+
Or using a `Painter`:
234+
235+
```kotlin
236+
fun SomeComposable(painter: Painter) {
237+
val loader = rememberPainterLoader()
238+
val paletteState = rememberPaletteState(loader = loader)
239+
LaunchedEffect(painter) {
240+
paletteState.generate(painter)
241+
}
242+
243+
// ...
244+
}
245+
```
246+
214247
Since the generation of the dominant color is an asynchronous operation that can fail, you can track
215248
the results of the operation using the `DominantColorState.result` object.
216249

@@ -219,8 +252,10 @@ the [demo app](demo/composeApp/src/commonMain/kotlin/com/kmpalette/demo/palette)
219252

220253
### Sources
221254

222-
In order to generate a color palette, you must first have an `ImageBitmap` object. This library
223-
provides some extensions artifacts for some popular sources.
255+
The `kmpalette-core` library provides the core functionality for generating color palettes from
256+
a `ImageBitmap` or a `Painter` object.
257+
258+
This library provides some extensions artifacts for some popular sources.
224259

225260
| Artifact | Library | Loader | Input Class | Demo |
226261
|----------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------|--------------------------------|------------------|------------------------------------------------------------------------------------------------------------------------|

demo/composeApp/build.gradle.kts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
2-
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
32

43
plugins {
54
alias(libs.plugins.multiplatform)
@@ -9,7 +8,6 @@ plugins {
98
alias(libs.plugins.libres)
109
}
1110

12-
@OptIn(ExperimentalKotlinGradlePluginApi::class)
1311
kotlin {
1412
applyDefaultHierarchyTemplate()
1513

@@ -67,6 +65,7 @@ kotlin {
6765
implementation(libs.kermit)
6866
implementation(libs.calf.filePicker)
6967
implementation(libs.ktor.client)
68+
implementation(libs.kamel)
7069
}
7170
}
7271

demo/composeApp/src/commonMain/kotlin/com/kmpalette/demo/HomeScreen.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ import cafe.adriel.voyager.navigator.currentOrThrow
1515
import com.kmpalette.demo.dominant.Base64DemoScreen
1616
import com.kmpalette.demo.dominant.DominantPhotoColorScreen
1717
import com.kmpalette.demo.dominant.NetworkDemoScreen
18+
import com.kmpalette.demo.dominant.NetworkPainterDemoScreen
1819
import com.kmpalette.demo.palette.LibresPaletteScreen
20+
import com.kmpalette.demo.palette.PainterPaletteScreen
1921
import com.kmpalette.demo.palette.ResourcesPaletteScreen
2022
import com.kmpalette.demo.theme.AppTheme
2123

@@ -37,6 +39,12 @@ class HomeScreen : Screen {
3739
Button(onClick = { navigator.push(ResourcesPaletteScreen()) }) {
3840
Text("Palette - Resources")
3941
}
42+
Button(onClick = { navigator.push(PainterPaletteScreen()) }) {
43+
Text("Palette - Painter")
44+
}
45+
Button(onClick = { navigator.push(NetworkPainterDemoScreen()) }) {
46+
Text("Dominant Color - Painter")
47+
}
4048
Button(onClick = { navigator.push(DominantPhotoColorScreen()) }) {
4149
Text("Dominant Color - Photo Picker")
4250
}

demo/composeApp/src/commonMain/kotlin/com/kmpalette/demo/dominant/DominantPhotoColorScreen.kt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import androidx.compose.runtime.setValue
3030
import androidx.compose.ui.Alignment
3131
import androidx.compose.ui.Modifier
3232
import androidx.compose.ui.graphics.ImageBitmap
33+
import androidx.compose.ui.graphics.Paint
34+
import androidx.compose.ui.graphics.painter.Painter
3335
import androidx.compose.ui.graphics.toArgb
3436
import androidx.compose.ui.unit.dp
3537
import cafe.adriel.voyager.core.screen.Screen
@@ -89,8 +91,9 @@ class DominantPhotoColorScreen : Screen {
8991
@Composable
9092
internal fun <T : Any> DominantDemoContent(
9193
dominantColorState: DominantColorState<T>,
92-
imageBitmap: ImageBitmap?,
93-
content: @Composable () -> Unit,
94+
imageBitmap: ImageBitmap? = null,
95+
painter: Painter? = null,
96+
content: @Composable () -> Unit = {},
9497
) {
9598
var style: PaletteStyle by remember { mutableStateOf(PaletteStyle.TonalSpot) }
9699

@@ -114,6 +117,12 @@ internal fun <T : Any> DominantDemoContent(
114117
contentDescription = null,
115118
modifier = Modifier.heightIn(max = 200.dp)
116119
)
120+
} else if (painter != null) {
121+
Image(
122+
painter = painter,
123+
contentDescription = null,
124+
modifier = Modifier.heightIn(max = 200.dp)
125+
)
117126
}
118127

119128
when (dominantColorState.result) {
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.kmpalette.demo.dominant
2+
3+
import androidx.compose.material3.CircularProgressIndicator
4+
import androidx.compose.material3.Text
5+
import androidx.compose.runtime.Composable
6+
import androidx.compose.runtime.LaunchedEffect
7+
import androidx.compose.ui.graphics.painter.Painter
8+
import cafe.adriel.voyager.core.screen.Screen
9+
import com.kmpalette.loader.rememberPainterLoader
10+
import com.kmpalette.rememberDominantColorState
11+
import io.kamel.core.Resource
12+
import io.kamel.image.asyncPainterResource
13+
import io.ktor.http.Url
14+
15+
class NetworkPainterDemoScreen : Screen {
16+
17+
private val demoImageUrl = Url("https://picsum.photos/600/300")
18+
19+
@Composable
20+
override fun Content() {
21+
when (val painterResource = asyncPainterResource(demoImageUrl)) {
22+
is Resource.Failure -> Text("Failed to load image")
23+
is Resource.Loading -> CircularProgressIndicator()
24+
is Resource.Success -> SuccessContent(painterResource)
25+
}
26+
}
27+
28+
@Composable
29+
private fun SuccessContent(resource: Resource.Success<Painter>) {
30+
val loader = rememberPainterLoader()
31+
val dominantColorState = rememberDominantColorState(loader)
32+
LaunchedEffect(resource) {
33+
dominantColorState.updateFrom(resource.value)
34+
}
35+
36+
DominantDemoContent(
37+
dominantColorState = dominantColorState,
38+
painter = resource.value,
39+
)
40+
}
41+
}

demo/composeApp/src/commonMain/kotlin/com/kmpalette/demo/palette/LibresPaletteScreen.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import com.kmpalette.loader.LibresLoader
77
import com.kmpalette.rememberPaletteState
88
import io.github.skeptick.libres.compose.painterResource
99

10-
private val images = listOf(
10+
internal val images = listOf(
1111
Res.image.bg_1,
1212
Res.image.bg_2,
1313
Res.image.bg_3,
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.kmpalette.demo.palette
2+
3+
import androidx.compose.runtime.Composable
4+
import cafe.adriel.voyager.core.screen.Screen
5+
import com.kmpalette.loader.rememberPainterLoader
6+
import com.kmpalette.rememberPaletteState
7+
import io.github.skeptick.libres.compose.painterResource
8+
9+
class PainterPaletteScreen : Screen {
10+
11+
@Composable
12+
override fun Content() {
13+
val painters = images.map { it.painterResource() }
14+
15+
val loader = rememberPainterLoader()
16+
PaletteScreen(
17+
images = painters,
18+
paletteState = rememberPaletteState(loader),
19+
painterResource = { _, painter -> painter },
20+
)
21+
}
22+
}

gradle/libs.versions.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ kover = "0.7.5"
3232
poko = "0.15.1"
3333
calf-filePicker = "0.3.0"
3434
okio = "3.6.0"
35+
kamel = "0.9.0"
3536

3637
# These are pinned for Android instrumented tests
3738
#noinspection GradleDependency
@@ -70,6 +71,7 @@ libres = { module = "io.github.skeptick.libres:libres-compose", version.ref = "l
7071
materialKolor = { module = "com.materialkolor:material-kolor", version.ref = "materialKolor" }
7172
voyager-navigator = { module = "cafe.adriel.voyager:voyager-navigator", version.ref = "voyager" }
7273
calf-filePicker = { module = "com.mohamedrejeb.calf:calf-file-picker", version.ref = "calf-filePicker" }
74+
kamel = { module = "media.kamel:kamel-image", version.ref = "kamel" }
7375

7476
[plugins]
7577
multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }

kmpalette-core/api/android/kmpalette-core.api

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,3 +162,7 @@ public final class com/kmpalette/loader/PainterLoader : com/kmpalette/loader/Ima
162162
public synthetic fun load (Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
163163
}
164164

165+
public final class com/kmpalette/loader/PainterLoaderKt {
166+
public static final fun rememberPainterLoader (Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/runtime/Composer;II)Lcom/kmpalette/loader/PainterLoader;
167+
}
168+

kmpalette-core/api/jvm/kmpalette-core.api

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,3 +162,7 @@ public final class com/kmpalette/loader/PainterLoader : com/kmpalette/loader/Ima
162162
public synthetic fun load (Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
163163
}
164164

165+
public final class com/kmpalette/loader/PainterLoaderKt {
166+
public static final fun rememberPainterLoader (Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/unit/LayoutDirection;Landroidx/compose/runtime/Composer;II)Lcom/kmpalette/loader/PainterLoader;
167+
}
168+

0 commit comments

Comments
 (0)