diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/KotlinExplorer.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/KotlinExplorer.kt index b115f938..7963682a 100644 --- a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/KotlinExplorer.kt +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/KotlinExplorer.kt @@ -32,8 +32,10 @@ import androidx.compose.ui.input.key.Key.Companion.L import androidx.compose.ui.input.key.Key.Companion.O import androidx.compose.ui.input.key.Key.Companion.P import androidx.compose.ui.text.style.TextAlign.Companion.Center +import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.dp import androidx.compose.ui.window.* +import androidx.compose.ui.window.WindowPosition.Aligned import dev.romainguy.kotlin.explorer.Shortcut.Ctrl import dev.romainguy.kotlin.explorer.Shortcut.CtrlShift import dev.romainguy.kotlin.explorer.dex.DexTextArea @@ -55,7 +57,10 @@ import org.jetbrains.jewel.intui.window.decoratedWindow import org.jetbrains.jewel.intui.window.styling.dark import org.jetbrains.jewel.intui.window.styling.light import org.jetbrains.jewel.ui.ComponentStyling -import org.jetbrains.jewel.ui.component.* +import org.jetbrains.jewel.ui.component.DefaultButton +import org.jetbrains.jewel.ui.component.Icon +import org.jetbrains.jewel.ui.component.Text +import org.jetbrains.jewel.ui.component.TextField import org.jetbrains.jewel.window.DecoratedWindow import org.jetbrains.jewel.window.TitleBar import org.jetbrains.jewel.window.newFullscreenControls @@ -433,13 +438,17 @@ fun main() = application { ComponentStyling.decoratedWindow(titleBarStyle = titleBarStyle), false ) { + val windowState = rememberWindowState( + size = explorerState.getWindowSize(), + position = explorerState.getWindowPosition(), + placement = explorerState.windowPlacement, + ) DecoratedWindow( - state = rememberWindowState( - position = WindowPosition.Aligned(Alignment.Center), - width = 1900.dp, - height = 1600.dp - ), - onCloseRequest = ::exitApplication, + state = windowState, + onCloseRequest = { + explorerState.setWindowState(windowState) + exitApplication() + }, title = "Kotlin Explorer" ) { TitleBar(Modifier.newFullscreenControls()) { @@ -449,3 +458,20 @@ fun main() = application { } } } + +private fun ExplorerState.getWindowSize() = DpSize(windowWidth.dp, windowHeight.dp) + +private fun ExplorerState.getWindowPosition(): WindowPosition { + val x = windowPosX + val y = windowPosY + return if (x > 0 && y > 0) WindowPosition(x.dp, y.dp) else Aligned(Alignment.Center) +} + +private fun ExplorerState.setWindowState(windowState: WindowState) { + windowWidth = windowState.size.width.value.toInt() + windowHeight = windowState.size.height.value.toInt() + windowPosX = windowState.position.x.value.toInt() + windowPosY = windowState.position.y.value.toInt() + windowPlacement = windowState.placement + +} \ No newline at end of file diff --git a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/State.kt b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/State.kt index b9a6c502..9fcc7232 100644 --- a/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/State.kt +++ b/src/jvmMain/kotlin/dev/romainguy/kotlin/explorer/State.kt @@ -17,6 +17,8 @@ package dev.romainguy.kotlin.explorer import androidx.compose.runtime.* +import androidx.compose.ui.window.WindowPlacement +import androidx.compose.ui.window.WindowPlacement.Floating import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths @@ -28,6 +30,11 @@ private const val Presentation = "PRESENTATION" private const val ShowLineNumbers = "SHOW_LINE_NUMBERS" private const val ShowDex = "SHOW_DEX" private const val ShowOat = "SHOW_OAT" +private const val WindowPosX = "WINDOW_X" +private const val WindowPosY = "WINDOW_Y" +private const val WindowWidth = "WINDOW_WIDTH" +private const val WindowHeight = "WINDOW_HEIGHT" +private const val Placement = "WINDOW_PLACEMENT" @Stable class ExplorerState( @@ -40,14 +47,26 @@ class ExplorerState( var showDex by BooleanState(ShowDex, true) var showOat by BooleanState(ShowOat, true) var sourceCode: String = readSourceCode(toolPaths) + var windowWidth by IntState(WindowWidth, 1900) + var windowHeight by IntState(WindowHeight, 1600) + var windowPosX by IntState(WindowPosX, -1) + var windowPosY by IntState(WindowPosY, -1) + var windowPlacement by SettingsState(Placement, Floating) { WindowPlacement.valueOf(this) } fun reloadToolPathsFromSettings() { toolPaths = createToolPaths(settings) } - private inner class BooleanState(private val key: String, initialValue: Boolean) : MutableState { - private val state = mutableStateOf(settings.entries[key]?.toBoolean() ?: initialValue) - override var value: Boolean + private inner class BooleanState(key: String, initialValue: Boolean) : + SettingsState(key, initialValue, { toBoolean() }) + + private inner class IntState(key: String, initialValue: Int) : + SettingsState(key, initialValue, { toInt() }) + + private open inner class SettingsState(private val key: String, initialValue: T, parse: String.() -> T) : + MutableState { + private val state = mutableStateOf(settings.entries[key]?.parse() ?: initialValue) + override var value: T get() = state.value set(value) { settings.entries[key] = value.toString()