Change the UI of damage & fatigue dialogs.
This commit is contained in:
parent
741bb7cf25
commit
894d8db493
15 changed files with 354 additions and 223 deletions
|
|
@ -84,6 +84,7 @@
|
||||||
<string name="character_sheet_edit__sub_characteristics__max_hit_point">Points de vie maximum</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__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__max_power_point">Points de pouvoir maximum</string>
|
||||||
|
<string name="character_sheet_edit__use_armor">Utiliser l'armure</string>
|
||||||
<string name="character_sheet_edit__sub_characteristics__power_point">Points de pouvoir</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__damage_bonus">Bonus aux dégats</string>
|
||||||
<string name="character_sheet_edit__sub_characteristics__armor">Armure</string>
|
<string name="character_sheet_edit__sub_characteristics__armor">Armure</string>
|
||||||
|
|
@ -253,6 +254,7 @@
|
||||||
|
|
||||||
<string name="chat__diminished_change">%1$s passe à %2$d d'état diminuée</string>
|
<string name="chat__diminished_change">%1$s passe à %2$d d'état diminuée</string>
|
||||||
<string name="chat__characteristic_change__hp_down">%1$s subit %2$d point(s) de dommage</string>
|
<string name="chat__characteristic_change__hp_down">%1$s subit %2$d point(s) de dommage</string>
|
||||||
|
<string name="chat__characteristic_change__hp_down_armor">%1$s subit %2$d point(s) de dommage (armure : %3$d)</string>
|
||||||
<string name="chat__characteristic_change__hp_up">%1$s récupère %2$d point(s) de vie</string>
|
<string name="chat__characteristic_change__hp_up">%1$s récupère %2$d point(s) de vie</string>
|
||||||
<string name="chat__characteristic_change__pp_down">%1$s utilise %2$d point(s) de pouvoir</string>
|
<string name="chat__characteristic_change__pp_down">%1$s utilise %2$d point(s) de pouvoir</string>
|
||||||
<string name="chat__characteristic_change__pp_up">%1$s récupère %2$d point(s) de pouvoir</string>
|
<string name="chat__characteristic_change__pp_up">%1$s récupère %2$d point(s) de pouvoir</string>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.pixelized.desktop.lwa.ui.composable.button
|
||||||
|
|
||||||
|
import androidx.compose.animation.core.Spring
|
||||||
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
|
import androidx.compose.animation.core.spring
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.material.Icon
|
||||||
|
import androidx.compose.material.IconButton
|
||||||
|
import androidx.compose.material.MaterialTheme
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
|
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import lwacharactersheet.composeapp.generated.resources.Res
|
||||||
|
import lwacharactersheet.composeapp.generated.resources.ic_remove_24dp
|
||||||
|
import org.jetbrains.compose.resources.painterResource
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SignButton(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
interactionSource: MutableInteractionSource? = null,
|
||||||
|
enabled: Boolean = true,
|
||||||
|
add: StateFlow<Boolean>,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
) {
|
||||||
|
IconButton(
|
||||||
|
onClick = onClick,
|
||||||
|
modifier = modifier,
|
||||||
|
enabled = enabled,
|
||||||
|
interactionSource = interactionSource,
|
||||||
|
) {
|
||||||
|
val rotation = animateFloatAsState(
|
||||||
|
animationSpec = spring(stiffness = Spring.StiffnessMediumLow),
|
||||||
|
targetValue = when (add.collectAsState().value) {
|
||||||
|
true -> 90f
|
||||||
|
else -> 0f
|
||||||
|
}
|
||||||
|
)
|
||||||
|
Icon(
|
||||||
|
modifier = Modifier.graphicsLayer {
|
||||||
|
this.rotationZ = rotation.value * 2f
|
||||||
|
},
|
||||||
|
painter = painterResource(Res.drawable.ic_remove_24dp),
|
||||||
|
tint = MaterialTheme.lwa.colorScheme.base.primary,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
Icon(
|
||||||
|
modifier = Modifier.graphicsLayer {
|
||||||
|
this.rotationZ = rotation.value * 3f
|
||||||
|
},
|
||||||
|
painter = painterResource(Res.drawable.ic_remove_24dp),
|
||||||
|
tint = MaterialTheme.lwa.colorScheme.base.primary,
|
||||||
|
contentDescription = null
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,40 +1,43 @@
|
||||||
package com.pixelized.desktop.lwa.ui.composable.character.characteristic
|
package com.pixelized.desktop.lwa.ui.composable.character.characteristic
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.text.BasicTextField
|
|
||||||
import androidx.compose.foundation.text.KeyboardActions
|
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.Surface
|
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.material.TextButton
|
import androidx.compose.material.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
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.text.font.FontWeight
|
import androidx.compose.ui.input.key.KeyEventType
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
import androidx.compose.ui.input.key.key
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.input.key.type
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.unit.DpSize
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.Dialog
|
import com.pixelized.desktop.lwa.ui.composable.button.SignButton
|
||||||
import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox
|
import com.pixelized.desktop.lwa.ui.composable.character.LwaDialog
|
||||||
import com.pixelized.desktop.lwa.utils.extention.onPreviewEscape
|
import com.pixelized.desktop.lwa.ui.composable.checkbox.LwaCheckBox
|
||||||
|
import com.pixelized.desktop.lwa.ui.composable.checkbox.LwaCheckBoxUio
|
||||||
|
import com.pixelized.desktop.lwa.ui.composable.key.KeyHandler
|
||||||
|
import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextField
|
||||||
|
import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextFieldUio
|
||||||
|
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import lwacharactersheet.composeapp.generated.resources.Res
|
import lwacharactersheet.composeapp.generated.resources.Res
|
||||||
|
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__use_armor
|
||||||
import lwacharactersheet.composeapp.generated.resources.dialog__cancel_action
|
import lwacharactersheet.composeapp.generated.resources.dialog__cancel_action
|
||||||
import lwacharactersheet.composeapp.generated.resources.dialog__confirm_action
|
import lwacharactersheet.composeapp.generated.resources.dialog__confirm_action
|
||||||
import org.jetbrains.compose.resources.stringResource
|
import org.jetbrains.compose.resources.stringResource
|
||||||
|
|
@ -44,9 +47,10 @@ data class CharacterSheetCharacteristicDialogUio(
|
||||||
val characterSheetId: String,
|
val characterSheetId: String,
|
||||||
val characteristic: Characteristic,
|
val characteristic: Characteristic,
|
||||||
val label: String,
|
val label: String,
|
||||||
val value: () -> TextFieldValue,
|
val add: StateFlow<Boolean>,
|
||||||
val onValueChange: (TextFieldValue) -> Unit,
|
val value: LwaTextFieldUio,
|
||||||
val maxValue: String,
|
val enableArmor: LwaCheckBoxUio?,
|
||||||
|
val enableConfirm: StateFlow<Boolean>,
|
||||||
) {
|
) {
|
||||||
@Stable
|
@Stable
|
||||||
enum class Characteristic {
|
enum class Characteristic {
|
||||||
|
|
@ -55,125 +59,131 @@ data class CharacterSheetCharacteristicDialogUio(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Stable
|
||||||
fun CharacterSheetCharacteristicDialog(
|
object CharacterSheetCharacteristicDialogDefault {
|
||||||
dialog: State<CharacterSheetCharacteristicDialogUio?>,
|
@Stable
|
||||||
onConfirm: (CharacterSheetCharacteristicDialogUio) -> Unit,
|
val paddings: PaddingValues =
|
||||||
onDismissRequest: () -> Unit,
|
PaddingValues(top = 16.dp, start = 8.dp, end = 8.dp, bottom = 8.dp)
|
||||||
) {
|
|
||||||
dialog.value?.let {
|
@Stable
|
||||||
Dialog(
|
val spacings: DpSize = DpSize(width = 4.dp, height = 8.dp)
|
||||||
onDismissRequest = onDismissRequest,
|
|
||||||
content = {
|
|
||||||
CharacterSheetCharacteristicContent(
|
|
||||||
dialog = it,
|
|
||||||
onConfirm = onConfirm,
|
|
||||||
onDismissRequest = onDismissRequest,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun CharacterSheetCharacteristicContent(
|
fun CharacterSheetCharacteristicDialog(
|
||||||
dialog: CharacterSheetCharacteristicDialogUio,
|
dialog: State<CharacterSheetCharacteristicDialogUio?>,
|
||||||
|
paddings: PaddingValues = CharacterSheetCharacteristicDialogDefault.paddings,
|
||||||
|
spacings: DpSize = CharacterSheetCharacteristicDialogDefault.spacings,
|
||||||
onConfirm: (CharacterSheetCharacteristicDialogUio) -> Unit,
|
onConfirm: (CharacterSheetCharacteristicDialogUio) -> Unit,
|
||||||
|
onSwapSign: (CharacterSheetCharacteristicDialogUio) -> Unit,
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
) {
|
) {
|
||||||
val typography = MaterialTheme.typography
|
LwaDialog(
|
||||||
val colors = MaterialTheme.colors
|
state = dialog,
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
onConfirm = { dialog.value?.let(onConfirm) }
|
||||||
|
) { state ->
|
||||||
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
LaunchedEffect(Unit) { focusRequester.requestFocus() }
|
||||||
|
|
||||||
val focusRequester = remember { FocusRequester() }
|
CharacterSheetCharacteristicDialogKeyHandler(
|
||||||
LaunchedEffect(Unit) {
|
onSwap = { onSwapSign(state) },
|
||||||
focusRequester.requestFocus()
|
)
|
||||||
}
|
|
||||||
|
|
||||||
Box(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier.padding(paddingValues = paddings),
|
||||||
.clickable(
|
verticalArrangement = Arrangement.spacedBy(space = spacings.height),
|
||||||
interactionSource = remember { MutableInteractionSource() },
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
indication = null,
|
) {
|
||||||
onClick = onDismissRequest,
|
Text(
|
||||||
|
style = MaterialTheme.typography.caption,
|
||||||
|
text = state.label,
|
||||||
)
|
)
|
||||||
.onPreviewEscape(
|
|
||||||
escape = onDismissRequest,
|
Row(
|
||||||
enter = { onConfirm(dialog) },
|
horizontalArrangement = Arrangement.spacedBy(space = spacings.width),
|
||||||
)
|
verticalAlignment = Alignment.Bottom,
|
||||||
.fillMaxSize()
|
) {
|
||||||
.padding(all = 32.dp),
|
SignButton(
|
||||||
contentAlignment = Alignment.Center,
|
modifier = Modifier
|
||||||
) {
|
.size(size = 56.dp)
|
||||||
DecoratedBox {
|
.background(
|
||||||
Surface {
|
color = MaterialTheme.lwa.colorScheme.elevated.base1dp,
|
||||||
Column(
|
shape = MaterialTheme.shapes.small,
|
||||||
verticalArrangement = Arrangement.spacedBy(space = 8.dp),
|
),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
add = state.add,
|
||||||
|
onClick = { onSwapSign(state) },
|
||||||
|
)
|
||||||
|
LwaTextField(
|
||||||
|
modifier = Modifier
|
||||||
|
.focusRequester(focusRequester = focusRequester)
|
||||||
|
.width(192.dp),
|
||||||
|
field = state.value,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
state.enableArmor?.let {
|
||||||
|
Row (
|
||||||
|
modifier = Modifier.align(alignment = Alignment.End),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(
|
||||||
|
space = spacings.width,
|
||||||
|
alignment = Alignment.End
|
||||||
|
),
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.padding(top = 16.dp, start = 24.dp, end = 24.dp),
|
|
||||||
style = MaterialTheme.typography.caption,
|
style = MaterialTheme.typography.caption,
|
||||||
text = dialog.label,
|
text = stringResource(Res.string.character_sheet_edit__use_armor),
|
||||||
|
)
|
||||||
|
LwaCheckBox(
|
||||||
|
field = it,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.align(alignment = Alignment.End),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(
|
||||||
|
space = spacings.width,
|
||||||
|
alignment = Alignment.End
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
TextButton(
|
||||||
|
onClick = onDismissRequest,
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
color = MaterialTheme.colors.primary.copy(alpha = .7f),
|
||||||
|
text = stringResource(Res.string.dialog__cancel_action)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
TextButton(
|
||||||
|
enabled = state.enableConfirm.collectAsState().value,
|
||||||
|
onClick = { onConfirm(state) },
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = stringResource(Res.string.dialog__confirm_action)
|
||||||
)
|
)
|
||||||
Row(
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
|
||||||
) {
|
|
||||||
BasicTextField(
|
|
||||||
modifier = Modifier
|
|
||||||
.focusRequester(focusRequester = focusRequester)
|
|
||||||
.alignByBaseline()
|
|
||||||
.width(width = 120.dp),
|
|
||||||
textStyle = remember {
|
|
||||||
typography.h5.copy(
|
|
||||||
color = colors.primary,
|
|
||||||
textAlign = TextAlign.End,
|
|
||||||
fontWeight = FontWeight.Bold
|
|
||||||
)
|
|
||||||
},
|
|
||||||
cursorBrush = SolidColor(MaterialTheme.colors.primary),
|
|
||||||
singleLine = true,
|
|
||||||
keyboardActions = KeyboardActions { onConfirm(dialog) },
|
|
||||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
|
||||||
value = dialog.value(),
|
|
||||||
onValueChange = dialog.onValueChange,
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.alignByBaseline(),
|
|
||||||
text = "/",
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
modifier = Modifier.alignByBaseline(),
|
|
||||||
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)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun CharacterSheetCharacteristicDialogKeyHandler(
|
||||||
|
onSwap: () -> Unit,
|
||||||
|
) {
|
||||||
|
KeyHandler {
|
||||||
|
if (it.type == KeyEventType.KeyDown) {
|
||||||
|
when (it.key) {
|
||||||
|
Key.AltLeft, Key.AltRight -> {
|
||||||
|
onSwap()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,15 +1,22 @@
|
||||||
package com.pixelized.desktop.lwa.ui.composable.character.characteristic
|
package com.pixelized.desktop.lwa.ui.composable.character.characteristic
|
||||||
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.ui.text.TextRange
|
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
|
||||||
import com.pixelized.desktop.lwa.repository.alteration.AlterationRepository
|
import com.pixelized.desktop.lwa.repository.alteration.AlterationRepository
|
||||||
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
|
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
|
||||||
import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterSheetCharacteristicDialogUio.Characteristic
|
import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterSheetCharacteristicDialogUio.Characteristic
|
||||||
|
import com.pixelized.desktop.lwa.ui.composable.checkbox.createLwaCheckBox
|
||||||
|
import com.pixelized.desktop.lwa.ui.composable.checkbox.createLwaCheckBoxFlow
|
||||||
|
import com.pixelized.desktop.lwa.ui.composable.textfield.createLwaTextField
|
||||||
|
import com.pixelized.desktop.lwa.ui.composable.textfield.createLwaTextFieldFlow
|
||||||
import com.pixelized.shared.lwa.model.AlteredCharacterSheetFactory
|
import com.pixelized.shared.lwa.model.AlteredCharacterSheetFactory
|
||||||
import com.pixelized.shared.lwa.model.alteration.FieldAlteration
|
import com.pixelized.shared.lwa.model.alteration.FieldAlteration
|
||||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
|
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import lwacharactersheet.composeapp.generated.resources.Res
|
import lwacharactersheet.composeapp.generated.resources.Res
|
||||||
|
import lwacharactersheet.composeapp.generated.resources.character__inventory__add_to_purse__title
|
||||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__hit_point
|
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__hit_point
|
||||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__power_point
|
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__power_point
|
||||||
import org.jetbrains.compose.resources.getString
|
import org.jetbrains.compose.resources.getString
|
||||||
|
|
@ -19,9 +26,13 @@ class CharacterSheetCharacteristicDialogFactory(
|
||||||
private val alterationRepository: AlterationRepository,
|
private val alterationRepository: AlterationRepository,
|
||||||
private val alteredCharacterSheetFactory: AlteredCharacterSheetFactory,
|
private val alteredCharacterSheetFactory: AlteredCharacterSheetFactory,
|
||||||
) {
|
) {
|
||||||
|
private val decimalChecker = Regex("""^\s*\d*\s*${'$'}""")
|
||||||
|
|
||||||
suspend fun convertToDialogUio(
|
suspend fun convertToDialogUio(
|
||||||
|
scope: CoroutineScope,
|
||||||
characterSheetId: String?,
|
characterSheetId: String?,
|
||||||
characteristic: Characteristic,
|
characteristic: Characteristic,
|
||||||
|
signFlow: StateFlow<Boolean>,
|
||||||
): CharacterSheetCharacteristicDialogUio? {
|
): CharacterSheetCharacteristicDialogUio? {
|
||||||
|
|
||||||
if (characterSheetId == null) return null
|
if (characterSheetId == null) return null
|
||||||
|
|
@ -32,10 +43,10 @@ class CharacterSheetCharacteristicDialogFactory(
|
||||||
|
|
||||||
if (characterSheet == null) return null
|
if (characterSheet == null) return null
|
||||||
|
|
||||||
val alterations: Map<String, List<FieldAlteration>> = alterationRepository.activeFieldAlterations(
|
val alterations: Map<String, List<FieldAlteration>> =
|
||||||
characterSheetId = characterSheetId,
|
alterationRepository.activeFieldAlterations(
|
||||||
)
|
characterSheetId = characterSheetId,
|
||||||
|
)
|
||||||
val alteredCharacterSheet = alteredCharacterSheetFactory.sheet(
|
val alteredCharacterSheet = alteredCharacterSheetFactory.sheet(
|
||||||
characterSheet = characterSheet,
|
characterSheet = characterSheet,
|
||||||
alterations = alterations,
|
alterations = alterations,
|
||||||
|
|
@ -43,36 +54,61 @@ class CharacterSheetCharacteristicDialogFactory(
|
||||||
|
|
||||||
return when (characteristic) {
|
return when (characteristic) {
|
||||||
Characteristic.Damage -> {
|
Characteristic.Damage -> {
|
||||||
val value = mutableStateOf(
|
val valueFlow = createLwaTextFieldFlow(
|
||||||
"${alteredCharacterSheet.maxHp - alteredCharacterSheet.damage}".let {
|
label = null,
|
||||||
TextFieldValue(text = it, selection = TextRange(it.length))
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
val armor = if (alteredCharacterSheet.armor > 0) {
|
||||||
|
createLwaCheckBoxFlow(
|
||||||
|
checked = true,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
CharacterSheetCharacteristicDialogUio(
|
CharacterSheetCharacteristicDialogUio(
|
||||||
characterSheetId = characterSheetId,
|
characterSheetId = characterSheetId,
|
||||||
characteristic = characteristic,
|
characteristic = characteristic,
|
||||||
label = getString(resource = Res.string.character_sheet_edit__sub_characteristics__hit_point),
|
label = getString(Res.string.character_sheet_edit__sub_characteristics__hit_point).let {
|
||||||
value = { value.value },
|
"$it : ${alteredCharacterSheet.maxHp - alteredCharacterSheet.damage}/${alteredCharacterSheet.maxHp}"
|
||||||
onValueChange = { value.value = it },
|
},
|
||||||
maxValue = "${alteredCharacterSheet.maxHp}",
|
add = signFlow,
|
||||||
|
value = valueFlow.createLwaTextField {
|
||||||
|
valueFlow.errorFlow.value = check(it)
|
||||||
|
valueFlow.valueFlow.value = it
|
||||||
|
},
|
||||||
|
enableArmor = armor?.createLwaCheckBox(),
|
||||||
|
enableConfirm = valueFlow.errorFlow.map { it.not() }.stateIn(
|
||||||
|
scope = scope,
|
||||||
|
started = SharingStarted.Lazily,
|
||||||
|
initialValue = valueFlow.errorFlow.value.not(),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Characteristic.Fatigue -> {
|
Characteristic.Fatigue -> {
|
||||||
val value = mutableStateOf(
|
val valueFlow = createLwaTextFieldFlow(
|
||||||
"${alteredCharacterSheet.maxPp - alteredCharacterSheet.fatigue}".let {
|
label = null,
|
||||||
TextFieldValue(text = it, selection = TextRange(it.length))
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
CharacterSheetCharacteristicDialogUio(
|
CharacterSheetCharacteristicDialogUio(
|
||||||
characterSheetId = characterSheetId,
|
characterSheetId = characterSheetId,
|
||||||
characteristic = characteristic,
|
characteristic = characteristic,
|
||||||
label = getString(resource = Res.string.character_sheet_edit__sub_characteristics__power_point),
|
label = getString(Res.string.character_sheet_edit__sub_characteristics__power_point).let {
|
||||||
value = { value.value },
|
"$it : ${alteredCharacterSheet.maxPp - alteredCharacterSheet.fatigue}/${alteredCharacterSheet.maxPp}"
|
||||||
onValueChange = { value.value = it },
|
},
|
||||||
maxValue = "${alteredCharacterSheet.maxPp}",
|
add = signFlow,
|
||||||
|
value = valueFlow.createLwaTextField {
|
||||||
|
valueFlow.errorFlow.value = check(it)
|
||||||
|
valueFlow.valueFlow.value = it
|
||||||
|
},
|
||||||
|
enableArmor = null,
|
||||||
|
enableConfirm = valueFlow.errorFlow.map { it.not() }.stateIn(
|
||||||
|
scope = scope,
|
||||||
|
started = SharingStarted.Lazily,
|
||||||
|
initialValue = valueFlow.errorFlow.value.not(),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun check(value: String): Boolean = !decimalChecker.matches(value)
|
||||||
}
|
}
|
||||||
|
|
@ -3,12 +3,15 @@ package com.pixelized.desktop.lwa.ui.composable.character.characteristic
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.pixelized.desktop.lwa.repository.alteration.AlterationRepository
|
import com.pixelized.desktop.lwa.repository.alteration.AlterationRepository
|
||||||
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
|
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
|
||||||
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
||||||
import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterSheetCharacteristicDialogUio.Characteristic
|
import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterSheetCharacteristicDialogUio.Characteristic
|
||||||
import com.pixelized.shared.lwa.model.AlteredCharacterSheetFactory
|
import com.pixelized.shared.lwa.model.AlteredCharacterSheetFactory
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.CharacterSheetEvent
|
import com.pixelized.shared.lwa.protocol.websocket.CharacterSheetEvent
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.update
|
||||||
|
|
||||||
class CharacterSheetCharacteristicDialogViewModel(
|
class CharacterSheetCharacteristicDialogViewModel(
|
||||||
private val characterSheetRepository: CharacterSheetRepository,
|
private val characterSheetRepository: CharacterSheetRepository,
|
||||||
|
|
@ -18,6 +21,8 @@ class CharacterSheetCharacteristicDialogViewModel(
|
||||||
private val network: NetworkRepository,
|
private val network: NetworkRepository,
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
|
private val signFlow = MutableStateFlow(false)
|
||||||
|
|
||||||
private val _statChangeDialog = mutableStateOf<CharacterSheetCharacteristicDialogUio?>(null)
|
private val _statChangeDialog = mutableStateOf<CharacterSheetCharacteristicDialogUio?>(null)
|
||||||
val statChangeDialog: State<CharacterSheetCharacteristicDialogUio?> get() = _statChangeDialog
|
val statChangeDialog: State<CharacterSheetCharacteristicDialogUio?> get() = _statChangeDialog
|
||||||
|
|
||||||
|
|
@ -25,19 +30,27 @@ class CharacterSheetCharacteristicDialogViewModel(
|
||||||
_statChangeDialog.value = null
|
_statChangeDialog.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun swapCharacteristicSign() {
|
||||||
|
signFlow.update { it.not() }
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun showSubCharacteristicDialog(
|
suspend fun showSubCharacteristicDialog(
|
||||||
characterSheetId: String?,
|
characterSheetId: String?,
|
||||||
characteristic: Characteristic,
|
characteristic: Characteristic,
|
||||||
) {
|
) {
|
||||||
|
signFlow.update { false }
|
||||||
_statChangeDialog.value = factory.convertToDialogUio(
|
_statChangeDialog.value = factory.convertToDialogUio(
|
||||||
|
scope = viewModelScope,
|
||||||
characterSheetId = characterSheetId,
|
characterSheetId = characterSheetId,
|
||||||
characteristic = characteristic,
|
characteristic = characteristic,
|
||||||
|
signFlow = signFlow,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun changeSubCharacteristic(
|
suspend fun changeSubCharacteristic(
|
||||||
characterSheetId: String?,
|
characterSheetId: String?,
|
||||||
characteristic: Characteristic,
|
characteristic: Characteristic,
|
||||||
|
useArmor: Boolean,
|
||||||
value: Int,
|
value: Int,
|
||||||
) {
|
) {
|
||||||
if (characterSheetId == null) return
|
if (characterSheetId == null) return
|
||||||
|
|
@ -49,29 +62,37 @@ class CharacterSheetCharacteristicDialogViewModel(
|
||||||
|
|
||||||
if (characterSheet == null) return
|
if (characterSheet == null) return
|
||||||
|
|
||||||
val alterations = alterationRepository.activeFieldAlterations(
|
val sign = if (signFlow.value) 1 else -1
|
||||||
characterSheetId = characterSheetId,
|
|
||||||
)
|
|
||||||
|
|
||||||
// we need the maximum HP / Power that the character sheet have.
|
|
||||||
val alteredSheet = alteredCharacterSheetFactory.sheet(
|
|
||||||
characterSheet = characterSheet,
|
|
||||||
alterations = alterations,
|
|
||||||
)
|
|
||||||
|
|
||||||
val message = when (characteristic) {
|
val message = when (characteristic) {
|
||||||
Characteristic.Damage -> CharacterSheetEvent.UpdateDamage(
|
Characteristic.Damage -> {
|
||||||
timestamp = System.currentTimeMillis(),
|
val armor = if (useArmor && signFlow.value.not()) {
|
||||||
characterSheetId = characterSheetId,
|
val alterations = alterationRepository.activeFieldAlterations(
|
||||||
oldValue = alteredSheet.damage,
|
characterSheetId = characterSheetId,
|
||||||
damage = alteredSheet.maxHp - value,
|
)
|
||||||
)
|
val alteredSheet = alteredCharacterSheetFactory.sheet(
|
||||||
|
characterSheet = characterSheet,
|
||||||
|
alterations = alterations,
|
||||||
|
)
|
||||||
|
alteredSheet.armor
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
|
CharacterSheetEvent.UpdateDamage(
|
||||||
|
timestamp = System.currentTimeMillis(),
|
||||||
|
characterSheetId = characterSheetId,
|
||||||
|
oldValue = characterSheet.damage,
|
||||||
|
damage = characterSheet.damage - value * sign - (armor ?: 0),
|
||||||
|
armor = armor,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Characteristic.Fatigue -> CharacterSheetEvent.UpdateFatigue(
|
Characteristic.Fatigue -> CharacterSheetEvent.UpdateFatigue(
|
||||||
timestamp = System.currentTimeMillis(),
|
timestamp = System.currentTimeMillis(),
|
||||||
characterSheetId = characterSheetId,
|
characterSheetId = characterSheetId,
|
||||||
oldValue = alteredSheet.fatigue,
|
oldValue = characterSheet.fatigue,
|
||||||
fatigue = alteredSheet.maxPp - value,
|
fatigue = characterSheet.fatigue - value * sign,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
package com.pixelized.desktop.lwa.ui.composable.character.purse
|
package com.pixelized.desktop.lwa.ui.composable.character.purse
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedContent
|
import androidx.compose.animation.AnimatedContent
|
||||||
import androidx.compose.animation.core.Spring
|
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
|
||||||
import androidx.compose.animation.core.spring
|
|
||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
||||||
import androidx.compose.animation.fadeOut
|
import androidx.compose.animation.fadeOut
|
||||||
import androidx.compose.animation.togetherWith
|
import androidx.compose.animation.togetherWith
|
||||||
|
|
@ -19,8 +16,6 @@ import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.material.Icon
|
|
||||||
import androidx.compose.material.IconButton
|
|
||||||
import androidx.compose.material.MaterialTheme
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.Surface
|
import androidx.compose.material.Surface
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
|
|
@ -35,13 +30,13 @@ import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
|
||||||
import androidx.compose.ui.input.key.Key
|
import androidx.compose.ui.input.key.Key
|
||||||
import androidx.compose.ui.input.key.KeyEventType
|
import androidx.compose.ui.input.key.KeyEventType
|
||||||
import androidx.compose.ui.input.key.key
|
import androidx.compose.ui.input.key.key
|
||||||
import androidx.compose.ui.input.key.type
|
import androidx.compose.ui.input.key.type
|
||||||
import androidx.compose.ui.unit.DpSize
|
import androidx.compose.ui.unit.DpSize
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.pixelized.desktop.lwa.ui.composable.button.SignButton
|
||||||
import com.pixelized.desktop.lwa.ui.composable.character.LwaDialog
|
import com.pixelized.desktop.lwa.ui.composable.character.LwaDialog
|
||||||
import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox
|
import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox
|
||||||
import com.pixelized.desktop.lwa.ui.composable.key.KeyHandler
|
import com.pixelized.desktop.lwa.ui.composable.key.KeyHandler
|
||||||
|
|
@ -53,8 +48,6 @@ import kotlinx.coroutines.flow.StateFlow
|
||||||
import lwacharactersheet.composeapp.generated.resources.Res
|
import lwacharactersheet.composeapp.generated.resources.Res
|
||||||
import lwacharactersheet.composeapp.generated.resources.dialog__cancel_action
|
import lwacharactersheet.composeapp.generated.resources.dialog__cancel_action
|
||||||
import lwacharactersheet.composeapp.generated.resources.dialog__confirm_action
|
import lwacharactersheet.composeapp.generated.resources.dialog__confirm_action
|
||||||
import lwacharactersheet.composeapp.generated.resources.ic_remove_24dp
|
|
||||||
import org.jetbrains.compose.resources.painterResource
|
|
||||||
import org.jetbrains.compose.resources.stringResource
|
import org.jetbrains.compose.resources.stringResource
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
|
|
@ -94,6 +87,10 @@ fun PurseDialog(
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
LaunchedEffect(Unit) { focusRequester.requestFocus() }
|
LaunchedEffect(Unit) { focusRequester.requestFocus() }
|
||||||
|
|
||||||
|
PurseDialogKeyHandler(
|
||||||
|
onSwap = { onSwapSign(state) },
|
||||||
|
)
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.padding(paddingValues = paddings),
|
modifier = Modifier.padding(paddingValues = paddings),
|
||||||
verticalArrangement = Arrangement.spacedBy(space = spacings.height),
|
verticalArrangement = Arrangement.spacedBy(space = spacings.height),
|
||||||
|
|
@ -162,10 +159,6 @@ fun PurseDialog(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PurseDialogKeyHandler(
|
|
||||||
onSwap = { onSwapSign(state) },
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,46 +195,6 @@ private fun PurseContent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun SignButton(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
interactionSource: MutableInteractionSource? = null,
|
|
||||||
enabled: Boolean = true,
|
|
||||||
add: StateFlow<Boolean>,
|
|
||||||
onClick: () -> Unit,
|
|
||||||
) {
|
|
||||||
IconButton(
|
|
||||||
onClick = onClick,
|
|
||||||
modifier = modifier,
|
|
||||||
enabled = enabled,
|
|
||||||
interactionSource = interactionSource,
|
|
||||||
) {
|
|
||||||
val rotation = animateFloatAsState(
|
|
||||||
animationSpec = spring(stiffness = Spring.StiffnessMediumLow),
|
|
||||||
targetValue = when (add.collectAsState().value) {
|
|
||||||
true -> 90f
|
|
||||||
else -> 0f
|
|
||||||
}
|
|
||||||
)
|
|
||||||
Icon(
|
|
||||||
modifier = Modifier.graphicsLayer {
|
|
||||||
this.rotationZ = rotation.value * 2f
|
|
||||||
},
|
|
||||||
painter = painterResource(Res.drawable.ic_remove_24dp),
|
|
||||||
tint = MaterialTheme.lwa.colorScheme.base.primary,
|
|
||||||
contentDescription = null
|
|
||||||
)
|
|
||||||
Icon(
|
|
||||||
modifier = Modifier.graphicsLayer {
|
|
||||||
this.rotationZ = rotation.value * 3f
|
|
||||||
},
|
|
||||||
painter = painterResource(Res.drawable.ic_remove_24dp),
|
|
||||||
tint = MaterialTheme.lwa.colorScheme.base.primary,
|
|
||||||
contentDescription = null
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun PurseDialogKeyHandler(
|
private fun PurseDialogKeyHandler(
|
||||||
onSwap: () -> Unit,
|
onSwap: () -> Unit,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.pixelized.desktop.lwa.ui.composable.checkbox
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Stable
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
||||||
|
@Stable
|
||||||
|
data class LwaCheckBoxFlow(
|
||||||
|
val checkedFlow: MutableStateFlow<Boolean>,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Stable
|
||||||
|
fun createLwaCheckBoxFlow(
|
||||||
|
checked: Boolean,
|
||||||
|
): LwaCheckBoxFlow {
|
||||||
|
return LwaCheckBoxFlow(
|
||||||
|
checkedFlow = MutableStateFlow(checked),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Stable
|
||||||
|
fun LwaCheckBoxFlow.createLwaCheckBox(
|
||||||
|
enable: Boolean = true,
|
||||||
|
onCheckedChange: (Boolean) -> Unit = { checkedFlow.value = it },
|
||||||
|
): LwaCheckBoxUio {
|
||||||
|
return LwaCheckBoxUio(
|
||||||
|
enable = enable,
|
||||||
|
checked = checkedFlow,
|
||||||
|
onCheckedChange = onCheckedChange,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -6,13 +6,13 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
@Stable
|
@Stable
|
||||||
data class LwaTextFieldFlow(
|
data class LwaTextFieldFlow(
|
||||||
val errorFlow: MutableStateFlow<Boolean>,
|
val errorFlow: MutableStateFlow<Boolean>,
|
||||||
val valueFlow: MutableStateFlow<String>,
|
|
||||||
val labelFlow: MutableStateFlow<String?>,
|
val labelFlow: MutableStateFlow<String?>,
|
||||||
|
val valueFlow: MutableStateFlow<String>,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun createLwaTextFieldFlow(
|
fun createLwaTextFieldFlow(
|
||||||
error: Boolean = false,
|
error: Boolean = false,
|
||||||
label: String,
|
label: String?,
|
||||||
value: String = "",
|
value: String = "",
|
||||||
): LwaTextFieldFlow {
|
): LwaTextFieldFlow {
|
||||||
return createLwaTextFieldFlow(
|
return createLwaTextFieldFlow(
|
||||||
|
|
@ -24,8 +24,8 @@ fun createLwaTextFieldFlow(
|
||||||
|
|
||||||
fun createLwaTextFieldFlow(
|
fun createLwaTextFieldFlow(
|
||||||
errorFlow: MutableStateFlow<Boolean> = MutableStateFlow(false),
|
errorFlow: MutableStateFlow<Boolean> = MutableStateFlow(false),
|
||||||
valueFlow: MutableStateFlow<String>,
|
|
||||||
labelFlow: MutableStateFlow<String?>,
|
labelFlow: MutableStateFlow<String?>,
|
||||||
|
valueFlow: MutableStateFlow<String>,
|
||||||
): LwaTextFieldFlow {
|
): LwaTextFieldFlow {
|
||||||
return LwaTextFieldFlow(
|
return LwaTextFieldFlow(
|
||||||
errorFlow = errorFlow,
|
errorFlow = errorFlow,
|
||||||
|
|
|
||||||
|
|
@ -206,12 +206,16 @@ fun CampaignScreen(
|
||||||
characteristicDialogViewModel.changeSubCharacteristic(
|
characteristicDialogViewModel.changeSubCharacteristic(
|
||||||
characterSheetId = dialog.characterSheetId,
|
characterSheetId = dialog.characterSheetId,
|
||||||
characteristic = dialog.characteristic,
|
characteristic = dialog.characteristic,
|
||||||
value = dialog.value().text.toIntOrNull() ?: 0,
|
useArmor= dialog.enableArmor?.checked?.value == true,
|
||||||
|
value = dialog.value.valueFlow.value.toIntOrNull() ?: 0,
|
||||||
)
|
)
|
||||||
characteristicDialogViewModel.hideSubCharacteristicDialog()
|
characteristicDialogViewModel.hideSubCharacteristicDialog()
|
||||||
blurController.hide()
|
blurController.hide()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onSwapSign = {
|
||||||
|
characteristicDialogViewModel.swapCharacteristicSign()
|
||||||
|
},
|
||||||
onDismissRequest = {
|
onDismissRequest = {
|
||||||
characteristicDialogViewModel.hideSubCharacteristicDialog()
|
characteristicDialogViewModel.hideSubCharacteristicDialog()
|
||||||
blurController.hide()
|
blurController.hide()
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import com.pixelized.shared.lwa.protocol.websocket.RollEvent
|
||||||
import com.pixelized.shared.lwa.protocol.websocket.SocketMessage
|
import com.pixelized.shared.lwa.protocol.websocket.SocketMessage
|
||||||
import lwacharactersheet.composeapp.generated.resources.Res
|
import lwacharactersheet.composeapp.generated.resources.Res
|
||||||
import lwacharactersheet.composeapp.generated.resources.chat__characteristic_change__hp_down
|
import lwacharactersheet.composeapp.generated.resources.chat__characteristic_change__hp_down
|
||||||
|
import lwacharactersheet.composeapp.generated.resources.chat__characteristic_change__hp_down_armor
|
||||||
import lwacharactersheet.composeapp.generated.resources.chat__characteristic_change__hp_up
|
import lwacharactersheet.composeapp.generated.resources.chat__characteristic_change__hp_up
|
||||||
import lwacharactersheet.composeapp.generated.resources.chat__characteristic_change__pp_down
|
import lwacharactersheet.composeapp.generated.resources.chat__characteristic_change__pp_down
|
||||||
import lwacharactersheet.composeapp.generated.resources.chat__characteristic_change__pp_up
|
import lwacharactersheet.composeapp.generated.resources.chat__characteristic_change__pp_up
|
||||||
|
|
@ -94,16 +95,19 @@ class TextMessageFactory(
|
||||||
?: return null
|
?: return null
|
||||||
// We are talking about damage / consumption there so old value have to be put first.
|
// We are talking about damage / consumption there so old value have to be put first.
|
||||||
val value = message.oldValue - message.damage
|
val value = message.oldValue - message.damage
|
||||||
|
val armor = message.armor
|
||||||
|
|
||||||
CharacteristicTextMessageUio(
|
CharacteristicTextMessageUio(
|
||||||
id = "${message.timestamp}-${message.characterSheetId}-Damage",
|
id = "${message.timestamp}-${message.characterSheetId}-Damage",
|
||||||
timestamp = formatTime.format(message.timestamp),
|
timestamp = formatTime.format(message.timestamp),
|
||||||
label = when {
|
label = when {
|
||||||
value < 0 -> Res.string.chat__characteristic_change__hp_down
|
value >= 0 -> Res.string.chat__characteristic_change__hp_up
|
||||||
else -> Res.string.chat__characteristic_change__hp_up
|
armor != null -> Res.string.chat__characteristic_change__hp_down_armor
|
||||||
|
else -> Res.string.chat__characteristic_change__hp_down
|
||||||
},
|
},
|
||||||
character = sheet.name,
|
character = sheet.name,
|
||||||
value = abs(value),
|
value = abs(value),
|
||||||
|
armor = message.armor,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -127,6 +131,7 @@ class TextMessageFactory(
|
||||||
},
|
},
|
||||||
character = sheet.name,
|
character = sheet.name,
|
||||||
value = abs(value),
|
value = abs(value),
|
||||||
|
armor = 0,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ data class CharacteristicTextMessageUio(
|
||||||
val label: StringResource,
|
val label: StringResource,
|
||||||
val character: String,
|
val character: String,
|
||||||
val value: Int,
|
val value: Int,
|
||||||
|
val armor: Int?,
|
||||||
) : TextMessage
|
) : TextMessage
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -52,7 +53,7 @@ fun CharacteristicTextMessage(
|
||||||
style = MaterialTheme.lwa.typography.chat.text,
|
style = MaterialTheme.lwa.typography.chat.text,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
text = stringResource(message.label, message.character, message.value),
|
text = stringResource(message.label, message.character, message.value, message.armor ?: 0),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -126,12 +126,16 @@ fun GMCharacterPage(
|
||||||
characteristicDialogViewModel.changeSubCharacteristic(
|
characteristicDialogViewModel.changeSubCharacteristic(
|
||||||
characterSheetId = dialog.characterSheetId,
|
characterSheetId = dialog.characterSheetId,
|
||||||
characteristic = dialog.characteristic,
|
characteristic = dialog.characteristic,
|
||||||
value = dialog.value().text.toIntOrNull() ?: 0,
|
useArmor= dialog.enableArmor?.checked?.value == true,
|
||||||
|
value = dialog.value.valueFlow.value.toIntOrNull() ?: 0,
|
||||||
)
|
)
|
||||||
characteristicDialogViewModel.hideSubCharacteristicDialog()
|
characteristicDialogViewModel.hideSubCharacteristicDialog()
|
||||||
blurController.hide()
|
blurController.hide()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onSwapSign = {
|
||||||
|
characteristicDialogViewModel.swapCharacteristicSign()
|
||||||
|
},
|
||||||
onDismissRequest = {
|
onDismissRequest = {
|
||||||
characteristicDialogViewModel.hideSubCharacteristicDialog()
|
characteristicDialogViewModel.hideSubCharacteristicDialog()
|
||||||
blurController.hide()
|
blurController.hide()
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,10 @@ fun Engine.putCharacterDamage(): suspend RoutingContext.() -> Unit {
|
||||||
name = "damage",
|
name = "damage",
|
||||||
code = APIResponse.ErrorCode.Damage,
|
code = APIResponse.ErrorCode.Damage,
|
||||||
)
|
)
|
||||||
|
val armor: Int = call.queryParameters.param(
|
||||||
|
name = "armor",
|
||||||
|
code = APIResponse.ErrorCode.Armor,
|
||||||
|
)
|
||||||
// fetch the character sheet
|
// fetch the character sheet
|
||||||
val characterSheet = characterService.character(characterSheetId)
|
val characterSheet = characterService.character(characterSheetId)
|
||||||
?: error("CharacterSheet with id:$characterSheetId not found.")
|
?: error("CharacterSheet with id:$characterSheetId not found.")
|
||||||
|
|
@ -36,6 +40,7 @@ fun Engine.putCharacterDamage(): suspend RoutingContext.() -> Unit {
|
||||||
characterSheetId = characterSheetId,
|
characterSheetId = characterSheetId,
|
||||||
oldValue = characterSheet.damage,
|
oldValue = characterSheet.damage,
|
||||||
damage = damage,
|
damage = damage,
|
||||||
|
armor = armor,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} catch (exception: Exception) {
|
} catch (exception: Exception) {
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ data class APIResponse<T>(
|
||||||
Active,
|
Active,
|
||||||
Equip,
|
Equip,
|
||||||
Damage,
|
Damage,
|
||||||
|
Armor,
|
||||||
Fatigue,
|
Fatigue,
|
||||||
Diminished,
|
Diminished,
|
||||||
Count,
|
Count,
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ sealed interface CharacterSheetEvent : SocketMessage, CharacterSheetIdMessage {
|
||||||
data class UpdateDamage(
|
data class UpdateDamage(
|
||||||
override val characterSheetId: String,
|
override val characterSheetId: String,
|
||||||
override val timestamp: Long,
|
override val timestamp: Long,
|
||||||
|
val armor: Int?,
|
||||||
val oldValue: Int,
|
val oldValue: Int,
|
||||||
val damage: Int,
|
val damage: Int,
|
||||||
) : CharacterSheetEvent
|
) : CharacterSheetEvent
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue