Small UI / UX adjustment on the character sheet detail/edit
This commit is contained in:
parent
d1a98b9075
commit
34a0ee13f0
24 changed files with 359 additions and 207 deletions
|
|
@ -1,5 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<resources>
|
||||
<string name="dialog__confirm_action">Confirmer</string>
|
||||
<string name="dialog__cancel_action">Annuler</string>
|
||||
|
||||
<string name="main_page__create_action">Créer une feuille de personnage</string>
|
||||
<string name="main_page__network_action">Configuration de la table</string>
|
||||
<string name="main_page__roll_history_action">Consulter l'historique des lancers</string>
|
||||
|
|
@ -19,8 +22,7 @@
|
|||
|
||||
<string name="character_sheet_edit__create__title">Création de personnage</string>
|
||||
<string name="character_sheet_edit__edit__title">Édition de personnage</string>
|
||||
<string name="character_sheet_edit__name_placeholder">Nom</string>
|
||||
<string name="character_sheet_edit__add_roll_action">Ajouter une action</string>
|
||||
<string name="character_sheet_edit__name_label">Nom</string>
|
||||
<string name="character_sheet_edit__save_action">Sauvegarder</string>
|
||||
<string name="character_sheet_edit__characteristics__title">Caractéristiques</string>
|
||||
<string name="character_sheet_edit__characteristics__str">Force</string>
|
||||
|
|
@ -32,7 +34,9 @@
|
|||
<string name="character_sheet_edit__characteristics__cha">Charisme</string>
|
||||
<string name="character_sheet_edit__sub_characteristics__title">Caractéristiques dérivées</string>
|
||||
<string name="character_sheet_edit__sub_characteristics__movement">Déplacement</string>
|
||||
<string name="character_sheet_edit__sub_characteristics__max_hit_point">Points de vie maximum</string>
|
||||
<string name="character_sheet_edit__sub_characteristics__hit_point">Points de vie</string>
|
||||
<string name="character_sheet_edit__sub_characteristics__max_power_point">Points de pouvoir maximum</string>
|
||||
<string name="character_sheet_edit__sub_characteristics__power_point">Points de pouvoir</string>
|
||||
<string name="character_sheet_edit__sub_characteristics__damage_bonus">Bonus aux dégats</string>
|
||||
<string name="character_sheet_edit__sub_characteristics__armor">Armure</string>
|
||||
|
|
@ -64,9 +68,10 @@
|
|||
<string name="character_sheet_edit__occupation__title">Occupations</string>
|
||||
<string name="character_sheet_edit__occupation__add_action">Ajouter une occupation</string>
|
||||
<string name="character_sheet_edit__actions__name_label">Nom</string>
|
||||
<string name="character_sheet_edit__actions__action_label">Bonus</string>
|
||||
<string name="character_sheet_edit__actions__action_label">Action de lancé</string>
|
||||
<string name="character_sheet_edit__magic__title">Compétences magiques</string>
|
||||
<string name="character_sheet_edit__magic__add_action">Ajouter une compétence magique</string>
|
||||
<string name="character_sheet_edit__add_roll_action">Ajouter une action de lancé</string>
|
||||
<string name="character_sheet_edit__delete__label">Supprimer</string>
|
||||
<string name="character_sheet_edit__occupation__label">Compétence d'occupation</string>
|
||||
|
||||
|
|
@ -91,8 +96,6 @@
|
|||
<string name="character_sheet__skills__magic_title">Compétences magiques</string>
|
||||
<string name="character_sheet__delete_dialog__title">Supprimer la feuille de personnage</string>
|
||||
<string name="character_sheet__delete_dialog__description">Êtes-vous sûr de vouloir supprimer "%1$s" ?</string>
|
||||
<string name="character_sheet__delete_dialog__confirm_action">Confirmer</string>
|
||||
<string name="character_sheet__delete_dialog__cancel_action">Annuler</string>
|
||||
|
||||
<string name="tooltip__characteristics__characteristics">Les caractéristiques constituent les aptitudes innées d’un personnage comme son intelligence, sa force, son charisme, etc. Elles ne sont pas acquises, mais peuvent être parfois augmentées par un entraînement ou une utilisation réussie. Les caractéristiques des humains normaux varient de 2 (niveau extrêmement bas) à 20 (maximum du potentiel humain), avec une moyenne de 10 ou 11. Plus une caractéristique est élevée plus le personnage est puissant dans cette aptitude.\nÀ la création de votre personnage, répartissez les valeurs suivantes dans les différentes caractéristiques : 15, 15, 13, 11, 10, 9 et 7.</string>
|
||||
<string name="tooltip__characteristics__strength">La Force représente essentiellement la puissance musculaire du personnage. Elle ne décrit pas nécessairement la masse musculaire brute, mais l’efficacité avec laquelle le personnage exerce ses muscles pour accomplir des actions physiques pénibles.</string>
|
||||
|
|
|
|||
|
|
@ -1,18 +1,21 @@
|
|||
package com.pixelized.desktop.lwa
|
||||
|
||||
import com.pixelized.desktop.lwa.business.DamageBonusUseCase
|
||||
import com.pixelized.desktop.lwa.business.RollUseCase
|
||||
import com.pixelized.desktop.lwa.business.SkillNormalizerUseCase
|
||||
import com.pixelized.desktop.lwa.business.SkillStepUseCase
|
||||
import com.pixelized.desktop.lwa.business.SkillValueComputationUseCase
|
||||
import com.pixelized.desktop.lwa.parser.arithmetic.ArithmeticParser
|
||||
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetJsonFactory
|
||||
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
|
||||
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetStore
|
||||
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
||||
import com.pixelized.desktop.lwa.repository.roll.RollHistoryRepository
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.common.SkillFieldFactory
|
||||
import com.pixelized.desktop.lwa.repository.roll_history.RollHistoryRepository
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetFactory
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetViewModel
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.CharacterSheetEditFactory
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.CharacterSheetEditViewModel
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.common.SkillFieldFactory
|
||||
import com.pixelized.desktop.lwa.screen.main.MainPageViewModel
|
||||
import com.pixelized.desktop.lwa.screen.network.NetworkFactory
|
||||
import com.pixelized.desktop.lwa.screen.network.NetworkViewModel
|
||||
|
|
@ -67,5 +70,8 @@ val parserDependencies
|
|||
val useCaseDependencies
|
||||
get() = module {
|
||||
factoryOf(::DamageBonusUseCase)
|
||||
factoryOf(::SkillStepUseCase)
|
||||
factoryOf(::SkillNormalizerUseCase)
|
||||
factoryOf(::RollUseCase)
|
||||
factoryOf(::SkillValueComputationUseCase)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package com.pixelized.desktop.lwa.business
|
||||
|
||||
object RollUseCase {
|
||||
class RollUseCase {
|
||||
|
||||
fun rollD100(): Int {
|
||||
return roll(quantity = 1, faces = 100)
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@ package com.pixelized.desktop.lwa.business
|
|||
|
||||
import kotlin.math.truncate
|
||||
|
||||
object SkillNormalizerUseCase {
|
||||
|
||||
class SkillNormalizerUseCase {
|
||||
fun normalize(value: Int): Int {
|
||||
return (truncate(value.toFloat() / 5f) * 5f).toInt()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,7 @@ import kotlin.math.max
|
|||
import kotlin.math.min
|
||||
import kotlin.math.round
|
||||
|
||||
object SkillStepUseCase {
|
||||
val NONE: IntRange = -1..-1
|
||||
class SkillStepUseCase {
|
||||
|
||||
data class SkillStep(
|
||||
val criticalSuccess: IntRange,
|
||||
|
|
@ -21,7 +20,8 @@ object SkillStepUseCase {
|
|||
*/
|
||||
fun computeSkillStep(skill: Int): SkillStep {
|
||||
val criticalSuccess = 1..min(roundToInt { skill * 0.05f }, 99)
|
||||
val specialSuccess = (roundToInt { skill * 0.05f } + 1)..min(roundToInt { skill * 0.2f }, 99)
|
||||
val specialSuccess =
|
||||
(roundToInt { skill * 0.05f } + 1)..min(roundToInt { skill * 0.2f }, 99)
|
||||
val success = (roundToInt { skill * 0.2f } + 1)..min(skill, 99)
|
||||
val criticalFailure = 100 - max(4 - criticalSuccess.last, 0)..100
|
||||
val failure = (success.last + 1) until criticalFailure.first
|
||||
|
|
@ -64,4 +64,8 @@ object SkillStepUseCase {
|
|||
}
|
||||
println(")")
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val NONE: IntRange = -1..-1
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ import kotlin.math.max
|
|||
|
||||
class SkillValueComputationUseCase(
|
||||
private val arithmeticParser: ArithmeticParser,
|
||||
private val rollUseCase: RollUseCase,
|
||||
) {
|
||||
fun computeSkillValue(
|
||||
sheet: CharacterSheet,
|
||||
|
|
@ -53,7 +54,7 @@ class SkillValueComputationUseCase(
|
|||
print("Roll ->")
|
||||
return arithmeticParser.parse(roll).sumOf { instruction ->
|
||||
val value = when (instruction) {
|
||||
is Instruction.Dice -> RollUseCase.roll(
|
||||
is Instruction.Dice -> rollUseCase.roll(
|
||||
quantity = instruction.quantity,
|
||||
faces = instruction.faces
|
||||
)
|
||||
|
|
@ -67,7 +68,7 @@ class SkillValueComputationUseCase(
|
|||
.parse(sheet.damageBonus)
|
||||
.firstOrNull()
|
||||
if (damageBonusInstructions is Instruction.Dice) {
|
||||
RollUseCase.roll(
|
||||
rollUseCase.roll(
|
||||
quantity = damageBonusInstructions.quantity,
|
||||
faces = damageBonusInstructions.faces
|
||||
)
|
||||
|
|
@ -81,7 +82,7 @@ class SkillValueComputationUseCase(
|
|||
.parse(sheet.damageBonus)
|
||||
.firstOrNull()
|
||||
if (damageBonusInstructions is Instruction.Dice) {
|
||||
RollUseCase.roll(
|
||||
rollUseCase.roll(
|
||||
quantity = damageBonusInstructions.quantity,
|
||||
faces = damageBonusInstructions.faces / 2,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import androidx.navigation.NavGraphBuilder
|
|||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.composable
|
||||
import com.pixelized.desktop.lwa.screen.main.MainPage
|
||||
import com.pixelized.desktop.lwa.screen.main.MainPageViewModel
|
||||
|
||||
object MainDestination {
|
||||
private const val ROUTE = "main"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package com.pixelized.desktop.lwa.repository.roll
|
||||
package com.pixelized.desktop.lwa.repository.roll_history
|
||||
|
||||
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
||||
import com.pixelized.desktop.lwa.repository.network.protocol.Message
|
||||
|
|
@ -235,10 +235,11 @@ fun CharacterSheetPage(
|
|||
value = it.value().text.toIntOrNull() ?: 0,
|
||||
)
|
||||
viewModel.hideSubCharacteristicDialog()
|
||||
blurController.hide()
|
||||
},
|
||||
onDismissRequest = {
|
||||
blurController.hide()
|
||||
viewModel.hideSubCharacteristicDialog()
|
||||
blurController.hide()
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -249,10 +250,11 @@ fun CharacterSheetPage(
|
|||
dialog = it
|
||||
)
|
||||
viewModel.hideDiminishedDialog()
|
||||
blurController.hide()
|
||||
},
|
||||
onDismissRequest = {
|
||||
blurController.hide()
|
||||
viewModel.hideDiminishedDialog()
|
||||
blurController.hide()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
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
|
||||
|
|
@ -29,13 +27,17 @@ import androidx.compose.runtime.State
|
|||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.key.Key
|
||||
import androidx.compose.ui.input.key.key
|
||||
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.theme.LwaColorPalette
|
||||
import com.pixelized.desktop.lwa.composable.decoratedBox.DecoratedBox
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__delete_dialog__cancel_action
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__delete_dialog__confirm_action
|
||||
|
||||
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
|
||||
|
|
@ -90,55 +92,64 @@ private fun Dialog(
|
|||
indication = null,
|
||||
onClick = onDismissRequest,
|
||||
)
|
||||
.onPreviewKeyEvent {
|
||||
when {
|
||||
it.key == Key.Escape -> {
|
||||
onDismissRequest()
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
.fillMaxSize()
|
||||
.padding(all = 32.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Surface(
|
||||
shape = remember { RoundedCornerShape(size = 16.dp) },
|
||||
) {
|
||||
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
|
||||
)
|
||||
DecoratedBox {
|
||||
Surface {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(space = 24.dp),
|
||||
) {
|
||||
TextButton(
|
||||
onClick = onDismissRequest,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(Res.string.character_sheet__delete_dialog__cancel_action)
|
||||
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 = { onConfirm(dialog) },
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(Res.string.character_sheet__delete_dialog__confirm_action)
|
||||
)
|
||||
TextButton(
|
||||
onClick = onDismissRequest,
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(Res.string.dialog__cancel_action)
|
||||
)
|
||||
}
|
||||
TextButton(
|
||||
onClick = { onConfirm(dialog) },
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(Res.string.dialog__confirm_action)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ 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.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.Stable
|
||||
|
|
@ -32,12 +33,19 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
import androidx.compose.ui.input.key.Key
|
||||
import androidx.compose.ui.input.key.key
|
||||
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
||||
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
|
||||
import com.pixelized.desktop.lwa.composable.decoratedBox.DecoratedBox
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
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 StatChangeDialogUio(
|
||||
|
|
@ -102,6 +110,15 @@ private fun Dialog(
|
|||
indication = null,
|
||||
onClick = onDismissRequest,
|
||||
)
|
||||
.onPreviewKeyEvent {
|
||||
when {
|
||||
it.key == Key.Escape -> {
|
||||
onDismissRequest()
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
.fillMaxSize()
|
||||
.padding(all = 32.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
|
|
@ -109,11 +126,11 @@ private fun Dialog(
|
|||
DecoratedBox {
|
||||
Surface {
|
||||
Column(
|
||||
modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp),
|
||||
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,
|
||||
)
|
||||
|
|
@ -148,6 +165,32 @@ private fun Dialog(
|
|||
text = dialog.maxValue,
|
||||
)
|
||||
}
|
||||
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 = { onConfirm(dialog) },
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(Res.string.dialog__confirm_action)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ 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
|
||||
|
|
@ -21,6 +22,7 @@ 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.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.Stable
|
||||
|
|
@ -31,12 +33,19 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
import androidx.compose.ui.input.key.Key
|
||||
import androidx.compose.ui.input.key.key
|
||||
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
||||
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
|
||||
import com.pixelized.desktop.lwa.composable.decoratedBox.DecoratedBox
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
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 DiminishedStatDialogUio(
|
||||
|
|
@ -99,6 +108,16 @@ private fun Dialog(
|
|||
indication = null,
|
||||
onClick = onDismissRequest,
|
||||
)
|
||||
.onPreviewKeyEvent {
|
||||
when {
|
||||
it.key == Key.Escape -> {
|
||||
onDismissRequest()
|
||||
true
|
||||
}
|
||||
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
.fillMaxSize()
|
||||
.padding(all = 32.dp),
|
||||
contentAlignment = Alignment.Center,
|
||||
|
|
@ -106,11 +125,11 @@ private fun Dialog(
|
|||
DecoratedBox {
|
||||
Surface {
|
||||
Column(
|
||||
modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(space = 8.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(start = 24.dp, end = 24.dp, top = 16.dp),
|
||||
style = MaterialTheme.typography.caption,
|
||||
text = dialog.label,
|
||||
)
|
||||
|
|
@ -132,6 +151,32 @@ private fun Dialog(
|
|||
value = dialog.value(),
|
||||
onValueChange = dialog.onValueChange,
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(top = 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 = { onConfirm(dialog) },
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(Res.string.dialog__confirm_action)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import androidx.compose.runtime.State
|
|||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import com.pixelized.desktop.lwa.business.DamageBonusUseCase
|
||||
import com.pixelized.desktop.lwa.business.SkillNormalizerUseCase.normalize
|
||||
import com.pixelized.desktop.lwa.business.SkillNormalizerUseCase
|
||||
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.common.SkillFieldFactory
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.common.occupation
|
||||
|
|
@ -21,7 +21,7 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__ch
|
|||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__int
|
||||
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__name_placeholder
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__name_label
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__acrobatics
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__aid
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__athletics
|
||||
|
|
@ -45,6 +45,8 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sk
|
|||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__armor
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__damage_bonus
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__hit_point
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__max_hit_point
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__max_power_point
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__movement
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__power_point
|
||||
import org.jetbrains.compose.resources.getString
|
||||
|
|
@ -56,17 +58,12 @@ import kotlin.math.min
|
|||
class CharacterSheetEditFactory(
|
||||
private val bonusDamageUseCase: DamageBonusUseCase,
|
||||
private val skillFactory: SkillFieldFactory,
|
||||
private val normalizer: SkillNormalizerUseCase,
|
||||
) {
|
||||
fun updateCharacterSheet(
|
||||
currentSheet: CharacterSheet?,
|
||||
editedSheet: CharacterSheetEditPageUio,
|
||||
): CharacterSheet {
|
||||
val maxHp = editedSheet.maxHp.unpack()?.toIntOrNull()
|
||||
?: currentSheet?.maxHp
|
||||
?: 0
|
||||
val maxPp = editedSheet.maxPp.unpack()?.toIntOrNull()
|
||||
?: currentSheet?.maxPp
|
||||
?: 0
|
||||
return CharacterSheet(
|
||||
id = editedSheet.id,
|
||||
name = editedSheet.name.value.value,
|
||||
|
|
@ -96,11 +93,19 @@ class CharacterSheetEditFactory(
|
|||
?: currentSheet?.movement
|
||||
?: 10,
|
||||
overrideMaxHp = editedSheet.maxHp.value.value.value.isNotBlank(),
|
||||
maxHp = maxHp,
|
||||
currentHp = max(0, min(maxHp, currentSheet?.currentHp ?: maxHp)),
|
||||
maxHp = editedSheet.maxHp.unpack()?.toIntOrNull()
|
||||
?: currentSheet?.maxHp
|
||||
?: 0,
|
||||
currentHp = editedSheet.currentHp.unpack()?.toIntOrNull()
|
||||
?: currentSheet?.currentHp
|
||||
?: 0,
|
||||
overrideMaxPP = editedSheet.maxPp.value.value.value.isNotBlank(),
|
||||
maxPp = maxPp,
|
||||
currentPp = max(0, min(maxPp, currentSheet?.currentPp ?: maxPp)),
|
||||
maxPp = editedSheet.maxPp.unpack()?.toIntOrNull()
|
||||
?: currentSheet?.maxPp
|
||||
?: 0,
|
||||
currentPp = editedSheet.currentPp.unpack()?.toIntOrNull()
|
||||
?: currentSheet?.currentPp
|
||||
?: 0,
|
||||
overrideDamageBonus = editedSheet.damageBonus.value.value.value.isNotBlank(),
|
||||
damageBonus = editedSheet.damageBonus.unpack()
|
||||
?: currentSheet?.damageBonus
|
||||
|
|
@ -226,10 +231,25 @@ class CharacterSheetEditFactory(
|
|||
val specialSkillsLabel = getString(Res.string.character_sheet_edit__skills__special_title)
|
||||
val magicSkillsLabel = getString(Res.string.character_sheet_edit__skills__magic_title)
|
||||
|
||||
val maxHitPoint = SimpleFieldUio(
|
||||
label = getString(Res.string.character_sheet_edit__sub_characteristics__max_hit_point),
|
||||
value = skillFactory.createWrapper(
|
||||
value = if (sheet?.overrideMaxHp == true) "${sheet.maxHp}" else "",
|
||||
placeholder = derivedStateOf { "${ceil((con() + hei()) / 2f).toInt()}" },
|
||||
)
|
||||
)
|
||||
val maxPowerPoint = SimpleFieldUio(
|
||||
label = getString(Res.string.character_sheet_edit__sub_characteristics__max_power_point),
|
||||
value = skillFactory.createWrapper(
|
||||
value = if (sheet?.overrideMaxPP == true) "${sheet.maxPp}" else "",
|
||||
placeholder = derivedStateOf { "${pow()}" },
|
||||
)
|
||||
)
|
||||
|
||||
return CharacterSheetEditPageUio(
|
||||
id = sheet?.id ?: UUID.randomUUID().toString(),
|
||||
name = skillFactory.createWrapper(
|
||||
label = getString(Res.string.character_sheet_edit__name_placeholder),
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__name_label)),
|
||||
value = sheet?.name ?: ""
|
||||
),
|
||||
strength = str,
|
||||
|
|
@ -246,18 +266,32 @@ class CharacterSheetEditFactory(
|
|||
placeholder = mutableStateOf("10"),
|
||||
)
|
||||
),
|
||||
maxHp = SimpleFieldUio(
|
||||
maxHp = maxHitPoint,
|
||||
currentHp = SimpleFieldUio(
|
||||
label = getString(Res.string.character_sheet_edit__sub_characteristics__hit_point),
|
||||
value = skillFactory.createWrapper(
|
||||
value = if (sheet?.overrideMaxHp == true) "${sheet.maxHp}" else "",
|
||||
placeholder = derivedStateOf { "${ceil((con() + hei()) / 2f).toInt()}" },
|
||||
enable = false,
|
||||
placeholder = derivedStateOf {
|
||||
val min = min(
|
||||
sheet?.currentHp ?: Int.MAX_VALUE,
|
||||
maxHitPoint.unpack()?.toIntOrNull() ?: Int.MAX_VALUE,
|
||||
)
|
||||
if (min != Int.MAX_VALUE) "$min" else ""
|
||||
},
|
||||
)
|
||||
),
|
||||
maxPp = SimpleFieldUio(
|
||||
maxPp = maxPowerPoint,
|
||||
currentPp = SimpleFieldUio(
|
||||
label = getString(Res.string.character_sheet_edit__sub_characteristics__power_point),
|
||||
value = skillFactory.createWrapper(
|
||||
value = if (sheet?.overrideMaxPP == true) "${sheet.maxPp}" else "",
|
||||
placeholder = derivedStateOf { "${pow()}" },
|
||||
enable = false,
|
||||
placeholder = derivedStateOf {
|
||||
val min = min(
|
||||
sheet?.currentPp ?: Int.MAX_VALUE,
|
||||
maxPowerPoint.unpack()?.toIntOrNull() ?: Int.MAX_VALUE,
|
||||
)
|
||||
if (min != Int.MAX_VALUE) "$min" else ""
|
||||
},
|
||||
)
|
||||
),
|
||||
damageBonus = SimpleFieldUio(
|
||||
|
|
@ -284,97 +318,97 @@ class CharacterSheetEditFactory(
|
|||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.COMBAT_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__combat),
|
||||
base = derivedStateOf { normalize(dex() * 2) },
|
||||
base = derivedStateOf { normalizer.normalize(dex() * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.DODGE_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__dodge),
|
||||
base = derivedStateOf { normalize(dex() * 2) },
|
||||
base = derivedStateOf { normalizer.normalize(dex() * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.GRAB_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__grab),
|
||||
base = derivedStateOf { normalize(str() + hei()) },
|
||||
base = derivedStateOf { normalizer.normalize(str() + hei()) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.THROW_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__throw),
|
||||
base = derivedStateOf { normalize(str() + dex()) },
|
||||
base = derivedStateOf { normalizer.normalize(str() + dex()) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.ATHLETICS_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__athletics),
|
||||
base = derivedStateOf { normalize(str() + con() * 2) },
|
||||
base = derivedStateOf { normalizer.normalize(str() + con() * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.ACROBATICS_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__acrobatics),
|
||||
base = derivedStateOf { normalize(dex() + con() * 2) },
|
||||
base = derivedStateOf { normalizer.normalize(dex() + con() * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.PERCEPTION_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__perception),
|
||||
base = derivedStateOf { normalize(10 + int() * 2) },
|
||||
base = derivedStateOf { normalizer.normalize(10 + int() * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.SEARCH_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__search),
|
||||
base = derivedStateOf { normalize(10 + int() * 2) },
|
||||
base = derivedStateOf { normalizer.normalize(10 + int() * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.EMPATHY_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__empathy),
|
||||
base = derivedStateOf { normalize(cha() + int()) },
|
||||
base = derivedStateOf { normalizer.normalize(cha() + int()) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.PERSUASION_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__persuasion),
|
||||
base = derivedStateOf { normalize(cha() * 3) },
|
||||
base = derivedStateOf { normalizer.normalize(cha() * 3) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.INTIMIDATION_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__intimidation),
|
||||
base = derivedStateOf { normalize(cha() + max(pow(), hei()) * 2) },
|
||||
base = derivedStateOf { normalizer.normalize(cha() + max(pow(), hei()) * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.SPIEL_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__spiel),
|
||||
base = derivedStateOf { normalize(cha() * 2 + int()) },
|
||||
base = derivedStateOf { normalizer.normalize(cha() * 2 + int()) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.BARGAIN_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__bargain),
|
||||
base = derivedStateOf { normalize(cha() * 2) },
|
||||
base = derivedStateOf { normalizer.normalize(cha() * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.DISCRETION_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__discretion),
|
||||
base = derivedStateOf { normalize(cha() + dex() * 2 - hei()) },
|
||||
base = derivedStateOf { normalizer.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),
|
||||
base = derivedStateOf { normalize(dex() * 2) },
|
||||
base = derivedStateOf { normalizer.normalize(dex() * 2) },
|
||||
),
|
||||
createBaseSkill(
|
||||
sheet = sheet,
|
||||
id = CharacterSheet.CommonSkillId.AID_ID,
|
||||
label = getString(Res.string.character_sheet_edit__skills__aid),
|
||||
base = derivedStateOf { normalize(int() + dex()) },
|
||||
base = derivedStateOf { normalizer.normalize(int() + dex()) },
|
||||
),
|
||||
),
|
||||
specialSkills = sheet?.specialSkills?.map { skill ->
|
||||
|
|
@ -415,11 +449,11 @@ class CharacterSheetEditFactory(
|
|||
ActionFieldUio(
|
||||
id = action.id,
|
||||
label = skillFactory.createWrapper(
|
||||
label = getString(Res.string.character_sheet_edit__actions__name_label),
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__name_label)),
|
||||
value = action.label,
|
||||
),
|
||||
action = skillFactory.createWrapper(
|
||||
label = getString(Res.string.character_sheet_edit__actions__action_label),
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__action_label)),
|
||||
value = action.roll,
|
||||
),
|
||||
option = skillFactory.deleteOption { onDeleteSkill(action.id) },
|
||||
|
|
@ -441,11 +475,11 @@ class CharacterSheetEditFactory(
|
|||
label = label,
|
||||
base = base,
|
||||
bonus = skillFactory.createWrapper(
|
||||
label = getString(Res.string.character_sheet_edit__skills__bonus_label),
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__bonus_label)),
|
||||
value = skill?.bonus?.toString() ?: "",
|
||||
),
|
||||
level = skillFactory.createWrapper(
|
||||
label = getString(Res.string.character_sheet_edit__skills__level_label),
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__level_label)),
|
||||
value = skill?.level?.toString() ?: "",
|
||||
),
|
||||
option = skillFactory.occupationOption(skill?.occupation ?: false),
|
||||
|
|
|
|||
|
|
@ -69,7 +69,9 @@ data class CharacterSheetEditPageUio(
|
|||
val charisma: SimpleFieldUio,
|
||||
val movement: SimpleFieldUio,
|
||||
val maxHp: SimpleFieldUio,
|
||||
val currentHp: SimpleFieldUio,
|
||||
val maxPp: SimpleFieldUio,
|
||||
val currentPp: SimpleFieldUio,
|
||||
val damageBonus: SimpleFieldUio,
|
||||
val armor: SimpleFieldUio,
|
||||
val commonSkills: List<BaseSkillFieldUio>,
|
||||
|
|
@ -92,7 +94,9 @@ data class CharacterSheetEditPageUio(
|
|||
get() = listOf(
|
||||
movement,
|
||||
maxHp,
|
||||
currentHp,
|
||||
maxPp,
|
||||
currentPp,
|
||||
damageBonus,
|
||||
armor,
|
||||
)
|
||||
|
|
@ -187,54 +191,60 @@ fun CharacterSheetEdit(
|
|||
wrapper = form.name,
|
||||
)
|
||||
|
||||
DecoratedBox(
|
||||
modifier = Modifier.animateContentSize(),
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 16.dp)
|
||||
) {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
DecoratedBox(
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
) {
|
||||
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,
|
||||
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.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__sub_characteristics__title),
|
||||
)
|
||||
form.subCharacteristics.forEach {
|
||||
SimpleField(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
field = it,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DecoratedBox(
|
||||
modifier = Modifier.animateContentSize(),
|
||||
) {
|
||||
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__sub_characteristics__title),
|
||||
)
|
||||
form.subCharacteristics.forEach {
|
||||
SimpleField(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
field = it,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DecoratedBox(
|
||||
modifier = Modifier.animateContentSize(),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.animateContentSize(),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
|
|
@ -256,9 +266,12 @@ fun CharacterSheetEdit(
|
|||
}
|
||||
|
||||
DecoratedBox(
|
||||
modifier = Modifier.animateContentSize(),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.animateContentSize(),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
|
|
@ -299,9 +312,12 @@ fun CharacterSheetEdit(
|
|||
}
|
||||
|
||||
DecoratedBox(
|
||||
modifier = Modifier.animateContentSize(),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.animateContentSize(),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Text(
|
||||
|
|
|
|||
|
|
@ -79,10 +79,10 @@ class CharacterSheetEditViewModel(
|
|||
val field = ActionFieldUio(
|
||||
id = id,
|
||||
label = skillFactory.createWrapper(
|
||||
label = getString(Res.string.character_sheet_edit__actions__name_label),
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__name_label)),
|
||||
),
|
||||
action = skillFactory.createWrapper(
|
||||
label = getString(Res.string.character_sheet_edit__actions__action_label),
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__action_label)),
|
||||
),
|
||||
option = skillFactory.deleteOption { deleteSkill(id) },
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.pixelized.desktop.lwa.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.screen.characterSheet.edit.composable.SkillFieldUio
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.ActionOption
|
||||
|
|
@ -29,22 +30,28 @@ class SkillFieldFactory {
|
|||
levelValue: String = "",
|
||||
options: List<OptionUio> = emptyList(),
|
||||
): SkillFieldUio {
|
||||
val baseLabel = getString(Res.string.character_sheet_edit__skills__base_label)
|
||||
return SkillFieldUio(
|
||||
id = id,
|
||||
label = createWrapper(
|
||||
label = label,
|
||||
label = mutableStateOf(labelValue),
|
||||
value = labelValue,
|
||||
),
|
||||
base = createWrapper(
|
||||
label = getString(Res.string.character_sheet_edit__skills__base_label),
|
||||
label = derivedStateOf {
|
||||
options
|
||||
.firstOrNull { it is CheckedOption && it.checked.value }
|
||||
?.let { "$baseLabel *" }
|
||||
?: baseLabel
|
||||
},
|
||||
value = baseValue,
|
||||
),
|
||||
bonus = createWrapper(
|
||||
label = getString(Res.string.character_sheet_edit__skills__bonus_label),
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__bonus_label)),
|
||||
value = bonusValue,
|
||||
),
|
||||
level = createWrapper(
|
||||
label = getString(Res.string.character_sheet_edit__skills__level_label),
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__level_label)),
|
||||
value = levelValue,
|
||||
),
|
||||
options = options,
|
||||
|
|
@ -53,7 +60,7 @@ class SkillFieldFactory {
|
|||
|
||||
fun createWrapper(
|
||||
enable: Boolean = true,
|
||||
label: String? = null,
|
||||
label: State<String?> = mutableStateOf(null),
|
||||
placeholder: State<String?> = mutableStateOf(null),
|
||||
value: String = "",
|
||||
): TextFieldWrapperUio {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ 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
|
||||
|
|
@ -47,6 +48,17 @@ fun BaseSkillForm(
|
|||
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,
|
||||
|
|
@ -73,7 +85,7 @@ fun BaseSkillForm(
|
|||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
color = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium),
|
||||
text = stringResource(Res.string.character_sheet_edit__skills__base_label),
|
||||
text = baseLabel.value,
|
||||
)
|
||||
Text(
|
||||
style = MaterialTheme.typography.body1,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,7 @@
|
|||
package com.pixelized.desktop.lwa.screen.characterSheet.edit.composable
|
||||
|
||||
import androidx.compose.desktop.ui.tooling.preview.Preview
|
||||
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.width
|
||||
import androidx.compose.material.DropdownMenu
|
||||
|
|
@ -12,7 +9,6 @@ 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.Delete
|
||||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
|
|
@ -21,15 +17,10 @@ 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.singleWindowApplication
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield.TextFieldWrapperUio
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield.TextFieldWrapper
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.ActionOption
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.CheckedOption
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.DropDownMenuItemWrapper
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.option.OptionUio
|
||||
import com.pixelized.desktop.lwa.utils.preview.ContentPreview
|
||||
import java.util.UUID
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield.TextFieldWrapper
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.textfield.TextFieldWrapperUio
|
||||
|
||||
@Stable
|
||||
class SkillFieldUio(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.pixelized.desktop.lwa.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
|
||||
|
|
@ -7,17 +8,18 @@ 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.graphics.Color
|
||||
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
|
||||
|
||||
@Stable
|
||||
data class TextFieldWrapperUio(
|
||||
val enable: Boolean,
|
||||
val label: String?,
|
||||
val label: State<String?>,
|
||||
val value: State<String>,
|
||||
val placeholder: State<String?>,
|
||||
val onValueChange: (String) -> Unit,
|
||||
|
|
@ -28,12 +30,18 @@ fun TextFieldWrapper(
|
|||
modifier: Modifier = Modifier,
|
||||
wrapper: TextFieldWrapperUio,
|
||||
) {
|
||||
val colorScheme = MaterialTheme.colors
|
||||
val focus = LocalFocusManager.current
|
||||
|
||||
TextField(
|
||||
modifier = modifier,
|
||||
modifier = Modifier.height(height = 56.dp).then(other = modifier),
|
||||
colors = TextFieldDefaults.textFieldColors(
|
||||
backgroundColor = MaterialTheme.colors.onSurface.copy(alpha = 0.03f),
|
||||
backgroundColor = remember(wrapper.enable) {
|
||||
when (wrapper.enable) {
|
||||
true -> colorScheme.onSurface.copy(alpha = 0.03f)
|
||||
else -> colorScheme.surface
|
||||
}
|
||||
},
|
||||
),
|
||||
keyboardActions = rememberKeyboardActions {
|
||||
focus.moveFocus(FocusDirection.Next)
|
||||
|
|
@ -49,7 +57,7 @@ fun TextFieldWrapper(
|
|||
)
|
||||
}
|
||||
},
|
||||
label = wrapper.label?.let {
|
||||
label = wrapper.label.value?.let {
|
||||
{
|
||||
Text(
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import com.pixelized.desktop.lwa.business.SkillStepUseCase
|
|||
import com.pixelized.desktop.lwa.business.SkillValueComputationUseCase
|
||||
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
|
||||
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
|
||||
import com.pixelized.desktop.lwa.repository.roll.RollHistoryRepository
|
||||
import com.pixelized.desktop.lwa.repository.roll_history.RollHistoryRepository
|
||||
import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetPageUio
|
||||
import com.pixelized.desktop.lwa.screen.roll.DifficultyUio.Difficulty
|
||||
import kotlinx.coroutines.Job
|
||||
|
|
@ -34,6 +34,7 @@ class RollViewModel(
|
|||
private val characterSheetRepository: CharacterSheetRepository,
|
||||
private val rollHistoryRepository: RollHistoryRepository,
|
||||
private val skillComputation: SkillValueComputationUseCase,
|
||||
private val skillStepUseCase: SkillStepUseCase,
|
||||
) : ViewModel() {
|
||||
|
||||
private lateinit var sheet: CharacterSheet
|
||||
|
|
@ -107,7 +108,7 @@ class RollViewModel(
|
|||
this.rollSuccessValue = rollSuccessValue
|
||||
|
||||
val rollStep = rollSuccessValue?.let {
|
||||
SkillStepUseCase.computeSkillStep(skill = it)
|
||||
skillStepUseCase.computeSkillStep(skill = it)
|
||||
}
|
||||
|
||||
_rollResult.value = null
|
||||
|
|
@ -158,7 +159,7 @@ class RollViewModel(
|
|||
delay(500)
|
||||
|
||||
val rollStep = rollSuccessValue?.let {
|
||||
SkillStepUseCase.computeSkillStep(
|
||||
skillStepUseCase.computeSkillStep(
|
||||
skill = when (_rollDifficulty.value?.difficulty) {
|
||||
Difficulty.EASY -> it * 2
|
||||
Difficulty.NORMAL -> it
|
||||
|
|
@ -221,7 +222,7 @@ class RollViewModel(
|
|||
difficulty = difficulty,
|
||||
)
|
||||
val rollStep = rollSuccessValue?.let {
|
||||
SkillStepUseCase.computeSkillStep(
|
||||
skillStepUseCase.computeSkillStep(
|
||||
skill = when (_rollDifficulty.value?.difficulty) {
|
||||
Difficulty.EASY -> it * 2
|
||||
Difficulty.NORMAL -> it
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import androidx.compose.runtime.State
|
|||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.pixelized.desktop.lwa.navigation.screen.LocalScreenController
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.roll_history__title
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import androidx.compose.runtime.mutableStateOf
|
|||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.pixelized.desktop.lwa.repository.network.protocol.RollMessage
|
||||
import com.pixelized.desktop.lwa.repository.roll.RollHistoryRepository
|
||||
import com.pixelized.desktop.lwa.repository.roll_history.RollHistoryRepository
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class RollHistoryViewModel(
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
package com.pixelized.desktop.lwa.utils.extention
|
||||
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.ObjectInputStream
|
||||
import java.io.ObjectOutputStream
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> ByteArray.fromByteArray(): T {
|
||||
val byteArrayInputStream = ByteArrayInputStream(this)
|
||||
val objectInput = ObjectInputStream(byteArrayInputStream)
|
||||
val result = objectInput.readObject() as T
|
||||
objectInput.close()
|
||||
byteArrayInputStream.close()
|
||||
return result
|
||||
}
|
||||
|
||||
fun Any.toByteArray(): ByteArray {
|
||||
val byteArrayOutputStream = ByteArrayOutputStream()
|
||||
val objectOutputStream = ObjectOutputStream(byteArrayOutputStream)
|
||||
objectOutputStream.writeObject(this)
|
||||
objectOutputStream.flush()
|
||||
val result = byteArrayOutputStream.toByteArray()
|
||||
byteArrayOutputStream.close()
|
||||
objectOutputStream.close()
|
||||
return result
|
||||
}
|
||||
|
|
@ -7,7 +7,6 @@ androidx-lifecycle = "2.8.3"
|
|||
androidx-navigation = "2.8.0-alpha10"
|
||||
ktor_version = "3.0.0"
|
||||
koin = "4.0.0"
|
||||
koinComposeMultiplatform = "1.2.0-Beta4"
|
||||
|
||||
[plugins]
|
||||
composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "compose-multiplatform" }
|
||||
|
|
@ -15,7 +14,6 @@ composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "k
|
|||
kotlinSerialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
|
||||
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
|
||||
|
||||
|
||||
[libraries]
|
||||
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue