Browse Source

Examples. Notepad. Move to 1.0.0-beta1

pull/1312/head
Igor Demin 3 years ago
parent
commit
ade07cb465
  1. 2
      examples/notepad/build.gradle.kts
  2. 2
      examples/notepad/src/main/kotlin/NotepadApplication.kt
  3. 3
      examples/notepad/src/main/kotlin/common/AppResources.kt
  4. 2
      examples/notepad/src/main/kotlin/main.kt
  5. 77
      examples/notepad/src/main/kotlin/util/AwtIcons.kt
  6. 3
      examples/notepad/src/main/kotlin/util/Dialogs.kt
  7. 1
      examples/notepad/src/main/kotlin/window/NotepadWindow.kt
  8. 12
      examples/notepad/src/main/kotlin/window/NotepadWindowState.kt

2
examples/notepad/build.gradle.kts

@ -5,7 +5,7 @@ plugins {
// __KOTLIN_COMPOSE_VERSION__ // __KOTLIN_COMPOSE_VERSION__
kotlin("jvm") version "1.5.31" kotlin("jvm") version "1.5.31"
// __LATEST_COMPOSE_RELEASE_VERSION__ // __LATEST_COMPOSE_RELEASE_VERSION__
id("org.jetbrains.compose") version ("1.0.0-alpha4-build411") id("org.jetbrains.compose") version ("1.0.0-beta1")
} }
repositories { repositories {

2
examples/notepad/src/main/kotlin/NotepadApplication.kt

@ -1,7 +1,6 @@
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.key import androidx.compose.runtime.key
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.window.ApplicationScope import androidx.compose.ui.window.ApplicationScope
import androidx.compose.ui.window.MenuScope import androidx.compose.ui.window.MenuScope
import androidx.compose.ui.window.Tray import androidx.compose.ui.window.Tray
@ -22,7 +21,6 @@ fun ApplicationScope.NotepadApplication(state: NotepadApplicationState) {
} }
} }
@OptIn(ExperimentalComposeUiApi::class)
@Composable @Composable
private fun ApplicationScope.ApplicationTray(state: NotepadApplicationState) { private fun ApplicationScope.ApplicationTray(state: NotepadApplicationState) {
Tray( Tray(

3
examples/notepad/src/main/kotlin/common/AppResources.kt

@ -18,13 +18,12 @@ val LocalAppResources = staticCompositionLocalOf<AppResources> {
@Composable @Composable
fun rememberAppResources(): AppResources { fun rememberAppResources(): AppResources {
val icon = rememberVectorPainter(Icons.Default.Description, Color(0xFF2CA4E1)) val icon = rememberVectorPainter(Icons.Default.Description, tintColor = Color(0xFF2CA4E1))
return remember { AppResources(icon) } return remember { AppResources(icon) }
} }
class AppResources(val icon: VectorPainter) class AppResources(val icon: VectorPainter)
@OptIn(ExperimentalComposeUiApi::class)
@Composable @Composable
fun rememberVectorPainter(image: ImageVector, tintColor: Color) = fun rememberVectorPainter(image: ImageVector, tintColor: Color) =
rememberVectorPainter( rememberVectorPainter(

2
examples/notepad/src/main/kotlin/main.kt

@ -1,10 +1,8 @@
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.window.application import androidx.compose.ui.window.application
import common.LocalAppResources import common.LocalAppResources
import common.rememberAppResources import common.rememberAppResources
@OptIn(ExperimentalComposeUiApi::class)
fun main() = application { fun main() = application {
CompositionLocalProvider(LocalAppResources provides rememberAppResources()) { CompositionLocalProvider(LocalAppResources provides rememberAppResources()) {
NotepadApplication(rememberApplicationState()) NotepadApplication(rememberApplicationState())

77
examples/notepad/src/main/kotlin/util/AwtIcons.kt

@ -1,77 +0,0 @@
package util
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.geometry.isSpecified
import androidx.compose.ui.graphics.Canvas
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.drawscope.CanvasDrawScope
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.awt.Point
import java.awt.image.BufferedImage
import java.awt.image.ColorModel
import java.awt.image.DataBuffer
import java.awt.image.DataBufferInt
import java.awt.image.Raster
import java.awt.image.SinglePixelPackedSampleModel
import kotlin.math.roundToInt
suspend fun ImageVector.toAwtImage(tintColor: Color): BufferedImage {
return withContext(Dispatchers.Default) {
compose {
val density = Density(1f)
val layoutDirection = LayoutDirection.Ltr
lateinit var result: BufferedImage
CompositionLocalProvider(
LocalDensity provides density,
LocalLayoutDirection provides layoutDirection,
) {
result = rememberVectorPainter(this@toAwtImage)
.toAwtImage(density, layoutDirection, ColorFilter.tint(tintColor))
}
result
}
}
}
private fun Painter.toAwtImage(
density: Density,
layoutDirection: LayoutDirection,
colorFilter: ColorFilter
): BufferedImage {
require(intrinsicSize.isSpecified) {
"Icon should support intrinsicSize"
}
val width = intrinsicSize.width.roundToInt()
val height = intrinsicSize.height.roundToInt()
val bitmap = ImageBitmap(width, height)
val canvas = Canvas(bitmap)
CanvasDrawScope().draw(
density, layoutDirection, canvas, intrinsicSize
) {
draw(intrinsicSize, colorFilter = colorFilter)
}
val pixels = IntArray(width * height)
bitmap.readPixels(pixels)
val bitMasks = intArrayOf(0xFF0000, 0xFF00, 0xFF, -0x1000000)
val sm = SinglePixelPackedSampleModel(DataBuffer.TYPE_INT, width, height, bitMasks)
val db = DataBufferInt(pixels, pixels.size)
val wr = Raster.createWritableRaster(sm, db, Point())
return BufferedImage(ColorModel.getRGBdefault(), wr, false, null)
}

3
examples/notepad/src/main/kotlin/util/Dialogs.kt

@ -6,6 +6,7 @@ import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.window.AwtWindow import androidx.compose.ui.window.AwtWindow
import androidx.compose.ui.window.FrameWindowScope import androidx.compose.ui.window.FrameWindowScope
import androidx.compose.ui.window.WindowScope import androidx.compose.ui.window.WindowScope
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -15,7 +16,6 @@ import java.io.File
import java.nio.file.Path import java.nio.file.Path
import javax.swing.JOptionPane import javax.swing.JOptionPane
@OptIn(ExperimentalComposeUiApi::class)
@Composable @Composable
fun FrameWindowScope.FileDialog( fun FrameWindowScope.FileDialog(
title: String, title: String,
@ -41,6 +41,7 @@ fun FrameWindowScope.FileDialog(
dispose = FileDialog::dispose dispose = FileDialog::dispose
) )
@OptIn(DelicateCoroutinesApi::class)
@Composable @Composable
fun WindowScope.YesNoCancelDialog( fun WindowScope.YesNoCancelDialog(
title: String, title: String,

1
examples/notepad/src/main/kotlin/window/NotepadWindow.kt

@ -14,7 +14,6 @@ import kotlinx.coroutines.launch
import util.FileDialog import util.FileDialog
import util.YesNoCancelDialog import util.YesNoCancelDialog
@OptIn(ExperimentalComposeUiApi::class)
@Composable @Composable
fun NotepadWindow(state: NotepadWindowState) { fun NotepadWindow(state: NotepadWindowState) {
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()

12
examples/notepad/src/main/kotlin/window/NotepadWindowState.kt

@ -8,15 +8,10 @@ import androidx.compose.ui.window.Notification
import androidx.compose.ui.window.WindowPlacement import androidx.compose.ui.window.WindowPlacement
import androidx.compose.ui.window.WindowState import androidx.compose.ui.window.WindowState
import common.Settings import common.Settings
import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.receiveAsFlow import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import util.AlertDialogResult import util.AlertDialogResult
import java.nio.file.Path import java.nio.file.Path
@ -129,11 +124,11 @@ class NotepadWindowState(
try { try {
saveJob?.join() saveJob?.join()
_notifications.offer(NotepadWindowNotification.SaveSuccess(path)) _notifications.trySend(NotepadWindowNotification.SaveSuccess(path))
} catch (e: Exception) { } catch (e: Exception) {
isChanged = true isChanged = true
e.printStackTrace() e.printStackTrace()
_notifications.offer(NotepadWindowNotification.SaveError(path)) _notifications.trySend(NotepadWindowNotification.SaveError(path))
} }
} }
@ -171,6 +166,7 @@ class NotepadWindowState(
} }
} }
@OptIn(DelicateCoroutinesApi::class)
private fun Path.launchSaving(text: String) = GlobalScope.launch { private fun Path.launchSaving(text: String) = GlobalScope.launch {
writeTextAsync(text) writeTextAsync(text)
} }

Loading…
Cancel
Save