Browse Source

[example] Migrate the image viewer on the new compose resources (#4433)

pull/4458/head v1.6.10-dev1498
Konstantin 9 months ago committed by GitHub
parent
commit
52c4bf3b1f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 10
      examples/imageviewer/desktopApp/build.gradle.kts
  2. 0
      examples/imageviewer/desktopApp/desktop-icons/icon-linux.png
  3. 0
      examples/imageviewer/desktopApp/desktop-icons/icon-mac.icns
  4. 0
      examples/imageviewer/desktopApp/desktop-icons/icon-windows.ico
  5. 4
      examples/imageviewer/gradle.properties
  6. 57
      examples/imageviewer/shared/build.gradle.kts
  7. 7
      examples/imageviewer/shared/src/androidMain/kotlin/example/imageviewer/storage/AndroidImageStorage.kt
  8. 7
      examples/imageviewer/shared/src/androidMain/kotlin/example/imageviewer/view/CameraView.android.kt
  9. 0
      examples/imageviewer/shared/src/commonMain/composeResources/drawable/ic_imageviewer_round.png
  10. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/1-thumbnail.jpg
  11. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/1.jpg
  12. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/10-thumbnail.jpg
  13. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/10.jpg
  14. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/11-thumbnail.jpg
  15. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/11.jpg
  16. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/12-thumbnail.jpg
  17. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/12.jpg
  18. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/13-thumbnail.jpg
  19. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/13.jpg
  20. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/14-thumbnail.jpg
  21. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/14.jpg
  22. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/15-thumbnail.jpg
  23. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/15.jpg
  24. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/16-thumbnail.jpg
  25. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/16.jpg
  26. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/17-thumbnail.jpg
  27. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/17.jpg
  28. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/2-thumbnail.jpg
  29. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/2.jpg
  30. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/3-thumbnail.jpg
  31. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/3.jpg
  32. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/4-thumbnail.jpg
  33. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/4.jpg
  34. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/5-thumbnail.jpg
  35. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/5.jpg
  36. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/6-thumbnail.jpg
  37. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/6.jpg
  38. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/7-thumbnail.jpg
  39. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/7.jpg
  40. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/8-thumbnail.jpg
  41. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/8.jpg
  42. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/9-thumbnail.jpg
  43. 0
      examples/imageviewer/shared/src/commonMain/composeResources/files/9.jpg
  44. 8
      examples/imageviewer/shared/src/commonMain/kotlin/example/imageviewer/Dependencies.kt
  45. 68
      examples/imageviewer/shared/src/commonMain/kotlin/example/imageviewer/ResourcePictures.kt
  46. BIN
      examples/imageviewer/shared/src/commonMain/resources/android-emulator-photo.jpg
  47. BIN
      examples/imageviewer/shared/src/commonMain/resources/dummy_map.png
  48. 19
      examples/imageviewer/shared/src/desktopMain/kotlin/example/imageviewer/view/CameraView.desktop.kt
  49. 16
      examples/imageviewer/shared/src/desktopMain/kotlin/example/imageviewer/view/ImageViewer.desktop.kt
  50. 5
      examples/imageviewer/shared/src/desktopMain/kotlin/example/imageviewer/view/LocationVisualizer.desktop.kt

10
examples/imageviewer/desktopApp/build.gradle.kts

@ -6,18 +6,14 @@ plugins {
} }
kotlin { kotlin {
jvm { jvm()
withJava()
}
sourceSets { sourceSets {
val jvmMain by getting { jvmMain.dependencies {
dependencies {
implementation(compose.desktop.currentOs) implementation(compose.desktop.currentOs)
implementation(project(":shared")) implementation(project(":shared"))
} }
} }
} }
}
compose.desktop { compose.desktop {
application { application {
@ -28,7 +24,7 @@ compose.desktop {
packageName = "ImageViewer" packageName = "ImageViewer"
packageVersion = "1.0.0" packageVersion = "1.0.0"
val iconsRoot = project.file("../shared/src/commonMain/resources") val iconsRoot = project.file("desktop-icons")
macOS { macOS {
iconFile.set(iconsRoot.resolve("icon-mac.icns")) iconFile.set(iconsRoot.resolve("icon-mac.icns"))
} }

0
examples/imageviewer/shared/src/commonMain/resources/icon-linux.png → examples/imageviewer/desktopApp/desktop-icons/icon-linux.png

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

0
examples/imageviewer/shared/src/commonMain/resources/icon-mac.icns → examples/imageviewer/desktopApp/desktop-icons/icon-mac.icns

0
examples/imageviewer/shared/src/commonMain/resources/icon-windows.ico → examples/imageviewer/desktopApp/desktop-icons/icon-windows.ico

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 66 KiB

4
examples/imageviewer/gradle.properties

@ -6,10 +6,6 @@ org.gradle.configuration-cache=true
org.gradle.caching=true org.gradle.caching=true
org.jetbrains.compose.experimental.jscanvas.enabled=true org.jetbrains.compose.experimental.jscanvas.enabled=true
org.jetbrains.compose.experimental.macos.enabled=true org.jetbrains.compose.experimental.macos.enabled=true
kotlin.mpp.androidSourceSetLayoutVersion=2
kotlin.native.useEmbeddableCompilerJar=true
# Enable kotlin/native experimental memory model
kotlin.native.binary.memoryModel=experimental
kotlin.version=1.9.22 kotlin.version=1.9.22
agp.version=8.0.2 agp.version=8.0.2
compose.version=1.6.0 compose.version=1.6.0

57
examples/imageviewer/shared/build.gradle.kts

@ -1,5 +1,3 @@
@file:Suppress("OPT_IN_IS_NOT_ENABLED")
plugins { plugins {
kotlin("multiplatform") kotlin("multiplatform")
id("com.android.library") id("com.android.library")
@ -26,65 +24,54 @@ kotlin {
} }
sourceSets { sourceSets {
val commonMain by getting { all {
dependencies { languageSettings {
optIn("org.jetbrains.compose.resources.ExperimentalResourceApi")
}
}
commonMain.dependencies {
implementation(compose.runtime) implementation(compose.runtime)
implementation(compose.foundation) implementation(compose.foundation)
implementation(compose.material) implementation(compose.material)
//implementation(compose.materialIconsExtended) // TODO not working on iOS for now implementation(compose.components.resources)
implementation("org.jetbrains.compose.components:components-resources:1.6.0-dev1275") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1") implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.5.0")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0")
// Kotlin Coroutines 1.7.1 contains Dispatchers.IO for iOS
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1")
}
} }
val androidMain by getting { androidMain.dependencies {
dependencies { api("androidx.activity:activity-compose:1.8.2")
api("androidx.activity:activity-compose:1.7.2")
api("androidx.appcompat:appcompat:1.6.1") api("androidx.appcompat:appcompat:1.6.1")
api("androidx.core:core-ktx:1.10.1") api("androidx.core:core-ktx:1.12.0")
implementation("androidx.camera:camera-camera2:1.2.3") implementation("androidx.camera:camera-camera2:1.3.1")
implementation("androidx.camera:camera-lifecycle:1.2.3") implementation("androidx.camera:camera-lifecycle:1.3.1")
implementation("androidx.camera:camera-view:1.2.3") implementation("androidx.camera:camera-view:1.3.1")
implementation("com.google.accompanist:accompanist-permissions:0.29.2-rc") implementation("com.google.accompanist:accompanist-permissions:0.29.2-rc")
implementation("com.google.android.gms:play-services-maps:18.1.0") implementation("com.google.android.gms:play-services-maps:18.2.0")
implementation("com.google.android.gms:play-services-location:21.0.1") implementation("com.google.android.gms:play-services-location:21.1.0")
implementation("com.google.maps.android:maps-compose:2.11.2") implementation("com.google.maps.android:maps-compose:2.11.2")
} }
} val desktopMain by getting
desktopMain.dependencies {
val desktopMain by getting {
dependencies {
implementation(compose.desktop.common) implementation(compose.desktop.common)
implementation(project(":mapview-desktop")) implementation(project(":mapview-desktop"))
} }
} val desktopTest by getting
desktopTest.dependencies {
val desktopTest by getting {
dependencies {
implementation(compose.desktop.currentOs) implementation(compose.desktop.currentOs)
implementation(compose.desktop.uiTestJUnit4) implementation(compose.desktop.uiTestJUnit4)
} }
} }
} }
}
android { android {
compileSdk = 34 compileSdk = 34
namespace = "example.imageviewer.shared" namespace = "example.imageviewer.shared"
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
sourceSets["main"].res.srcDirs("src/androidMain/res") sourceSets["main"].res.srcDirs("src/androidMain/res")
sourceSets["main"].resources.srcDirs("src/commonMain/resources")
defaultConfig { defaultConfig {
minSdk = 26 minSdk = 26
} }
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlin { kotlin {
jvmToolchain(17) jvmToolchain(17)
} }

7
examples/imageviewer/shared/src/androidMain/kotlin/example/imageviewer/storage/AndroidImageStorage.kt

@ -13,15 +13,13 @@ import example.imageviewer.ImageStorage
import example.imageviewer.PlatformStorableImage import example.imageviewer.PlatformStorableImage
import example.imageviewer.model.PictureData import example.imageviewer.model.PictureData
import example.imageviewer.toImageBitmap import example.imageviewer.toImageBitmap
import imageviewer.shared.generated.resources.Res
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.readResourceBytes
import java.io.File import java.io.File
private const val maxStorableImageSizePx = 2000 private const val maxStorableImageSizePx = 2000
@ -102,7 +100,6 @@ class AndroidImageStorage(
picture.jpgFile.readBytes().toImageBitmap() picture.jpgFile.readBytes().toImageBitmap()
} }
@OptIn(ExperimentalResourceApi::class)
suspend fun getUri(context: Context, picture: PictureData): Uri = withContext(Dispatchers.IO) { suspend fun getUri(context: Context, picture: PictureData): Uri = withContext(Dispatchers.IO) {
if (!sharedImagesDir.exists()) { if (!sharedImagesDir.exists()) {
sharedImagesDir.mkdirs() sharedImagesDir.mkdirs()
@ -117,7 +114,7 @@ class AndroidImageStorage(
if (!tempFileToShare.exists()) { if (!tempFileToShare.exists()) {
tempFileToShare.createNewFile() tempFileToShare.createNewFile()
} }
tempFileToShare.writeBytes(readResourceBytes(picture.resource)) tempFileToShare.writeBytes(Res.readBytes(picture.resource))
} }
} }
FileProvider.getUriForFile( FileProvider.getUriForFile(

7
examples/imageviewer/shared/src/androidMain/kotlin/example/imageviewer/view/CameraView.android.kt

@ -34,12 +34,10 @@ import example.imageviewer.icon.IconPhotoCamera
import example.imageviewer.model.GpsPosition import example.imageviewer.model.GpsPosition
import example.imageviewer.model.PictureData import example.imageviewer.model.PictureData
import example.imageviewer.model.createCameraPictureData import example.imageviewer.model.createCameraPictureData
import imageviewer.shared.generated.resources.Res
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.readResourceBytes
import java.nio.ByteBuffer import java.nio.ByteBuffer
import java.util.*
import java.util.concurrent.Executors import java.util.concurrent.Executors
import kotlin.coroutines.resume import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine import kotlin.coroutines.suspendCoroutine
@ -69,7 +67,6 @@ actual fun CameraView(
} }
} }
@OptIn(ExperimentalResourceApi::class)
@SuppressLint("MissingPermission") @SuppressLint("MissingPermission")
@Composable @Composable
private fun CameraWithGrantedPermission( private fun CameraWithGrantedPermission(
@ -176,7 +173,7 @@ private fun CameraWithGrantedPermission(
delay(5000) delay(5000)
if (capturePhotoStarted) { if (capturePhotoStarted) {
addLocationInfoAndReturnResult( addLocationInfoAndReturnResult(
readResourceBytes("android-emulator-photo.jpg").toImageBitmap() Res.readBytes("files/android-emulator-photo.jpg").toImageBitmap()
) )
} }
} }

0
examples/imageviewer/shared/src/commonMain/resources/ic_imageviewer_round.png → examples/imageviewer/shared/src/commonMain/composeResources/drawable/ic_imageviewer_round.png

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

0
examples/imageviewer/shared/src/commonMain/resources/1-thumbnail.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/1-thumbnail.jpg

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

0
examples/imageviewer/shared/src/commonMain/resources/1.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/1.jpg

Before

Width:  |  Height:  |  Size: 664 KiB

After

Width:  |  Height:  |  Size: 664 KiB

0
examples/imageviewer/shared/src/commonMain/resources/10-thumbnail.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/10-thumbnail.jpg

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

0
examples/imageviewer/shared/src/commonMain/resources/10.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/10.jpg

Before

Width:  |  Height:  |  Size: 107 KiB

After

Width:  |  Height:  |  Size: 107 KiB

0
examples/imageviewer/shared/src/commonMain/resources/11-thumbnail.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/11-thumbnail.jpg

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

0
examples/imageviewer/shared/src/commonMain/resources/11.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/11.jpg

Before

Width:  |  Height:  |  Size: 190 KiB

After

Width:  |  Height:  |  Size: 190 KiB

0
examples/imageviewer/shared/src/commonMain/resources/12-thumbnail.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/12-thumbnail.jpg

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

0
examples/imageviewer/shared/src/commonMain/resources/12.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/12.jpg

Before

Width:  |  Height:  |  Size: 137 KiB

After

Width:  |  Height:  |  Size: 137 KiB

0
examples/imageviewer/shared/src/commonMain/resources/13-thumbnail.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/13-thumbnail.jpg

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

0
examples/imageviewer/shared/src/commonMain/resources/13.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/13.jpg

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 110 KiB

0
examples/imageviewer/shared/src/commonMain/resources/14-thumbnail.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/14-thumbnail.jpg

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

0
examples/imageviewer/shared/src/commonMain/resources/14.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/14.jpg

Before

Width:  |  Height:  |  Size: 458 KiB

After

Width:  |  Height:  |  Size: 458 KiB

0
examples/imageviewer/shared/src/commonMain/resources/15-thumbnail.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/15-thumbnail.jpg

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

0
examples/imageviewer/shared/src/commonMain/resources/15.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/15.jpg

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 132 KiB

0
examples/imageviewer/shared/src/commonMain/resources/16-thumbnail.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/16-thumbnail.jpg

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

0
examples/imageviewer/shared/src/commonMain/resources/16.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/16.jpg

Before

Width:  |  Height:  |  Size: 264 KiB

After

Width:  |  Height:  |  Size: 264 KiB

0
examples/imageviewer/shared/src/commonMain/resources/17-thumbnail.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/17-thumbnail.jpg

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

0
examples/imageviewer/shared/src/commonMain/resources/17.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/17.jpg

Before

Width:  |  Height:  |  Size: 513 KiB

After

Width:  |  Height:  |  Size: 513 KiB

0
examples/imageviewer/shared/src/commonMain/resources/2-thumbnail.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/2-thumbnail.jpg

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

0
examples/imageviewer/shared/src/commonMain/resources/2.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/2.jpg

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 37 KiB

0
examples/imageviewer/shared/src/commonMain/resources/3-thumbnail.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/3-thumbnail.jpg

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

0
examples/imageviewer/shared/src/commonMain/resources/3.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/3.jpg

Before

Width:  |  Height:  |  Size: 826 KiB

After

Width:  |  Height:  |  Size: 826 KiB

0
examples/imageviewer/shared/src/commonMain/resources/4-thumbnail.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/4-thumbnail.jpg

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

0
examples/imageviewer/shared/src/commonMain/resources/4.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/4.jpg

Before

Width:  |  Height:  |  Size: 300 KiB

After

Width:  |  Height:  |  Size: 300 KiB

0
examples/imageviewer/shared/src/commonMain/resources/5-thumbnail.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/5-thumbnail.jpg

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

0
examples/imageviewer/shared/src/commonMain/resources/5.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/5.jpg

Before

Width:  |  Height:  |  Size: 305 KiB

After

Width:  |  Height:  |  Size: 305 KiB

0
examples/imageviewer/shared/src/commonMain/resources/6-thumbnail.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/6-thumbnail.jpg

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

0
examples/imageviewer/shared/src/commonMain/resources/6.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/6.jpg

Before

Width:  |  Height:  |  Size: 342 KiB

After

Width:  |  Height:  |  Size: 342 KiB

0
examples/imageviewer/shared/src/commonMain/resources/7-thumbnail.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/7-thumbnail.jpg

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

0
examples/imageviewer/shared/src/commonMain/resources/7.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/7.jpg

Before

Width:  |  Height:  |  Size: 417 KiB

After

Width:  |  Height:  |  Size: 417 KiB

0
examples/imageviewer/shared/src/commonMain/resources/8-thumbnail.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/8-thumbnail.jpg

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 17 KiB

0
examples/imageviewer/shared/src/commonMain/resources/8.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/8.jpg

Before

Width:  |  Height:  |  Size: 474 KiB

After

Width:  |  Height:  |  Size: 474 KiB

0
examples/imageviewer/shared/src/commonMain/resources/9-thumbnail.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/9-thumbnail.jpg

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

0
examples/imageviewer/shared/src/commonMain/resources/9.jpg → examples/imageviewer/shared/src/commonMain/composeResources/files/9.jpg

Before

Width:  |  Height:  |  Size: 303 KiB

After

Width:  |  Height:  |  Size: 303 KiB

8
examples/imageviewer/shared/src/commonMain/kotlin/example/imageviewer/Dependencies.kt

@ -6,12 +6,10 @@ import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.ImageBitmap
import example.imageviewer.filter.PlatformContext import example.imageviewer.filter.PlatformContext
import example.imageviewer.model.PictureData import example.imageviewer.model.PictureData
import imageviewer.shared.generated.resources.Res
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.emptyFlow
import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.readResourceBytes
@OptIn(ExperimentalResourceApi::class)
abstract class Dependencies { abstract class Dependencies {
abstract val notification: Notification abstract val notification: Notification
abstract val imageStorage: ImageStorage abstract val imageStorage: ImageStorage
@ -22,7 +20,7 @@ abstract class Dependencies {
val imageProvider: ImageProvider = object : ImageProvider { val imageProvider: ImageProvider = object : ImageProvider {
override suspend fun getImage(picture: PictureData): ImageBitmap = when (picture) { override suspend fun getImage(picture: PictureData): ImageBitmap = when (picture) {
is PictureData.Resource -> { is PictureData.Resource -> {
readResourceBytes(picture.resource).toImageBitmap() Res.readBytes(picture.resource).toImageBitmap()
} }
is PictureData.Camera -> { is PictureData.Camera -> {
@ -32,7 +30,7 @@ abstract class Dependencies {
override suspend fun getThumbnail(picture: PictureData): ImageBitmap = when (picture) { override suspend fun getThumbnail(picture: PictureData): ImageBitmap = when (picture) {
is PictureData.Resource -> { is PictureData.Resource -> {
readResourceBytes(picture.thumbnailResource).toImageBitmap() Res.readBytes(picture.thumbnailResource).toImageBitmap()
} }
is PictureData.Camera -> { is PictureData.Camera -> {

68
examples/imageviewer/shared/src/commonMain/kotlin/example/imageviewer/ResourcePictures.kt

@ -5,8 +5,8 @@ import example.imageviewer.model.PictureData
val resourcePictures = arrayOf( val resourcePictures = arrayOf(
PictureData.Resource( PictureData.Resource(
resource = "1.jpg", resource = "files/1.jpg",
thumbnailResource = "1-thumbnail.jpg", thumbnailResource = "files/1-thumbnail.jpg",
name = "Mountain K2", name = "Mountain K2",
description = """ description = """
K2, at 8,611 meters above sea level, is the second-highest mountain on Earth, after Mount Everest. K2, at 8,611 meters above sea level, is the second-highest mountain on Earth, after Mount Everest.
@ -17,8 +17,8 @@ val resourcePictures = arrayOf(
gps = GpsPosition(35.8825, 76.513333) gps = GpsPosition(35.8825, 76.513333)
), ),
PictureData.Resource( PictureData.Resource(
resource = "2.jpg", resource = "files/2.jpg",
thumbnailResource = "2-thumbnail.jpg", thumbnailResource = "files/2-thumbnail.jpg",
name = "Kina The Calico", name = "Kina The Calico",
description = """ description = """
This cute kitty 🐱 loves one thing above all: soups and sauces! This cute kitty 🐱 loves one thing above all: soups and sauces!
@ -29,8 +29,8 @@ val resourcePictures = arrayOf(
gps = GpsPosition(48.138018, 11.5737048) gps = GpsPosition(48.138018, 11.5737048)
), ),
PictureData.Resource( PictureData.Resource(
resource = "3.jpg", resource = "files/3.jpg",
thumbnailResource = "3-thumbnail.jpg", thumbnailResource = "files/3-thumbnail.jpg",
name = "Blue City", name = "Blue City",
description = """ description = """
Is a city in northwest Morocco. Is a city in northwest Morocco.
@ -41,8 +41,8 @@ val resourcePictures = arrayOf(
gps = GpsPosition(35.171389, -5.269722) gps = GpsPosition(35.171389, -5.269722)
), ),
PictureData.Resource( PictureData.Resource(
resource = "4.jpg", resource = "files/4.jpg",
thumbnailResource = "4-thumbnail.jpg", thumbnailResource = "files/4-thumbnail.jpg",
name = "Tokyo Skytree", name = "Tokyo Skytree",
description = """ description = """
Tokyo Skytree is a broadcasting and observation tower in Sumida, Tokyo. Tokyo Skytree is a broadcasting and observation tower in Sumida, Tokyo.
@ -52,8 +52,8 @@ val resourcePictures = arrayOf(
gps = GpsPosition(35.7101, 139.8107) gps = GpsPosition(35.7101, 139.8107)
), ),
PictureData.Resource( PictureData.Resource(
resource = "5.jpg", resource = "files/5.jpg",
thumbnailResource = "5-thumbnail.jpg", thumbnailResource = "files/5-thumbnail.jpg",
name = "Taranaki", name = "Taranaki",
description = """ description = """
Mount Taranaki is a dormant stratovolcano in the Taranaki region on the west coast of New Zealand's North Island. Mount Taranaki is a dormant stratovolcano in the Taranaki region on the west coast of New Zealand's North Island.
@ -64,8 +64,8 @@ val resourcePictures = arrayOf(
gps = GpsPosition(-39.296389, 174.064722) gps = GpsPosition(-39.296389, 174.064722)
), ),
PictureData.Resource( PictureData.Resource(
resource = "6.jpg", resource = "files/6.jpg",
thumbnailResource = "6-thumbnail.jpg", thumbnailResource = "files/6-thumbnail.jpg",
name = "Auckland SkyCity", name = "Auckland SkyCity",
description = """ description = """
SkyCity Casino History SkyCity Casino History
@ -76,8 +76,8 @@ val resourcePictures = arrayOf(
gps = GpsPosition(-36.846589, 174.760871) gps = GpsPosition(-36.846589, 174.760871)
), ),
PictureData.Resource( PictureData.Resource(
resource = "7.jpg", resource = "files/7.jpg",
thumbnailResource = "7-thumbnail.jpg", thumbnailResource = "files/7-thumbnail.jpg",
name = "Berliner Fernsehturm", name = "Berliner Fernsehturm",
description = """ description = """
At 368 meters, the Berlin television tower is the tallest building in Germany and the fifth tallest television tower in Europe. At 368 meters, the Berlin television tower is the tallest building in Germany and the fifth tallest television tower in Europe.
@ -88,8 +88,8 @@ val resourcePictures = arrayOf(
gps = GpsPosition(52.520833, 13.409444) gps = GpsPosition(52.520833, 13.409444)
), ),
PictureData.Resource( PictureData.Resource(
resource = "8.jpg", resource = "files/8.jpg",
thumbnailResource = "8-thumbnail.jpg", thumbnailResource = "files/8-thumbnail.jpg",
name = "Hoggar Mountains", name = "Hoggar Mountains",
description = """ description = """
The Hoggar Mountains are a highland region in the central Sahara in southern Algeria, along the Tropic of Cancer. The Hoggar Mountains are a highland region in the central Sahara in southern Algeria, along the Tropic of Cancer.
@ -99,8 +99,8 @@ val resourcePictures = arrayOf(
gps = GpsPosition(22.133333, 6.166667) gps = GpsPosition(22.133333, 6.166667)
), ),
PictureData.Resource( PictureData.Resource(
resource = "9.jpg", resource = "files/9.jpg",
thumbnailResource = "9-thumbnail.jpg", thumbnailResource = "files/9-thumbnail.jpg",
name = "Nakhal Fort", name = "Nakhal Fort",
description = """ description = """
Nakhal Fort is a large fortification in Al Batinah Region of Oman. Nakhal Fort is a large fortification in Al Batinah Region of Oman.
@ -111,8 +111,8 @@ val resourcePictures = arrayOf(
gps = GpsPosition(23.395, 57.829) gps = GpsPosition(23.395, 57.829)
), ),
PictureData.Resource( PictureData.Resource(
resource = "10.jpg", resource = "files/10.jpg",
thumbnailResource = "10-thumbnail.jpg", thumbnailResource = "files/10-thumbnail.jpg",
name = "Mountain Ararat", name = "Mountain Ararat",
description = """ description = """
Mount Ararat is a snow-capped and dormant compound volcano in the extreme east of Turkey. Mount Ararat is a snow-capped and dormant compound volcano in the extreme east of Turkey.
@ -123,8 +123,8 @@ val resourcePictures = arrayOf(
gps = GpsPosition(40.169339, 44.488434) gps = GpsPosition(40.169339, 44.488434)
), ),
PictureData.Resource( PictureData.Resource(
resource = "11.jpg", resource = "files/11.jpg",
thumbnailResource = "11-thumbnail.jpg", thumbnailResource = "files/11-thumbnail.jpg",
name = "Cabo da Roca", name = "Cabo da Roca",
description = """ description = """
The view on Cabo da Roca. The view on Cabo da Roca.
@ -134,8 +134,8 @@ val resourcePictures = arrayOf(
gps = GpsPosition(38.789283172, -9.4909725957) gps = GpsPosition(38.789283172, -9.4909725957)
), ),
PictureData.Resource( PictureData.Resource(
resource = "12.jpg", resource = "files/12.jpg",
thumbnailResource = "12-thumbnail.jpg", thumbnailResource = "files/12-thumbnail.jpg",
name = "Surprised Whiskers 🐱", name = "Surprised Whiskers 🐱",
description = """ description = """
Surprised Whiskers: A Furry Tale. Surprised Whiskers: A Furry Tale.
@ -146,8 +146,8 @@ val resourcePictures = arrayOf(
gps = GpsPosition(52.3560485, 4.9085645) gps = GpsPosition(52.3560485, 4.9085645)
), ),
PictureData.Resource( PictureData.Resource(
resource = "13.jpg", resource = "files/13.jpg",
thumbnailResource = "13-thumbnail.jpg", thumbnailResource = "files/13-thumbnail.jpg",
name = "Software Engineering Donut", name = "Software Engineering Donut",
description = """ description = """
Munich Munich
@ -159,8 +159,8 @@ val resourcePictures = arrayOf(
gps = GpsPosition(48.1764708, 11.4580367) gps = GpsPosition(48.1764708, 11.4580367)
), ),
PictureData.Resource( PictureData.Resource(
resource = "14.jpg", resource = "files/14.jpg",
thumbnailResource = "14-thumbnail.jpg", thumbnailResource = "files/14-thumbnail.jpg",
name = "Seligman Police Car.", name = "Seligman Police Car.",
description = """ description = """
Seligman, USA Seligman, USA
@ -172,8 +172,8 @@ val resourcePictures = arrayOf(
gps = GpsPosition(35.3259364, -112.8553165) gps = GpsPosition(35.3259364, -112.8553165)
), ),
PictureData.Resource( PictureData.Resource(
resource = "15.jpg", resource = "files/15.jpg",
thumbnailResource = "15-thumbnail.jpg", thumbnailResource = "files/15-thumbnail.jpg",
name = "Good Luck Charms", name = "Good Luck Charms",
description = """ description = """
Munich Munich
@ -186,8 +186,8 @@ val resourcePictures = arrayOf(
gps = GpsPosition(48.1458602, 11.5053059) gps = GpsPosition(48.1458602, 11.5053059)
), ),
PictureData.Resource( PictureData.Resource(
resource = "16.jpg", resource = "files/16.jpg",
thumbnailResource = "16-thumbnail.jpg", thumbnailResource = "files/16-thumbnail.jpg",
name = "Pong Restaurant", name = "Pong Restaurant",
description = """ description = """
Stockholm, Sweden Stockholm, Sweden
@ -199,8 +199,8 @@ val resourcePictures = arrayOf(
gps = GpsPosition(59.3364318, 18.0587228) gps = GpsPosition(59.3364318, 18.0587228)
), ),
PictureData.Resource( PictureData.Resource(
resource = "17.jpg", resource = "files/17.jpg",
thumbnailResource = "17-thumbnail.jpg", thumbnailResource = "files/17-thumbnail.jpg",
name = "Loki", name = "Loki",
description = """ description = """
Meet Loki, my black cat - a furry feline with big, beautiful eyes and an arrogant attitude. Meet Loki, my black cat - a furry feline with big, beautiful eyes and an arrogant attitude.

BIN
examples/imageviewer/shared/src/commonMain/resources/android-emulator-photo.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

BIN
examples/imageviewer/shared/src/commonMain/resources/dummy_map.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 MiB

19
examples/imageviewer/shared/src/desktopMain/kotlin/example/imageviewer/view/CameraView.desktop.kt

@ -2,35 +2,34 @@ package example.imageviewer.view
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.*
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import example.imageviewer.* import example.imageviewer.*
import example.imageviewer.icon.IconPhotoCamera import example.imageviewer.icon.IconPhotoCamera
import example.imageviewer.model.PictureData import example.imageviewer.model.PictureData
import example.imageviewer.model.createCameraPictureData import example.imageviewer.model.createCameraPictureData
import org.jetbrains.compose.resources.ExperimentalResourceApi import imageviewer.shared.generated.resources.Res
import org.jetbrains.compose.resources.imageResource
@OptIn(ExperimentalResourceApi::class)
@Composable @Composable
actual fun CameraView( actual fun CameraView(
modifier: Modifier, modifier: Modifier,
onCapture: (picture: PictureData.Camera, image: PlatformStorableImage) -> Unit onCapture: (picture: PictureData.Camera, image: PlatformStorableImage) -> Unit
) { ) {
val randomPicture = remember { resourcePictures.random() } val randomPicture = remember { resourcePictures.random() }
val imageBitmap = imageResource(randomPicture.resource) var imageBitmap by remember { mutableStateOf(ImageBitmap(1, 1)) }
LaunchedEffect(randomPicture) {
imageBitmap = Res.readBytes(randomPicture.resource).toImageBitmap()
}
Box(Modifier.fillMaxSize().background(Color.Black)) { Box(Modifier.fillMaxSize().background(Color.Black)) {
Image( Image(
bitmap = imageResource(randomPicture.resource), bitmap = imageBitmap,
contentDescription = "Camera stub", contentDescription = "Camera stub",
Modifier.fillMaxSize() Modifier.fillMaxSize()
) )

16
examples/imageviewer/shared/src/desktopMain/kotlin/example/imageviewer/view/ImageViewer.desktop.kt

@ -4,26 +4,29 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.Surface import androidx.compose.material.Surface
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.input.key.Key import androidx.compose.ui.input.key.Key
import androidx.compose.ui.input.key.KeyEventType import androidx.compose.ui.input.key.KeyEventType
import androidx.compose.ui.input.key.key import androidx.compose.ui.input.key.key
import androidx.compose.ui.input.key.type import androidx.compose.ui.input.key.type
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.* import androidx.compose.ui.window.ApplicationScope
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.WindowPosition
import androidx.compose.ui.window.WindowState
import example.imageviewer.* import example.imageviewer.*
import example.imageviewer.Notification
import example.imageviewer.filter.PlatformContext import example.imageviewer.filter.PlatformContext
import example.imageviewer.model.* import example.imageviewer.model.PictureData
import example.imageviewer.style.ImageViewerTheme import example.imageviewer.style.ImageViewerTheme
import imageviewer.shared.generated.resources.Res
import imageviewer.shared.generated.resources.ic_imageviewer_round
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asSharedFlow
import org.jetbrains.compose.resources.painterResource
import java.awt.Dimension import java.awt.Dimension
import java.awt.Toolkit import java.awt.Toolkit
@ -40,7 +43,6 @@ class ExternalNavigationEventBus {
} }
} }
@OptIn(ExperimentalComposeUiApi::class)
@Composable @Composable
fun ApplicationScope.ImageViewerDesktop() { fun ApplicationScope.ImageViewerDesktop() {
val ioScope = rememberCoroutineScope { ioDispatcher } val ioScope = rememberCoroutineScope { ioDispatcher }
@ -57,7 +59,7 @@ fun ApplicationScope.ImageViewerDesktop() {
position = WindowPosition.Aligned(Alignment.Center), position = WindowPosition.Aligned(Alignment.Center),
size = getPreferredWindowSize(720, 857) size = getPreferredWindowSize(720, 857)
), ),
icon = painterResource("ic_imageviewer_round.png"), icon = painterResource(Res.drawable.ic_imageviewer_round),
// https://github.com/JetBrains/compose-jb/issues/2741 // https://github.com/JetBrains/compose-jb/issues/2741
onKeyEvent = { onKeyEvent = {
if (it.type == KeyEventType.KeyUp) { if (it.type == KeyEventType.KeyUp) {

5
examples/imageviewer/shared/src/desktopMain/kotlin/example/imageviewer/view/LocationVisualizer.desktop.kt

@ -1,15 +1,10 @@
package example.imageviewer.view package example.imageviewer.view
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import example.imageviewer.model.GpsPosition import example.imageviewer.model.GpsPosition
import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.painterResource
@OptIn(ExperimentalResourceApi::class)
@Composable @Composable
actual fun LocationVisualizer( actual fun LocationVisualizer(
modifier: Modifier, modifier: Modifier,

Loading…
Cancel
Save