Remember window position

This commit is contained in:
dotmg 2026-01-06 20:15:57 +01:00
parent a8b4472f67
commit 27aabc139d
6 changed files with 171 additions and 2 deletions

View file

@ -0,0 +1,9 @@
package mg.dot.feufaro
import android.content.Context
import org.koin.core.context.GlobalContext
actual fun getConfigDirectoryPath(): String {
val context = GlobalContext.get().get<Context>()
return context.filesDir.absolutePath
}

View file

@ -0,0 +1,3 @@
package mg.dot.feufaro
expect fun getConfigDirectoryPath(): String

View file

@ -17,6 +17,14 @@ interface FileRepository {
// Lecture de fichier entier en tant que String
suspend fun readFileContent(filePath: String): String
suspend fun getOutputStream(filePath: String): OutputStream
//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.
@ -54,4 +62,102 @@ class CommonFileRepository : FileRepository { // IMPORTS AND IMPLEMENTS THE comm
}
}
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
}
}

View file

@ -0,0 +1,8 @@
package mg.dot.feufaro
data class WindowState(
val width: Int,
val height: Int,
val x: Int,
val y: Int
)

View file

@ -0,0 +1,5 @@
package mg.dot.feufaro
actual fun getConfigDirectoryPath(): String {
return System.getProperty("user.home")
}

View file

@ -1,13 +1,22 @@
package mg.dot.feufaro
import androidx.compose.ui.Alignment
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.WindowPosition
import androidx.compose.ui.window.application
import androidx.compose.ui.window.rememberWindowState
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import mg.dot.feufaro.di.commonModule
import mg.dot.feufaro.di.desktopModule
import org.koin.compose.KoinContext
import org.koin.core.context.GlobalContext.startKoin
import org.koin.core.context.KoinContext
import org.koin.core.logger.Level
import org.koin.compose.KoinContext
fun main() = application {
@ -20,8 +29,37 @@ fun main() = application {
val fileRepository = org.koin.core.context.GlobalContext.get().get<FileRepository>()
println("FileRepository initialized for Desktop: $fileRepository")
val initialWindowState: WindowState? = runBlocking {
fileRepository.readWindowState()
}
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(
onCloseRequest = ::exitApplication,
state = windowState,
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();
},
title = "Feufaro",
) {
KoinContext {