Add support for special / critical roll action.
This commit is contained in:
parent
9cc6414648
commit
51e63202e3
24 changed files with 537 additions and 193 deletions
|
|
@ -29,6 +29,10 @@
|
|||
<string name="roll_page__dc_normal__label">Normal</string>
|
||||
<string name="roll_page__dc_hard__label">Difficile</string>
|
||||
<string name="roll_page__dc_impossible__label">Impossible</string>
|
||||
<string name="roll_page__criticality__label">Type de jet :</string>
|
||||
<string name="roll_page__criticality_normal__label">Normal</string>
|
||||
<string name="roll_page__criticality_special__label">Spécial</string>
|
||||
<string name="roll_page__criticality_critical__label">Critique</string>
|
||||
|
||||
<string name="character_sheet_edit__create__title">Création de personnage</string>
|
||||
<string name="character_sheet_edit__edit__title">Édition de personnage</string>
|
||||
|
|
@ -117,7 +121,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">Action de lancer</string>
|
||||
<string name="character_sheet_edit__actions__description_label">Description</string>
|
||||
<string name="character_sheet_edit__actions__default_action_label">Action normal</string>
|
||||
<string name="character_sheet_edit__actions__spacial_action_label">Action spécial</string>
|
||||
<string name="character_sheet_edit__actions__critical_action_label">Action critique</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 lancer</string>
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ class LwaClientImpl(
|
|||
override suspend fun updateCharacter(
|
||||
sheet: CharacterSheetJson,
|
||||
) = client
|
||||
.put("$root/character/update") {
|
||||
.put("$root/character/update/sheet") {
|
||||
contentType(ContentType.Application.Json)
|
||||
setBody(sheet)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
package com.pixelized.desktop.lwa.ui.composable.checkbox
|
||||
|
||||
import androidx.compose.material.Checkbox
|
||||
import androidx.compose.material.CheckboxColors
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.pixelized.desktop.lwa.ui.theme.color.component.LwaCheckboxColors
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
@Stable
|
||||
data class LwaCheckBoxUio(
|
||||
val enable: Boolean = true,
|
||||
val checked: StateFlow<Boolean>,
|
||||
val onCheckedChange: (Boolean) -> Unit,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun LwaCheckBox(
|
||||
modifier: Modifier = Modifier,
|
||||
colors: CheckboxColors = LwaCheckboxColors(),
|
||||
field: LwaCheckBoxUio,
|
||||
) {
|
||||
val checked = field.checked.collectAsState()
|
||||
|
||||
Checkbox(
|
||||
modifier = modifier,
|
||||
checked = checked.value,
|
||||
colors = colors,
|
||||
onCheckedChange = field.onCheckedChange,
|
||||
)
|
||||
}
|
||||
|
|
@ -3,7 +3,6 @@ package com.pixelized.desktop.lwa.ui.overlay.roll
|
|||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import com.pixelized.shared.lwa.model.campaign.Campaign
|
||||
import kotlinx.coroutines.CancellableContinuation
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlinx.coroutines.sync.Mutex
|
||||
|
|
@ -24,7 +23,7 @@ class RollHostState {
|
|||
val rollAction: State<RollAction?> get() = currentRollAction
|
||||
|
||||
suspend fun showRollOverlay(
|
||||
roll: RollAction.RollActionUio,
|
||||
roll: RollAction.Uio,
|
||||
): RollResult = mutex.withLock {
|
||||
try {
|
||||
return suspendCancellableCoroutine { continuation ->
|
||||
|
|
@ -40,7 +39,7 @@ class RollHostState {
|
|||
|
||||
@Stable
|
||||
private class RollActionImpl(
|
||||
override val roll: RollAction.RollActionUio,
|
||||
override val roll: RollAction.Uio,
|
||||
private val continuation: CancellableContinuation<RollResult>,
|
||||
) : RollAction {
|
||||
override fun action(result: RollResult) {
|
||||
|
|
@ -61,15 +60,30 @@ enum class RollResult {
|
|||
|
||||
@Stable
|
||||
interface RollAction {
|
||||
val roll: RollActionUio
|
||||
val roll: Uio
|
||||
|
||||
fun action(result: RollResult)
|
||||
|
||||
@Stable
|
||||
data class RollActionUio(
|
||||
val characterSheetId: String,
|
||||
val label: String,
|
||||
val rollAction: String,
|
||||
val rollSuccessValue: Int?,
|
||||
)
|
||||
sealed interface Uio {
|
||||
val characterSheetId: String
|
||||
val label: String
|
||||
|
||||
@Stable
|
||||
data class BoundedRollActionUio(
|
||||
override val characterSheetId: String,
|
||||
override val label: String,
|
||||
val rollAction: String,
|
||||
val rollSuccessValue: Int,
|
||||
): Uio
|
||||
|
||||
@Stable
|
||||
data class BoundlessRollActionUio(
|
||||
override val characterSheetId: String,
|
||||
override val label: String,
|
||||
val canBeCritical: Boolean,
|
||||
val rollDefaultAction: String,
|
||||
val rollSpecialAction: String?,
|
||||
val rollCriticalAction: String?,
|
||||
): Uio
|
||||
}
|
||||
}
|
||||
|
|
@ -44,6 +44,7 @@ import androidx.compose.ui.graphics.graphicsLayer
|
|||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.CriticalityUio.Criticality
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.DifficultyUio.Difficulty
|
||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||
import com.pixelized.desktop.lwa.utils.DisableInteractionSource
|
||||
|
|
@ -58,6 +59,10 @@ import lwacharactersheet.composeapp.generated.resources.roll_page__dc_impossible
|
|||
import lwacharactersheet.composeapp.generated.resources.roll_page__dc_normal__label
|
||||
import lwacharactersheet.composeapp.generated.resources.roll_page__roll__label
|
||||
import lwacharactersheet.composeapp.generated.resources.roll_page__roll__success_label
|
||||
import lwacharactersheet.composeapp.generated.resources.roll_page__criticality__label
|
||||
import lwacharactersheet.composeapp.generated.resources.roll_page__criticality_normal__label
|
||||
import lwacharactersheet.composeapp.generated.resources.roll_page__criticality_special__label
|
||||
import lwacharactersheet.composeapp.generated.resources.roll_page__criticality_critical__label
|
||||
import org.jetbrains.compose.resources.painterResource
|
||||
import org.jetbrains.compose.resources.stringResource
|
||||
|
||||
|
|
@ -83,6 +88,16 @@ data class DifficultyUio(
|
|||
}
|
||||
}
|
||||
|
||||
@Stable
|
||||
data class CriticalityUio(
|
||||
val open: Boolean,
|
||||
val criticality: Criticality,
|
||||
) {
|
||||
enum class Criticality {
|
||||
NORMAL, SPECIAL, CRITICAL
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun RollPage(
|
||||
modifier: Modifier = Modifier,
|
||||
|
|
@ -231,6 +246,25 @@ fun RollPage(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
viewModel.rollCriticality.value?.let {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.padding(bottom = 16.dp)
|
||||
.clickable(
|
||||
interactionSource = remember { DisableInteractionSource() },
|
||||
indication = null,
|
||||
onClick = { },
|
||||
)
|
||||
) {
|
||||
Criticality(
|
||||
criticality = it,
|
||||
onToggle = { viewModel.toggleCriticality() },
|
||||
onCriticality = { viewModel.onCriticality(it) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -299,19 +333,19 @@ fun Difficulty(
|
|||
expanded = difficulty.open,
|
||||
onDismissRequest = { onToggle() }
|
||||
) {
|
||||
DifficultyDropDownItem(
|
||||
LocalDropDownItem(
|
||||
label = stringResource(Res.string.roll_page__dc_easy__label),
|
||||
onClick = { onDifficulty(Difficulty.EASY) },
|
||||
)
|
||||
DifficultyDropDownItem(
|
||||
LocalDropDownItem(
|
||||
label = stringResource(Res.string.roll_page__dc_normal__label),
|
||||
onClick = { onDifficulty(Difficulty.NORMAL) },
|
||||
)
|
||||
DifficultyDropDownItem(
|
||||
LocalDropDownItem(
|
||||
label = stringResource(Res.string.roll_page__dc_hard__label),
|
||||
onClick = { onDifficulty(Difficulty.HARD) },
|
||||
)
|
||||
DifficultyDropDownItem(
|
||||
LocalDropDownItem(
|
||||
label = stringResource(Res.string.roll_page__dc_impossible__label),
|
||||
onClick = { onDifficulty(Difficulty.IMPOSSIBLE) },
|
||||
)
|
||||
|
|
@ -319,8 +353,88 @@ fun Difficulty(
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
private fun DifficultyDropDownItem(
|
||||
fun Criticality(
|
||||
modifier: Modifier = Modifier,
|
||||
criticality: CriticalityUio,
|
||||
onToggle: () -> Unit,
|
||||
onCriticality: (Criticality) -> Unit,
|
||||
) {
|
||||
ExposedDropdownMenuBox(
|
||||
modifier = modifier,
|
||||
expanded = criticality.open,
|
||||
onExpandedChange = { onToggle() },
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(
|
||||
horizontal = 16.dp,
|
||||
vertical = 8.dp,
|
||||
),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.typography.body1,
|
||||
text = stringResource(Res.string.roll_page__criticality__label)
|
||||
)
|
||||
AnimatedContent(
|
||||
targetState = criticality.criticality,
|
||||
transitionSpec = {
|
||||
val enter = fadeIn() + slideInVertically { -16 }
|
||||
val exit = fadeOut() + slideOutVertically { 16 }
|
||||
enter togetherWith exit using SizeTransform(clip = false)
|
||||
},
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline().animateContentSize(),
|
||||
style = MaterialTheme.typography.body1,
|
||||
color = MaterialTheme.colors.primary,
|
||||
text = when (it) {
|
||||
Criticality.NORMAL -> stringResource(Res.string.roll_page__criticality_normal__label)
|
||||
Criticality.SPECIAL -> stringResource(Res.string.roll_page__criticality_special__label)
|
||||
Criticality.CRITICAL -> stringResource(Res.string.roll_page__criticality_critical__label)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
val rotation = animateFloatAsState(
|
||||
targetValue = if (criticality.open) -180f else 0f,
|
||||
)
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.offset(x = (-12).dp)
|
||||
.graphicsLayer { rotationZ = rotation.value },
|
||||
imageVector = Icons.Default.ArrowDropDown,
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
|
||||
ExposedDropdownMenu(
|
||||
expanded = criticality.open,
|
||||
onDismissRequest = { onToggle() }
|
||||
) {
|
||||
LocalDropDownItem(
|
||||
label = stringResource(Res.string.roll_page__criticality_normal__label),
|
||||
onClick = { onCriticality(Criticality.NORMAL) },
|
||||
)
|
||||
LocalDropDownItem(
|
||||
label = stringResource(Res.string.roll_page__criticality_special__label),
|
||||
onClick = { onCriticality(Criticality.SPECIAL) },
|
||||
)
|
||||
LocalDropDownItem(
|
||||
label = stringResource(Res.string.roll_page__criticality_critical__label),
|
||||
onClick = { onCriticality(Criticality.CRITICAL) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LocalDropDownItem(
|
||||
modifier: Modifier = Modifier,
|
||||
contentPadding: PaddingValues = PaddingValues(horizontal = 16.dp),
|
||||
label: String,
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import androidx.lifecycle.ViewModel
|
|||
import com.pixelized.desktop.lwa.repository.alteration.AlterationRepository
|
||||
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
|
||||
import com.pixelized.desktop.lwa.repository.network.NetworkRepository
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.CriticalityUio.Criticality
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.DifficultyUio.Difficulty
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction.RollActionUio
|
||||
import com.pixelized.shared.lwa.model.AlteredCharacterSheet
|
||||
import com.pixelized.shared.lwa.model.AlteredCharacterSheetFactory
|
||||
import com.pixelized.shared.lwa.protocol.websocket.RollEvent
|
||||
|
|
@ -42,7 +42,7 @@ class RollViewModel(
|
|||
private val alteredCharacterSheetFactory: AlteredCharacterSheetFactory,
|
||||
) : ViewModel() {
|
||||
private var alteredCharacterSheet: AlteredCharacterSheet? = null
|
||||
private var rollAction: RollActionUio? = null
|
||||
private var rollAction: RollAction.Uio? = null
|
||||
|
||||
var lastRollResult: RollResult = RollResult.Dismissed
|
||||
private set
|
||||
|
|
@ -64,6 +64,9 @@ class RollViewModel(
|
|||
private val _rollDifficulty = mutableStateOf<DifficultyUio?>(null)
|
||||
val rollDifficulty: State<DifficultyUio?> get() = _rollDifficulty
|
||||
|
||||
private val _rollCriticality = mutableStateOf<CriticalityUio?>(null)
|
||||
val rollCriticality: State<CriticalityUio?> get() = _rollCriticality
|
||||
|
||||
private val _shareResult = mutableStateOf(true)
|
||||
val shareResult: State<Boolean> = _shareResult
|
||||
|
||||
|
|
@ -88,7 +91,7 @@ class RollViewModel(
|
|||
* return true if the viewModel is ready to roll, otherwise false.
|
||||
*/
|
||||
suspend fun prepareRoll(
|
||||
roll: RollActionUio,
|
||||
roll: RollAction.Uio,
|
||||
) {
|
||||
rollRotation.snapTo(0f)
|
||||
rollScale.snapTo(1f)
|
||||
|
|
@ -111,23 +114,39 @@ class RollViewModel(
|
|||
|
||||
this.rollAction = roll
|
||||
|
||||
val rollStep = roll.rollSuccessValue?.let {
|
||||
skillStepUseCase.computeSkillStep(skill = it)
|
||||
}
|
||||
val rollStep = roll
|
||||
.let { it as? RollAction.Uio.BoundedRollActionUio }
|
||||
?.rollSuccessValue
|
||||
?.let { skillStepUseCase.computeSkillStep(skill = it) }
|
||||
|
||||
_shareResult.value = true
|
||||
_cancellable.value = true
|
||||
_rollResult.value = null
|
||||
|
||||
_rollTitle.value = RollTitleUio(
|
||||
label = roll.label,
|
||||
value = rollStep?.success?.last
|
||||
)
|
||||
_rollDifficulty.value = roll.rollSuccessValue?.let {
|
||||
DifficultyUio(
|
||||
open = false,
|
||||
difficulty = Difficulty.NORMAL,
|
||||
)
|
||||
}
|
||||
|
||||
_rollDifficulty.value = roll
|
||||
.let { it as? RollAction.Uio.BoundedRollActionUio }
|
||||
?.rollSuccessValue
|
||||
?.let {
|
||||
DifficultyUio(
|
||||
open = false,
|
||||
difficulty = Difficulty.NORMAL,
|
||||
)
|
||||
}
|
||||
|
||||
_rollCriticality.value = roll
|
||||
.let { it as? RollAction.Uio.BoundlessRollActionUio }
|
||||
?.takeIf { it.canBeCritical }
|
||||
?.let {
|
||||
CriticalityUio(
|
||||
open = false,
|
||||
criticality = Criticality.NORMAL
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun roll() {
|
||||
|
|
@ -151,22 +170,34 @@ class RollViewModel(
|
|||
delay(500)
|
||||
_cancellable.value = false
|
||||
// compute the skill critical success to critical failure ranges.
|
||||
val rollStep = rollAction.rollSuccessValue?.let {
|
||||
skillStepUseCase.computeSkillStep(
|
||||
skill = when (_rollDifficulty.value?.difficulty) {
|
||||
Difficulty.EASY -> it * 2
|
||||
Difficulty.NORMAL -> it
|
||||
Difficulty.HARD -> it / 2
|
||||
Difficulty.IMPOSSIBLE -> it / 4
|
||||
else -> it
|
||||
}
|
||||
)
|
||||
}
|
||||
val rollStep = rollAction
|
||||
.let { it as? RollAction.Uio.BoundedRollActionUio }
|
||||
?.rollSuccessValue?.let {
|
||||
skillStepUseCase.computeSkillStep(
|
||||
skill = when (_rollDifficulty.value?.difficulty) {
|
||||
Difficulty.EASY -> it * 2
|
||||
Difficulty.NORMAL -> it
|
||||
Difficulty.HARD -> it / 2
|
||||
Difficulty.IMPOSSIBLE -> it / 4
|
||||
else -> it
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// compute the expression.
|
||||
val expression = when (rollAction) {
|
||||
is RollAction.Uio.BoundedRollActionUio -> rollAction.rollAction
|
||||
is RollAction.Uio.BoundlessRollActionUio -> when (rollCriticality.value?.criticality) {
|
||||
Criticality.NORMAL -> rollAction.rollDefaultAction
|
||||
Criticality.SPECIAL -> rollAction.rollSpecialAction
|
||||
Criticality.CRITICAL -> rollAction.rollCriticalAction
|
||||
null -> null
|
||||
}
|
||||
} ?: ""
|
||||
// compute the roll (typically use the expression inside the rollAction)
|
||||
val roll = skillComputation.computeRoll(
|
||||
sheet = alteredCharacterSheet,
|
||||
expression = rollAction.rollAction,
|
||||
expression = expression,
|
||||
)
|
||||
|
||||
// check where the roll fall into the rollSteps.
|
||||
|
|
@ -227,22 +258,38 @@ class RollViewModel(
|
|||
open = false,
|
||||
difficulty = difficulty,
|
||||
)
|
||||
val rollStep = rollAction?.rollSuccessValue?.let {
|
||||
skillStepUseCase.computeSkillStep(
|
||||
skill = when (_rollDifficulty.value?.difficulty) {
|
||||
Difficulty.EASY -> it * 2
|
||||
Difficulty.NORMAL -> it
|
||||
Difficulty.HARD -> it / 2
|
||||
Difficulty.IMPOSSIBLE -> it / 4
|
||||
else -> it
|
||||
}
|
||||
)
|
||||
}
|
||||
val rollStep = rollAction
|
||||
.let { it as? RollAction.Uio.BoundedRollActionUio }
|
||||
?.rollSuccessValue
|
||||
?.let {
|
||||
skillStepUseCase.computeSkillStep(
|
||||
skill = when (_rollDifficulty.value?.difficulty) {
|
||||
Difficulty.EASY -> it * 2
|
||||
Difficulty.NORMAL -> it
|
||||
Difficulty.HARD -> it / 2
|
||||
Difficulty.IMPOSSIBLE -> it / 4
|
||||
else -> it
|
||||
}
|
||||
)
|
||||
}
|
||||
_rollTitle.value = _rollTitle.value?.copy(
|
||||
value = rollStep?.success?.last
|
||||
)
|
||||
}
|
||||
|
||||
fun toggleCriticality() {
|
||||
_rollCriticality.value = _rollCriticality.value?.copy(
|
||||
open = _rollCriticality.value?.open?.not() ?: false
|
||||
)
|
||||
}
|
||||
|
||||
fun onCriticality(criticality: Criticality) {
|
||||
_rollCriticality.value = CriticalityUio(
|
||||
open = false,
|
||||
criticality = criticality,
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun diceRotationAnimation() {
|
||||
rollRotation.animateTo(
|
||||
targetValue = rollRotation.value.let { it - it % 360 } + 360f * 3,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
package com.pixelized.desktop.lwa.ui.screen.campaign.player.detail
|
||||
|
||||
import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipUio
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction.RollActionUio
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction
|
||||
|
||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.header.CharacterDetailHeaderUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.sheet.CharacterDetailSheetActionUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.sheet.CharacterDetailSheetCharacteristicUio
|
||||
|
|
@ -130,7 +131,7 @@ class CharacterDetailFactory(
|
|||
title = getString(Res.string.character_sheet__characteristics__str),
|
||||
description = getString(Res.string.tooltip__characteristics__strength),
|
||||
),
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = getString(Res.string.character_sheet__characteristics__str),
|
||||
rollAction = "1d100",
|
||||
|
|
@ -144,7 +145,7 @@ class CharacterDetailFactory(
|
|||
title = getString(Res.string.character_sheet__characteristics__dex),
|
||||
description = getString(Res.string.tooltip__characteristics__dexterity),
|
||||
),
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = getString(Res.string.character_sheet__characteristics__dex),
|
||||
rollAction = "1d100",
|
||||
|
|
@ -158,7 +159,7 @@ class CharacterDetailFactory(
|
|||
title = getString(Res.string.character_sheet__characteristics__con),
|
||||
description = getString(Res.string.tooltip__characteristics__constitution),
|
||||
),
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = getString(Res.string.character_sheet__characteristics__con),
|
||||
rollAction = "1d100",
|
||||
|
|
@ -172,7 +173,7 @@ class CharacterDetailFactory(
|
|||
title = getString(Res.string.character_sheet__characteristics__hei),
|
||||
description = getString(Res.string.tooltip__characteristics__height),
|
||||
),
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = getString(Res.string.character_sheet__characteristics__hei),
|
||||
rollAction = "1d100",
|
||||
|
|
@ -186,7 +187,7 @@ class CharacterDetailFactory(
|
|||
title = getString(Res.string.character_sheet__characteristics__int),
|
||||
description = getString(Res.string.tooltip__characteristics__intelligence),
|
||||
),
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = getString(Res.string.character_sheet__characteristics__int),
|
||||
rollAction = "1d100",
|
||||
|
|
@ -200,7 +201,7 @@ class CharacterDetailFactory(
|
|||
title = getString(Res.string.character_sheet__characteristics__pow),
|
||||
description = getString(Res.string.tooltip__characteristics__power),
|
||||
),
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = getString(Res.string.character_sheet__characteristics__pow),
|
||||
rollAction = "1d100",
|
||||
|
|
@ -214,7 +215,7 @@ class CharacterDetailFactory(
|
|||
title = getString(Res.string.character_sheet__characteristics__cha),
|
||||
description = getString(Res.string.tooltip__characteristics__charisma),
|
||||
),
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = getString(Res.string.character_sheet__characteristics__cha),
|
||||
rollAction = "1d100",
|
||||
|
|
@ -241,7 +242,7 @@ class CharacterDetailFactory(
|
|||
description = it,
|
||||
)
|
||||
},
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = skill.label,
|
||||
rollAction = "1d100",
|
||||
|
|
@ -268,7 +269,7 @@ class CharacterDetailFactory(
|
|||
description = it,
|
||||
)
|
||||
},
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = skill.label,
|
||||
rollAction = "1d100",
|
||||
|
|
@ -295,7 +296,7 @@ class CharacterDetailFactory(
|
|||
description = it,
|
||||
)
|
||||
},
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = skill.label,
|
||||
rollAction = "1d100",
|
||||
|
|
@ -313,14 +314,16 @@ class CharacterDetailFactory(
|
|||
description = it,
|
||||
)
|
||||
},
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundlessRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = action.label,
|
||||
rollAction = action.roll,
|
||||
rollSuccessValue = null,
|
||||
canBeCritical = action.canBeCritical,
|
||||
rollDefaultAction = action.default,
|
||||
rollSpecialAction = action.special,
|
||||
rollCriticalAction = action.critical,
|
||||
)
|
||||
)
|
||||
}
|
||||
}.sortedWith(compareBy(Collator.getInstance()) { it.label }),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -17,7 +17,7 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.ui.composable.shapes.MasteryShape
|
||||
import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipUio
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction.RollActionUio
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.ic_d20_24dp
|
||||
import org.jetbrains.compose.resources.painterResource
|
||||
|
|
@ -27,7 +27,7 @@ data class CharacterDetailSheetActionUio(
|
|||
val actionId: String,
|
||||
val label: String,
|
||||
val tooltips: TooltipUio?,
|
||||
val roll: RollActionUio,
|
||||
val roll: RollAction.Uio,
|
||||
)
|
||||
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -15,14 +15,14 @@ import androidx.compose.ui.unit.dp
|
|||
import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox
|
||||
import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipLayout
|
||||
import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipUio
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction.RollActionUio
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction
|
||||
|
||||
@Stable
|
||||
data class CharacterDetailSheetCharacteristicUio(
|
||||
val value: String,
|
||||
val label: String,
|
||||
val tooltips: TooltipUio,
|
||||
val roll: RollActionUio,
|
||||
val roll: RollAction.Uio,
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import androidx.compose.ui.unit.dp
|
|||
import com.pixelized.desktop.lwa.ui.composable.shapes.MasteryShape
|
||||
import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipLayout
|
||||
import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipUio
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction.RollActionUio
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction
|
||||
|
||||
@Stable
|
||||
data class CharacterDetailSheetSkillUio(
|
||||
|
|
@ -31,7 +31,7 @@ data class CharacterDetailSheetSkillUio(
|
|||
val used: Boolean,
|
||||
val occupation: Boolean,
|
||||
val tooltips: TooltipUio?,
|
||||
val roll: RollActionUio,
|
||||
val roll: RollAction.Uio,
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package com.pixelized.desktop.lwa.ui.screen.characterSheet.detail
|
||||
|
||||
import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipUio
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction.RollActionUio
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.CharacterSheetPageUio.Characteristic
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.CharacterSheetPageUio.Node
|
||||
import com.pixelized.shared.lwa.model.AlteredCharacterSheetFactory
|
||||
|
|
@ -70,7 +70,7 @@ class CharacterSheetFactory(
|
|||
title = getString(Res.string.character_sheet__characteristics__str),
|
||||
description = getString(Res.string.tooltip__characteristics__strength),
|
||||
),
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = getString(Res.string.character_sheet__characteristics__str),
|
||||
rollAction = "1d100",
|
||||
|
|
@ -86,7 +86,7 @@ class CharacterSheetFactory(
|
|||
title = getString(Res.string.character_sheet__characteristics__dex),
|
||||
description = getString(Res.string.tooltip__characteristics__dexterity),
|
||||
),
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = getString(Res.string.character_sheet__characteristics__dex),
|
||||
rollAction = "1d100",
|
||||
|
|
@ -102,7 +102,7 @@ class CharacterSheetFactory(
|
|||
title = getString(Res.string.character_sheet__characteristics__con),
|
||||
description = getString(Res.string.tooltip__characteristics__constitution),
|
||||
),
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = getString(Res.string.character_sheet__characteristics__con),
|
||||
rollAction = "1d100",
|
||||
|
|
@ -118,7 +118,7 @@ class CharacterSheetFactory(
|
|||
title = getString(Res.string.character_sheet__characteristics__hei),
|
||||
description = getString(Res.string.tooltip__characteristics__height),
|
||||
),
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = getString(Res.string.character_sheet__characteristics__hei),
|
||||
rollAction = "1d100",
|
||||
|
|
@ -134,7 +134,7 @@ class CharacterSheetFactory(
|
|||
title = getString(Res.string.character_sheet__characteristics__int),
|
||||
description = getString(Res.string.tooltip__characteristics__intelligence),
|
||||
),
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = getString(Res.string.character_sheet__characteristics__int),
|
||||
rollAction = "1d100",
|
||||
|
|
@ -150,7 +150,7 @@ class CharacterSheetFactory(
|
|||
title = getString(Res.string.character_sheet__characteristics__pow),
|
||||
description = getString(Res.string.tooltip__characteristics__power),
|
||||
),
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = getString(Res.string.character_sheet__characteristics__pow),
|
||||
rollAction = "1d100",
|
||||
|
|
@ -166,7 +166,7 @@ class CharacterSheetFactory(
|
|||
title = getString(Res.string.character_sheet__characteristics__cha),
|
||||
description = getString(Res.string.tooltip__characteristics__charisma),
|
||||
),
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = getString(Res.string.character_sheet__characteristics__cha),
|
||||
rollAction = "1d100",
|
||||
|
|
@ -271,7 +271,7 @@ class CharacterSheetFactory(
|
|||
description = it,
|
||||
)
|
||||
},
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = skill.label,
|
||||
rollAction = "1d100",
|
||||
|
|
@ -297,7 +297,7 @@ class CharacterSheetFactory(
|
|||
description = it,
|
||||
)
|
||||
},
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = skill.label,
|
||||
rollAction = "1d100",
|
||||
|
|
@ -323,7 +323,7 @@ class CharacterSheetFactory(
|
|||
description = it,
|
||||
)
|
||||
},
|
||||
roll = RollActionUio(
|
||||
roll = RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = skill.label,
|
||||
rollAction = "1d100",
|
||||
|
|
@ -331,16 +331,19 @@ class CharacterSheetFactory(
|
|||
),
|
||||
)
|
||||
},
|
||||
actions = characterSheet.actions.mapNotNull {
|
||||
if (it.roll.isEmpty()) return@mapNotNull null
|
||||
actions = characterSheet.actions.mapNotNull { action ->
|
||||
if (action.default.isEmpty()) return@mapNotNull null
|
||||
|
||||
CharacterSheetPageUio.Roll(
|
||||
label = it.label,
|
||||
value = it.roll,
|
||||
roll = RollActionUio(
|
||||
label = action.label,
|
||||
value = action.default,
|
||||
roll = RollAction.Uio.BoundlessRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = it.label,
|
||||
rollAction = it.roll,
|
||||
rollSuccessValue = null,
|
||||
label = action.label,
|
||||
canBeCritical = action.canBeCritical,
|
||||
rollDefaultAction = action.default,
|
||||
rollSpecialAction = action.special,
|
||||
rollCriticalAction = action.critical,
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipUio
|
|||
import com.pixelized.desktop.lwa.ui.navigation.screen.LocalScreenController
|
||||
import com.pixelized.desktop.lwa.ui.navigation.window.LocalWindow
|
||||
import com.pixelized.desktop.lwa.ui.navigation.window.destination.navigateToCharacterSheetEdit
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction.RollActionUio
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollPage
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollViewModel
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.CharacterSheetPageUio.Characteristic
|
||||
|
|
@ -108,7 +108,7 @@ data class CharacterSheetPageUio(
|
|||
val value: String,
|
||||
val editable: Boolean,
|
||||
val tooltips: TooltipUio?,
|
||||
val roll: RollActionUio?,
|
||||
val roll: RollAction.Uio?,
|
||||
)
|
||||
|
||||
@Stable
|
||||
|
|
@ -118,14 +118,14 @@ data class CharacterSheetPageUio(
|
|||
val value: Int,
|
||||
val used: Boolean,
|
||||
val tooltips: TooltipUio? = null,
|
||||
val roll: RollActionUio,
|
||||
val roll: RollAction.Uio,
|
||||
)
|
||||
|
||||
@Stable
|
||||
data class Roll(
|
||||
val label: String,
|
||||
val value: String,
|
||||
val roll: RollActionUio,
|
||||
val roll: RollAction.Uio,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package com.pixelized.desktop.lwa.ui.screen.characterSheet.edit
|
|||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import com.pixelized.desktop.lwa.ui.composable.checkbox.LwaCheckBoxUio
|
||||
import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextFieldUio
|
||||
import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.common.SkillFieldFactory
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.common.occupation
|
||||
|
|
@ -14,9 +16,13 @@ import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.textfi
|
|||
import com.pixelized.desktop.lwa.utils.extention.unAccent
|
||||
import com.pixelized.shared.lwa.model.characterSheet.CharacterSheet
|
||||
import com.pixelized.shared.lwa.usecase.CharacterSheetUseCase
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__action_label
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__critical_action_label
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__default_action_label
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__description_label
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__name_label
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__spacial_action_label
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__cha
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__con
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__characteristics__dex
|
||||
|
|
@ -186,10 +192,12 @@ class CharacterSheetEditFactory(
|
|||
actions = editedSheet.actions.map {
|
||||
CharacterSheet.Roll(
|
||||
id = it.id,
|
||||
label = it.label.value.value,
|
||||
description = null, // TODO
|
||||
canBeCritical = false, // TODO
|
||||
roll = it.action.value.value,
|
||||
label = it.label.valueFlow.value,
|
||||
description = it.description.valueFlow.value,
|
||||
canBeCritical = it.canBeCritical.checked.value,
|
||||
default = it.default.valueFlow.value,
|
||||
special = it.special?.valueFlow?.value,
|
||||
critical = it.critical?.valueFlow?.value,
|
||||
)
|
||||
},
|
||||
)
|
||||
|
|
@ -456,13 +464,28 @@ class CharacterSheetEditFactory(
|
|||
actions = sheet?.actions?.map { action ->
|
||||
ActionFieldUio(
|
||||
id = action.id,
|
||||
label = skillFieldFactory.createWrapper(
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__name_label)),
|
||||
label = createLwaTextField(
|
||||
label = getString(Res.string.character_sheet_edit__actions__name_label),
|
||||
value = action.label,
|
||||
),
|
||||
action = skillFieldFactory.createWrapper(
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__action_label)),
|
||||
value = action.roll,
|
||||
description = createLwaTextField(
|
||||
label = getString(Res.string.character_sheet_edit__actions__description_label),
|
||||
value = action.description ?: "",
|
||||
),
|
||||
canBeCritical = createLwaBox(
|
||||
checked = action.canBeCritical,
|
||||
),
|
||||
default = createLwaTextField(
|
||||
label = getString(Res.string.character_sheet_edit__actions__default_action_label),
|
||||
value = action.default,
|
||||
),
|
||||
special = createLwaTextField(
|
||||
label = getString(Res.string.character_sheet_edit__actions__spacial_action_label),
|
||||
value = action.special,
|
||||
),
|
||||
critical = createLwaTextField(
|
||||
label = getString(Res.string.character_sheet_edit__actions__critical_action_label),
|
||||
value = action.critical,
|
||||
),
|
||||
option = skillFieldFactory.deleteOption { onDeleteSkill(action.id) },
|
||||
)
|
||||
|
|
@ -471,6 +494,41 @@ class CharacterSheetEditFactory(
|
|||
}
|
||||
}
|
||||
|
||||
fun createLwaTextField(
|
||||
enable: Boolean = true,
|
||||
isError: Boolean = false,
|
||||
label: String? = null,
|
||||
placeholder: String? = null,
|
||||
value: String? = null,
|
||||
): LwaTextFieldUio {
|
||||
val valueFlow = MutableStateFlow(value ?: "")
|
||||
val labelFlow = MutableStateFlow(label)
|
||||
val placeholderFlow = MutableStateFlow(placeholder)
|
||||
val isErrorFlow = MutableStateFlow(isError)
|
||||
|
||||
return LwaTextFieldUio(
|
||||
enable = enable,
|
||||
isError = isErrorFlow,
|
||||
labelFlow = labelFlow,
|
||||
valueFlow = valueFlow,
|
||||
placeHolderFlow = placeholderFlow,
|
||||
onValueChange = { valueFlow.value = it },
|
||||
)
|
||||
}
|
||||
|
||||
fun createLwaBox(
|
||||
enable: Boolean = true,
|
||||
checked: Boolean,
|
||||
): LwaCheckBoxUio {
|
||||
val checkedFlow = MutableStateFlow(checked)
|
||||
|
||||
return LwaCheckBoxUio(
|
||||
enable = enable,
|
||||
checked = checkedFlow,
|
||||
onCheckedChange = { checkedFlow.value = it },
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun createLevelUpWrapper(
|
||||
shouldLevelUp: Boolean,
|
||||
): LevelUpWrapperUio {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ import com.pixelized.desktop.lwa.ui.navigation.screen.LocalScreenController
|
|||
import com.pixelized.desktop.lwa.ui.navigation.window.LocalWindow
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.copy.CharacterSheetCopyDialog
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.delete.CharacterSheetDeleteDialog
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.dialog.CharacterSheetDeleteConfirmationDialog
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.ActionField
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.ActionFieldUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.BaseSkillFieldUio
|
||||
|
|
@ -430,8 +429,10 @@ fun CharacterSheetEdit(
|
|||
) {
|
||||
form.actions.forEach {
|
||||
ActionField(
|
||||
modifier = Modifier.fillMaxWidth().padding(end = (4 + 2).dp),
|
||||
action = it
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(end = 6.dp, bottom = 16.dp),
|
||||
action = it,
|
||||
)
|
||||
}
|
||||
TextButton(
|
||||
|
|
|
|||
|
|
@ -14,8 +14,11 @@ import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.Action
|
|||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__action_label
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__critical_action_label
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__description_label
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__default_action_label
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__name_label
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__actions__spacial_action_label
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__copy__label
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__copy__title
|
||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__magic_title
|
||||
|
|
@ -125,11 +128,28 @@ class CharacterSheetEditViewModel(
|
|||
val id = UUID.randomUUID().toString()
|
||||
val field = ActionFieldUio(
|
||||
id = id,
|
||||
label = skillFactory.createWrapper(
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__name_label)),
|
||||
label = sheetFactory.createLwaTextField(
|
||||
label = getString(Res.string.character_sheet_edit__actions__name_label),
|
||||
value = "",
|
||||
),
|
||||
action = skillFactory.createWrapper(
|
||||
label = mutableStateOf(getString(Res.string.character_sheet_edit__actions__action_label)),
|
||||
description = sheetFactory.createLwaTextField(
|
||||
label = getString(Res.string.character_sheet_edit__actions__description_label),
|
||||
value = "",
|
||||
),
|
||||
canBeCritical = sheetFactory.createLwaBox(
|
||||
checked = false,
|
||||
),
|
||||
default = sheetFactory.createLwaTextField(
|
||||
label = getString(Res.string.character_sheet_edit__actions__default_action_label),
|
||||
value = "",
|
||||
),
|
||||
special = sheetFactory.createLwaTextField(
|
||||
label = getString(Res.string.character_sheet_edit__actions__spacial_action_label),
|
||||
value = "",
|
||||
),
|
||||
critical = sheetFactory.createLwaTextField(
|
||||
label = getString(Res.string.character_sheet_edit__actions__critical_action_label),
|
||||
value = "",
|
||||
),
|
||||
option = skillFactory.deleteOption { deleteSkill(id) },
|
||||
)
|
||||
|
|
@ -151,7 +171,7 @@ class CharacterSheetEditViewModel(
|
|||
},
|
||||
actions = _characterSheet.value.actions.toMutableList().also { actions ->
|
||||
actions.removeIf { it.id == skillId }
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
package com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable
|
||||
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.material.DropdownMenu
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
|
|
@ -12,45 +13,57 @@ import androidx.compose.material.icons.Icons
|
|||
import androidx.compose.material.icons.filled.MoreVert
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.ui.composable.checkbox.LwaCheckBox
|
||||
import com.pixelized.desktop.lwa.ui.composable.checkbox.LwaCheckBoxUio
|
||||
import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextField
|
||||
import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextFieldUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.option.ActionOption
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.option.DropDownActionMenuItem
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.textfield.TextFieldWrapper
|
||||
import com.pixelized.desktop.lwa.ui.screen.characterSheet.edit.composable.textfield.TextFieldWrapperUio
|
||||
|
||||
@Stable
|
||||
data class ActionFieldUio(
|
||||
val id: String,
|
||||
val label: TextFieldWrapperUio,
|
||||
val action: TextFieldWrapperUio,
|
||||
val label: LwaTextFieldUio,
|
||||
val description: LwaTextFieldUio,
|
||||
val canBeCritical: LwaCheckBoxUio,
|
||||
val default: LwaTextFieldUio,
|
||||
val special: LwaTextFieldUio?,
|
||||
val critical: LwaTextFieldUio?,
|
||||
val option: ActionOption.DeleteOptionUio,
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun ActionField(
|
||||
modifier: Modifier = Modifier,
|
||||
space: Dp = 4.dp,
|
||||
action: ActionFieldUio,
|
||||
) {
|
||||
val showMenu = remember { mutableStateOf(false) }
|
||||
val canBeCritical = action.canBeCritical.checked.collectAsState()
|
||||
|
||||
Row(
|
||||
Column(
|
||||
modifier = modifier,
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp, alignment = Alignment.End),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
verticalArrangement = Arrangement.spacedBy(space = space),
|
||||
) {
|
||||
TextFieldWrapper(
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
wrapper = action.label,
|
||||
)
|
||||
TextFieldWrapper(
|
||||
modifier = Modifier.width(width = (192+4).dp),
|
||||
wrapper = action.action,
|
||||
)
|
||||
Box {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = space),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
LwaTextField(
|
||||
modifier = Modifier.weight(1f),
|
||||
field = action.label,
|
||||
)
|
||||
LwaCheckBox(
|
||||
field = action.canBeCritical,
|
||||
)
|
||||
IconButton(
|
||||
onClick = { showMenu.value = showMenu.value.not() },
|
||||
) {
|
||||
|
|
@ -59,19 +72,47 @@ fun ActionField(
|
|||
tint = MaterialTheme.colors.primary,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
DropdownMenu(
|
||||
expanded = showMenu.value,
|
||||
onDismissRequest = { showMenu.value = false }
|
||||
) {
|
||||
DropDownActionMenuItem(
|
||||
wrapper = action.option,
|
||||
onClick = {
|
||||
showMenu.value = false
|
||||
action.option.onOption()
|
||||
}
|
||||
)
|
||||
DropdownMenu(
|
||||
expanded = showMenu.value,
|
||||
onDismissRequest = { showMenu.value = false }
|
||||
) {
|
||||
DropDownActionMenuItem(
|
||||
wrapper = action.option,
|
||||
onClick = {
|
||||
showMenu.value = false
|
||||
action.option.onOption()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().animateContentSize(),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = space),
|
||||
) {
|
||||
LwaTextField(
|
||||
modifier = Modifier.weight(1f),
|
||||
field = action.default,
|
||||
)
|
||||
if (canBeCritical.value) {
|
||||
action.special?.let { field ->
|
||||
LwaTextField(
|
||||
modifier = Modifier.weight(1f),
|
||||
field = field,
|
||||
)
|
||||
}
|
||||
action.critical?.let { field ->
|
||||
LwaTextField(
|
||||
modifier = Modifier.weight(1f),
|
||||
field = field,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
LwaTextField(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
singleLine = false,
|
||||
field = action.description,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -41,6 +41,7 @@ import androidx.compose.runtime.rememberCoroutineScope
|
|||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.LocalWindowController
|
||||
|
|
@ -153,11 +154,12 @@ private fun GameMasterContent(
|
|||
.clickable { onGameMaster(gameMaster.value.not()) }
|
||||
.padding(all = 8.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp)
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 8.dp)
|
||||
) {
|
||||
Text(
|
||||
color = MaterialTheme.lwa.colorScheme.base.primary,
|
||||
style = MaterialTheme.typography.caption,
|
||||
style = MaterialTheme.typography.body2,
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
text = stringResource(Res.string.game_master__action),
|
||||
)
|
||||
Switch(
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import androidx.compose.foundation.background
|
|||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.calculateStartPadding
|
||||
|
|
@ -107,47 +106,40 @@ fun GMCharacter(
|
|||
.background(color = MaterialTheme.lwa.colorScheme.elevated.base1dp)
|
||||
.then(other = modifier),
|
||||
) {
|
||||
Column {
|
||||
Row(
|
||||
modifier = Modifier.padding(start = startPadding),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.padding(start = startPadding),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp),
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.lwa.typography.base.body1,
|
||||
text = character.name,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.lwa.typography.base.caption,
|
||||
text = stringResource(
|
||||
Res.string.game_master__character_level__label,
|
||||
character.level,
|
||||
),
|
||||
)
|
||||
}
|
||||
OverflowActionMenu(
|
||||
character = character,
|
||||
onAction = onAction,
|
||||
)
|
||||
}
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(paddingValues = padding)
|
||||
.padding(bottom = 8.dp),
|
||||
modifier = Modifier.weight(weight = 1f),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = 4.dp),
|
||||
) {
|
||||
character.tags.forEach { tag ->
|
||||
GMTag(
|
||||
elevation = 4.dp,
|
||||
tag = tag,
|
||||
)
|
||||
}
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.lwa.typography.base.body1,
|
||||
text = character.name,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.lwa.typography.base.caption,
|
||||
text = stringResource(
|
||||
Res.string.game_master__character_level__label,
|
||||
character.level,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
character.tags.forEach { tag ->
|
||||
GMTag(
|
||||
elevation = 4.dp,
|
||||
tag = tag,
|
||||
)
|
||||
}
|
||||
|
||||
OverflowActionMenu(
|
||||
character = character,
|
||||
onAction = onAction,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
package com.pixelized.desktop.lwa.ui.screen.levelup
|
||||
|
||||
import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipUio
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction.RollActionUio
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction
|
||||
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollResult
|
||||
import com.pixelized.desktop.lwa.ui.screen.levelup.items.LevelUpCharacteristicUio
|
||||
import com.pixelized.desktop.lwa.ui.screen.levelup.items.LevelUpSkillUio
|
||||
|
|
@ -312,7 +313,7 @@ class LevelUpFactory(
|
|||
)
|
||||
},
|
||||
roll = when (results[skill.id]) {
|
||||
null -> RollActionUio(
|
||||
null -> RollAction.Uio.BoundedRollActionUio(
|
||||
characterSheetId = characterSheetId,
|
||||
label = skill.label,
|
||||
rollAction = "1d100",
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import androidx.compose.ui.unit.dp
|
|||
import com.pixelized.desktop.lwa.ui.composable.shapes.MasteryShape
|
||||
import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipLayout
|
||||
import com.pixelized.desktop.lwa.ui.composable.tooltip.TooltipUio
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction.RollActionUio
|
||||
import com.pixelized.desktop.lwa.ui.overlay.roll.RollAction
|
||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||
import lwacharactersheet.composeapp.generated.resources.Res
|
||||
import lwacharactersheet.composeapp.generated.resources.level_up__skill_level
|
||||
|
|
@ -41,7 +41,7 @@ data class LevelUpSkillUio(
|
|||
val levelUp: Boolean,
|
||||
val occupation: Boolean,
|
||||
val tooltips: TooltipUio?,
|
||||
val roll: RollActionUio?,
|
||||
val roll: RollAction.Uio?,
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue