Add PP and HP managmenet
This commit is contained in:
		
							parent
							
								
									f6d026d50f
								
							
						
					
					
						commit
						3705fbd947
					
				
					 5 changed files with 305 additions and 8 deletions
				
			
		| 
						 | 
					@ -4,66 +4,105 @@ import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheet
 | 
				
			||||||
import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetPageUio.Characteristic
 | 
					import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetPageUio.Characteristic
 | 
				
			||||||
import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetPageUio.Node
 | 
					import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetPageUio.Node
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.Res
 | 
					import lwacharactersheet.composeapp.generated.resources.Res
 | 
				
			||||||
import lwacharactersheet.composeapp.generated.resources.*
 | 
					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__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__movement
 | 
				
			||||||
 | 
					import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__power_point
 | 
				
			||||||
import org.jetbrains.compose.resources.getString
 | 
					import org.jetbrains.compose.resources.getString
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CharacterSheetFactory {
 | 
					class CharacterSheetFactory {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    companion object {
 | 
				
			||||||
 | 
					        const val HP = "HP"
 | 
				
			||||||
 | 
					        const val PP = "PP"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    suspend fun convertToUio(model: CharacterSheet): CharacterSheetPageUio {
 | 
					    suspend fun convertToUio(model: CharacterSheet): CharacterSheetPageUio {
 | 
				
			||||||
        return CharacterSheetPageUio(
 | 
					        return CharacterSheetPageUio(
 | 
				
			||||||
            id = model.id,
 | 
					            id = model.id,
 | 
				
			||||||
            name = model.name,
 | 
					            name = model.name,
 | 
				
			||||||
            characteristics = listOf(
 | 
					            characteristics = listOf(
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
 | 
					                    id = "STR",
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__characteristics__str),
 | 
					                    label = getString(Res.string.character_sheet__characteristics__str),
 | 
				
			||||||
                    value = "${model.strength}",
 | 
					                    value = "${model.strength}",
 | 
				
			||||||
 | 
					                    editable = false,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
 | 
					                    id = "DEX",
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__characteristics__dex),
 | 
					                    label = getString(Res.string.character_sheet__characteristics__dex),
 | 
				
			||||||
                    value = "${model.dexterity}",
 | 
					                    value = "${model.dexterity}",
 | 
				
			||||||
 | 
					                    editable = false,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
 | 
					                    id = "CON",
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__characteristics__con),
 | 
					                    label = getString(Res.string.character_sheet__characteristics__con),
 | 
				
			||||||
                    value = "${model.constitution}",
 | 
					                    value = "${model.constitution}",
 | 
				
			||||||
 | 
					                    editable = false,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
 | 
					                    id = "HEI",
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__characteristics__hei),
 | 
					                    label = getString(Res.string.character_sheet__characteristics__hei),
 | 
				
			||||||
                    value = "${model.height}",
 | 
					                    value = "${model.height}",
 | 
				
			||||||
 | 
					                    editable = false,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
 | 
					                    id = "INT",
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__characteristics__int),
 | 
					                    label = getString(Res.string.character_sheet__characteristics__int),
 | 
				
			||||||
                    value = "${model.intelligence}",
 | 
					                    value = "${model.intelligence}",
 | 
				
			||||||
 | 
					                    editable = false,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
 | 
					                    id = "POW",
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__characteristics__pow),
 | 
					                    label = getString(Res.string.character_sheet__characteristics__pow),
 | 
				
			||||||
                    value = "${model.power}",
 | 
					                    value = "${model.power}",
 | 
				
			||||||
 | 
					                    editable = false,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
 | 
					                    id = "CHA",
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__characteristics__cha),
 | 
					                    label = getString(Res.string.character_sheet__characteristics__cha),
 | 
				
			||||||
                    value = "${model.charisma}",
 | 
					                    value = "${model.charisma}",
 | 
				
			||||||
 | 
					                    editable = false,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            subCharacteristics = listOf(
 | 
					            subCharacteristics = listOf(
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
 | 
					                    id = "MOV",
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__sub_characteristics__movement),
 | 
					                    label = getString(Res.string.character_sheet__sub_characteristics__movement),
 | 
				
			||||||
                    value = "${model.movement}",
 | 
					                    value = "${model.movement}",
 | 
				
			||||||
 | 
					                    editable = false,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
 | 
					                    id = HP,
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__sub_characteristics__hit_point),
 | 
					                    label = getString(Res.string.character_sheet__sub_characteristics__hit_point),
 | 
				
			||||||
                    value = "${model.currentHp}/${model.maxHp}",
 | 
					                    value = "${model.currentHp}/${model.maxHp}",
 | 
				
			||||||
 | 
					                    editable = true,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
 | 
					                    id = PP,
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__sub_characteristics__power_point),
 | 
					                    label = getString(Res.string.character_sheet__sub_characteristics__power_point),
 | 
				
			||||||
                    value = "${model.currentPP}/${model.maxPP}",
 | 
					                    value = "${model.currentPP}/${model.maxPP}",
 | 
				
			||||||
 | 
					                    editable = true,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
 | 
					                    id = "DMG",
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__sub_characteristics__damage_bonus),
 | 
					                    label = getString(Res.string.character_sheet__sub_characteristics__damage_bonus),
 | 
				
			||||||
                    value = model.damageBonus,
 | 
					                    value = model.damageBonus,
 | 
				
			||||||
 | 
					                    editable = false,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
                Characteristic(
 | 
					                Characteristic(
 | 
				
			||||||
 | 
					                    id = "ARMOR",
 | 
				
			||||||
                    label = getString(Res.string.character_sheet__sub_characteristics__armor),
 | 
					                    label = getString(Res.string.character_sheet__sub_characteristics__armor),
 | 
				
			||||||
                    value = "${model.armor}",
 | 
					                    value = "${model.armor}",
 | 
				
			||||||
 | 
					                    editable = false,
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
            ),
 | 
					            ),
 | 
				
			||||||
            skills = model.skills.mapNotNull {
 | 
					            skills = model.skills.mapNotNull {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,6 +45,8 @@ import com.pixelized.desktop.lwa.composable.overlay.BlurOverlay
 | 
				
			||||||
import com.pixelized.desktop.lwa.composable.overlay.BlurOverlayViewModel
 | 
					import com.pixelized.desktop.lwa.composable.overlay.BlurOverlayViewModel
 | 
				
			||||||
import com.pixelized.desktop.lwa.navigation.LocalScreenController
 | 
					import com.pixelized.desktop.lwa.navigation.LocalScreenController
 | 
				
			||||||
import com.pixelized.desktop.lwa.navigation.destination.navigateToCharacterSheetEdit
 | 
					import com.pixelized.desktop.lwa.navigation.destination.navigateToCharacterSheetEdit
 | 
				
			||||||
 | 
					import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.CharacterSheetDeleteConfirmationDialog
 | 
				
			||||||
 | 
					import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.CharacterSheetStatDialog
 | 
				
			||||||
import com.pixelized.desktop.lwa.screen.roll.RollPage
 | 
					import com.pixelized.desktop.lwa.screen.roll.RollPage
 | 
				
			||||||
import com.pixelized.desktop.lwa.screen.roll.RollViewModel
 | 
					import com.pixelized.desktop.lwa.screen.roll.RollViewModel
 | 
				
			||||||
import kotlinx.coroutines.launch
 | 
					import kotlinx.coroutines.launch
 | 
				
			||||||
| 
						 | 
					@ -70,8 +72,10 @@ data class CharacterSheetPageUio(
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    @Stable
 | 
					    @Stable
 | 
				
			||||||
    data class Characteristic(
 | 
					    data class Characteristic(
 | 
				
			||||||
 | 
					        val id: String,
 | 
				
			||||||
        val label: String,
 | 
					        val label: String,
 | 
				
			||||||
        val value: String,
 | 
					        val value: String,
 | 
				
			||||||
 | 
					        val editable: Boolean,
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Stable
 | 
					    @Stable
 | 
				
			||||||
| 
						 | 
					@ -132,6 +136,9 @@ fun CharacterSheetPage(
 | 
				
			||||||
                            )
 | 
					                            )
 | 
				
			||||||
                            overlayViewModel.show()
 | 
					                            overlayViewModel.show()
 | 
				
			||||||
                        },
 | 
					                        },
 | 
				
			||||||
 | 
					                        onSubCharacteristic = {
 | 
				
			||||||
 | 
					                            viewModel.showSubCharacteristicDialog(id = it.id)
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
                        onSkill = { node ->
 | 
					                        onSkill = { node ->
 | 
				
			||||||
                            rollViewModel.prepareRoll(sheet = sheet, node = node)
 | 
					                            rollViewModel.prepareRoll(sheet = sheet, node = node)
 | 
				
			||||||
                            overlayViewModel.show()
 | 
					                            overlayViewModel.show()
 | 
				
			||||||
| 
						 | 
					@ -161,6 +168,20 @@ fun CharacterSheetPage(
 | 
				
			||||||
            viewModel.hideConfirmCharacterDeletionDialog()
 | 
					            viewModel.hideConfirmCharacterDeletionDialog()
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CharacterSheetStatDialog(
 | 
				
			||||||
 | 
					        dialog = viewModel.statChangeDialog,
 | 
				
			||||||
 | 
					        onConfirm = {
 | 
				
			||||||
 | 
					            viewModel.changeSubCharacteristic(
 | 
				
			||||||
 | 
					                characteristicId = it.id,
 | 
				
			||||||
 | 
					                value = it.value().text.toIntOrNull() ?: 0,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            viewModel.hideSubCharacteristicDialog()
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        onDismissRequest = {
 | 
				
			||||||
 | 
					            viewModel.hideSubCharacteristicDialog()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Composable
 | 
					@Composable
 | 
				
			||||||
| 
						 | 
					@ -171,6 +192,7 @@ fun CharacterSheetPageContent(
 | 
				
			||||||
    onEdit: () -> Unit,
 | 
					    onEdit: () -> Unit,
 | 
				
			||||||
    onDelete: () -> Unit,
 | 
					    onDelete: () -> Unit,
 | 
				
			||||||
    onCharacteristic: (characteristic: CharacterSheetPageUio.Characteristic) -> Unit,
 | 
					    onCharacteristic: (characteristic: CharacterSheetPageUio.Characteristic) -> Unit,
 | 
				
			||||||
 | 
					    onSubCharacteristic: (characteristic: CharacterSheetPageUio.Characteristic) -> Unit,
 | 
				
			||||||
    onSkill: (skill: CharacterSheetPageUio.Node) -> Unit,
 | 
					    onSkill: (skill: CharacterSheetPageUio.Node) -> Unit,
 | 
				
			||||||
    onUseSkill: (skill: CharacterSheetPageUio.Node) -> Unit,
 | 
					    onUseSkill: (skill: CharacterSheetPageUio.Node) -> Unit,
 | 
				
			||||||
    onRoll: (roll: CharacterSheetPageUio.Roll) -> Unit,
 | 
					    onRoll: (roll: CharacterSheetPageUio.Roll) -> Unit,
 | 
				
			||||||
| 
						 | 
					@ -252,9 +274,13 @@ fun CharacterSheetPageContent(
 | 
				
			||||||
                                text = stringResource(Res.string.character_sheet__sub_characteristics__title),
 | 
					                                text = stringResource(Res.string.character_sheet__sub_characteristics__title),
 | 
				
			||||||
                            )
 | 
					                            )
 | 
				
			||||||
                            characterSheet.subCharacteristics.forEach {
 | 
					                            characterSheet.subCharacteristics.forEach {
 | 
				
			||||||
                                Characteristics(
 | 
					                                SubCharacteristics(
 | 
				
			||||||
                                    modifier = Modifier.cell(),
 | 
					                                    modifier = Modifier.cell(),
 | 
				
			||||||
                                    characteristic = it,
 | 
					                                    characteristic = it,
 | 
				
			||||||
 | 
					                                    onCharacteristic = when {
 | 
				
			||||||
 | 
					                                        it.editable -> onSubCharacteristic
 | 
				
			||||||
 | 
					                                        else -> null
 | 
				
			||||||
 | 
					                                    }
 | 
				
			||||||
                                )
 | 
					                                )
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
| 
						 | 
					@ -372,24 +398,32 @@ private fun Stat(
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Composable
 | 
					@Composable
 | 
				
			||||||
private fun Characteristics(
 | 
					private fun SubCharacteristics(
 | 
				
			||||||
    modifier: Modifier = Modifier,
 | 
					    modifier: Modifier = Modifier,
 | 
				
			||||||
    paddingValues: PaddingValues = PaddingValues(horizontal = 8.dp),
 | 
					    paddingValues: PaddingValues = PaddingValues(horizontal = 8.dp),
 | 
				
			||||||
    characteristic: CharacterSheetPageUio.Characteristic,
 | 
					    characteristic: CharacterSheetPageUio.Characteristic,
 | 
				
			||||||
 | 
					    onCharacteristic: ((characteristic: CharacterSheetPageUio.Characteristic) -> Unit)?,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    Row(
 | 
					    Row(
 | 
				
			||||||
        modifier = Modifier.padding(paddingValues = paddingValues).then(other = modifier),
 | 
					        modifier = Modifier
 | 
				
			||||||
 | 
					            .clickable(enabled = characteristic.editable && onCharacteristic != null) {
 | 
				
			||||||
 | 
					                onCharacteristic?.invoke(characteristic)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            .padding(paddingValues = paddingValues).then(other = modifier),
 | 
				
			||||||
        horizontalArrangement = Arrangement.SpaceBetween,
 | 
					        horizontalArrangement = Arrangement.SpaceBetween,
 | 
				
			||||||
 | 
					        verticalAlignment = Alignment.CenterVertically,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        Text(
 | 
					        Text(
 | 
				
			||||||
            modifier = Modifier.alignByBaseline(),
 | 
					 | 
				
			||||||
            style = MaterialTheme.typography.body1,
 | 
					            style = MaterialTheme.typography.body1,
 | 
				
			||||||
            text = characteristic.label
 | 
					            text = characteristic.label
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        Text(
 | 
					        Text(
 | 
				
			||||||
            modifier = Modifier.alignByBaseline(),
 | 
					 | 
				
			||||||
            style = MaterialTheme.typography.body1,
 | 
					            style = MaterialTheme.typography.body1,
 | 
				
			||||||
            fontWeight = FontWeight.Bold,
 | 
					            fontWeight = FontWeight.Bold,
 | 
				
			||||||
 | 
					            color = when (characteristic.editable && onCharacteristic != null) {
 | 
				
			||||||
 | 
					                true -> MaterialTheme.colors.primary
 | 
				
			||||||
 | 
					                else -> MaterialTheme.colors.onSurface
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            text = characteristic.value,
 | 
					            text = characteristic.value,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,12 +4,18 @@ import androidx.compose.runtime.Composable
 | 
				
			||||||
import androidx.compose.runtime.Stable
 | 
					import androidx.compose.runtime.Stable
 | 
				
			||||||
import androidx.compose.runtime.State
 | 
					import androidx.compose.runtime.State
 | 
				
			||||||
import androidx.compose.runtime.mutableStateOf
 | 
					import androidx.compose.runtime.mutableStateOf
 | 
				
			||||||
 | 
					import androidx.compose.ui.text.TextRange
 | 
				
			||||||
 | 
					import androidx.compose.ui.text.input.TextFieldValue
 | 
				
			||||||
import androidx.lifecycle.SavedStateHandle
 | 
					import androidx.lifecycle.SavedStateHandle
 | 
				
			||||||
import androidx.lifecycle.ViewModel
 | 
					import androidx.lifecycle.ViewModel
 | 
				
			||||||
import com.pixelized.desktop.lwa.navigation.destination.CharacterSheetDestination
 | 
					import com.pixelized.desktop.lwa.navigation.destination.CharacterSheetDestination
 | 
				
			||||||
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
 | 
					import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
 | 
				
			||||||
 | 
					import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.CharacterSheetDeleteConfirmationDialogUio
 | 
				
			||||||
 | 
					import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.StatChangeDialogUio
 | 
				
			||||||
import com.pixelized.desktop.lwa.utils.extention.collectAsState
 | 
					import com.pixelized.desktop.lwa.utils.extention.collectAsState
 | 
				
			||||||
import kotlinx.coroutines.runBlocking
 | 
					import kotlinx.coroutines.runBlocking
 | 
				
			||||||
 | 
					import kotlin.math.max
 | 
				
			||||||
 | 
					import kotlin.math.min
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CharacterSheetViewModel(
 | 
					class CharacterSheetViewModel(
 | 
				
			||||||
    savedStateHandle: SavedStateHandle,
 | 
					    savedStateHandle: SavedStateHandle,
 | 
				
			||||||
| 
						 | 
					@ -24,6 +30,9 @@ class CharacterSheetViewModel(
 | 
				
			||||||
    val displayDeleteConfirmationDialog: State<CharacterSheetDeleteConfirmationDialogUio?>
 | 
					    val displayDeleteConfirmationDialog: State<CharacterSheetDeleteConfirmationDialogUio?>
 | 
				
			||||||
        get() = _displayDeleteConfirmationDialog
 | 
					        get() = _displayDeleteConfirmationDialog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private val _statChangeDialog = mutableStateOf<StatChangeDialogUio?>(null)
 | 
				
			||||||
 | 
					    val statChangeDialog: State<StatChangeDialogUio?> get() = _statChangeDialog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    val sheet: State<CharacterSheetPageUio?>
 | 
					    val sheet: State<CharacterSheetPageUio?>
 | 
				
			||||||
        @Composable
 | 
					        @Composable
 | 
				
			||||||
        @Stable
 | 
					        @Stable
 | 
				
			||||||
| 
						 | 
					@ -35,7 +44,7 @@ class CharacterSheetViewModel(
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    suspend fun deleteCharacter(id: String) {
 | 
					    fun deleteCharacter(id: String) {
 | 
				
			||||||
        repository.delete(id = id)
 | 
					        repository.delete(id = id)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,4 +83,61 @@ class CharacterSheetViewModel(
 | 
				
			||||||
    fun hideConfirmCharacterDeletionDialog() {
 | 
					    fun hideConfirmCharacterDeletionDialog() {
 | 
				
			||||||
        _displayDeleteConfirmationDialog.value = null
 | 
					        _displayDeleteConfirmationDialog.value = null
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun showSubCharacteristicDialog(id: String) {
 | 
				
			||||||
 | 
					        repository.characterSheetFlow(id = argument.id).value?.let { sheet ->
 | 
				
			||||||
 | 
					            _statChangeDialog.value = when (id) {
 | 
				
			||||||
 | 
					                CharacterSheetFactory.HP -> {
 | 
				
			||||||
 | 
					                    val value = mutableStateOf(
 | 
				
			||||||
 | 
					                        "${sheet.currentHp}".let {
 | 
				
			||||||
 | 
					                            TextFieldValue(text = it, selection = TextRange(it.length))
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                    StatChangeDialogUio(
 | 
				
			||||||
 | 
					                        id = CharacterSheetFactory.HP,
 | 
				
			||||||
 | 
					                        value = { value.value },
 | 
				
			||||||
 | 
					                        onValueChange = { value.value = it },
 | 
				
			||||||
 | 
					                        placeholder = "${sheet.currentHp}",
 | 
				
			||||||
 | 
					                        maxValue = "${sheet.maxHp}",
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                CharacterSheetFactory.PP -> {
 | 
				
			||||||
 | 
					                    val value = mutableStateOf(
 | 
				
			||||||
 | 
					                        "${sheet.currentPP}".let {
 | 
				
			||||||
 | 
					                            TextFieldValue(text = it, selection = TextRange(it.length))
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                    StatChangeDialogUio(
 | 
				
			||||||
 | 
					                        id = CharacterSheetFactory.PP,
 | 
				
			||||||
 | 
					                        value = { value.value },
 | 
				
			||||||
 | 
					                        onValueChange = { value.value = it },
 | 
				
			||||||
 | 
					                        placeholder = "${sheet.currentPP}",
 | 
				
			||||||
 | 
					                        maxValue = "${sheet.maxPP}",
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                else -> null
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun hideSubCharacteristicDialog() {
 | 
				
			||||||
 | 
					        _statChangeDialog.value = null
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fun changeSubCharacteristic(
 | 
				
			||||||
 | 
					        characteristicId: String,
 | 
				
			||||||
 | 
					        value: Int,
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
 | 
					        val sheet = repository.characterSheetFlow(id = argument.id).value
 | 
				
			||||||
 | 
					        val updated = when (characteristicId) {
 | 
				
			||||||
 | 
					            CharacterSheetFactory.HP -> sheet?.copy(currentHp = max(0, min(sheet.maxHp, value)))
 | 
				
			||||||
 | 
					            CharacterSheetFactory.PP -> sheet?.copy(currentPP = max(0, min(sheet.maxPP, value)))
 | 
				
			||||||
 | 
					            else -> null
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        updated?.let {
 | 
				
			||||||
 | 
					            repository.save(it)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
package com.pixelized.desktop.lwa.screen.characterSheet.detail
 | 
					package com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import androidx.compose.animation.AnimatedContent
 | 
					import androidx.compose.animation.AnimatedContent
 | 
				
			||||||
import androidx.compose.animation.AnimatedVisibility
 | 
					import androidx.compose.animation.AnimatedVisibility
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,158 @@
 | 
				
			||||||
 | 
					package com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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.background
 | 
				
			||||||
 | 
					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.Row
 | 
				
			||||||
 | 
					import androidx.compose.foundation.layout.fillMaxSize
 | 
				
			||||||
 | 
					import androidx.compose.foundation.layout.padding
 | 
				
			||||||
 | 
					import androidx.compose.foundation.layout.width
 | 
				
			||||||
 | 
					import androidx.compose.foundation.shape.RoundedCornerShape
 | 
				
			||||||
 | 
					import androidx.compose.foundation.text.KeyboardActions
 | 
				
			||||||
 | 
					import androidx.compose.foundation.text.KeyboardOptions
 | 
				
			||||||
 | 
					import androidx.compose.material.MaterialTheme
 | 
				
			||||||
 | 
					import androidx.compose.material.Surface
 | 
				
			||||||
 | 
					import androidx.compose.material.Text
 | 
				
			||||||
 | 
					import androidx.compose.material.TextField
 | 
				
			||||||
 | 
					import androidx.compose.runtime.Composable
 | 
				
			||||||
 | 
					import androidx.compose.runtime.LaunchedEffect
 | 
				
			||||||
 | 
					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.focus.FocusRequester
 | 
				
			||||||
 | 
					import androidx.compose.ui.focus.focusRequester
 | 
				
			||||||
 | 
					import androidx.compose.ui.graphics.Color
 | 
				
			||||||
 | 
					import androidx.compose.ui.text.font.FontWeight
 | 
				
			||||||
 | 
					import androidx.compose.ui.text.input.ImeAction
 | 
				
			||||||
 | 
					import androidx.compose.ui.text.input.TextFieldValue
 | 
				
			||||||
 | 
					import androidx.compose.ui.text.style.TextAlign
 | 
				
			||||||
 | 
					import androidx.compose.ui.unit.dp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private val DefaultScrimColor = Color.Black.copy(alpha = 0.6f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Stable
 | 
				
			||||||
 | 
					data class StatChangeDialogUio(
 | 
				
			||||||
 | 
					    val id: String,
 | 
				
			||||||
 | 
					    val value: () -> TextFieldValue,
 | 
				
			||||||
 | 
					    val placeholder: String,
 | 
				
			||||||
 | 
					    val onValueChange: (TextFieldValue) -> Unit,
 | 
				
			||||||
 | 
					    val maxValue: String,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Composable
 | 
				
			||||||
 | 
					fun CharacterSheetStatDialog(
 | 
				
			||||||
 | 
					    dialog: State<StatChangeDialogUio?>,
 | 
				
			||||||
 | 
					    onConfirm: (StatChangeDialogUio) -> Unit,
 | 
				
			||||||
 | 
					    onDismissRequest: () -> Unit,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    AnimatedVisibility(
 | 
				
			||||||
 | 
					        visible = dialog.value != null,
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
 | 
					        Box(
 | 
				
			||||||
 | 
					            modifier = Modifier
 | 
				
			||||||
 | 
					                .fillMaxSize()
 | 
				
			||||||
 | 
					                .background(color = DefaultScrimColor),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    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: StatChangeDialogUio,
 | 
				
			||||||
 | 
					    onConfirm: (StatChangeDialogUio) -> Unit,
 | 
				
			||||||
 | 
					    onDismissRequest: () -> Unit,
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					    val typography = MaterialTheme.typography
 | 
				
			||||||
 | 
					    val colors = MaterialTheme.colors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    val focusRequester = remember { FocusRequester() }
 | 
				
			||||||
 | 
					    LaunchedEffect(Unit) {
 | 
				
			||||||
 | 
					        focusRequester.requestFocus()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Box(
 | 
				
			||||||
 | 
					        modifier = Modifier
 | 
				
			||||||
 | 
					            .clickable(
 | 
				
			||||||
 | 
					                interactionSource = remember { MutableInteractionSource() },
 | 
				
			||||||
 | 
					                indication = null,
 | 
				
			||||||
 | 
					                onClick = onDismissRequest,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					            .fillMaxSize()
 | 
				
			||||||
 | 
					            .padding(all = 32.dp),
 | 
				
			||||||
 | 
					        contentAlignment = Alignment.Center,
 | 
				
			||||||
 | 
					    ) {
 | 
				
			||||||
 | 
					        Surface(
 | 
				
			||||||
 | 
					            shape = remember { RoundedCornerShape(size = 16.dp) },
 | 
				
			||||||
 | 
					        ) {
 | 
				
			||||||
 | 
					            Row(
 | 
				
			||||||
 | 
					                modifier = Modifier.padding(all = 16.dp),
 | 
				
			||||||
 | 
					                horizontalArrangement = Arrangement.spacedBy(4.dp),
 | 
				
			||||||
 | 
					            ) {
 | 
				
			||||||
 | 
					                TextField(
 | 
				
			||||||
 | 
					                    modifier = Modifier
 | 
				
			||||||
 | 
					                        .focusRequester(focusRequester = focusRequester)
 | 
				
			||||||
 | 
					                        .alignByBaseline()
 | 
				
			||||||
 | 
					                        .width(width = 120.dp),
 | 
				
			||||||
 | 
					                    value = dialog.value(),
 | 
				
			||||||
 | 
					                    textStyle = remember {
 | 
				
			||||||
 | 
					                        typography.body1.copy(
 | 
				
			||||||
 | 
					                            color = colors.primary,
 | 
				
			||||||
 | 
					                            textAlign = TextAlign.End,
 | 
				
			||||||
 | 
					                            fontWeight = FontWeight.Bold
 | 
				
			||||||
 | 
					                        )
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    singleLine = true,
 | 
				
			||||||
 | 
					                    keyboardActions = KeyboardActions { onConfirm(dialog) },
 | 
				
			||||||
 | 
					                    keyboardOptions = KeyboardOptions(imeAction =  ImeAction.Done),
 | 
				
			||||||
 | 
					                    placeholder = { dialog.placeholder },
 | 
				
			||||||
 | 
					                    onValueChange = dialog.onValueChange,
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                Text(
 | 
				
			||||||
 | 
					                    modifier = Modifier.alignByBaseline(),
 | 
				
			||||||
 | 
					                    text = "/",
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                Text(
 | 
				
			||||||
 | 
					                    modifier = Modifier.alignByBaseline(),
 | 
				
			||||||
 | 
					                    text = dialog.maxValue,
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue