Fix windows management by introducting key()

This commit is contained in:
Thomas Andres Gomez 2024-11-27 11:36:53 +01:00
parent 51021d41d5
commit f8168a8997
32 changed files with 420 additions and 59 deletions

View file

@ -17,7 +17,8 @@
<string name="roll_page__dc_hard__label">Difficile</string>
<string name="roll_page__dc_impossible__label">Impossible</string>
<string name="character_sheet_edit__title">Création de personnage</string>
<string name="character_sheet_edit__create__title">Création de personnage</string>
<string name="character_sheet_edit__edit__title">Édition de personnage</string>
<string name="character_sheet_edit__name_placeholder">Nom</string>
<string name="character_sheet_edit__add_roll_action">Ajouter une action</string>
<string name="character_sheet_edit__save_action">Sauvegarder</string>
@ -67,7 +68,6 @@
<string name="character_sheet_edit__delete__label">Supprimer</string>
<string name="character_sheet_edit__occupation__label">Compétence d'occupation</string>
<string name="character_sheet__diminished__label">État diminuer</string>
<string name="character_sheet__edit__label">Modifier</string>
<string name="character_sheet__delete__label">Supprimer</string>

View file

@ -143,7 +143,7 @@ private fun WindowsHandler(
is CharacterSheetCreateWindow -> CharacterSheetMainNavHost(
startDestination = CharacterSheetEditDestination.navigationRoute(
id = null,
id = window.sheetId,
enableBack = false,
),
)

View file

@ -5,21 +5,27 @@ import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.WindowState
import androidx.compose.ui.window.rememberWindowState
import com.pixelized.desktop.lwa.navigation.window.destination.Window
val LocalWindow = compositionLocalOf<Window> {
error("Local Window is not yet ready")
}
val LocalWindowState = compositionLocalOf<WindowState> {
error("Local Window state is not yet ready")
}
@Stable
class WindowController {
private val _windows = mutableStateOf<Set<Window>>(emptySet())
val windows: State<Set<Window>> get() = _windows
private val _windows = mutableStateOf<Map<String, Window>>(emptyMap())
val windows: State<Map<String, Window>> get() = _windows
fun showWindow(window: Window) {
_windows.value = _windows.value.toMutableSet().apply { add(window) }
_windows.value = _windows.value.toMutableMap().apply { this[window.id] = window }
}
fun hideWindow(window: Window) {
@ -27,7 +33,7 @@ class WindowController {
}
fun hideWindow(id: String) {
_windows.value = _windows.value.toMutableSet().apply { removeIf { it.id == id } }
_windows.value = _windows.value.toMutableMap().apply { this.remove(id) }
}
}
@ -36,16 +42,20 @@ fun WindowsNavHost(
controller: WindowController,
content: @Composable (Window) -> Unit,
) {
controller.windows.value.forEach { window ->
CompositionLocalProvider(
LocalWindow provides window,
) {
Window(
onCloseRequest = { controller.hideWindow(id = window.id) },
state = window.state,
title = window.title,
controller.windows.value.forEach { (id, window) ->
key(id) {
val state = rememberWindowState(size = window.size)
CompositionLocalProvider(
LocalWindow provides window,
LocalWindowState provides state,
) {
content.invoke(window)
Window(
onCloseRequest = { controller.hideWindow(id = window.id) },
state = state,
title = window.title,
) {
content.invoke(window)
}
}
}
}

View file

@ -5,8 +5,11 @@ import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
@Stable
class CharacterSheetCreateWindow : Window(
title = "",
class CharacterSheetCreateWindow(
title: String,
val sheetId: String?,
) : Window(
title = title,
size = size,
) {
companion object {

View file

@ -1,32 +1,12 @@
package com.pixelized.desktop.lwa.navigation.window.destination
import androidx.compose.runtime.Stable
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.window.WindowPlacement
import androidx.compose.ui.window.WindowPosition
import androidx.compose.ui.window.WindowState
import java.util.UUID
@Stable
sealed class Window(
val id: String = UUID.randomUUID().toString(),
val title: String,
size: DpSize,
) {
val state = WindowState(
placement = WindowPlacement.Floating,
isMinimized = false,
position = WindowPosition.PlatformDefault,
width = size.width,
height = size.height,
)
val width: Dp get() = state.size.width
val height: Dp get() = state.size.height
val size: DpSize get() = state.size
suspend fun resize(size: DpSize) {
state.size = size
}
}
val size: DpSize,
)

View file

@ -41,7 +41,6 @@ import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf
@ -60,15 +59,15 @@ import com.pixelized.desktop.lwa.composable.decoratedBox.DecoratedBox
import com.pixelized.desktop.lwa.composable.tooltip.TooltipLayout
import com.pixelized.desktop.lwa.composable.tooltip.TooltipUio
import com.pixelized.desktop.lwa.navigation.screen.LocalScreenController
import com.pixelized.desktop.lwa.navigation.screen.destination.navigateToCharacterSheetEdit
import com.pixelized.desktop.lwa.navigation.window.LocalWindow
import com.pixelized.desktop.lwa.navigation.window.destination.CharacterSheetWindow
import com.pixelized.desktop.lwa.navigation.window.destination.CharacterSheetCreateWindow
import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.CharacterSheetDeleteConfirmationDialog
import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.CharacterSheetStatDialog
import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.DiminishedStatDialog
import com.pixelized.desktop.lwa.screen.roll.RollPage
import com.pixelized.desktop.lwa.screen.roll.RollViewModel
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.character_sheet__delete__label
import lwacharactersheet.composeapp.generated.resources.character_sheet__edit__label
@ -76,8 +75,10 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet__skills_
import lwacharactersheet.composeapp.generated.resources.character_sheet__skills__magic_title
import lwacharactersheet.composeapp.generated.resources.character_sheet__skills__special_title
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__title
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__edit__title
import lwacharactersheet.composeapp.generated.resources.ic_d20_32dp
import lwacharactersheet.composeapp.generated.resources.ic_skull_32dp
import org.jetbrains.compose.resources.getString
import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
@ -128,10 +129,6 @@ fun CharacterSheetPage(
val scope = rememberCoroutineScope()
val blurController = remember { BlurContentController() }
LaunchedEffect(Unit) {
window.resize(size = CharacterSheetWindow.size)
}
Surface(
modifier = Modifier.fillMaxSize(),
) {
@ -150,9 +147,11 @@ fun CharacterSheetPage(
}
},
onEdit = {
screen.navigateToCharacterSheetEdit(
id = sheet.id,
enableBack = true,
windowController.showWindow(
window = CharacterSheetCreateWindow(
title = runBlocking { getString(Res.string.character_sheet_edit__edit__title) },
sheetId = sheet.id,
),
)
},
onDelete = {

View file

@ -21,7 +21,6 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Add
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.Stable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
@ -33,7 +32,6 @@ import com.pixelized.desktop.lwa.LocalWindowController
import com.pixelized.desktop.lwa.composable.decoratedBox.DecoratedBox
import com.pixelized.desktop.lwa.navigation.screen.LocalScreenController
import com.pixelized.desktop.lwa.navigation.window.LocalWindow
import com.pixelized.desktop.lwa.navigation.window.destination.CharacterSheetCreateWindow
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.BaseSkillFieldUio
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.BaseSkillForm
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.FieldUio
@ -51,7 +49,6 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sa
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__magic_action
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__special_action
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__title
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__title
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
@ -106,14 +103,11 @@ fun CharacterSheetEditPage(
val screen = LocalScreenController.current
val scope = rememberCoroutineScope()
LaunchedEffect(Unit) {
window.resize(size = CharacterSheetCreateWindow.size)
}
Surface(
modifier = Modifier.fillMaxSize(),
) {
CharacterSheetEdit(
title = window.title,
form = viewModel.characterSheet.value,
onBack = remember {
if (viewModel.enableBack) {
@ -151,6 +145,8 @@ fun CharacterSheetEditPage(
@Composable
fun CharacterSheetEdit(
modifier: Modifier = Modifier,
title: String,
form: CharacterSheetEditPageUio,
onBack: (() -> Unit)?,
onNewSpecialSkill: () -> Unit,
@ -159,13 +155,14 @@ fun CharacterSheetEdit(
onSave: () -> Unit,
) {
Scaffold(
modifier = modifier,
topBar = {
TopAppBar(
title = {
Text(
overflow = TextOverflow.Ellipsis,
maxLines = 1,
text = stringResource(Res.string.character_sheet_edit__title),
text = title,
)
},
navigationIcon = onBack?.let { action: () -> Unit ->

View file

@ -25,10 +25,13 @@ import com.pixelized.desktop.lwa.navigation.screen.destination.navigateToNetwork
import com.pixelized.desktop.lwa.navigation.screen.destination.navigateToRollHistory
import com.pixelized.desktop.lwa.navigation.window.destination.CharacterSheetCreateWindow
import com.pixelized.desktop.lwa.navigation.window.destination.CharacterSheetWindow
import kotlinx.coroutines.runBlocking
import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__create__title
import lwacharactersheet.composeapp.generated.resources.main_page__create_action
import lwacharactersheet.composeapp.generated.resources.main_page__network_action
import lwacharactersheet.composeapp.generated.resources.main_page__roll_history_action
import org.jetbrains.compose.resources.getString
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
@ -66,7 +69,12 @@ fun MainPage(
)
},
onCreateCharacter = {
window.showWindow(window = CharacterSheetCreateWindow())
window.showWindow(
window = CharacterSheetCreateWindow(
title = runBlocking { getString(Res.string.character_sheet_edit__create__title) },
sheetId = null,
)
)
},
onRollHistory = {
screen.navigateToRollHistory()