From 763f575be4d8c5001ce04df7ba849cacdf467a66 Mon Sep 17 00:00:00 2001 From: Thomas Andres Gomez Date: Fri, 9 May 2025 17:38:32 +0200 Subject: [PATCH] Refactor: clean unused legacy character sheet stuff. --- .../kotlin/com/pixelized/desktop/lwa/App.kt | 17 - .../com/pixelized/desktop/lwa/Module.kt | 10 - .../destination/CharacterSheetDestination.kt | 52 -- .../CharacterSheetEditDestination.kt | 52 -- .../destination/CharacterSheetEditWindow.kt | 32 - .../destination/CharacterSheetWindow.kt | 32 - .../detail/CharacterDetailPanelViewModel.kt | 5 - .../characterSheet/CharacterSheetNavHost.kt | 35 - .../copy/CharacterSheetCopyDialog.kt | 183 ----- .../delete/CharacterSheetDeleteDialog.kt | 151 ---- .../detail/CharacterSheetFactory.kt | 352 --------- .../detail/CharacterSheetPage.kt | 690 ------------------ .../detail/CharacterSheetViewModel.kt | 95 --- .../CharacterSheetDeleteConfirmationDialog.kt | 130 ---- .../rememberCharacterSheetPagePreview.kt | 141 ---- .../edit/CharacterSheetEditFactory.kt | 623 ---------------- .../edit/CharacterSheetEditPage.kt | 477 ------------ .../edit/CharacterSheetEditViewModel.kt | 205 ------ .../edit/common/SkillFieldFactory.kt | 101 --- .../edit/composable/ActionField.kt | 118 --- .../edit/composable/BaseSkillField.kt | 137 ---- .../edit/composable/LevelUpField.kt | 41 -- .../edit/composable/SimpleField.kt | 49 -- .../edit/composable/SpecialSkillField.kt | 106 --- .../edit/composable/option/ActionOption.kt | 51 -- .../edit/composable/option/CheckedOption.kt | 56 -- .../edit/composable/option/Option.kt | 31 - .../edit/composable/textfield/FormWrapper.kt | 79 -- 28 files changed, 4051 deletions(-) delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/navigation/screen/destination/CharacterSheetDestination.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/navigation/screen/destination/CharacterSheetEditDestination.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/navigation/window/destination/CharacterSheetEditWindow.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/navigation/window/destination/CharacterSheetWindow.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/CharacterSheetNavHost.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/copy/CharacterSheetCopyDialog.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/delete/CharacterSheetDeleteDialog.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetFactory.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetPage.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetViewModel.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/dialog/CharacterSheetDeleteConfirmationDialog.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/preview/rememberCharacterSheetPagePreview.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditFactory.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditPage.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditViewModel.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/common/SkillFieldFactory.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/ActionField.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/BaseSkillField.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/LevelUpField.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/SimpleField.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/SpecialSkillField.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/ActionOption.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/CheckedOption.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/Option.kt delete mode 100644 composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/textfield/FormWrapper.kt diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/App.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/App.kt index c9c4fb8..c2e1415 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/App.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/App.kt @@ -35,17 +35,12 @@ import com.pixelized.desktop.lwa.ui.composable.blur.BlurContentController import com.pixelized.desktop.lwa.ui.composable.key.KeyEventHandler import com.pixelized.desktop.lwa.ui.composable.key.LocalKeyEventHandlers import com.pixelized.desktop.lwa.ui.navigation.screen.MainNavHost -import com.pixelized.desktop.lwa.ui.navigation.screen.destination.CharacterSheetDestination -import com.pixelized.desktop.lwa.ui.navigation.screen.destination.CharacterSheetEditDestination import com.pixelized.desktop.lwa.ui.navigation.window.LocalWindowState import com.pixelized.desktop.lwa.ui.navigation.window.WindowController import com.pixelized.desktop.lwa.ui.navigation.window.WindowsNavHost -import com.pixelized.desktop.lwa.ui.navigation.window.destination.CharacterSheetEditWindow -import com.pixelized.desktop.lwa.ui.navigation.window.destination.CharacterSheetWindow import com.pixelized.desktop.lwa.ui.navigation.window.destination.GameMasterWindow import com.pixelized.desktop.lwa.ui.navigation.window.rememberMaxWindowHeight import com.pixelized.desktop.lwa.ui.overlay.roll.RollHostState -import com.pixelized.desktop.lwa.ui.screen.characterSheet.CharacterSheetMainNavHost import com.pixelized.desktop.lwa.ui.screen.gamemaster.GameMasterNavHost import com.pixelized.desktop.lwa.ui.theme.LwaTheme import com.pixelized.desktop.lwa.utils.InstallCoil @@ -162,18 +157,6 @@ private fun WindowsHandler( controller = windowController, content = { window -> when (window) { - is CharacterSheetWindow -> CharacterSheetMainNavHost( - startDestination = CharacterSheetDestination.navigationRoute( - characterSheetId = window.characterSheetId, - ), - ) - - is CharacterSheetEditWindow -> CharacterSheetMainNavHost( - startDestination = CharacterSheetEditDestination.navigationRoute( - characterSheetId = window.characterSheetId, - ), - ) - is GameMasterWindow -> LwaScaffold { GameMasterNavHost() } diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/Module.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/Module.kt index f4ea2b0..78e7204 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/Module.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/Module.kt @@ -46,11 +46,6 @@ import com.pixelized.desktop.lwa.ui.screen.campaign.text.CampaignChatViewModel import com.pixelized.desktop.lwa.ui.screen.campaign.text.TextMessageFactory import com.pixelized.desktop.lwa.ui.screen.campaign.toolbar.CampaignToolbarViewModel import com.pixelized.desktop.lwa.ui.screen.campaign.toolbar.links.ResourcesViewModel -import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.CharacterSheetFactory -import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.CharacterSheetViewModel -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.CharacterSheetEditFactory -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.CharacterSheetEditViewModel -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.common.SkillFieldFactory import com.pixelized.desktop.lwa.ui.screen.gamemaster.GameMasterViewModel import com.pixelized.desktop.lwa.ui.screen.gamemaster.action.GMActionViewModel import com.pixelized.desktop.lwa.ui.screen.gamemaster.alteration.edit.GMAlterationEditFactory @@ -144,10 +139,7 @@ val repositoryDependencies val factoryDependencies get() = module { - factoryOf(::CharacterSheetFactory) - factoryOf(::CharacterSheetEditFactory) factoryOf(::NetworkFactory) - factoryOf(::SkillFieldFactory) factoryOf(::SettingsFactory) factoryOf(::CampaignJsonFactory) factoryOf(::CharacterRibbonFactory) @@ -177,8 +169,6 @@ val viewModelDependencies viewModelOf(::DataSyncViewModel) viewModelOf(::CampaignToolbarViewModel) viewModelOf(::ResourcesViewModel) - viewModelOf(::CharacterSheetViewModel) - viewModelOf(::CharacterSheetEditViewModel) viewModelOf(::RollViewModel) viewModelOf(::NetworkViewModel) viewModelOf(::PlayerRibbonViewModel) diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/navigation/screen/destination/CharacterSheetDestination.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/navigation/screen/destination/CharacterSheetDestination.kt deleted file mode 100644 index 24ff993..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/navigation/screen/destination/CharacterSheetDestination.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.pixelized.desktop.lwa.ui.navigation.screen.destination - -import androidx.lifecycle.SavedStateHandle -import androidx.navigation.NavGraphBuilder -import androidx.navigation.NavHostController -import androidx.navigation.NavType -import androidx.navigation.compose.composable -import androidx.navigation.navArgument -import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.CharacterSheetPage -import com.pixelized.desktop.lwa.utils.extention.ARG - -object CharacterSheetDestination { - private const val ROUTE = "characterSheet" - private const val CHARACTER_SHEET_ID = "characterSheetId" - - fun baseRoute() = "$ROUTE?${CHARACTER_SHEET_ID.ARG}" - - fun navigationRoute(characterSheetId: String) = "$ROUTE?$CHARACTER_SHEET_ID=${characterSheetId}" - - fun arguments() = listOf( - navArgument(CHARACTER_SHEET_ID) { - nullable = false - type = NavType.StringType - }, - ) - - data class Argument( - val characterSheetId: String, - ) { - constructor(savedStateHandle: SavedStateHandle) : this( - characterSheetId = savedStateHandle - .get(CHARACTER_SHEET_ID) - ?: error("missing characterSheetId parameter"), - ) - } -} - -fun NavGraphBuilder.composableCharacterSheetPage() { - composable( - route = CharacterSheetDestination.baseRoute(), - arguments = CharacterSheetDestination.arguments(), - ) { - CharacterSheetPage() - } -} - -fun NavHostController.navigateToCharacterSheet( - characterSheetId: String, -) { - val route = CharacterSheetDestination.navigationRoute(characterSheetId = characterSheetId) - navigate(route = route) -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/navigation/screen/destination/CharacterSheetEditDestination.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/navigation/screen/destination/CharacterSheetEditDestination.kt deleted file mode 100644 index b7dfaf3..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/navigation/screen/destination/CharacterSheetEditDestination.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.pixelized.desktop.lwa.ui.navigation.screen.destination - -import androidx.compose.runtime.Stable -import androidx.lifecycle.SavedStateHandle -import androidx.navigation.NavGraphBuilder -import androidx.navigation.NavHostController -import androidx.navigation.NavType -import androidx.navigation.compose.composable -import androidx.navigation.navArgument -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.CharacterSheetEditPage -import com.pixelized.desktop.lwa.utils.extention.ARG - -object CharacterSheetEditDestination { - private const val ROUTE = "character.sheet.edit" - private const val CHARACTER_ID = "id" - - fun baseRoute() = "$ROUTE?${CHARACTER_ID.ARG}" - - fun navigationRoute(characterSheetId: String?) = "$ROUTE?$CHARACTER_ID=$characterSheetId" - - fun arguments() = listOf( - navArgument(CHARACTER_ID) { - nullable = true - type = NavType.StringType - }, - ) - - @Stable - data class Argument( - val id: String?, - ) { - constructor(savedStateHandle: SavedStateHandle) : this( - id = savedStateHandle.get(CHARACTER_ID), - ) - } -} - -fun NavGraphBuilder.composableCharacterSheetEditPage() { - composable( - route = CharacterSheetEditDestination.baseRoute(), - arguments = CharacterSheetEditDestination.arguments(), - ) { - CharacterSheetEditPage() - } -} - -fun NavHostController.navigateToCharacterSheetEdit( - id: String? = null, -) { - val route = CharacterSheetEditDestination.navigationRoute(characterSheetId = id) - navigate(route = route) -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/navigation/window/destination/CharacterSheetEditWindow.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/navigation/window/destination/CharacterSheetEditWindow.kt deleted file mode 100644 index 06e1c79..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/navigation/window/destination/CharacterSheetEditWindow.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.pixelized.desktop.lwa.ui.navigation.window.destination - -import androidx.compose.runtime.Stable -import androidx.compose.ui.unit.DpSize -import androidx.compose.ui.unit.dp -import com.pixelized.desktop.lwa.ui.navigation.window.WindowController - -@Stable -class CharacterSheetEditWindow( - val characterSheetId: String?, - title: String, - size: DpSize, -) : Window( - title = title, - size = size, -) - -fun WindowController.navigateToCharacterSheetEdit( - characterId: String?, - title: String = "", -) { - showWindow( - window = CharacterSheetEditWindow( - characterSheetId = characterId, - title = title, - size = DpSize( - width = 600.dp, - height = maxWindowHeight - 32.dp, - ), - ) - ) -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/navigation/window/destination/CharacterSheetWindow.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/navigation/window/destination/CharacterSheetWindow.kt deleted file mode 100644 index f886c8a..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/navigation/window/destination/CharacterSheetWindow.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.pixelized.desktop.lwa.ui.navigation.window.destination - -import androidx.compose.runtime.Stable -import androidx.compose.ui.unit.DpSize -import androidx.compose.ui.unit.dp -import com.pixelized.desktop.lwa.ui.navigation.window.WindowController - -@Stable -class CharacterSheetWindow( - val characterSheetId: String, - title: String, - size: DpSize, -) : Window( - title = title, - size = size, -) - -fun WindowController.navigateToCharacterSheet( - characterSheetId: String, - title: String = "Feuille de personnage", -) { - showWindow( - window = CharacterSheetWindow( - characterSheetId = characterSheetId, - title = title, - size = DpSize( - width = 400.dp + 64.dp, - height = maxWindowHeight - 32.dp, - ), - ) - ) -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetailPanelViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetailPanelViewModel.kt index f19b235..6716fee 100644 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetailPanelViewModel.kt +++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/detail/CharacterDetailPanelViewModel.kt @@ -6,8 +6,6 @@ import androidx.navigation.NavHostController import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository import com.pixelized.desktop.lwa.repository.network.NetworkRepository import com.pixelized.desktop.lwa.ui.navigation.screen.destination.gamemaster.navigateToGameMasterCharacterEditPage -import com.pixelized.desktop.lwa.ui.navigation.window.WindowController -import com.pixelized.desktop.lwa.ui.navigation.window.destination.navigateToCharacterSheetEdit import com.pixelized.desktop.lwa.ui.overlay.roll.RollResult import com.pixelized.desktop.lwa.ui.overlay.roll.RollResult.BoundedRollResult.Difficulty import com.pixelized.desktop.lwa.ui.overlay.roll.RollResult.BoundedRollResult.Result @@ -23,9 +21,6 @@ import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn -import lwacharactersheet.composeapp.generated.resources.Res -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__edit__title -import org.jetbrains.compose.resources.getString class CharacterDetailPanelViewModel( private val characterSheetRepository: CharacterSheetRepository, diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/CharacterSheetNavHost.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/CharacterSheetNavHost.kt deleted file mode 100644 index 27660d0..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/CharacterSheetNavHost.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet - -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material.Surface -import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.ui.Modifier -import androidx.navigation.NavHostController -import androidx.navigation.compose.NavHost -import androidx.navigation.compose.rememberNavController -import com.pixelized.desktop.lwa.ui.navigation.screen.LocalScreenController -import com.pixelized.desktop.lwa.ui.navigation.screen.destination.composableCharacterSheetEditPage -import com.pixelized.desktop.lwa.ui.navigation.screen.destination.composableCharacterSheetPage - -@Composable -fun CharacterSheetMainNavHost( - controller: NavHostController = rememberNavController(), - startDestination: String, -) { - CompositionLocalProvider( - LocalScreenController provides controller, - ) { - Surface( - modifier = Modifier.fillMaxSize(), - ) { - NavHost( - navController = controller, - startDestination = startDestination, - ) { - composableCharacterSheetPage() - composableCharacterSheetEditPage() - } - } - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/copy/CharacterSheetCopyDialog.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/copy/CharacterSheetCopyDialog.kt deleted file mode 100644 index 613492b..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/copy/CharacterSheetCopyDialog.kt +++ /dev/null @@ -1,183 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.copy - -import androidx.compose.animation.AnimatedContent -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.SizeTransform -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.slideInVertically -import androidx.compose.animation.slideOutVertically -import androidx.compose.animation.togetherWith -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Surface -import androidx.compose.material.Text -import androidx.compose.material.TextButton -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.Stable -import androidx.compose.runtime.State -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.unit.dp -import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox -import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextField -import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextFieldUio -import com.pixelized.desktop.lwa.ui.theme.lwa -import com.pixelized.desktop.lwa.utils.extention.onPreviewEscape -import lwacharactersheet.composeapp.generated.resources.Res -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__copy__error -import lwacharactersheet.composeapp.generated.resources.dialog__cancel_action -import lwacharactersheet.composeapp.generated.resources.dialog__confirm_action -import org.jetbrains.compose.resources.stringResource - - -@Stable -data class CharacterSheetCopyDialogUio( - val label: String, - val value: LwaTextFieldUio, - val validate: () -> Boolean, -) - -@Composable -fun CharacterSheetCopyDialog( - dialog: State, - onConfirm: (CharacterSheetCopyDialogUio) -> Unit, - onDismissRequest: () -> Unit, -) { - AnimatedContent( - modifier = Modifier.fillMaxSize(), - targetState = dialog.value, - transitionSpec = { - val enter = fadeIn() + slideInVertically { 32 } - val exit = fadeOut() + slideOutVertically { 32 } - enter togetherWith exit using SizeTransform(clip = false) - }, - ) { - Box( - modifier = Modifier.fillMaxSize() - ) { - when (it) { - null -> Box( - modifier = Modifier, - ) - - else -> { - val focusRequester = remember { - FocusRequester() - } - LaunchedEffect(Unit) { - focusRequester.requestFocus() - } - Dialog( - dialog = it, - focusRequester = focusRequester, - onConfirm = onConfirm, - onDismissRequest = onDismissRequest, - ) - } - } - } - } -} - -@Composable -private fun Dialog( - dialog: CharacterSheetCopyDialogUio, - focusRequester: FocusRequester = remember { FocusRequester() }, - onConfirm: (CharacterSheetCopyDialogUio) -> Unit, - onDismissRequest: () -> Unit, -) { - Box( - modifier = Modifier - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null, - onClick = onDismissRequest, - ) - .onPreviewEscape( - escape = onDismissRequest, - enter = { onConfirm(dialog) }, - ) - .fillMaxSize() - .padding(all = 32.dp), - contentAlignment = Alignment.Center, - ) { - DecoratedBox { - Surface { - Column( - verticalArrangement = Arrangement.spacedBy(space = 8.dp), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Text( - modifier = Modifier.padding(top = 16.dp, start = 24.dp, end = 24.dp), - style = MaterialTheme.typography.caption, - text = dialog.label, - ) - - LwaTextField( - modifier = Modifier - .focusRequester(focusRequester = focusRequester) - .width(512.dp), - field = dialog.value, - ) - - AnimatedVisibility( - visible = dialog.value.errorFlow.collectAsState().value, - enter = fadeIn(), - exit = fadeOut(), - ) { - Text( - style = MaterialTheme.lwa.typography.system.caption, - color = MaterialTheme.lwa.colorScheme.base.error, - text = stringResource(Res.string.character_sheet_edit__copy__error) - ) - } - - Row( - modifier = Modifier - .padding(bottom = 4.dp) - .padding(horizontal = 16.dp) - .align(alignment = Alignment.End), - horizontalArrangement = Arrangement.spacedBy( - space = 4.dp, - alignment = Alignment.End - ) - ) { - TextButton( - onClick = onDismissRequest, - ) { - Text( - color = MaterialTheme.colors.primary.copy(alpha = .7f), - text = stringResource(Res.string.dialog__cancel_action) - ) - } - TextButton( - onClick = { - if (dialog.validate()) { - onConfirm(dialog) - } - }, - ) { - Text( - text = stringResource(Res.string.dialog__confirm_action) - ) - } - } - } - } - } - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/delete/CharacterSheetDeleteDialog.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/delete/CharacterSheetDeleteDialog.kt deleted file mode 100644 index ed90852..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/delete/CharacterSheetDeleteDialog.kt +++ /dev/null @@ -1,151 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.delete - -import androidx.compose.animation.AnimatedContent -import androidx.compose.animation.SizeTransform -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.slideInVertically -import androidx.compose.animation.slideOutVertically -import androidx.compose.animation.togetherWith -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Surface -import androidx.compose.material.Text -import androidx.compose.material.TextButton -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.runtime.State -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox -import com.pixelized.desktop.lwa.utils.extention.onPreviewEscape -import lwacharactersheet.composeapp.generated.resources.Res -import lwacharactersheet.composeapp.generated.resources.character_sheet__delete_dialog__description -import lwacharactersheet.composeapp.generated.resources.character_sheet__delete_dialog__title -import lwacharactersheet.composeapp.generated.resources.dialog__cancel_action -import lwacharactersheet.composeapp.generated.resources.dialog__confirm_action -import org.jetbrains.compose.resources.stringResource - -@Stable -data class CharacterSheetDeleteDialogUio( - val characterSheetId: String, - val name: String, -) - -@Composable -fun CharacterSheetDeleteDialog( - dialog: State, - onConfirm: (CharacterSheetDeleteDialogUio) -> Unit, - onDismissRequest: () -> Unit, -) { - AnimatedContent( - modifier = Modifier.fillMaxSize(), - targetState = dialog.value, - transitionSpec = { - val enter = fadeIn() + slideInVertically { 32 } - val exit = fadeOut() + slideOutVertically { 32 } - enter togetherWith exit using SizeTransform(clip = false) - }, - ) { - Box( - modifier = Modifier.fillMaxSize() - ) { - when (it) { - null -> Box( - modifier = Modifier, - ) - - else -> { - Dialog( - dialog = it, - onConfirm = onConfirm, - onDismissRequest = onDismissRequest, - ) - } - } - } - } -} - -@Composable -private fun Dialog( - dialog: CharacterSheetDeleteDialogUio, - onConfirm: (CharacterSheetDeleteDialogUio) -> Unit, - onDismissRequest: () -> Unit, -) { - Box( - modifier = Modifier - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null, - onClick = onDismissRequest, - ) - .onPreviewEscape( - escape = onDismissRequest, - enter = { onConfirm(dialog) }, - ) - .fillMaxSize() - .padding(all = 32.dp), - contentAlignment = Alignment.Center, - ) { - DecoratedBox { - Surface { - Column( - verticalArrangement = Arrangement.spacedBy(space = 24.dp), - ) { - Text( - modifier = Modifier - .padding(horizontal = 24.dp) - .padding(top = 24.dp), - style = MaterialTheme.typography.h6, - text = stringResource(Res.string.character_sheet__delete_dialog__title), - ) - Text( - modifier = Modifier - .padding(horizontal = 24.dp), - style = MaterialTheme.typography.body1, - text = stringResource( - Res.string.character_sheet__delete_dialog__description, - dialog.name - ), - ) - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = 4.dp), - horizontalArrangement = Arrangement.spacedBy( - space = 4.dp, - alignment = Alignment.End - ) - ) { - TextButton( - onClick = onDismissRequest, - ) { - Text( - text = stringResource(Res.string.dialog__cancel_action) - ) - } - TextButton( - onClick = { onConfirm(dialog) }, - ) { - Text( - text = stringResource(Res.string.dialog__confirm_action) - ) - } - } - } - } - } - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetFactory.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetFactory.kt deleted file mode 100644 index 35bd6dc..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetFactory.kt +++ /dev/null @@ -1,352 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.detail - -import com.pixelized.desktop.lwa.ui.composable.tooltip.BasicTooltipUio -import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction -import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.CharacterSheetPageUio.Characteristic -import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.CharacterSheetPageUio.Node -import com.pixelized.shared.lwa.model.AlteredCharacterSheetFactory -import com.pixelized.shared.lwa.model.alteration.FieldAlteration -import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet -import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId -import com.pixelized.shared.lwa.usecase.ExpressionUseCase -import lwacharactersheet.composeapp.generated.resources.Res -import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__cha -import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__con -import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__dex -import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__hei -import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__int -import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__pow -import lwacharactersheet.composeapp.generated.resources.character_sheet__characteristics__str -import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__armor -import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__damage_bonus -import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__hit_point -import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__hp_grow -import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__learning -import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__movement -import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__power_point -import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__charisma -import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__constitution -import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__dexterity -import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__height -import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__intelligence -import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__power -import lwacharactersheet.composeapp.generated.resources.tooltip__characteristics__strength -import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__armor -import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__bonus_damage -import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__hit_point -import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__hp_grow -import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__learning -import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__movement -import lwacharactersheet.composeapp.generated.resources.tooltip__sub_characteristics__power_point -import org.jetbrains.compose.resources.getString - -class CharacterSheetFactory( - private val alteredCharacterSheetFactory: AlteredCharacterSheetFactory, - private val skillUseCase: ExpressionUseCase, -) { - suspend fun convertToUio( - characterSheetId: String, - characterSheet: CharacterSheet?, - alterations: Map>, - ): CharacterSheetPageUio? { - if (characterSheet == null) return null - - val alteredCharacterSheet = alteredCharacterSheetFactory.sheet( - characterSheet = characterSheet, - alterations = alterations, - ) - - return CharacterSheetPageUio( - id = alteredCharacterSheet.id, - name = alteredCharacterSheet.name, - diminished = alteredCharacterSheet.diminished, - characteristics = listOf( - Characteristic( - id = CharacteristicId.STR, - label = getString(Res.string.character_sheet__characteristics__str), - value = "${alteredCharacterSheet.strength}", - editable = false, - tooltips = BasicTooltipUio( - title = getString(Res.string.character_sheet__characteristics__str), - description = getString(Res.string.tooltip__characteristics__strength), - ), - roll = RollAction.Uio.BoundedRollActionUio( - characterSheetId = characterSheetId, - label = getString(Res.string.character_sheet__characteristics__str), - rollAction = "1d100", - rollSuccessValue = alteredCharacterSheet.strength * 5 - alteredCharacterSheet.diminished, - ), - ), - Characteristic( - id = CharacteristicId.DEX, - label = getString(Res.string.character_sheet__characteristics__dex), - value = "${alteredCharacterSheet.dexterity}", - editable = false, - tooltips = BasicTooltipUio( - title = getString(Res.string.character_sheet__characteristics__dex), - description = getString(Res.string.tooltip__characteristics__dexterity), - ), - roll = RollAction.Uio.BoundedRollActionUio( - characterSheetId = characterSheetId, - label = getString(Res.string.character_sheet__characteristics__dex), - rollAction = "1d100", - rollSuccessValue = alteredCharacterSheet.dexterity * 5 - alteredCharacterSheet.diminished, - ), - ), - Characteristic( - id = CharacteristicId.CON, - label = getString(Res.string.character_sheet__characteristics__con), - value = "${alteredCharacterSheet.constitution}", - editable = false, - tooltips = BasicTooltipUio( - title = getString(Res.string.character_sheet__characteristics__con), - description = getString(Res.string.tooltip__characteristics__constitution), - ), - roll = RollAction.Uio.BoundedRollActionUio( - characterSheetId = characterSheetId, - label = getString(Res.string.character_sheet__characteristics__con), - rollAction = "1d100", - rollSuccessValue = alteredCharacterSheet.constitution * 5 - alteredCharacterSheet.diminished, - ), - ), - Characteristic( - id = CharacteristicId.HEI, - label = getString(Res.string.character_sheet__characteristics__hei), - value = "${alteredCharacterSheet.height}", - editable = false, - tooltips = BasicTooltipUio( - title = getString(Res.string.character_sheet__characteristics__hei), - description = getString(Res.string.tooltip__characteristics__height), - ), - roll = RollAction.Uio.BoundedRollActionUio( - characterSheetId = characterSheetId, - label = getString(Res.string.character_sheet__characteristics__hei), - rollAction = "1d100", - rollSuccessValue = alteredCharacterSheet.height * 5 - alteredCharacterSheet.diminished, - ), - ), - Characteristic( - id = CharacteristicId.INT, - label = getString(Res.string.character_sheet__characteristics__int), - value = "${alteredCharacterSheet.intelligence}", - editable = false, - tooltips = BasicTooltipUio( - title = getString(Res.string.character_sheet__characteristics__int), - description = getString(Res.string.tooltip__characteristics__intelligence), - ), - roll = RollAction.Uio.BoundedRollActionUio( - characterSheetId = characterSheetId, - label = getString(Res.string.character_sheet__characteristics__int), - rollAction = "1d100", - rollSuccessValue = alteredCharacterSheet.intelligence * 5 - alteredCharacterSheet.diminished, - ), - ), - Characteristic( - id = CharacteristicId.POW, - label = getString(Res.string.character_sheet__characteristics__pow), - value = "${alteredCharacterSheet.power}", - editable = false, - tooltips = BasicTooltipUio( - title = getString(Res.string.character_sheet__characteristics__pow), - description = getString(Res.string.tooltip__characteristics__power), - ), - roll = RollAction.Uio.BoundedRollActionUio( - characterSheetId = characterSheetId, - label = getString(Res.string.character_sheet__characteristics__pow), - rollAction = "1d100", - rollSuccessValue = alteredCharacterSheet.power * 5 - alteredCharacterSheet.diminished, - ), - ), - Characteristic( - id = CharacteristicId.CHA, - label = getString(Res.string.character_sheet__characteristics__cha), - value = "${alteredCharacterSheet.charisma}", - editable = false, - tooltips = BasicTooltipUio( - title = getString(Res.string.character_sheet__characteristics__cha), - description = getString(Res.string.tooltip__characteristics__charisma), - ), - roll = RollAction.Uio.BoundedRollActionUio( - characterSheetId = characterSheetId, - label = getString(Res.string.character_sheet__characteristics__cha), - rollAction = "1d100", - rollSuccessValue = alteredCharacterSheet.charisma * 5 - alteredCharacterSheet.diminished, - ), - ), - ), - subCharacteristics = listOf( - Characteristic( - id = CharacteristicId.MOV, - label = getString(Res.string.character_sheet__sub_characteristics__movement), - value = "${alteredCharacterSheet.movement}", - editable = false, - tooltips = BasicTooltipUio( - title = getString(Res.string.character_sheet__sub_characteristics__movement), - description = getString(Res.string.tooltip__sub_characteristics__movement), - ), - roll = null, - ), - Characteristic( - id = CharacteristicId.HP, - label = getString(Res.string.character_sheet__sub_characteristics__hit_point), - value = alteredCharacterSheet.maxHp.let { maxHp -> "${maxHp - alteredCharacterSheet.damage}/${maxHp}" }, - editable = true, - tooltips = BasicTooltipUio( - title = getString(Res.string.character_sheet__sub_characteristics__hit_point), - description = getString(Res.string.tooltip__sub_characteristics__hit_point), - ), - roll = null, - ), - Characteristic( - id = CharacteristicId.PP, - label = getString(Res.string.character_sheet__sub_characteristics__power_point), - value = alteredCharacterSheet.maxPp.let { maxPp -> "${maxPp - alteredCharacterSheet.power}/${maxPp}" }, - editable = true, - tooltips = BasicTooltipUio( - title = getString(Res.string.character_sheet__sub_characteristics__power_point), - description = getString(Res.string.tooltip__sub_characteristics__power_point), - ), - roll = null, - ), - Characteristic( - id = CharacteristicId.DMG, - label = getString(Res.string.character_sheet__sub_characteristics__damage_bonus), - value = alteredCharacterSheet.damageBonus, - editable = false, - tooltips = BasicTooltipUio( - title = getString(Res.string.character_sheet__sub_characteristics__damage_bonus), - description = getString(Res.string.tooltip__sub_characteristics__bonus_damage), - ), - roll = null, - ), - Characteristic( - id = CharacteristicId.ARMOR, - label = getString(Res.string.character_sheet__sub_characteristics__armor), - value = "${alteredCharacterSheet.armor}", - editable = false, - tooltips = BasicTooltipUio( - title = getString(Res.string.character_sheet__sub_characteristics__armor), - description = getString(Res.string.tooltip__sub_characteristics__armor), - ), - roll = null, - ), - Characteristic( - id = CharacteristicId.LB, - label = getString(Res.string.character_sheet__sub_characteristics__learning), - value = "${alteredCharacterSheet.learning}", - editable = false, - tooltips = BasicTooltipUio( - title = getString(Res.string.character_sheet__sub_characteristics__learning), - description = getString(Res.string.tooltip__sub_characteristics__learning), - ), - roll = null, - ), - Characteristic( - id = CharacteristicId.GHP, - label = getString(Res.string.character_sheet__sub_characteristics__hp_grow), - value = "${alteredCharacterSheet.hpGrow}", - editable = false, - tooltips = BasicTooltipUio( - title = getString(Res.string.character_sheet__sub_characteristics__hp_grow), - description = getString(Res.string.tooltip__sub_characteristics__hp_grow), - ), - roll = null, - ), - ), - commonSkills = characterSheet.commonSkills.map { skill -> - val value = skillUseCase.computeSkillValue( - sheet = alteredCharacterSheet, - skill = skill, - diminished = alteredCharacterSheet.diminished, - alterations = alterations, - ) - Node( - id = skill.id, - label = skill.label, - value = value, - used = skill.used, - tooltips = skill.description?.let { - BasicTooltipUio( - title = skill.label, - description = it, - ) - }, - roll = RollAction.Uio.BoundedRollActionUio( - characterSheetId = characterSheetId, - label = skill.label, - rollAction = "1d100", - rollSuccessValue = value, - ), - ) - }, - specialSKills = characterSheet.specialSkills.map { skill -> - val value = skillUseCase.computeSkillValue( - sheet = alteredCharacterSheet, - skill = skill, - diminished = alteredCharacterSheet.diminished, - alterations = alterations, - ) - Node( - id = skill.id, - label = skill.label, - value = value, - used = skill.used, - tooltips = skill.description?.let { - BasicTooltipUio( - title = skill.label, - description = it, - ) - }, - roll = RollAction.Uio.BoundedRollActionUio( - characterSheetId = characterSheetId, - label = skill.label, - rollAction = "1d100", - rollSuccessValue = value, - ), - ) - }, - magicsSkills = characterSheet.magicSkills.map { skill -> - val value = skillUseCase.computeSkillValue( - sheet = alteredCharacterSheet, - skill = skill, - diminished = alteredCharacterSheet.diminished, - alterations = alterations, - ) - Node( - id = skill.id, - label = skill.label, - value = value, - used = skill.used, - tooltips = skill.description?.let { - BasicTooltipUio( - title = skill.label, - description = it, - ) - }, - roll = RollAction.Uio.BoundedRollActionUio( - characterSheetId = characterSheetId, - label = skill.label, - rollAction = "1d100", - rollSuccessValue = value, - ), - ) - }, - actions = characterSheet.actions.mapNotNull { action -> - if (action.default.isEmpty()) return@mapNotNull null - - CharacterSheetPageUio.Roll( - label = action.label, - value = action.default, - roll = RollAction.Uio.BoundlessRollActionUio( - characterSheetId = characterSheetId, - label = action.label, - canBeCritical = action.canBeCritical, - rollDefaultAction = action.default, - rollSpecialAction = action.special, - rollCriticalAction = action.critical, - ) - ) - } - ) - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetPage.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetPage.kt deleted file mode 100644 index f16e491..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetPage.kt +++ /dev/null @@ -1,690 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.detail - -import androidx.compose.animation.AnimatedContent -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.SizeTransform -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.slideInVertically -import androidx.compose.animation.slideOutVertically -import androidx.compose.animation.togetherWith -import androidx.compose.desktop.ui.tooling.preview.Preview -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.ScrollState -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.heightIn -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll -import androidx.compose.material.Checkbox -import androidx.compose.material.CheckboxDefaults -import androidx.compose.material.DropdownMenu -import androidx.compose.material.DropdownMenuItem -import androidx.compose.material.Icon -import androidx.compose.material.IconButton -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Scaffold -import androidx.compose.material.Surface -import androidx.compose.material.Text -import androidx.compose.material.TopAppBar -import androidx.compose.material.icons.Icons -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.Stable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import com.pixelized.desktop.lwa.LocalWindowController -import com.pixelized.desktop.lwa.ui.composable.blur.BlurContent -import com.pixelized.desktop.lwa.ui.composable.blur.BlurContentController -import com.pixelized.desktop.lwa.ui.composable.character.diminished.CharacterSheetDiminishedDialogViewModel -import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox -import com.pixelized.desktop.lwa.ui.composable.tooltip.BasicTooltipLayout -import com.pixelized.desktop.lwa.ui.composable.tooltip.BasicTooltipUio -import com.pixelized.desktop.lwa.ui.navigation.screen.LocalScreenController -import com.pixelized.desktop.lwa.ui.navigation.window.LocalWindow -import com.pixelized.desktop.lwa.ui.navigation.window.destination.navigateToCharacterSheetEdit -import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction -import com.pixelized.desktop.lwa.ui.overlay.roll.RollPage -import com.pixelized.desktop.lwa.ui.overlay.roll.RollViewModel -import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.CharacterSheetPageUio.Characteristic -import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.dialog.CharacterSheetDeleteConfirmationDialog -import com.pixelized.desktop.lwa.ui.composable.character.diminished.CharacterSheetDiminishedDialog -import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.preview.rememberCharacterSheetPreview -import com.pixelized.desktop.lwa.utils.preview.ContentPreview -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 -import lwacharactersheet.composeapp.generated.resources.character_sheet__skills__common_title -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_24dp -import lwacharactersheet.composeapp.generated.resources.ic_skull_24dp -import org.jetbrains.compose.resources.getString -import org.jetbrains.compose.resources.painterResource -import org.jetbrains.compose.resources.stringResource -import org.koin.compose.viewmodel.koinViewModel - -@Stable -data class CharacterSheetPageUio( - val id: String, - val name: String, - val diminished: Int, - val characteristics: List, - val subCharacteristics: List, - val commonSkills: List, - val specialSKills: List, - val magicsSkills: List, - val actions: List, -) { - @Stable - data class Characteristic( - val id: String, - val label: String, - val value: String, - val editable: Boolean, - val tooltips: BasicTooltipUio?, - val roll: RollAction.Uio?, - ) - - @Stable - data class Node( - val id: String, - val label: String, - val value: Int, - val used: Boolean, - val tooltips: BasicTooltipUio? = null, - val roll: RollAction.Uio, - ) - - @Stable - data class Roll( - val label: String, - val value: String, - val roll: RollAction.Uio, - ) -} - -@Composable -fun CharacterSheetPage( - viewModel: CharacterSheetViewModel = koinViewModel(), - diminishedDialogViewModel: CharacterSheetDiminishedDialogViewModel = koinViewModel(), - rollViewModel: RollViewModel = koinViewModel(), -) { - val windowController = LocalWindowController.current - val screen = LocalScreenController.current - val window = LocalWindow.current - val scope = rememberCoroutineScope() - val blurController = remember { BlurContentController() } - val sheet = viewModel.sheetFlow.collectAsState() - - Surface( - modifier = Modifier.fillMaxSize(), - ) { - BlurContent( - controller = blurController, - content = { - sheet.value?.let { sheet -> - CharacterSheetPageContent( - modifier = Modifier.fillMaxSize(), - characterSheet = sheet, - onDiminished = { - blurController.show() - scope.launch { - diminishedDialogViewModel.showDiminishedDialog( - characterSheetId = it - ) - } - }, - onEdit = { - windowController.navigateToCharacterSheetEdit( - title = runBlocking { getString(Res.string.character_sheet_edit__edit__title) }, - characterId = sheet.id, - ) - }, - onDelete = { - blurController.show() - viewModel.showConfirmCharacterDeletionDialog() - }, - onCharacteristic = { characteristic -> - if (characteristic.roll == null) return@CharacterSheetPageContent - scope.launch { - rollViewModel.prepareRoll(characteristic.roll) - blurController.show() - viewModel.showRollOverlay() - } - }, - onSubCharacteristic = { -// blurController.show() -// scope.launch { -// viewModel.showSubCharacteristicDialog(id = it.id) -// } - }, - onSkill = { node -> - scope.launch { - blurController.show() - rollViewModel.prepareRoll(node.roll) - viewModel.showRollOverlay() - } - }, - onUseSkill = viewModel::onUseSkill, - onRoll = { roll -> - scope.launch { - blurController.show() - rollViewModel.prepareRoll(roll.roll) - viewModel.showRollOverlay() - } - }, - ) - } - }, - ) - - AnimatedContent( - targetState = viewModel.displayRollOverlay.value, - transitionSpec = { - val enter = fadeIn() + slideInVertically { 64 } - val exit = fadeOut() + slideOutVertically { 64 } - enter togetherWith exit - }, - ) { roll -> - when (roll) { - true -> RollPage( - viewModel = rollViewModel, - onDismissRequest = { - blurController.hide() - viewModel.hideRollOverlay() - }, - onRoll = { - scope.launch { - rollViewModel.roll() - } - } - ) - - else -> Box( - modifier = Modifier.fillMaxSize() - ) - } - } - - CharacterSheetDeleteConfirmationDialog( - dialog = viewModel.displayDeleteConfirmationDialog, - onConfirm = { - scope.launch { - viewModel.deleteCharacter(id = it.id) - if (screen.popBackStack().not()) { - windowController.hideWindow(window = window) - } - } - }, - onDismissRequest = { - blurController.hide() - viewModel.hideConfirmCharacterDeletionDialog() - }, - ) - - CharacterSheetDiminishedDialog( - dialog = viewModel.diminishedDialog, - onConfirm = { - scope.launch { - diminishedDialogViewModel.changeDiminished(dialog = it) - diminishedDialogViewModel.hideDiminishedDialog() - blurController.hide() - } - }, - onDismissRequest = { - diminishedDialogViewModel.hideDiminishedDialog() - blurController.hide() - }, - ) - } -} - -@Composable -fun CharacterSheetPageContent( - modifier: Modifier = Modifier, - scrollState: ScrollState = rememberScrollState(), - characterSheet: CharacterSheetPageUio, - onDiminished: (characterSheetId: String) -> Unit, - onEdit: () -> Unit, - onDelete: () -> Unit, - onCharacteristic: (characteristic: Characteristic) -> Unit, - onSubCharacteristic: (characteristic: Characteristic) -> Unit, - onSkill: (skill: CharacterSheetPageUio.Node) -> Unit, - onUseSkill: (skill: CharacterSheetPageUio.Node) -> Unit, - onRoll: (roll: CharacterSheetPageUio.Roll) -> Unit, -) { - Scaffold( - modifier = modifier, - topBar = { - TopAppBar( - title = { - Text( - overflow = TextOverflow.Ellipsis, - maxLines = 1, - text = characterSheet.name, - ) - }, - actions = { - val showMenu = remember { mutableStateOf(false) } - Box { - IconButton( - onClick = { onDiminished(characterSheet.id) }, - ) { - Icon( - modifier = Modifier.size(size = 24.dp), - painter = painterResource(Res.drawable.ic_skull_24dp), - tint = MaterialTheme.colors.primary, - contentDescription = null, - ) - } - AnimatedContent( - modifier = Modifier.align(alignment = Alignment.BottomCenter), - targetState = characterSheet.diminished, - transitionSpec = { - val sign = if (targetState > initialState) 1 else -1 - val enter = fadeIn() + slideInVertically { 16 * sign } - val exit = fadeOut() + slideOutVertically { -16 * sign } - enter togetherWith exit using SizeTransform(clip = false) - } - ) { - Text( - style = MaterialTheme.typography.caption, - color = MaterialTheme.colors.onSurface, - text = "${it}", - ) - } - } - IconButton( - onClick = { showMenu.value = showMenu.value.not() }, - ) { - Icon( - imageVector = Icons.Default.MoreVert, - tint = MaterialTheme.colors.primary, - contentDescription = null, - ) - } - DropdownMenu( - expanded = showMenu.value, - onDismissRequest = { showMenu.value = false } - ) { - DropdownMenuItem( - onClick = { - showMenu.value = false - onEdit() - }, - ) { - Icon( - imageVector = Icons.Default.Edit, - tint = MaterialTheme.colors.primary, - contentDescription = null, - ) - Text( - modifier = Modifier.padding(start = 8.dp), - color = MaterialTheme.colors.primary, - text = stringResource(Res.string.character_sheet__edit__label), - ) - } - DropdownMenuItem( - onClick = { - showMenu.value = false - onDelete() - }, - ) { - Icon( - imageVector = Icons.Default.Delete, - tint = MaterialTheme.colors.primary, - contentDescription = null, - ) - Text( - modifier = Modifier.padding(start = 8.dp), - color = MaterialTheme.colors.primary, - text = stringResource(Res.string.character_sheet__delete__label), - ) - } - } - }, - ) - }, - content = { paddingValues -> - Row( - modifier = Modifier - .verticalScroll(state = scrollState) - .padding(paddingValues) - .padding(all = 16.dp), - horizontalArrangement = Arrangement.spacedBy(space = 16.dp), - ) { - Column( - modifier = Modifier - .fillMaxHeight() - .width(100.dp), - verticalArrangement = Arrangement.spacedBy(space = 16.dp), - ) { - characterSheet.characteristics.forEach { - Stat( - modifier = Modifier - .fillMaxWidth() - .heightIn(min = 120.dp), - characteristic = it, - onClick = { onCharacteristic(it) }, - ) - } - } - Column( - modifier = Modifier - .fillMaxHeight() - .weight(2f / 3f), - verticalArrangement = Arrangement.spacedBy(space = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - DecoratedBox( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 8.dp), - ) { - Column { - Text( - modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp), - style = MaterialTheme.typography.caption, - textAlign = TextAlign.Center, - text = stringResource(Res.string.character_sheet__sub_characteristics__title), - ) - characterSheet.subCharacteristics.forEach { - SubCharacteristics( - modifier = Modifier.cell(), - characteristic = it, - onCharacteristic = when { - it.editable -> onSubCharacteristic - else -> null - } - ) - } - } - } - DecoratedBox( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 8.dp), - ) { - Column { - Text( - modifier = Modifier - .fillMaxWidth() - .padding(bottom = 8.dp), - style = MaterialTheme.typography.caption, - textAlign = TextAlign.Center, - text = stringResource(Res.string.character_sheet__skills__common_title), - ) - characterSheet.commonSkills.forEach { skill -> - Skill( - modifier = Modifier.cell(), - node = skill, - onClick = { onSkill(skill) }, - onUse = { onUseSkill(skill) }, - ) - } - } - } - AnimatedVisibility( - visible = characterSheet.specialSKills.isNotEmpty() - ) { - DecoratedBox( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 8.dp), - ) { - Column { - Text( - modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp), - style = MaterialTheme.typography.caption, - textAlign = TextAlign.Center, - text = stringResource(Res.string.character_sheet__skills__special_title), - ) - characterSheet.specialSKills.forEach { occupation -> - Skill( - modifier = Modifier.cell(), - node = occupation, - onClick = { onSkill(occupation) }, - onUse = { onUseSkill(occupation) }, - ) - } - } - } - } - AnimatedVisibility( - visible = characterSheet.magicsSkills.isNotEmpty() - ) { - DecoratedBox( - modifier = Modifier - .fillMaxWidth() - .padding(vertical = 8.dp), - ) { - Column { - Text( - modifier = Modifier.fillMaxWidth().padding(bottom = 8.dp), - style = MaterialTheme.typography.caption, - textAlign = TextAlign.Center, - text = stringResource(Res.string.character_sheet__skills__magic_title), - ) - characterSheet.magicsSkills.forEach { magic -> - Skill( - modifier = Modifier.cell(), - node = magic, - onClick = { onSkill(magic) }, - onUse = { onUseSkill(magic) }, - ) - } - } - } - } - characterSheet.actions.forEach { roll -> - Roll( - modifier = Modifier.cell(), - label = roll.label, - onClick = { onRoll(roll) }, - ) - } - } - } - } - ) -} - -@OptIn(ExperimentalFoundationApi::class) -@Composable -private fun Stat( - modifier: Modifier = Modifier, - paddingValues: PaddingValues = PaddingValues(all = 8.dp), - characteristic: Characteristic, - onClick: () -> Unit, -) { - BasicTooltipLayout( - tooltip = characteristic.tooltips, - content = { - DecoratedBox( - modifier = Modifier - .clickable(onClick = onClick) - .padding(paddingValues = paddingValues) - .then(other = modifier), - ) { - Text( - modifier = Modifier.align(alignment = Alignment.TopCenter), - style = MaterialTheme.typography.caption, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - text = characteristic.label, - ) - Text( - modifier = Modifier.align(alignment = Alignment.Center), - style = MaterialTheme.typography.h3, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - color = MaterialTheme.colors.primary, - text = characteristic.value - ) - } - }, - ) -} - -@OptIn(ExperimentalFoundationApi::class) -@Composable -private fun SubCharacteristics( - modifier: Modifier = Modifier, - paddingValues: PaddingValues = PaddingValues(horizontal = 8.dp), - characteristic: Characteristic, - onCharacteristic: ((characteristic: Characteristic) -> Unit)?, -) { - BasicTooltipLayout( - tooltip = characteristic.tooltips, - content = { - Row( - modifier = Modifier - .clickable(enabled = characteristic.editable && onCharacteristic != null) { - onCharacteristic?.invoke(characteristic) - } - .padding(paddingValues = paddingValues).then(other = modifier), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - style = MaterialTheme.typography.body1, - text = characteristic.label - ) - Text( - style = MaterialTheme.typography.body1, - fontWeight = FontWeight.Bold, - color = when (characteristic.editable && onCharacteristic != null) { - true -> MaterialTheme.colors.primary - else -> MaterialTheme.colors.onSurface - }, - text = characteristic.value, - ) - } - }, - ) -} - -@OptIn(ExperimentalFoundationApi::class) -@Composable -private fun Skill( - modifier: Modifier = Modifier, - paddingValues: PaddingValues = PaddingValues(horizontal = 8.dp), - node: CharacterSheetPageUio.Node, - onClick: () -> Unit, - onUse: () -> Unit, -) { - BasicTooltipLayout( - tooltip = node.tooltips, - content = { - Row( - modifier = Modifier - .clickable(onClick = onClick) - .padding(paddingValues = paddingValues) - .then(other = modifier), - horizontalArrangement = Arrangement.spacedBy(space = 4.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - modifier = Modifier.weight(1f), - style = MaterialTheme.typography.body1, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - text = node.label - ) - Text( - style = MaterialTheme.typography.body1, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colors.primary, - text = "${node.value}", - ) - Checkbox( - modifier = Modifier.size(size = 32.dp), - checked = node.used, - colors = CheckboxDefaults.colors( - checkedColor = MaterialTheme.colors.primary, - ), - onCheckedChange = { onUse() }, - ) - } - }, - ) -} - -@Composable -private fun Roll( - modifier: Modifier = Modifier, - paddingValues: PaddingValues = PaddingValues(start = 10.dp, end = 14.dp), - label: String, - onClick: () -> Unit, -) { - Row( - modifier = Modifier - .clickable(onClick = onClick) - .padding(paddingValues = paddingValues) - .then(other = modifier), - horizontalArrangement = Arrangement.SpaceBetween, - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - modifier = Modifier.weight(1f), - style = MaterialTheme.typography.body1, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - text = label - ) - Icon( - modifier = Modifier.size(size = 24.dp), - painter = painterResource(Res.drawable.ic_d20_24dp), - tint = MaterialTheme.colors.primary, - contentDescription = null, - ) - } -} - -private fun Modifier.cell(): Modifier = this.fillMaxWidth().height(height = 32.dp) - -@Composable -@Preview -private fun DecoratedBoxPreview() { - ContentPreview { - CharacterSheetPageContent( - modifier = Modifier.fillMaxSize(), - scrollState = rememberScrollState(), - characterSheet = rememberCharacterSheetPreview(), - onDiminished = { }, - onEdit = { }, - onDelete = { }, - onCharacteristic = { }, - onSubCharacteristic = { }, - onSkill = { }, - onUseSkill = { }, - onRoll = { }, - ) - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetViewModel.kt deleted file mode 100644 index 068ef7b..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/CharacterSheetViewModel.kt +++ /dev/null @@ -1,95 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.detail - -import androidx.compose.runtime.State -import androidx.compose.runtime.mutableStateOf -import androidx.lifecycle.SavedStateHandle -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.pixelized.desktop.lwa.repository.alteration.AlterationRepository -import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository -import com.pixelized.desktop.lwa.repository.network.NetworkRepository -import com.pixelized.desktop.lwa.ui.navigation.screen.destination.CharacterSheetDestination -import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.dialog.CharacterSheetDeleteConfirmationDialogUio -import com.pixelized.desktop.lwa.ui.composable.character.diminished.CharacterSheetDiminishedDialogUio -import com.pixelized.shared.lwa.protocol.websocket.CharacterSheetEvent -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.stateIn -import kotlinx.coroutines.launch - -private typealias CSDCDialogUio = CharacterSheetDeleteConfirmationDialogUio - -class CharacterSheetViewModel( - private val characterRepository: CharacterSheetRepository, - private val networkRepository: NetworkRepository, - alteration: AlterationRepository, - factory: CharacterSheetFactory, - savedStateHandle: SavedStateHandle, -) : ViewModel() { - - private val argument = CharacterSheetDestination.Argument(savedStateHandle) - - private val _displayDeleteConfirmationDialog = mutableStateOf(null) - val displayDeleteConfirmationDialog: State get() = _displayDeleteConfirmationDialog - - private val _displayRollOverlay = mutableStateOf(false) - val displayRollOverlay: State get() = _displayRollOverlay - - private val _diminishedDialog = mutableStateOf(null) - val diminishedDialog: State get() = _diminishedDialog - - val sheetFlow = combine( - characterRepository.characterDetailFlow(characterSheetId = argument.characterSheetId), - alteration.activeFieldAlterationsFlow(characterSheetId = argument.characterSheetId), - transform = { characterSheet, alterations -> - factory.convertToUio( - characterSheetId = argument.characterSheetId, - characterSheet = characterSheet, - alterations = alterations, - ) - }, - ).stateIn( - scope = viewModelScope, - started = SharingStarted.Eagerly, - initialValue = null, - ) - - suspend fun deleteCharacter(id: String) { - characterRepository.deleteCharacter(characterSheetId = id) - } - - fun onUseSkill(skill: CharacterSheetPageUio.Node) { - viewModelScope.launch { - networkRepository.share( - message = CharacterSheetEvent.UpdateSkillUsageEvent( - timestamp = System.currentTimeMillis(), - characterSheetId = argument.characterSheetId, - skillId = skill.id, - used = skill.used.not(), - ) - ) - } - } - - fun showConfirmCharacterDeletionDialog() { - val preview = characterRepository.characterPreview( - characterId = argument.characterSheetId - ) ?: return - _displayDeleteConfirmationDialog.value = CharacterSheetDeleteConfirmationDialogUio( - id = preview.characterSheetId, - name = preview.name, - ) - } - - fun hideConfirmCharacterDeletionDialog() { - _displayDeleteConfirmationDialog.value = null - } - - fun showRollOverlay() { - _displayRollOverlay.value = true - } - - fun hideRollOverlay() { - _displayRollOverlay.value = false - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/dialog/CharacterSheetDeleteConfirmationDialog.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/dialog/CharacterSheetDeleteConfirmationDialog.kt deleted file mode 100644 index e7e890b..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/dialog/CharacterSheetDeleteConfirmationDialog.kt +++ /dev/null @@ -1,130 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.dialog - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Surface -import androidx.compose.material.Text -import androidx.compose.material.TextButton -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.runtime.State -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import androidx.compose.ui.window.Dialog -import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox -import com.pixelized.desktop.lwa.utils.extention.onPreviewEscape -import lwacharactersheet.composeapp.generated.resources.Res -import lwacharactersheet.composeapp.generated.resources.character_sheet__delete_dialog__description -import lwacharactersheet.composeapp.generated.resources.character_sheet__delete_dialog__title -import lwacharactersheet.composeapp.generated.resources.dialog__cancel_action -import lwacharactersheet.composeapp.generated.resources.dialog__confirm_action -import org.jetbrains.compose.resources.stringResource - -@Stable -data class CharacterSheetDeleteConfirmationDialogUio( - val id: String, - val name: String, -) - -@Composable -fun CharacterSheetDeleteConfirmationDialog( - dialog: State, - onConfirm: (CharacterSheetDeleteConfirmationDialogUio) -> Unit, - onDismissRequest: () -> Unit, -) { - dialog.value?.let { - Dialog( - onDismissRequest = onDismissRequest, - content = { - CharacterSheetDeleteConfirmationContent( - dialog = it, - onConfirm = onConfirm, - onDismissRequest = onDismissRequest, - ) - } - ) - } -} - -@Composable -private fun CharacterSheetDeleteConfirmationContent( - dialog: CharacterSheetDeleteConfirmationDialogUio, - onConfirm: (CharacterSheetDeleteConfirmationDialogUio) -> Unit, - onDismissRequest: () -> Unit, -) { - Box( - modifier = Modifier - .clickable( - interactionSource = remember { MutableInteractionSource() }, - indication = null, - onClick = onDismissRequest, - ) - .onPreviewEscape( - escape = onDismissRequest, - enter = { onConfirm(dialog) }, - ) - .fillMaxSize() - .padding(all = 32.dp), - contentAlignment = Alignment.Center, - ) { - DecoratedBox { - Surface { - Column( - verticalArrangement = Arrangement.spacedBy(space = 24.dp), - ) { - Text( - modifier = Modifier - .padding(horizontal = 24.dp) - .padding(top = 24.dp), - style = MaterialTheme.typography.h6, - text = stringResource(Res.string.character_sheet__delete_dialog__title), - ) - Text( - modifier = Modifier - .padding(horizontal = 24.dp), - style = MaterialTheme.typography.body1, - text = stringResource( - Res.string.character_sheet__delete_dialog__description, - dialog.name - ), - ) - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp) - .padding(bottom = 4.dp), - horizontalArrangement = Arrangement.spacedBy( - space = 4.dp, - alignment = Alignment.End - ) - ) { - TextButton( - onClick = onDismissRequest, - ) { - Text( - text = stringResource(Res.string.dialog__cancel_action) - ) - } - TextButton( - onClick = { onConfirm(dialog) }, - ) { - Text( - text = stringResource(Res.string.dialog__confirm_action) - ) - } - } - } - } - } - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/preview/rememberCharacterSheetPagePreview.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/preview/rememberCharacterSheetPagePreview.kt deleted file mode 100644 index 09618b9..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/detail/preview/rememberCharacterSheetPagePreview.kt +++ /dev/null @@ -1,141 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.preview - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.runtime.remember -import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet.CharacteristicId -import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.CharacterSheetPageUio -import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.CharacterSheetPageUio.Characteristic - - -@Composable -@Stable -fun rememberCharacterSheetPreview(): CharacterSheetPageUio { - return remember { - CharacterSheetPageUio( - id = "Koryas_Id", - name = "Koryas", - diminished = 0, - characteristics = listOf( - Characteristic( - id = CharacteristicId.STR, - label = "Force", - value = "10", - tooltips = null, - editable = false, - roll = null, - ), - Characteristic( - id = CharacteristicId.DEX, - label = "Dexterité", - value = "10", - tooltips = null, - editable = false, - roll = null, - ), - Characteristic( - id = CharacteristicId.CON, - label = "Constitution", - value = "10", - tooltips = null, - editable = false, - roll = null, - ), - Characteristic( - id = CharacteristicId.HEI, - label = "Taille", - value = "10", - tooltips = null, - editable = false, - roll = null, - ), - Characteristic( - id = CharacteristicId.INT, - label = "Intelligence", - value = "10", - tooltips = null, - editable = false, - roll = null, - ), - Characteristic( - id = CharacteristicId.POW, - label = "Pouvoir", - value = "10", - tooltips = null, - editable = false, - roll = null, - ), - Characteristic( - id = CharacteristicId.CHA, - label = "Charisme", - value = "10", - tooltips = null, - editable = false, - roll = null, - ), - ), - subCharacteristics = listOf( - Characteristic( - id = CharacteristicId.MOV, - label = "Mouvement", - value = "10", - tooltips = null, - editable = false, - roll = null, - ), - Characteristic( - id = CharacteristicId.HP, - label = "Point de vie", - value = "20/20", - tooltips = null, - editable = true, - roll = null, - ), - Characteristic( - id = CharacteristicId.PP, - label = "Point de pouvoir", - value = "15/15", - tooltips = null, - editable = true, - roll = null, - ), - Characteristic( - id = CharacteristicId.DMG, - label = "Domage bonus", - value = "1d4", - tooltips = null, - editable = false, - roll = null, - ), - Characteristic( - id = CharacteristicId.ARMOR, - label = "Armure", - value = "0", - tooltips = null, - editable = false, - roll = null, - ), - Characteristic( - id = CharacteristicId.LB, - label = "Apprentissage", - value = "0", - tooltips = null, - editable = false, - roll = null, - ), - Characteristic( - id = CharacteristicId.GHP, - label = "Bonus de PV", - value = "5", - tooltips = null, - editable = false, - roll = null, - ), - ), - commonSkills = emptyList(), - specialSKills = emptyList(), - magicsSkills = emptyList(), - actions = emptyList(), - ) - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditFactory.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditFactory.kt deleted file mode 100644 index 4adfc0f..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditFactory.kt +++ /dev/null @@ -1,623 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.edit - -import androidx.compose.runtime.State -import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.mutableStateOf -import com.pixelized.desktop.lwa.ui.composable.checkbox.LwaCheckBoxUio -import com.pixelized.desktop.lwa.ui.composable.textfield.createLwaTextField -import com.pixelized.desktop.lwa.ui.composable.textfield.createLwaTextFieldFlow -import com.pixelized.desktop.lwa.ui.composable.tooltip.BasicTooltipUio -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.common.SkillFieldFactory -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.common.occupation -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.ActionFieldUio -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.BaseSkillFieldUio -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.LevelUpWrapperUio -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.SimpleFieldUio -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.textfield.TextFieldWrapperUio -import com.pixelized.desktop.lwa.utils.extention.unAccent -import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet -import com.pixelized.shared.lwa.usecase.CharacterSheetUseCase -import kotlinx.coroutines.flow.MutableStateFlow -import lwacharactersheet.composeapp.generated.resources.Res -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__critical_action_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__default_action_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__description_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__name_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__spacial_action_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__cha -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__con -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__dex -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__hei -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__int -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__level -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__portrait -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__pow -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__str -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__thumbnail -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__level_up -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__name_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__acrobatics_base -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__acrobatics_description -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__acrobatics_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__aid_base -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__aid_description -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__aid_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__athletics_base -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__athletics_description -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__athletics_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__bargain_base -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__bargain_description -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__bargain_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__bonus_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__combat_base -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__combat_description -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__combat_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__discretion_base -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__discretion_description -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__discretion_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__dodge_base -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__dodge_description -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__dodge_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__empathy_base -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__empathy_description -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__empathy_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__grab_base -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__grab_description -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__grab_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__intimidation_base -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__intimidation_description -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__intimidation_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__level_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__magic_title -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__perception_base -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__perception_description -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__perception_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__persuasion_base -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__persuasion_description -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__persuasion_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__search_base -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__search_description -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__search_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__sleight_of_hand_base -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__sleight_of_hand_description -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__sleight_of_hand_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__special_title -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__spiel_base -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__spiel_description -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__spiel_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__throw_base -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__throw_description -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__throw_label -import org.jetbrains.compose.resources.getString -import kotlin.math.max - -class CharacterSheetEditFactory( - private val skillFieldFactory: SkillFieldFactory, - private val characterSheetUseCase: CharacterSheetUseCase, -) { - suspend fun updateCharacterSheet( - currentSheet: CharacterSheet?, - editedSheet: CharacterSheetEditPageUio, - ): CharacterSheet { - - val level = editedSheet.level.unpack()?.toIntOrNull() - ?: currentSheet?.level - ?: 1 - val strength = editedSheet.strength.unpack()?.toIntOrNull() - ?: currentSheet?.strength - ?: 0 - val dexterity = editedSheet.dexterity.unpack()?.toIntOrNull() - ?: currentSheet?.dexterity - ?: 0 - val constitution = editedSheet.constitution.unpack()?.toIntOrNull() - ?: currentSheet?.constitution - ?: 0 - val height = editedSheet.height.unpack()?.toIntOrNull() - ?: currentSheet?.height - ?: 0 - val intelligence = editedSheet.intelligence.unpack()?.toIntOrNull() - ?: currentSheet?.intelligence - ?: 0 - val power = editedSheet.power.unpack()?.toIntOrNull() - ?: currentSheet?.power - ?: 0 - val charisma = editedSheet.charisma.unpack()?.toIntOrNull() - ?: currentSheet?.charisma - ?: 0 - - return CharacterSheet( - id = editedSheet.id.value, - name = editedSheet.name.value.value, - job = "", - portrait = editedSheet.portrait.value.value, - thumbnail = editedSheet.thumbnail.value.value, - externalLink = "", - level = level, - shouldLevelUp = editedSheet.levelUp.checked.value, - strength = strength, - dexterity = dexterity, - constitution = constitution, - height = height, - intelligence = intelligence, - power = power, - charisma = charisma, - damage = currentSheet?.damage ?: 0, - fatigue = currentSheet?.fatigue ?: 0, - diminished = currentSheet?.diminished ?: 0, - alterations = currentSheet?.alterations ?: emptyList(), - commonSkills = editedSheet.commonSkills.map { editedSkill -> - val currentSkill = currentSheet?.commonSkills?.firstOrNull { - it.id == editedSkill.id - } - CharacterSheet.Skill( - id = editedSkill.id, - label = editedSkill.label, - description = currentSkill?.description - ?: commonSkillDescription(skillId = editedSkill.id), - base = currentSkill?.base - ?: commonSkillBase(skillId = editedSkill.id), - bonus = editedSkill.bonus.value.value.takeIf { it.isNotBlank() }, - level = editedSkill.level.value.value.toIntOrNull() ?: 0, - occupation = editedSkill.option.checked.value, - used = currentSkill?.used ?: false, - ) - }, - specialSkills = editedSheet.specialSkills.map { editedSkill -> - val currentSkill = currentSheet?.specialSkills?.firstOrNull { - it.id == editedSkill.id - } - CharacterSheet.Skill( - id = editedSkill.id, - label = editedSkill.label.value.value, - description = editedSkill.description.value.value, - base = editedSkill.base.value.value, - bonus = editedSkill.bonus.value.value.takeIf { it.isNotBlank() }, - level = editedSkill.level.value.value.toIntOrNull() ?: 0, - occupation = editedSkill.options.occupation, - used = currentSkill?.used ?: false, - ) - }, - magicSkills = editedSheet.magicSkills.map { editedSkill -> - val currentSkill = currentSheet?.magicSkills?.firstOrNull { - it.id == editedSkill.id - } - CharacterSheet.Skill( - id = editedSkill.id, - label = editedSkill.label.value.value, - description = editedSkill.description.value.value, - base = editedSkill.base.value.value, - bonus = editedSkill.bonus.value.value.takeIf { it.isNotBlank() }, - level = editedSkill.level.value.value.toIntOrNull() ?: 0, - occupation = editedSkill.options.occupation, - used = currentSkill?.used ?: false, - ) - }, - actions = editedSheet.actions.map { - CharacterSheet.Roll( - id = it.id, - label = it.label.valueFlow.value, - description = it.description.valueFlow.value, - canBeCritical = it.canBeCritical.checked.value, - default = it.default.valueFlow.value, - special = it.special?.valueFlow?.value, - critical = it.critical?.valueFlow?.value, - ) - }, - tags = emptyList(), - ) - } - - suspend fun convertToUio( - sheet: CharacterSheet?, - onDeleteSkill: (id: String) -> Unit, - ): CharacterSheetEditPageUio { - val str = SimpleFieldUio( - label = getString(Res.string.character_sheet_edit__characteristics__str), - value = skillFieldFactory.createWrapper( - value = sheet?.strength?.toString() ?: "", - placeholder = mutableStateOf("10") - ), - ) - val dex = SimpleFieldUio( - label = getString(Res.string.character_sheet_edit__characteristics__dex), - value = skillFieldFactory.createWrapper( - value = sheet?.dexterity?.toString() ?: "", - placeholder = mutableStateOf("10"), - ), - ) - val con = SimpleFieldUio( - label = getString(Res.string.character_sheet_edit__characteristics__con), - value = skillFieldFactory.createWrapper( - value = sheet?.constitution?.toString() ?: "", - placeholder = mutableStateOf("10"), - ) - ) - val hei = SimpleFieldUio( - label = getString(Res.string.character_sheet_edit__characteristics__hei), - value = skillFieldFactory.createWrapper( - value = sheet?.height?.toString() ?: "", - placeholder = mutableStateOf("10"), - ) - ) - val int = SimpleFieldUio( - label = getString(Res.string.character_sheet_edit__characteristics__int), - value = skillFieldFactory.createWrapper( - value = sheet?.intelligence?.toString() ?: "", - placeholder = mutableStateOf("10"), - ) - ) - val pow = SimpleFieldUio( - label = getString(Res.string.character_sheet_edit__characteristics__pow), - value = skillFieldFactory.createWrapper( - value = sheet?.power?.toString() ?: "", - placeholder = mutableStateOf("10"), - ) - ) - val cha = SimpleFieldUio( - label = getString(Res.string.character_sheet_edit__characteristics__cha), - value = skillFieldFactory.createWrapper( - value = sheet?.charisma?.toString() ?: "", - placeholder = mutableStateOf("10"), - ) - ) - - fun str(): Int = str.unpack()?.toIntOrNull() ?: 0 - fun dex(): Int = dex.unpack()?.toIntOrNull() ?: 0 - fun con(): Int = con.unpack()?.toIntOrNull() ?: 0 - fun hei(): Int = hei.unpack()?.toIntOrNull() ?: 0 - fun int(): Int = int.unpack()?.toIntOrNull() ?: 0 - fun pow(): Int = pow.unpack()?.toIntOrNull() ?: 0 - fun cha(): Int = cha.unpack()?.toIntOrNull() ?: 0 - - val specialSkillsLabel = getString(Res.string.character_sheet_edit__skills__special_title) - val magicSkillsLabel = getString(Res.string.character_sheet_edit__skills__magic_title) - val portrait = mutableStateOf(sheet?.portrait ?: "") - val thumbnail = mutableStateOf(sheet?.thumbnail ?: "") - - return with(characterSheetUseCase) { - val name = skillFieldFactory.createWrapper( - label = mutableStateOf(getString(Res.string.character_sheet_edit__name_label)), - value = sheet?.name ?: "" - ) - CharacterSheetEditPageUio( - id = derivedStateOf { - sheet?.id ?: name.value.value.unAccent().replace(" ", "_") - }, - levelUp = createLevelUpWrapper(shouldLevelUp = sheet?.shouldLevelUp ?: false), - name = name, - level = SimpleFieldUio( - label = getString(Res.string.character_sheet_edit__characteristics__level), - value = skillFieldFactory.createWrapper( - value = sheet?.level?.toString() ?: "", - placeholder = mutableStateOf("1"), - ) - ), - portrait = TextFieldWrapperUio( - enable = true, - label = mutableStateOf(getString(Res.string.character_sheet_edit__characteristics__portrait)), - value = portrait, - placeholder = mutableStateOf(null), - onValueChange = { portrait.value = it }, - ), - thumbnail = TextFieldWrapperUio( - enable = true, - label = mutableStateOf(getString(Res.string.character_sheet_edit__characteristics__thumbnail)), - value = thumbnail, - placeholder = mutableStateOf(null), - onValueChange = { thumbnail.value = it }, - ), - strength = str, - dexterity = dex, - constitution = con, - height = hei, - intelligence = int, - power = pow, - charisma = cha, - commonSkills = listOf( - createBaseSkill( - sheet = sheet, - id = CharacterSheet.CommonSkillId.COMBAT_ID, - label = getString(Res.string.character_sheet_edit__skills__combat_label), - description = getString(Res.string.character_sheet_edit__skills__combat_description), - base = derivedStateOf { normalize(dex() * 2) }, - ), - createBaseSkill( - sheet = sheet, - id = CharacterSheet.CommonSkillId.DODGE_ID, - label = getString(Res.string.character_sheet_edit__skills__dodge_label), - description = getString(Res.string.character_sheet_edit__skills__dodge_description), - base = derivedStateOf { normalize(dex() * 2) }, - ), - createBaseSkill( - sheet = sheet, - id = CharacterSheet.CommonSkillId.GRAB_ID, - label = getString(Res.string.character_sheet_edit__skills__grab_label), - description = getString(Res.string.character_sheet_edit__skills__grab_description), - base = derivedStateOf { normalize(str() + hei()) }, - ), - createBaseSkill( - sheet = sheet, - id = CharacterSheet.CommonSkillId.THROW_ID, - label = getString(Res.string.character_sheet_edit__skills__throw_label), - description = getString(Res.string.character_sheet_edit__skills__throw_description), - base = derivedStateOf { normalize(str() + dex()) }, - ), - createBaseSkill( - sheet = sheet, - id = CharacterSheet.CommonSkillId.ATHLETICS_ID, - label = getString(Res.string.character_sheet_edit__skills__athletics_label), - description = getString(Res.string.character_sheet_edit__skills__athletics_description), - base = derivedStateOf { normalize(str() + con() * 2) }, - ), - createBaseSkill( - sheet = sheet, - id = CharacterSheet.CommonSkillId.ACROBATICS_ID, - label = getString(Res.string.character_sheet_edit__skills__acrobatics_label), - description = getString(Res.string.character_sheet_edit__skills__acrobatics_description), - base = derivedStateOf { normalize(dex() + con() * 2) }, - ), - createBaseSkill( - sheet = sheet, - id = CharacterSheet.CommonSkillId.PERCEPTION_ID, - label = getString(Res.string.character_sheet_edit__skills__perception_label), - description = getString(Res.string.character_sheet_edit__skills__perception_description), - base = derivedStateOf { normalize(10 + int() * 2) }, - ), - createBaseSkill( - sheet = sheet, - id = CharacterSheet.CommonSkillId.SEARCH_ID, - label = getString(Res.string.character_sheet_edit__skills__search_label), - description = getString(Res.string.character_sheet_edit__skills__search_description), - base = derivedStateOf { normalize(10 + int() * 2) }, - ), - createBaseSkill( - sheet = sheet, - id = CharacterSheet.CommonSkillId.EMPATHY_ID, - label = getString(Res.string.character_sheet_edit__skills__empathy_label), - description = getString(Res.string.character_sheet_edit__skills__empathy_description), - base = derivedStateOf { normalize(cha() + int()) }, - ), - createBaseSkill( - sheet = sheet, - id = CharacterSheet.CommonSkillId.PERSUASION_ID, - label = getString(Res.string.character_sheet_edit__skills__persuasion_label), - description = getString(Res.string.character_sheet_edit__skills__persuasion_description), - base = derivedStateOf { normalize(cha() * 3) }, - ), - createBaseSkill( - sheet = sheet, - id = CharacterSheet.CommonSkillId.INTIMIDATION_ID, - label = getString(Res.string.character_sheet_edit__skills__intimidation_label), - description = getString(Res.string.character_sheet_edit__skills__intimidation_description), - base = derivedStateOf { normalize(cha() + max(pow(), hei()) * 2) }, - ), - createBaseSkill( - sheet = sheet, - id = CharacterSheet.CommonSkillId.SPIEL_ID, - label = getString(Res.string.character_sheet_edit__skills__spiel_label), - description = getString(Res.string.character_sheet_edit__skills__spiel_description), - base = derivedStateOf { normalize(cha() * 2 + int()) }, - ), - createBaseSkill( - sheet = sheet, - id = CharacterSheet.CommonSkillId.BARGAIN_ID, - label = getString(Res.string.character_sheet_edit__skills__bargain_label), - description = getString(Res.string.character_sheet_edit__skills__bargain_description), - base = derivedStateOf { normalize(cha() * 2) }, - ), - createBaseSkill( - sheet = sheet, - id = CharacterSheet.CommonSkillId.DISCRETION_ID, - label = getString(Res.string.character_sheet_edit__skills__discretion_label), - description = getString(Res.string.character_sheet_edit__skills__discretion_description), - base = derivedStateOf { normalize(cha() + dex() * 2 - hei()) }, - ), - createBaseSkill( - sheet = sheet, - id = CharacterSheet.CommonSkillId.SLEIGHT_OF_HAND_ID, - label = getString(Res.string.character_sheet_edit__skills__sleight_of_hand_label), - description = getString(Res.string.character_sheet_edit__skills__sleight_of_hand_description), - base = derivedStateOf { normalize(dex() * 2) }, - ), - createBaseSkill( - sheet = sheet, - id = CharacterSheet.CommonSkillId.AID_ID, - label = getString(Res.string.character_sheet_edit__skills__aid_label), - description = getString(Res.string.character_sheet_edit__skills__aid_description), - base = derivedStateOf { normalize(int() + dex()) }, - ), - ), - specialSkills = sheet?.specialSkills?.map { skill -> - skillFieldFactory.createSkill( - id = skill.id, - label = specialSkillsLabel, - descriptionValue = skill.description ?: "", - labelValue = skill.label, - baseValue = skill.base, - bonusValue = skill.bonus ?: "", - levelValue = skill.level.takeIf { it > 0 }?.toString() ?: "", - options = run { - val current = sheet.specialSkills.firstOrNull { it.id == skill.id } - listOf( - skillFieldFactory.occupationOption(current?.occupation ?: false), - skillFieldFactory.deleteOption { onDeleteSkill(skill.id) }, - ) - }, - ) - } ?: emptyList(), - magicSkills = sheet?.magicSkills?.map { skill -> - skillFieldFactory.createSkill( - id = skill.id, - label = magicSkillsLabel, - descriptionValue = skill.description ?: "", - labelValue = skill.label, - baseValue = skill.base, - bonusValue = skill.bonus ?: "", - levelValue = skill.level.takeIf { it > 0 }?.toString() ?: "", - options = run { - val current = sheet.magicSkills.firstOrNull { it.id == skill.id } - listOf( - skillFieldFactory.occupationOption( - checked = current?.occupation ?: false - ), - skillFieldFactory.deleteOption { onDeleteSkill(skill.id) }, - ) - }, - ) - } ?: emptyList(), - actions = sheet?.actions?.map { action -> - ActionFieldUio( - id = action.id, - label = createLwaTextFieldFlow( - label = getString(Res.string.character_sheet_edit__actions__name_label), - value = action.label, - ).createLwaTextField(), - description = createLwaTextFieldFlow( - label = getString(Res.string.character_sheet_edit__actions__description_label), - value = action.description ?: "", - ).createLwaTextField(), - canBeCritical = createLwaBox( - checked = action.canBeCritical, - ), - default = createLwaTextFieldFlow( - label = getString(Res.string.character_sheet_edit__actions__default_action_label), - value = action.default, - ).createLwaTextField(), - special = createLwaTextFieldFlow( - label = getString(Res.string.character_sheet_edit__actions__spacial_action_label), - value = action.special ?: "", - ).createLwaTextField(), - critical = createLwaTextFieldFlow( - label = getString(Res.string.character_sheet_edit__actions__critical_action_label), - value = action.critical ?: "", - ).createLwaTextField(), - option = skillFieldFactory.deleteOption { onDeleteSkill(action.id) }, - ) - } ?: emptyList(), - ) - } - } - - fun createLwaBox( - enable: Boolean = true, - checked: Boolean, - ): LwaCheckBoxUio { - val checkedFlow = MutableStateFlow(checked) - - return LwaCheckBoxUio( - enable = enable, - checked = checkedFlow, - onCheckedChange = { checkedFlow.value = it }, - ) - } - - private suspend fun createLevelUpWrapper( - shouldLevelUp: Boolean, - ): LevelUpWrapperUio { - val field = mutableStateOf(shouldLevelUp) - return LevelUpWrapperUio( - label = getString(Res.string.character_sheet_edit__level_up), - checked = field, - onCheck = { field.value = it }, - ) - } - - private suspend fun createBaseSkill( - sheet: CharacterSheet?, - id: String, - label: String, - description: String, - base: State, - ): BaseSkillFieldUio { - val skill = sheet?.commonSkills?.firstOrNull { it.id == id } - - return BaseSkillFieldUio( - id = id, - label = label, - base = base, - bonus = skillFieldFactory.createWrapper( - label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__bonus_label)), - value = skill?.bonus ?: "", - ), - level = skillFieldFactory.createWrapper( - label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__level_label)), - value = skill?.level?.takeIf { it > 0 }?.toString() ?: "", - ), - option = skillFieldFactory.occupationOption(skill?.occupation ?: false), - tooltip = BasicTooltipUio( - title = label, - description = description, - ) - ) - } - - private fun SimpleFieldUio.unpack(): String? { - return value.value.value.ifBlank { value.placeholder.value } - } - - private suspend fun commonSkillBase(skillId: String): String { - return when (skillId) { - CharacterSheet.CommonSkillId.COMBAT_ID -> getString(Res.string.character_sheet_edit__skills__combat_base) - CharacterSheet.CommonSkillId.DODGE_ID -> getString(Res.string.character_sheet_edit__skills__dodge_base) - CharacterSheet.CommonSkillId.GRAB_ID -> getString(Res.string.character_sheet_edit__skills__grab_base) - CharacterSheet.CommonSkillId.THROW_ID -> getString(Res.string.character_sheet_edit__skills__throw_base) - CharacterSheet.CommonSkillId.ATHLETICS_ID -> getString(Res.string.character_sheet_edit__skills__athletics_base) - CharacterSheet.CommonSkillId.ACROBATICS_ID -> getString(Res.string.character_sheet_edit__skills__acrobatics_base) - CharacterSheet.CommonSkillId.PERCEPTION_ID -> getString(Res.string.character_sheet_edit__skills__perception_base) - CharacterSheet.CommonSkillId.SEARCH_ID -> getString(Res.string.character_sheet_edit__skills__search_base) - CharacterSheet.CommonSkillId.EMPATHY_ID -> getString(Res.string.character_sheet_edit__skills__empathy_base) - CharacterSheet.CommonSkillId.PERSUASION_ID -> getString(Res.string.character_sheet_edit__skills__persuasion_base) - CharacterSheet.CommonSkillId.INTIMIDATION_ID -> getString(Res.string.character_sheet_edit__skills__intimidation_base) - CharacterSheet.CommonSkillId.SPIEL_ID -> getString(Res.string.character_sheet_edit__skills__spiel_base) - CharacterSheet.CommonSkillId.BARGAIN_ID -> getString(Res.string.character_sheet_edit__skills__bargain_base) - CharacterSheet.CommonSkillId.DISCRETION_ID -> getString(Res.string.character_sheet_edit__skills__discretion_base) - CharacterSheet.CommonSkillId.SLEIGHT_OF_HAND_ID -> getString(Res.string.character_sheet_edit__skills__sleight_of_hand_base) - CharacterSheet.CommonSkillId.AID_ID -> getString(Res.string.character_sheet_edit__skills__aid_base) - else -> "" - } - } - - private suspend fun commonSkillLabel(skillId: String): String { - return when (skillId) { - CharacterSheet.CommonSkillId.COMBAT_ID -> getString(Res.string.character_sheet_edit__skills__combat_label) - CharacterSheet.CommonSkillId.DODGE_ID -> getString(Res.string.character_sheet_edit__skills__dodge_label) - CharacterSheet.CommonSkillId.GRAB_ID -> getString(Res.string.character_sheet_edit__skills__grab_label) - CharacterSheet.CommonSkillId.THROW_ID -> getString(Res.string.character_sheet_edit__skills__throw_label) - CharacterSheet.CommonSkillId.ATHLETICS_ID -> getString(Res.string.character_sheet_edit__skills__athletics_label) - CharacterSheet.CommonSkillId.ACROBATICS_ID -> getString(Res.string.character_sheet_edit__skills__acrobatics_label) - CharacterSheet.CommonSkillId.PERCEPTION_ID -> getString(Res.string.character_sheet_edit__skills__perception_label) - CharacterSheet.CommonSkillId.SEARCH_ID -> getString(Res.string.character_sheet_edit__skills__search_label) - CharacterSheet.CommonSkillId.EMPATHY_ID -> getString(Res.string.character_sheet_edit__skills__empathy_label) - CharacterSheet.CommonSkillId.PERSUASION_ID -> getString(Res.string.character_sheet_edit__skills__persuasion_label) - CharacterSheet.CommonSkillId.INTIMIDATION_ID -> getString(Res.string.character_sheet_edit__skills__intimidation_label) - CharacterSheet.CommonSkillId.SPIEL_ID -> getString(Res.string.character_sheet_edit__skills__spiel_label) - CharacterSheet.CommonSkillId.BARGAIN_ID -> getString(Res.string.character_sheet_edit__skills__bargain_label) - CharacterSheet.CommonSkillId.DISCRETION_ID -> getString(Res.string.character_sheet_edit__skills__discretion_label) - CharacterSheet.CommonSkillId.SLEIGHT_OF_HAND_ID -> getString(Res.string.character_sheet_edit__skills__sleight_of_hand_label) - CharacterSheet.CommonSkillId.AID_ID -> getString(Res.string.character_sheet_edit__skills__aid_label) - else -> "" - } - } - - private suspend fun commonSkillDescription(skillId: String): String { - return when (skillId) { - CharacterSheet.CommonSkillId.COMBAT_ID -> getString(Res.string.character_sheet_edit__skills__combat_description) - CharacterSheet.CommonSkillId.DODGE_ID -> getString(Res.string.character_sheet_edit__skills__dodge_description) - CharacterSheet.CommonSkillId.GRAB_ID -> getString(Res.string.character_sheet_edit__skills__grab_description) - CharacterSheet.CommonSkillId.THROW_ID -> getString(Res.string.character_sheet_edit__skills__throw_description) - CharacterSheet.CommonSkillId.ATHLETICS_ID -> getString(Res.string.character_sheet_edit__skills__athletics_description) - CharacterSheet.CommonSkillId.ACROBATICS_ID -> getString(Res.string.character_sheet_edit__skills__acrobatics_description) - CharacterSheet.CommonSkillId.PERCEPTION_ID -> getString(Res.string.character_sheet_edit__skills__perception_description) - CharacterSheet.CommonSkillId.SEARCH_ID -> getString(Res.string.character_sheet_edit__skills__search_description) - CharacterSheet.CommonSkillId.EMPATHY_ID -> getString(Res.string.character_sheet_edit__skills__empathy_description) - CharacterSheet.CommonSkillId.PERSUASION_ID -> getString(Res.string.character_sheet_edit__skills__persuasion_description) - CharacterSheet.CommonSkillId.INTIMIDATION_ID -> getString(Res.string.character_sheet_edit__skills__intimidation_description) - CharacterSheet.CommonSkillId.SPIEL_ID -> getString(Res.string.character_sheet_edit__skills__spiel_description) - CharacterSheet.CommonSkillId.BARGAIN_ID -> getString(Res.string.character_sheet_edit__skills__bargain_description) - CharacterSheet.CommonSkillId.DISCRETION_ID -> getString(Res.string.character_sheet_edit__skills__discretion_description) - CharacterSheet.CommonSkillId.SLEIGHT_OF_HAND_ID -> getString(Res.string.character_sheet_edit__skills__sleight_of_hand_description) - CharacterSheet.CommonSkillId.AID_ID -> getString(Res.string.character_sheet_edit__skills__aid_description) - else -> "" - } - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditPage.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditPage.kt deleted file mode 100644 index 788ac5f..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditPage.kt +++ /dev/null @@ -1,477 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.edit - -import androidx.compose.animation.animateContentSize -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.offset -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.text.selection.SelectionContainer -import androidx.compose.foundation.verticalScroll -import androidx.compose.material.Icon -import androidx.compose.material.IconButton -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Scaffold -import androidx.compose.material.Surface -import androidx.compose.material.Text -import androidx.compose.material.TextButton -import androidx.compose.material.TopAppBar -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Add -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.runtime.State -import androidx.compose.runtime.rememberCoroutineScope -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import com.pixelized.desktop.lwa.LocalWindowController -import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox -import com.pixelized.desktop.lwa.ui.navigation.screen.LocalScreenController -import com.pixelized.desktop.lwa.ui.navigation.window.LocalWindow -import com.pixelized.desktop.lwa.ui.screen.characterSheet.copy.CharacterSheetCopyDialog -import com.pixelized.desktop.lwa.ui.screen.characterSheet.delete.CharacterSheetDeleteDialog -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.ActionField -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.ActionFieldUio -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.BaseSkillFieldUio -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.BaseSkillForm -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.LevelUpField -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.LevelUpWrapperUio -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.SimpleField -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.SimpleFieldUio -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.SkillFieldUio -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.SkillForm -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.textfield.TextFieldWrapper -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.textfield.TextFieldWrapperUio -import com.pixelized.desktop.lwa.ui.theme.lwa -import kotlinx.coroutines.launch -import lwacharactersheet.composeapp.generated.resources.Res -import lwacharactersheet.composeapp.generated.resources.character_sheet__skills__common_title -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_edit__add_roll_action -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__title -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__save_action -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.ic_delete_forever_24dp -import lwacharactersheet.composeapp.generated.resources.ic_save_24dp -import lwacharactersheet.composeapp.generated.resources.ic_save_as_24dp -import org.jetbrains.compose.resources.painterResource -import org.jetbrains.compose.resources.stringResource -import org.koin.compose.viewmodel.koinViewModel - -@Stable -data class CharacterSheetEditPageUio( - val id: State, - val levelUp: LevelUpWrapperUio, - val name: TextFieldWrapperUio, - val level: SimpleFieldUio, - val portrait: TextFieldWrapperUio, - val thumbnail: TextFieldWrapperUio, - val strength: SimpleFieldUio, - val dexterity: SimpleFieldUio, - val constitution: SimpleFieldUio, - val height: SimpleFieldUio, - val intelligence: SimpleFieldUio, - val power: SimpleFieldUio, - val charisma: SimpleFieldUio, - val commonSkills: List, - val specialSkills: List, - val magicSkills: List, - val actions: List, -) { - val characteristics - get() = listOf( - strength, - dexterity, - constitution, - height, - intelligence, - power, - charisma, - ) -} - -@Composable -fun CharacterSheetEditPage( - viewModel: CharacterSheetEditViewModel = koinViewModel(), -) { - val windowController = LocalWindowController.current - val window = LocalWindow.current - val screen = LocalScreenController.current - val scope = rememberCoroutineScope() - - Surface( - modifier = Modifier.fillMaxSize(), - ) { - CharacterSheetEdit( - title = window.title, - form = viewModel.characterSheet.value, - onNewSpecialSkill = { - scope.launch { - viewModel.onNewSpecialSkill() - } - }, - onNewMagicSkill = { - scope.launch { - viewModel.onNewMagicSkill() - } - }, - onNewAction = { - scope.launch { - viewModel.onNewAction() - } - }, - onDelete = { - scope.launch { - viewModel.showDeleteCharacterSheetDialog() - } - }, - onCopy = { - scope.launch { - viewModel.showCopyCharacterSheetDialog() - } - }, - onSave = { - scope.launch { - viewModel.save() - if (screen.popBackStack().not()) { - windowController.hideWindow(window = window) - } - } - }, - ) - } - - CharacterSheetCopyDialog( - dialog = viewModel.copyCharacterSheetDialog, - onConfirm = { dialog -> - scope.launch { - val characterSheetId = dialog.value.valueFlow.value - viewModel.saveAs(characterSheetId = characterSheetId) - if (screen.popBackStack().not()) { - windowController.hideWindow(window = window) - } - } - }, - onDismissRequest = { - viewModel.hideCopyCharacterSheetDialog() - } - ) - - CharacterSheetDeleteDialog( - dialog = viewModel.deleteCharacterSheetDialog, - onConfirm = { dialog -> - scope.launch { - viewModel.delete(characterSheetId = dialog.characterSheetId) - if (screen.popBackStack().not()) { - windowController.hideWindow(window = window) - } - } - }, - onDismissRequest = { - viewModel.hideDeleteCharacterSheetDialog() - } - ) -} - -@Composable -fun CharacterSheetEdit( - modifier: Modifier = Modifier, - title: String, - form: CharacterSheetEditPageUio, - onNewSpecialSkill: () -> Unit, - onNewMagicSkill: () -> Unit, - onNewAction: () -> Unit, - onDelete: () -> Unit, - onCopy: () -> Unit, - onSave: () -> Unit, -) { - Scaffold( - modifier = modifier, - topBar = { - TopAppBar( - title = { - Text( - overflow = TextOverflow.Ellipsis, - maxLines = 1, - text = title, - ) - }, - actions = { - IconButton( - onClick = onDelete, - ) { - Icon( - painter = painterResource(Res.drawable.ic_delete_forever_24dp), - tint = MaterialTheme.colors.primary, - contentDescription = null, - ) - } - IconButton( - onClick = onCopy, - ) { - Icon( - painter = painterResource(Res.drawable.ic_save_as_24dp), - tint = MaterialTheme.colors.primary, - contentDescription = null, - ) - } - IconButton( - onClick = onSave, - ) { - Icon( - painter = painterResource(Res.drawable.ic_save_24dp), - tint = MaterialTheme.colors.primary, - contentDescription = null, - ) - } - }, - ) - }, - content = { paddingValues -> - Column( - modifier = Modifier - .verticalScroll(state = rememberScrollState()) - .padding(paddingValues = paddingValues) - .padding(all = 16.dp), - verticalArrangement = Arrangement.spacedBy(space = 16.dp) - ) { - Row( - modifier = Modifier.fillMaxWidth(), - ) { - Text( - style = MaterialTheme.lwa.typography.system.caption, - text = "id : " - ) - SelectionContainer { - Text( - style = MaterialTheme.lwa.typography.system.caption, - text = form.id.value, - ) - } - } - - TextFieldWrapper( - modifier = Modifier.fillMaxWidth(), - wrapper = form.name, - ) - - TextFieldWrapper( - modifier = Modifier.fillMaxWidth(), - wrapper = form.portrait, - ) - - TextFieldWrapper( - modifier = Modifier.fillMaxWidth(), - wrapper = form.thumbnail, - ) - - Row( - verticalAlignment = Alignment.CenterVertically, - ) { - LevelUpField( - modifier = Modifier.weight(1f).offset(y = 4.dp), - field = form.levelUp, - ) - SimpleField( - modifier = Modifier.weight(2f), - field = form.level, - ) - } - - Row( - horizontalArrangement = Arrangement.spacedBy(space = 16.dp) - ) { - DecoratedBox( - modifier = Modifier.weight(weight = 1f), - ) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Text( - modifier = Modifier.padding(vertical = 8.dp), - overflow = TextOverflow.Ellipsis, - maxLines = 1, - style = MaterialTheme.typography.caption, - text = stringResource(Res.string.character_sheet_edit__characteristics__title), - ) - form.characteristics.forEach { - SimpleField( - modifier = Modifier.fillMaxWidth(), - field = it, - ) - } - } - } - } - - DecoratedBox( - modifier = Modifier - .fillMaxWidth() - .animateContentSize(), - ) { - Column( - modifier = Modifier.fillMaxWidth(), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - Text( - modifier = Modifier.padding(vertical = 8.dp), - overflow = TextOverflow.Ellipsis, - maxLines = 1, - style = MaterialTheme.typography.caption, - text = stringResource(Res.string.character_sheet__skills__common_title), - ) - form.commonSkills.forEach { - BaseSkillForm( - modifier = Modifier - .fillMaxWidth() - .padding(end = 4.dp), - field = it, - ) - } - } - } - - DecoratedBox( - modifier = Modifier - .fillMaxWidth() - .animateContentSize(), - ) { - Column( - modifier = Modifier.fillMaxWidth(), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(space = 16.dp), - ) { - Text( - modifier = Modifier.padding(vertical = 8.dp), - overflow = TextOverflow.Ellipsis, - maxLines = 1, - style = MaterialTheme.typography.caption, - text = stringResource(Res.string.character_sheet__skills__special_title), - ) - form.specialSkills.forEach { - SkillForm( - modifier = Modifier - .fillMaxWidth() - .padding(end = 4.dp), - field = it, - ) - } - TextButton( - modifier = Modifier.align(alignment = Alignment.End), - onClick = onNewSpecialSkill, - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(space = 4.dp), - ) { - Text( - overflow = TextOverflow.Ellipsis, - maxLines = 1, - text = stringResource(Res.string.character_sheet_edit__skills__special_action), - ) - Icon( - imageVector = Icons.Default.Add, - contentDescription = null, - ) - } - } - } - } - - DecoratedBox( - modifier = Modifier - .fillMaxWidth() - .animateContentSize(), - ) { - Column( - modifier = Modifier.fillMaxWidth(), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(space = 16.dp), - ) { - Text( - modifier = Modifier.padding(vertical = 8.dp), - overflow = TextOverflow.Ellipsis, - maxLines = 1, - style = MaterialTheme.typography.caption, - text = stringResource(Res.string.character_sheet__skills__magic_title), - ) - form.magicSkills.forEach { - SkillForm( - modifier = Modifier - .fillMaxWidth() - .padding(end = 4.dp), - field = it, - ) - } - TextButton( - modifier = Modifier.align(alignment = Alignment.End), - onClick = onNewMagicSkill, - ) { - Row( - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(space = 4.dp), - ) { - Text( - overflow = TextOverflow.Ellipsis, - maxLines = 1, - text = stringResource(Res.string.character_sheet_edit__skills__magic_action), - ) - Icon( - imageVector = Icons.Default.Add, - contentDescription = null, - ) - } - } - } - } - - Column( - modifier = Modifier - .fillMaxWidth() - .animateContentSize(), - ) { - form.actions.forEach { - ActionField( - modifier = Modifier - .fillMaxWidth() - .padding(end = 6.dp, bottom = 16.dp), - action = it, - ) - } - TextButton( - modifier = Modifier.align(alignment = Alignment.End), - onClick = onNewAction, - ) { - Text( - overflow = TextOverflow.Ellipsis, - maxLines = 1, - text = stringResource(Res.string.character_sheet_edit__add_roll_action) - ) - } - } - - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.End, - ) { - TextButton( - onClick = onSave, - ) { - Text( - overflow = TextOverflow.Ellipsis, - maxLines = 1, - text = stringResource(Res.string.character_sheet_edit__save_action), - ) - } - } - } - } - ) -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditViewModel.kt deleted file mode 100644 index 9b7dc49..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/CharacterSheetEditViewModel.kt +++ /dev/null @@ -1,205 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.edit - -import androidx.compose.runtime.State -import androidx.compose.runtime.mutableStateOf -import androidx.lifecycle.SavedStateHandle -import androidx.lifecycle.ViewModel -import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository -import com.pixelized.desktop.lwa.ui.composable.textfield.createLwaTextField -import com.pixelized.desktop.lwa.ui.composable.textfield.createLwaTextFieldFlow -import com.pixelized.desktop.lwa.ui.navigation.screen.destination.CharacterSheetEditDestination -import com.pixelized.desktop.lwa.ui.screen.characterSheet.copy.CharacterSheetCopyDialogUio -import com.pixelized.desktop.lwa.ui.screen.characterSheet.delete.CharacterSheetDeleteDialogUio -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.common.SkillFieldFactory -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.ActionFieldUio -import kotlinx.coroutines.runBlocking -import lwacharactersheet.composeapp.generated.resources.Res -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__critical_action_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__default_action_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__description_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__name_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__spacial_action_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__copy__label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__copy__title -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__magic_title -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__special_title -import org.jetbrains.compose.resources.getString -import java.util.UUID - -class CharacterSheetEditViewModel( - private val characterSheetRepository: CharacterSheetRepository, - private val sheetFactory: CharacterSheetEditFactory, - private val skillFactory: SkillFieldFactory, - savedStateHandle: SavedStateHandle, -) : ViewModel() { - - private val argument = CharacterSheetEditDestination.Argument(savedStateHandle) - - private val copyDialog = mutableStateOf(null) - val copyCharacterSheetDialog: State = copyDialog - - private val deleteDialog = mutableStateOf(null) - val deleteCharacterSheetDialog: State = deleteDialog - - private val _characterSheet = mutableStateOf( - runBlocking { - sheetFactory.convertToUio( - sheet = characterSheetRepository.characterDetail(characterSheetId = argument.id), - onDeleteSkill = ::deleteSkill, - ) - } - ) - val characterSheet: State get() = _characterSheet - - suspend fun showCopyCharacterSheetDialog() { - val idFieldFlow = createLwaTextFieldFlow( - label = getString(Res.string.character_sheet_edit__copy__label), - value = argument.id ?: "", - ) - copyDialog.value = CharacterSheetCopyDialogUio( - label = getString(Res.string.character_sheet_edit__copy__title), - value = idFieldFlow.createLwaTextField(), - validate = { - characterSheetRepository.checkCharacterSheetIdValidity( - characterSheetId = idFieldFlow.valueFlow.value - ).also { - idFieldFlow.errorFlow.value = it.not() - } - } - ) - } - - fun hideCopyCharacterSheetDialog() { - copyDialog.value = null - } - - fun showDeleteCharacterSheetDialog() { - deleteDialog.value = CharacterSheetDeleteDialogUio( - characterSheetId = argument.id ?: "", - name = characterSheet.value.name.value.value, - ) - } - - fun hideDeleteCharacterSheetDialog() { - deleteDialog.value = null - } - - suspend fun onNewSpecialSkill() { - val id = UUID.randomUUID().toString() - val skill = skillFactory.createSkill( - id = id, - label = getString(Res.string.character_sheet_edit__skills__special_title), - options = listOf( - skillFactory.occupationOption(checked = true), - skillFactory.deleteOption { deleteSkill(skillId = id) } - ), - ) - val skills = _characterSheet.value.specialSkills - .toMutableList() - .also { it.add(skill) } - _characterSheet.value = characterSheet.value.copy( - specialSkills = skills, - ) - } - - suspend fun onNewMagicSkill() { - val id = UUID.randomUUID().toString() - val skill = skillFactory.createSkill( - id = id, - label = getString(Res.string.character_sheet_edit__skills__magic_title), - options = listOf( - skillFactory.occupationOption(checked = false), - skillFactory.deleteOption { deleteSkill(skillId = id) } - ), - ) - val skills = _characterSheet.value.magicSkills - .toMutableList() - .also { it.add(skill) } - _characterSheet.value = characterSheet.value.copy( - magicSkills = skills, - ) - } - - suspend fun onNewAction() { - val id = UUID.randomUUID().toString() - val field = ActionFieldUio( - id = id, - label = createLwaTextFieldFlow( - label = getString(Res.string.character_sheet_edit__actions__name_label), - value = "", - ).createLwaTextField(), - description = createLwaTextFieldFlow( - label = getString(Res.string.character_sheet_edit__actions__description_label), - value = "", - ).createLwaTextField(), - canBeCritical = sheetFactory.createLwaBox( - checked = false, - ), - default = createLwaTextFieldFlow( - label = getString(Res.string.character_sheet_edit__actions__default_action_label), - value = "", - ).createLwaTextField(), - special = createLwaTextFieldFlow( - label = getString(Res.string.character_sheet_edit__actions__spacial_action_label), - value = "", - ).createLwaTextField(), - critical = createLwaTextFieldFlow( - label = getString(Res.string.character_sheet_edit__actions__critical_action_label), - value = "", - ).createLwaTextField(), - option = skillFactory.deleteOption { deleteSkill(id) }, - ) - val actions = _characterSheet.value.actions.toMutableList().also { - it.add(field) - } - _characterSheet.value = _characterSheet.value.copy( - actions = actions, - ) - } - - private fun deleteSkill(skillId: String) { - _characterSheet.value = _characterSheet.value.copy( - specialSkills = _characterSheet.value.specialSkills.toMutableList().also { skills -> - skills.removeIf { it.id == skillId } - }, - magicSkills = _characterSheet.value.magicSkills.toMutableList().also { skills -> - skills.removeIf { it.id == skillId } - }, - actions = _characterSheet.value.actions.toMutableList().also { actions -> - actions.removeIf { it.id == skillId } - }, - ) - } - - suspend fun save() { - val updatedSheet = sheetFactory.updateCharacterSheet( - currentSheet = characterSheetRepository.characterDetail(characterSheetId = _characterSheet.value.id.value), - editedSheet = _characterSheet.value, - ) - characterSheetRepository.updateCharacter( - sheet = updatedSheet, - create = argument.id == null, - ) - } - - suspend fun saveAs( - characterSheetId: String, - ) { - val updatedSheet = sheetFactory.updateCharacterSheet( - currentSheet = characterSheetRepository.characterDetail(characterSheetId = _characterSheet.value.id.value), - editedSheet = _characterSheet.value, - ) - characterSheetRepository.updateCharacter( - sheet = updatedSheet.copy(id = characterSheetId), - create = true, - ) - } - - suspend fun delete( - characterSheetId: String, - ) { - characterSheetRepository.deleteCharacter( - characterSheetId = characterSheetId - ) - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/common/SkillFieldFactory.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/common/SkillFieldFactory.kt deleted file mode 100644 index e19d7b8..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/common/SkillFieldFactory.kt +++ /dev/null @@ -1,101 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.common - -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Delete -import androidx.compose.runtime.State -import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.mutableStateOf -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.SkillFieldUio -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.option.ActionOption -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.option.CheckedOption -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.option.OptionUio -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.textfield.TextFieldWrapperUio -import lwacharactersheet.composeapp.generated.resources.Res -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__delete__label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__occupation__label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__base_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__bonus_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__description_label -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__level_label -import org.jetbrains.compose.resources.getString -import java.util.UUID - -class SkillFieldFactory { - - suspend fun createSkill( - id: String = UUID.randomUUID().toString(), - label: String, - labelValue: String = "", - descriptionValue: String = "", - baseValue: String = "", - bonusValue: String = "", - levelValue: String = "", - options: List = emptyList(), - ): SkillFieldUio { - val baseLabel = getString(Res.string.character_sheet_edit__skills__base_label) - return SkillFieldUio( - id = id, - label = createWrapper( - label = mutableStateOf(label), - value = labelValue, - ), - description = createWrapper( - label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__description_label)), - value = descriptionValue, - ), - base = createWrapper( - label = derivedStateOf { - options - .firstOrNull { it is CheckedOption && it.checked.value } - ?.let { "$baseLabel *" } - ?: baseLabel - }, - value = baseValue, - ), - bonus = createWrapper( - label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__bonus_label)), - value = bonusValue, - ), - level = createWrapper( - label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__level_label)), - value = levelValue, - ), - options = options, - ) - } - - fun createWrapper( - enable: Boolean = true, - label: State = mutableStateOf(null), - placeholder: State = mutableStateOf(null), - value: String = "", - ): TextFieldWrapperUio { - val state = mutableStateOf(value) - return TextFieldWrapperUio( - enable = enable, - label = label, - value = state, - placeholder = placeholder, - onValueChange = { state.value = it }, - ) - } - - suspend fun deleteOption(onDelete: () -> Unit) = ActionOption.DeleteOptionUio( - icon = Icons.Default.Delete, - label = getString(Res.string.character_sheet_edit__delete__label), - onOption = onDelete, - ) - - suspend fun occupationOption(checked: Boolean) = mutableStateOf(checked).let { state -> - CheckedOption.OccupationOption( - checked = state, - label = getString(Res.string.character_sheet_edit__occupation__label), - onOption = { state.value = state.value.not() }, - ) - } -} - -val List.occupation: Boolean - get() = this.firstNotNullOfOrNull { - if (it is CheckedOption.OccupationOption) it.checked.value else null - } ?: false \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/ActionField.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/ActionField.kt deleted file mode 100644 index 6f6cfae..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/ActionField.kt +++ /dev/null @@ -1,118 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable - -import androidx.compose.animation.animateContentSize -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.material.DropdownMenu -import androidx.compose.material.Icon -import androidx.compose.material.IconButton -import androidx.compose.material.MaterialTheme -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.MoreVert -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import com.pixelized.desktop.lwa.ui.composable.checkbox.LwaCheckBox -import com.pixelized.desktop.lwa.ui.composable.checkbox.LwaCheckBoxUio -import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextField -import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextFieldUio -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.option.ActionOption -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.option.DropDownActionMenuItem - -@Stable -data class ActionFieldUio( - val id: String, - val label: LwaTextFieldUio, - val description: LwaTextFieldUio, - val canBeCritical: LwaCheckBoxUio, - val default: LwaTextFieldUio, - val special: LwaTextFieldUio?, - val critical: LwaTextFieldUio?, - val option: ActionOption.DeleteOptionUio, -) - -@Composable -fun ActionField( - modifier: Modifier = Modifier, - space: Dp = 4.dp, - action: ActionFieldUio, -) { - val showMenu = remember { mutableStateOf(false) } - val canBeCritical = action.canBeCritical.checked.collectAsState() - - Column( - modifier = modifier, - verticalArrangement = Arrangement.spacedBy(space = space), - ) { - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(space = space), - verticalAlignment = Alignment.CenterVertically, - ) { - LwaTextField( - modifier = Modifier.weight(1f), - field = action.label, - ) - LwaCheckBox( - field = action.canBeCritical, - ) - IconButton( - onClick = { showMenu.value = showMenu.value.not() }, - ) { - Icon( - imageVector = Icons.Default.MoreVert, - tint = MaterialTheme.colors.primary, - contentDescription = null, - ) - DropdownMenu( - expanded = showMenu.value, - onDismissRequest = { showMenu.value = false } - ) { - DropDownActionMenuItem( - wrapper = action.option, - onClick = { - showMenu.value = false - action.option.onOption() - } - ) - } - } - } - Row( - modifier = Modifier.fillMaxWidth().animateContentSize(), - horizontalArrangement = Arrangement.spacedBy(space = space), - ) { - LwaTextField( - modifier = Modifier.weight(1f), - field = action.default, - ) - if (canBeCritical.value) { - action.special?.let { field -> - LwaTextField( - modifier = Modifier.weight(1f), - field = field, - ) - } - action.critical?.let { field -> - LwaTextField( - modifier = Modifier.weight(1f), - field = field, - ) - } - } - } - LwaTextField( - modifier = Modifier.fillMaxWidth(), - singleLine = false, - field = action.description, - ) - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/BaseSkillField.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/BaseSkillField.kt deleted file mode 100644 index 4831030..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/BaseSkillField.kt +++ /dev/null @@ -1,137 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable - -import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.material.ContentAlpha -import androidx.compose.material.DropdownMenu -import androidx.compose.material.Icon -import androidx.compose.material.IconButton -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.MoreVert -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.runtime.State -import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import com.pixelized.desktop.lwa.ui.composable.tooltip.BasicTooltipLayout -import com.pixelized.desktop.lwa.ui.composable.tooltip.BasicTooltipUio -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.option.CheckedOption -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.option.DropDownCheckedMenuItem -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.textfield.TextFieldWrapper -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.textfield.TextFieldWrapperUio -import lwacharactersheet.composeapp.generated.resources.Res -import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__base_label -import org.jetbrains.compose.resources.stringResource - -@Stable -class BaseSkillFieldUio( - val id: String, - val label: String, - val base: State, - val bonus: TextFieldWrapperUio, - val level: TextFieldWrapperUio, - val option: CheckedOption, - val tooltip: BasicTooltipUio, -) - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun BaseSkillForm( - modifier: Modifier = Modifier, - field: BaseSkillFieldUio, -) { - val showMenu = remember { mutableStateOf(false) } - val baseLabel = stringResource(Res.string.character_sheet_edit__skills__base_label) - .let { label -> - remember { - derivedStateOf { - when (field.option.checked.value) { - true -> "$label *" - else -> label - } - } - } - } - - Row( - modifier = modifier, - horizontalArrangement = Arrangement.spacedBy(space = 4.dp, alignment = Alignment.End), - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - modifier = Modifier - .weight(1f) - .padding(start = 16.dp, bottom = 12.dp) - .align(alignment = Alignment.Bottom), - style = MaterialTheme.typography.body1, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - text = field.label, - ) - BasicTooltipLayout( - modifier = Modifier - .width(width = 96.dp) - .padding(start = 16.dp), - tooltip = field.tooltip, - ) { - Column { - Text( - style = MaterialTheme.typography.caption, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - color = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium), - text = baseLabel.value, - ) - Text( - style = MaterialTheme.typography.body1, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - text = "+${field.base.value}", - ) - } - } - TextFieldWrapper( - modifier = Modifier.width(width = 96.dp), - wrapper = field.bonus, - ) - TextFieldWrapper( - modifier = Modifier.width(width = 96.dp), - wrapper = field.level, - ) - Box { - IconButton( - onClick = { showMenu.value = showMenu.value.not() }, - ) { - Icon( - imageVector = Icons.Default.MoreVert, - tint = MaterialTheme.colors.primary, - contentDescription = null, - ) - } - DropdownMenu( - expanded = showMenu.value, - onDismissRequest = { showMenu.value = false } - ) { - DropDownCheckedMenuItem( - wrapper = field.option, - onClick = { - showMenu.value = false - field.option.onOption() - } - ) - } - } - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/LevelUpField.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/LevelUpField.kt deleted file mode 100644 index a97cd55..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/LevelUpField.kt +++ /dev/null @@ -1,41 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable - -import androidx.compose.foundation.layout.Row -import androidx.compose.material.Checkbox -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.runtime.State -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import com.pixelized.desktop.lwa.ui.theme.color.component.LwaCheckboxColors -import com.pixelized.desktop.lwa.ui.theme.lwa - -@Stable -class LevelUpWrapperUio( - val label: String, - val checked: State, - val onCheck: (Boolean) -> Unit, -) - -@Composable -fun LevelUpField( - modifier: Modifier = Modifier, - field: LevelUpWrapperUio, -) { - Row( - modifier = modifier, - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - style = MaterialTheme.typography.body1, - text = field.label, - ) - Checkbox( - colors = LwaCheckboxColors(), - checked = field.checked.value, - onCheckedChange = field.onCheck, - ) - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/SimpleField.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/SimpleField.kt deleted file mode 100644 index 89cd0cb..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/SimpleField.kt +++ /dev/null @@ -1,49 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.textfield.TextFieldWrapper -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.textfield.TextFieldWrapperUio - -@Stable -class SimpleFieldUio( - val label: String, - val value: TextFieldWrapperUio, -) - -@Composable -fun SimpleField( - modifier: Modifier = Modifier, - field: SimpleFieldUio, -) { - Row( - modifier = modifier, - horizontalArrangement = Arrangement.spacedBy(space = 4.dp, alignment = Alignment.End), - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - modifier = Modifier - .weight(1f) - .padding(start = 16.dp, bottom = 12.dp) - .align(alignment = Alignment.Bottom), - style = MaterialTheme.typography.body1, - overflow = TextOverflow.Ellipsis, - maxLines = 1, - text = field.label, - ) - TextFieldWrapper( - modifier = Modifier.width(width = 96.dp), - wrapper = field.value, - ) - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/SpecialSkillField.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/SpecialSkillField.kt deleted file mode 100644 index bdf2589..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/SpecialSkillField.kt +++ /dev/null @@ -1,106 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.width -import androidx.compose.material.DropdownMenu -import androidx.compose.material.Icon -import androidx.compose.material.IconButton -import androidx.compose.material.MaterialTheme -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.MoreVert -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.option.DropDownMenuItemWrapper -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.option.OptionUio -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.textfield.TextFieldWrapper -import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.textfield.TextFieldWrapperUio - -@Stable -class SkillFieldUio( - val id: String, - val label: TextFieldWrapperUio, - val description: TextFieldWrapperUio, - val base: TextFieldWrapperUio, - val bonus: TextFieldWrapperUio, - val level: TextFieldWrapperUio, - val options: List, -) - -@Composable -fun SkillForm( - modifier: Modifier = Modifier, - field: SkillFieldUio, -) { - val showMenu = remember { mutableStateOf(false) } - - Row( - modifier = modifier, - horizontalArrangement = Arrangement.spacedBy(space = 4.dp), - ) { - Column( - modifier = Modifier.weight(1f), - verticalArrangement = Arrangement.spacedBy(space = 4.dp) - ) { - Row( - horizontalArrangement = Arrangement.spacedBy(space = 4.dp), - ) { - TextFieldWrapper( - modifier = Modifier.weight(1f), - wrapper = field.label, - ) - TextFieldWrapper( - modifier = Modifier.width(width = 96.dp), - wrapper = field.base, - ) - TextFieldWrapper( - modifier = Modifier.width(width = 96.dp), - wrapper = field.bonus, - ) - TextFieldWrapper( - modifier = Modifier.width(width = 96.dp), - wrapper = field.level, - ) - } - TextFieldWrapper( - modifier = Modifier.fillMaxWidth(), - singleLine = false, - wrapper = field.description, - ) - } - if (field.options.isNotEmpty()) { - Box { - IconButton( - onClick = { showMenu.value = showMenu.value.not() }, - ) { - Icon( - imageVector = Icons.Default.MoreVert, - tint = MaterialTheme.colors.primary, - contentDescription = null, - ) - } - DropdownMenu( - expanded = showMenu.value, - onDismissRequest = { showMenu.value = false } - ) { - field.options.forEach { - DropDownMenuItemWrapper( - wrapper = it, - onClick = { - showMenu.value = false - it.onOption() - } - ) - } - } - } - } - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/ActionOption.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/ActionOption.kt deleted file mode 100644 index 14d4e01..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/ActionOption.kt +++ /dev/null @@ -1,51 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.option - -import androidx.compose.foundation.layout.padding -import androidx.compose.material.DropdownMenuItem -import androidx.compose.material.Icon -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.unit.dp - -@Stable -sealed class ActionOption( - val icon: ImageVector, - val label: String, - onOption: () -> Unit, -) : OptionUio(onOption = onOption) { - class DeleteOptionUio( - icon: ImageVector, - label: String, - onOption: () -> Unit, - ) : ActionOption( - icon = icon, - label = label, - onOption = onOption, - ) -} - -@Composable -fun DropDownActionMenuItem( - modifier: Modifier = Modifier, - wrapper: ActionOption, - onClick: () -> Unit, -) { - DropdownMenuItem( - modifier = modifier, - onClick = onClick, - ) { - Icon( - tint = MaterialTheme.colors.primary, - imageVector = wrapper.icon, - contentDescription = null, - ) - Text( - modifier = Modifier.padding(start = 8.dp), - text = wrapper.label, - ) - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/CheckedOption.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/CheckedOption.kt deleted file mode 100644 index c0b657e..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/CheckedOption.kt +++ /dev/null @@ -1,56 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.option - -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.material.Checkbox -import androidx.compose.material.CheckboxDefaults -import androidx.compose.material.DropdownMenuItem -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.runtime.State -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp - -@Stable -sealed class CheckedOption( - val label: String, - val checked: State, - onOption: () -> Unit, -) : OptionUio(onOption = onOption) { - class OccupationOption( - label: String, - checked: State, - onOption: () -> Unit, - ) : CheckedOption( - label = label, - checked = checked, - onOption = onOption, - ) -} - -@Composable -fun DropDownCheckedMenuItem( - modifier: Modifier = Modifier, - wrapper: CheckedOption, - onClick: () -> Unit, -) { - DropdownMenuItem( - modifier = modifier, - onClick = onClick, - ) { - Checkbox( - modifier = Modifier.size(size = 24.dp), - checked = wrapper.checked.value, - colors = CheckboxDefaults.colors( - checkedColor = MaterialTheme.colors.primary, - ), - onCheckedChange = null - ) - Text( - modifier = Modifier.padding(start = 8.dp), - text = wrapper.label, - ) - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/Option.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/Option.kt deleted file mode 100644 index 88e7244..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/option/Option.kt +++ /dev/null @@ -1,31 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.option - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.ui.Modifier - -@Stable -sealed class OptionUio( - val onOption: () -> Unit, -) - -@Composable -fun DropDownMenuItemWrapper( - modifier: Modifier = Modifier, - wrapper: OptionUio, - onClick: () -> Unit, -) { - when (wrapper) { - is ActionOption -> DropDownActionMenuItem( - modifier = modifier, - wrapper = wrapper, - onClick = onClick, - ) - - is CheckedOption -> DropDownCheckedMenuItem( - modifier = modifier, - wrapper = wrapper, - onClick = onClick, - ) - } -} \ No newline at end of file diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/textfield/FormWrapper.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/textfield/FormWrapper.kt deleted file mode 100644 index baf50fe..0000000 --- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/characterSheet/edit/composable/textfield/FormWrapper.kt +++ /dev/null @@ -1,79 +0,0 @@ -package com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.textfield - -import androidx.compose.foundation.layout.height -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text -import androidx.compose.material.TextField -import androidx.compose.material.TextFieldDefaults -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.runtime.State -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.FocusDirection -import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.unit.dp -import com.pixelized.desktop.lwa.utils.rememberKeyboardActions -import kotlin.math.sin - -@Stable -data class TextFieldWrapperUio( - val enable: Boolean, - val label: State, - val value: State, - val placeholder: State, - val onValueChange: (String) -> Unit, -) - -@Composable -fun TextFieldWrapper( - modifier: Modifier = Modifier, - singleLine: Boolean = true, - wrapper: TextFieldWrapperUio, -) { - val colorScheme = MaterialTheme.colors - val focus = LocalFocusManager.current - val localModifier = if (singleLine) { - Modifier.height(height = 56.dp) - } else { - Modifier - } - - TextField( - modifier = localModifier.then(other = modifier), - colors = TextFieldDefaults.textFieldColors( - backgroundColor = remember(wrapper.enable) { - when (wrapper.enable) { - true -> colorScheme.onSurface.copy(alpha = 0.03f) - else -> colorScheme.surface - } - }, - ), - keyboardActions = rememberKeyboardActions { - focus.moveFocus(FocusDirection.Next) - }, - enabled = wrapper.enable, - singleLine = singleLine, - placeholder = wrapper.placeholder.value?.let { - { - Text( - overflow = TextOverflow.Ellipsis, - maxLines = 1, - text = it - ) - } - }, - label = wrapper.label.value?.let { - { - Text( - overflow = TextOverflow.Ellipsis, - maxLines = 1, - text = it - ) - } - }, - onValueChange = { wrapper.onValueChange(it) }, - value = wrapper.value.value, - ) -} \ No newline at end of file