fix Remember window position & last dir used
This commit is contained in:
parent
5cf90d54d4
commit
ccf2153376
5 changed files with 60 additions and 133 deletions
|
|
@ -83,6 +83,7 @@ kotlin {
|
||||||
implementation(kotlin("stdlib-jdk8"))
|
implementation(kotlin("stdlib-jdk8"))
|
||||||
implementation(compose.desktop.currentOs)
|
implementation(compose.desktop.currentOs)
|
||||||
//implementation("org.jetbrains.compose.foundation:foundation-desktop")
|
//implementation("org.jetbrains.compose.foundation:foundation-desktop")
|
||||||
|
implementation("com.russhwolf:multiplatform-settings-no-arg:1.3.0")
|
||||||
|
|
||||||
//implementation(libs.ktmidi)
|
//implementation(libs.ktmidi)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,6 @@ interface FileRepository {
|
||||||
suspend fun readFileContent(filePath: String): String
|
suspend fun readFileContent(filePath: String): String
|
||||||
suspend fun getOutputStream(filePath: String): OutputStream
|
suspend fun getOutputStream(filePath: String): OutputStream
|
||||||
//Lire le dernier dossier d'importation
|
//Lire le dernier dossier d'importation
|
||||||
suspend fun readLastDirectoryPath(): String?
|
|
||||||
|
|
||||||
//Enregistrer le dernier dossier d'importation
|
|
||||||
suspend fun saveLastDirectoryPath(path: String)
|
|
||||||
|
|
||||||
suspend fun readWindowState(): WindowState?
|
|
||||||
suspend fun saveWindowState(state: WindowState)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is just a regular class that implements the common 'FileRepository' interface.
|
// This is just a regular class that implements the common 'FileRepository' interface.
|
||||||
|
|
@ -60,104 +53,6 @@ class CommonFileRepository : FileRepository { // IMPORTS AND IMPLEMENTS THE comm
|
||||||
println("Could not read /"+assetFileName.removePrefix("assets://"))
|
println("Could not read /"+assetFileName.removePrefix("assets://"))
|
||||||
throw IOException("Could not read asset file: $assetFileName", e)
|
throw IOException("Could not read asset file: $assetFileName", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
private val CONFIG_FILE_NAME = "feufaro.conf"
|
|
||||||
private val configDir = getConfigDirectoryPath()
|
|
||||||
private val configFile: File get() = File(System.getProperty("user.home"), CONFIG_FILE_NAME)
|
|
||||||
|
|
||||||
override suspend fun readLastDirectoryPath(): String? {
|
|
||||||
var file = configFile
|
|
||||||
var lastPath: String? = null
|
|
||||||
try {
|
|
||||||
val fileContents = file.readText().trim()
|
|
||||||
if(fileContents.startsWith("LAST_DIR: ")) {
|
|
||||||
lastPath = fileContents.substringAfter("LAST_DIR: ").trim()
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
System.err.println("Erreur de $CONFIG_FILE_NAME : ${e.message}")
|
|
||||||
}
|
|
||||||
return lastPath
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun saveLastDirectoryPath(path: String) {
|
|
||||||
val pathDir = File(path).parent
|
|
||||||
if (pathDir != null) {
|
|
||||||
try {
|
|
||||||
var file = configFile
|
|
||||||
file.parentFile?.mkdirs()
|
|
||||||
//file.writeText(pathDir)
|
|
||||||
|
|
||||||
configFile.writeText("LAST_DIR: $pathDir/")
|
|
||||||
} catch (e: Exception) {
|
|
||||||
System.err.println("Erreur d'écriture de $CONFIG_FILE_NAME : ${e.message}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun saveWindowState(state: WindowState) = withContext(Dispatchers.IO) {
|
|
||||||
val file = configFile
|
|
||||||
|
|
||||||
val allLines: MutableList<String> = try {
|
|
||||||
file.readLines().toMutableList()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
mutableListOf()
|
|
||||||
}
|
|
||||||
|
|
||||||
while (allLines.size < 3) {
|
|
||||||
allLines.add("")
|
|
||||||
}
|
|
||||||
|
|
||||||
val positionLine = "WINDOW_POS: ${state.x},${state.y}"
|
|
||||||
val sizeLine = "WINDOW_SIZE: ${state.width},${state.height}"
|
|
||||||
|
|
||||||
allLines[1] = positionLine
|
|
||||||
allLines[2] = sizeLine
|
|
||||||
|
|
||||||
try {
|
|
||||||
file.parentFile?.mkdirs()
|
|
||||||
|
|
||||||
file.writeText(allLines.joinToString("\n"))
|
|
||||||
} catch (e: Exception) {
|
|
||||||
System.err.println("Erreur d'écriture du fichier .conf : ${e.message}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override suspend fun readWindowState(): WindowState? = withContext(Dispatchers.IO) {
|
|
||||||
val file = configFile
|
|
||||||
if (!file.exists()) {
|
|
||||||
return@withContext null
|
|
||||||
}
|
|
||||||
val lines = try {
|
|
||||||
file.readLines()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
System.err.println("Erreur de lecture : ${e.message}")
|
|
||||||
return@withContext null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lines.size < 3) {
|
|
||||||
System.err.println("Fichier de configuration incomplet .")
|
|
||||||
//return@withContext null
|
|
||||||
}
|
|
||||||
|
|
||||||
val posLine = lines[1].substringAfter("WINDOW_POS:", "").trim()
|
|
||||||
val posParts = posLine.split(",")
|
|
||||||
|
|
||||||
val x = posParts.getOrNull(0)?.toIntOrNull()
|
|
||||||
val y = posParts.getOrNull(1)?.toIntOrNull()
|
|
||||||
|
|
||||||
val sizeLine = lines[2].substringAfter("WINDOW_SIZE:", "").trim()
|
|
||||||
val sizeParts = sizeLine.split(",")
|
|
||||||
|
|
||||||
val width = sizeParts.getOrNull(0)?.toIntOrNull()
|
|
||||||
val height = sizeParts.getOrNull(1)?.toIntOrNull()
|
|
||||||
|
|
||||||
if (x != null && y != null && width != null && height != null) {
|
|
||||||
return@withContext WindowState(width, height, x, y)
|
|
||||||
}
|
|
||||||
|
|
||||||
return@withContext null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
package mg.dot.feufaro
|
||||||
|
|
||||||
|
import com.russhwolf.settings.Settings
|
||||||
|
import com.russhwolf.settings.set
|
||||||
|
import androidx.compose.ui.unit.DpSize
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.window.WindowPlacement
|
||||||
|
import androidx.compose.ui.window.WindowState
|
||||||
|
import androidx.compose.ui.window.WindowPosition
|
||||||
|
|
||||||
|
class SaveSettings {
|
||||||
|
|
||||||
|
private val settings: Settings = Settings()
|
||||||
|
|
||||||
|
fun loadLastUsedDir(): String {
|
||||||
|
val lastDirectory = settings.getString("last_dir", "/")
|
||||||
|
|
||||||
|
return lastDirectory
|
||||||
|
}
|
||||||
|
|
||||||
|
fun saveLastUsedDir(lastDir: String) {
|
||||||
|
settings["last_dir"] = lastDir
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadWindowState(): WindowState {
|
||||||
|
val width = settings.getInt("window_width", 800)
|
||||||
|
val height = settings.getInt("window_height", 600)
|
||||||
|
val x = settings.getInt("window_x", 100)
|
||||||
|
val y = settings.getInt("window_y", 100)
|
||||||
|
|
||||||
|
return WindowState(
|
||||||
|
size = DpSize(width.dp, height.dp),
|
||||||
|
position = WindowPosition(x.dp, y.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun saveWindowState(state: WindowState) {
|
||||||
|
settings["window_width"] = state.size.width.value.toInt()
|
||||||
|
settings["window_height"] = state.size.height.value.toInt()
|
||||||
|
settings["window_x"] = state.position.x.value.toInt()
|
||||||
|
settings["window_y"] = state.position.y.value.toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,14 @@
|
||||||
package mg.dot.feufaro.solfa
|
package mg.dot.feufaro.solfa
|
||||||
|
|
||||||
import SharedScreenModel
|
import SharedScreenModel
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.SupervisorJob
|
import kotlinx.coroutines.SupervisorJob
|
||||||
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 mg.dot.feufaro.FileRepository
|
import mg.dot.feufaro.FileRepository
|
||||||
|
import mg.dot.feufaro.SaveSettings
|
||||||
import mg.dot.feufaro.getConfigDirectoryPath
|
import mg.dot.feufaro.getConfigDirectoryPath
|
||||||
import mg.dot.feufaro.launchFilePicker
|
import mg.dot.feufaro.launchFilePicker
|
||||||
import mg.dot.feufaro.midi.MidiPitch
|
import mg.dot.feufaro.midi.MidiPitch
|
||||||
|
|
@ -146,19 +148,21 @@ class Solfa(val sharedScreenModel: SharedScreenModel, private val fileRepository
|
||||||
|
|
||||||
fun loadFile() {
|
fun loadFile() {
|
||||||
val screenModelScope= CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
|
val screenModelScope= CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
|
||||||
|
val stateSettings = SaveSettings()
|
||||||
|
|
||||||
screenModelScope.launch {
|
screenModelScope.launch {
|
||||||
val initialPath = fileRepository.readLastDirectoryPath()
|
val initialPath = stateSettings.loadLastUsedDir()
|
||||||
val homedir = getConfigDirectoryPath();
|
val homedir = getConfigDirectoryPath();
|
||||||
|
|
||||||
launchFilePicker(
|
launchFilePicker(
|
||||||
mimeTypes = arrayOf("text/plain"),
|
mimeTypes = arrayOf("text/plain"),
|
||||||
initialDirectory = initialPath,
|
initialDirectory = if (initialPath.isNotBlank()) initialPath else homedir,
|
||||||
onFileSelected = { path ->
|
onFileSelected = { path ->
|
||||||
if (path != null) {
|
if (path != null) {
|
||||||
sharedScreenModel.reset()
|
sharedScreenModel.reset()
|
||||||
parse(path)
|
parse(path)
|
||||||
screenModelScope.launch {
|
screenModelScope.launch {
|
||||||
fileRepository.saveLastDirectoryPath(path)
|
stateSettings.saveLastUsedDir(path)
|
||||||
}
|
}
|
||||||
//loadSolfa()
|
//loadSolfa()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package mg.dot.feufaro
|
package mg.dot.feufaro
|
||||||
|
|
||||||
|
import androidx.compose.runtime.DisposableEffect
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.unit.DpSize
|
import androidx.compose.ui.unit.DpSize
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
@ -29,35 +31,12 @@ fun main() = application {
|
||||||
val fileRepository = org.koin.core.context.GlobalContext.get().get<FileRepository>()
|
val fileRepository = org.koin.core.context.GlobalContext.get().get<FileRepository>()
|
||||||
println("FileRepository initialized for Desktop: $fileRepository")
|
println("FileRepository initialized for Desktop: $fileRepository")
|
||||||
|
|
||||||
val initialWindowState: WindowState? = runBlocking {
|
val stateManager = remember { SaveSettings() }
|
||||||
fileRepository.readWindowState()
|
val windowState = remember { stateManager.loadWindowState() }
|
||||||
}
|
|
||||||
val defaultWidth = 1200.dp
|
|
||||||
val defaultHeight = 800.dp
|
|
||||||
val windowState = rememberWindowState(
|
|
||||||
size = DpSize(
|
|
||||||
width = initialWindowState?.width?.dp ?: defaultWidth,
|
|
||||||
height = initialWindowState?.height?.dp ?: defaultHeight,
|
|
||||||
),
|
|
||||||
position = if (initialWindowState != null) {
|
|
||||||
WindowPosition(initialWindowState.x.dp, initialWindowState.y.dp)
|
|
||||||
} else {
|
|
||||||
WindowPosition(Alignment.Center)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
Window(
|
Window(
|
||||||
state = windowState,
|
state = windowState,
|
||||||
onCloseRequest = {
|
onCloseRequest = {
|
||||||
val currentState = WindowState(
|
|
||||||
width = windowState.size.width.value.toInt(),
|
|
||||||
height = windowState.size.height.value.toInt(),
|
|
||||||
x = windowState.position.x.value.toInt(),
|
|
||||||
y = windowState.position.y.value.toInt()
|
|
||||||
)
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
fileRepository.saveWindowState(currentState)
|
|
||||||
}
|
|
||||||
exitApplication();
|
exitApplication();
|
||||||
},
|
},
|
||||||
title = "Feufaro",
|
title = "Feufaro",
|
||||||
|
|
@ -65,5 +44,10 @@ fun main() = application {
|
||||||
KoinContext {
|
KoinContext {
|
||||||
App()
|
App()
|
||||||
}
|
}
|
||||||
|
DisposableEffect(Unit){
|
||||||
|
onDispose {
|
||||||
|
stateManager.saveWindowState(windowState)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Reference in a new issue