Add quality of life (icons, formula instead of plain Ints)
This commit is contained in:
		
							parent
							
								
									8884d047a6
								
							
						
					
					
						commit
						f99a938e64
					
				
					 16 changed files with 235 additions and 145 deletions
				
			
		| 
						 | 
				
			
			@ -14,45 +14,31 @@ class SkillValueComputationUseCase(
 | 
			
		|||
        skill: CharacterSheet.Skill,
 | 
			
		||||
        diminished: Int,
 | 
			
		||||
    ): Int {
 | 
			
		||||
        val baseSum = arithmeticParser.parse(skill.base).sumOf { instruction ->
 | 
			
		||||
            when (instruction) {
 | 
			
		||||
                is Instruction.Dice -> 0
 | 
			
		||||
 | 
			
		||||
                is Instruction.Flat -> {
 | 
			
		||||
                    instruction.value
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                is Instruction.Word -> {
 | 
			
		||||
                    when (instruction.type) {
 | 
			
		||||
                        Instruction.Word.Type.BDC -> 0
 | 
			
		||||
                        Instruction.Word.Type.BDD -> 0
 | 
			
		||||
                        Instruction.Word.Type.STR -> sheet.strength
 | 
			
		||||
                        Instruction.Word.Type.DEX -> sheet.dexterity
 | 
			
		||||
                        Instruction.Word.Type.CON -> sheet.constitution
 | 
			
		||||
                        Instruction.Word.Type.HEI -> sheet.height
 | 
			
		||||
                        Instruction.Word.Type.INT -> sheet.intelligence
 | 
			
		||||
                        Instruction.Word.Type.POW -> sheet.power
 | 
			
		||||
                        Instruction.Word.Type.CHA -> sheet.charisma
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } * instruction.sign
 | 
			
		||||
        val base: Int = arithmeticParser.parse(skill.base).compute(sheet = sheet).let {
 | 
			
		||||
            when (skill.occupation) {
 | 
			
		||||
                true -> max(MIN_OCCUPATION_VALUE, it)
 | 
			
		||||
                else -> it
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        val bonus = skill.bonus?.let(arithmeticParser::parse)?.compute(sheet = sheet) ?: 0
 | 
			
		||||
        val level = skill.level?.let(arithmeticParser::parse)?.compute(sheet = sheet) ?: 0
 | 
			
		||||
 | 
			
		||||
        val base = if (skill.occupation) {
 | 
			
		||||
            max(MIN_OCCUPATION_VALUE, baseSum)
 | 
			
		||||
        } else {
 | 
			
		||||
            baseSum
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return max(base + (skill.bonus ?: 0) + (skill.level ?: 0) - diminished, 0)
 | 
			
		||||
        return max(base + bonus + level - diminished, 0)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fun computeRoll(
 | 
			
		||||
        sheet: CharacterSheet,
 | 
			
		||||
        roll: String,
 | 
			
		||||
    ): Int { // TODO Roll detail instead of an simple Int.
 | 
			
		||||
    ): Int {
 | 
			
		||||
        return arithmeticParser.parse(value = roll).compute(sheet = sheet)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // TODO return RollDetail instance instead of an simple Int.
 | 
			
		||||
    private fun List<Instruction>.compute(
 | 
			
		||||
        sheet: CharacterSheet,
 | 
			
		||||
    ): Int {
 | 
			
		||||
        print("Roll ->")
 | 
			
		||||
        return arithmeticParser.parse(roll).sumOf { instruction ->
 | 
			
		||||
        return sumOf { instruction ->
 | 
			
		||||
            print(" ($instruction):")
 | 
			
		||||
            val value = when (instruction) {
 | 
			
		||||
                is Instruction.Dice -> rollUseCase.roll(dice = instruction)
 | 
			
		||||
| 
						 | 
				
			
			@ -99,7 +85,9 @@ class SkillValueComputationUseCase(
 | 
			
		|||
            }
 | 
			
		||||
 | 
			
		||||
            (value * instruction.sign).also { print("$it") }
 | 
			
		||||
        }.also { println() }
 | 
			
		||||
        }.also {
 | 
			
		||||
            println()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,8 +36,8 @@ data class CharacterSheet(
 | 
			
		|||
        val label: String,
 | 
			
		||||
        val description: String?,
 | 
			
		||||
        val base: String,
 | 
			
		||||
        val bonus: Int?,
 | 
			
		||||
        val level: Int?,
 | 
			
		||||
        val bonus: String?,
 | 
			
		||||
        val level: String?,
 | 
			
		||||
        val occupation: Boolean,
 | 
			
		||||
        val used: Boolean,
 | 
			
		||||
    )
 | 
			
		||||
| 
						 | 
				
			
			@ -66,4 +66,19 @@ data class CharacterSheet(
 | 
			
		|||
        const val SLEIGHT_OF_HAND_ID = "SLEIGHT_OF_HAND"
 | 
			
		||||
        const val AID_ID = "AID"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    object CharacteristicId {
 | 
			
		||||
        const val STR = "STR"
 | 
			
		||||
        const val DEX = "DEX"
 | 
			
		||||
        const val CON = "CON"
 | 
			
		||||
        const val HEI = "HEI"
 | 
			
		||||
        const val INT = "INT"
 | 
			
		||||
        const val POW = "POW"
 | 
			
		||||
        const val CHA = "CHA"
 | 
			
		||||
        const val MOV = "MOV"
 | 
			
		||||
        const val HP = "HP"
 | 
			
		||||
        const val PP = "PP"
 | 
			
		||||
        const val DMG = "DMG"
 | 
			
		||||
        const val ARMOR = "ARMOR"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -38,8 +38,8 @@ data class CharacterSheetJsonV1(
 | 
			
		|||
        val label: String,
 | 
			
		||||
        val description: String?,
 | 
			
		||||
        val base: String,
 | 
			
		||||
        val bonus: Int?,
 | 
			
		||||
        val level: Int?,
 | 
			
		||||
        val bonus: String?,
 | 
			
		||||
        val level: String?,
 | 
			
		||||
        val occupation: Boolean,
 | 
			
		||||
        val used: Boolean,
 | 
			
		||||
    )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@ import com.pixelized.desktop.lwa.business.SkillValueComputationUseCase
 | 
			
		|||
import com.pixelized.desktop.lwa.composable.tooltip.TooltipUio
 | 
			
		||||
import com.pixelized.desktop.lwa.repository.characterSheet.SkillDescriptionFactory
 | 
			
		||||
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
 | 
			
		||||
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet.CharacteristicId
 | 
			
		||||
import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetPageUio.Characteristic
 | 
			
		||||
import com.pixelized.desktop.lwa.screen.characterSheet.detail.CharacterSheetPageUio.Node
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.Res
 | 
			
		||||
| 
						 | 
				
			
			@ -37,21 +38,19 @@ class CharacterSheetFactory(
 | 
			
		|||
    private val skillUseCase: SkillValueComputationUseCase,
 | 
			
		||||
    private val skillDescriptionFactory: SkillDescriptionFactory,
 | 
			
		||||
) {
 | 
			
		||||
    companion object {
 | 
			
		||||
        const val HP = "HP"
 | 
			
		||||
        const val PP = "PP"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun convertToUio(
 | 
			
		||||
        sheet: CharacterSheet,
 | 
			
		||||
        sheet: CharacterSheet?,
 | 
			
		||||
        diminished: Int,
 | 
			
		||||
    ): CharacterSheetPageUio {
 | 
			
		||||
    ): CharacterSheetPageUio? {
 | 
			
		||||
        if (sheet == null) return null
 | 
			
		||||
 | 
			
		||||
        return CharacterSheetPageUio(
 | 
			
		||||
            id = sheet.id,
 | 
			
		||||
            name = sheet.name,
 | 
			
		||||
            characteristics = listOf(
 | 
			
		||||
                Characteristic(
 | 
			
		||||
                    id = "STR",
 | 
			
		||||
                    id = CharacteristicId.STR,
 | 
			
		||||
                    label = getString(Res.string.character_sheet__characteristics__str),
 | 
			
		||||
                    value = "${sheet.strength}",
 | 
			
		||||
                    tooltips = TooltipUio(
 | 
			
		||||
| 
						 | 
				
			
			@ -61,7 +60,7 @@ class CharacterSheetFactory(
 | 
			
		|||
                    editable = false,
 | 
			
		||||
                ),
 | 
			
		||||
                Characteristic(
 | 
			
		||||
                    id = "DEX",
 | 
			
		||||
                    id = CharacteristicId.DEX,
 | 
			
		||||
                    label = getString(Res.string.character_sheet__characteristics__dex),
 | 
			
		||||
                    value = "${sheet.dexterity}",
 | 
			
		||||
                    tooltips = TooltipUio(
 | 
			
		||||
| 
						 | 
				
			
			@ -71,7 +70,7 @@ class CharacterSheetFactory(
 | 
			
		|||
                    editable = false,
 | 
			
		||||
                ),
 | 
			
		||||
                Characteristic(
 | 
			
		||||
                    id = "CON",
 | 
			
		||||
                    id = CharacteristicId.CON,
 | 
			
		||||
                    label = getString(Res.string.character_sheet__characteristics__con),
 | 
			
		||||
                    value = "${sheet.constitution}",
 | 
			
		||||
                    tooltips = TooltipUio(
 | 
			
		||||
| 
						 | 
				
			
			@ -81,7 +80,7 @@ class CharacterSheetFactory(
 | 
			
		|||
                    editable = false,
 | 
			
		||||
                ),
 | 
			
		||||
                Characteristic(
 | 
			
		||||
                    id = "HEI",
 | 
			
		||||
                    id = CharacteristicId.HEI,
 | 
			
		||||
                    label = getString(Res.string.character_sheet__characteristics__hei),
 | 
			
		||||
                    value = "${sheet.height}",
 | 
			
		||||
                    tooltips = TooltipUio(
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +90,7 @@ class CharacterSheetFactory(
 | 
			
		|||
                    editable = false,
 | 
			
		||||
                ),
 | 
			
		||||
                Characteristic(
 | 
			
		||||
                    id = "INT",
 | 
			
		||||
                    id = CharacteristicId.INT,
 | 
			
		||||
                    label = getString(Res.string.character_sheet__characteristics__int),
 | 
			
		||||
                    value = "${sheet.intelligence}",
 | 
			
		||||
                    tooltips = TooltipUio(
 | 
			
		||||
| 
						 | 
				
			
			@ -101,7 +100,7 @@ class CharacterSheetFactory(
 | 
			
		|||
                    editable = false,
 | 
			
		||||
                ),
 | 
			
		||||
                Characteristic(
 | 
			
		||||
                    id = "POW",
 | 
			
		||||
                    id = CharacteristicId.POW,
 | 
			
		||||
                    label = getString(Res.string.character_sheet__characteristics__pow),
 | 
			
		||||
                    value = "${sheet.power}",
 | 
			
		||||
                    tooltips = TooltipUio(
 | 
			
		||||
| 
						 | 
				
			
			@ -111,7 +110,7 @@ class CharacterSheetFactory(
 | 
			
		|||
                    editable = false,
 | 
			
		||||
                ),
 | 
			
		||||
                Characteristic(
 | 
			
		||||
                    id = "CHA",
 | 
			
		||||
                    id = CharacteristicId.CHA,
 | 
			
		||||
                    label = getString(Res.string.character_sheet__characteristics__cha),
 | 
			
		||||
                    value = "${sheet.charisma}",
 | 
			
		||||
                    tooltips = TooltipUio(
 | 
			
		||||
| 
						 | 
				
			
			@ -123,7 +122,7 @@ class CharacterSheetFactory(
 | 
			
		|||
            ),
 | 
			
		||||
            subCharacteristics = listOf(
 | 
			
		||||
                Characteristic(
 | 
			
		||||
                    id = "MOV",
 | 
			
		||||
                    id = CharacteristicId.MOV,
 | 
			
		||||
                    label = getString(Res.string.character_sheet__sub_characteristics__movement),
 | 
			
		||||
                    value = "${sheet.movement}",
 | 
			
		||||
                    tooltips = TooltipUio(
 | 
			
		||||
| 
						 | 
				
			
			@ -133,7 +132,7 @@ class CharacterSheetFactory(
 | 
			
		|||
                    editable = false,
 | 
			
		||||
                ),
 | 
			
		||||
                Characteristic(
 | 
			
		||||
                    id = HP,
 | 
			
		||||
                    id = CharacteristicId.HP,
 | 
			
		||||
                    label = getString(Res.string.character_sheet__sub_characteristics__hit_point),
 | 
			
		||||
                    value = "${sheet.currentHp}/${sheet.maxHp}",
 | 
			
		||||
                    tooltips = TooltipUio(
 | 
			
		||||
| 
						 | 
				
			
			@ -143,7 +142,7 @@ class CharacterSheetFactory(
 | 
			
		|||
                    editable = true,
 | 
			
		||||
                ),
 | 
			
		||||
                Characteristic(
 | 
			
		||||
                    id = PP,
 | 
			
		||||
                    id = CharacteristicId.PP,
 | 
			
		||||
                    label = getString(Res.string.character_sheet__sub_characteristics__power_point),
 | 
			
		||||
                    value = "${sheet.currentPp}/${sheet.maxPp}",
 | 
			
		||||
                    tooltips = TooltipUio(
 | 
			
		||||
| 
						 | 
				
			
			@ -153,7 +152,7 @@ class CharacterSheetFactory(
 | 
			
		|||
                    editable = true,
 | 
			
		||||
                ),
 | 
			
		||||
                Characteristic(
 | 
			
		||||
                    id = "DMG",
 | 
			
		||||
                    id = CharacteristicId.DMG,
 | 
			
		||||
                    label = getString(Res.string.character_sheet__sub_characteristics__damage_bonus),
 | 
			
		||||
                    value = sheet.damageBonus,
 | 
			
		||||
                    tooltips = TooltipUio(
 | 
			
		||||
| 
						 | 
				
			
			@ -163,7 +162,7 @@ class CharacterSheetFactory(
 | 
			
		|||
                    editable = false,
 | 
			
		||||
                ),
 | 
			
		||||
                Characteristic(
 | 
			
		||||
                    id = "ARMOR",
 | 
			
		||||
                    id = CharacteristicId.ARMOR,
 | 
			
		||||
                    label = getString(Res.string.character_sheet__sub_characteristics__armor),
 | 
			
		||||
                    value = "${sheet.armor}",
 | 
			
		||||
                    tooltips = TooltipUio(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,8 +77,8 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet__skills_
 | 
			
		|||
import lwacharactersheet.composeapp.generated.resources.character_sheet__skills__special_title
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__title
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__edit__title
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.ic_d20_32dp
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.ic_skull_32dp
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.ic_d20_24dp
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.ic_skull_24dp
 | 
			
		||||
import org.jetbrains.compose.resources.getString
 | 
			
		||||
import org.jetbrains.compose.resources.painterResource
 | 
			
		||||
import org.jetbrains.compose.resources.stringResource
 | 
			
		||||
| 
						 | 
				
			
			@ -295,7 +295,7 @@ fun CharacterSheetPageContent(
 | 
			
		|||
                        ) {
 | 
			
		||||
                            Icon(
 | 
			
		||||
                                modifier = Modifier.size(size = 24.dp),
 | 
			
		||||
                                painter = painterResource(Res.drawable.ic_skull_32dp),
 | 
			
		||||
                                painter = painterResource(Res.drawable.ic_skull_24dp),
 | 
			
		||||
                                tint = MaterialTheme.colors.primary,
 | 
			
		||||
                                contentDescription = null,
 | 
			
		||||
                            )
 | 
			
		||||
| 
						 | 
				
			
			@ -657,7 +657,7 @@ private fun Roll(
 | 
			
		|||
        )
 | 
			
		||||
        Icon(
 | 
			
		||||
            modifier = Modifier.size(size = 24.dp),
 | 
			
		||||
            painter = painterResource(Res.drawable.ic_d20_32dp),
 | 
			
		||||
            painter = painterResource(Res.drawable.ic_d20_24dp),
 | 
			
		||||
            tint = MaterialTheme.colors.primary,
 | 
			
		||||
            contentDescription = null,
 | 
			
		||||
        )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
package com.pixelized.desktop.lwa.screen.characterSheet.detail
 | 
			
		||||
 | 
			
		||||
import androidx.compose.runtime.Composable
 | 
			
		||||
import androidx.compose.runtime.Stable
 | 
			
		||||
import androidx.compose.runtime.State
 | 
			
		||||
import androidx.compose.runtime.collectAsState
 | 
			
		||||
import androidx.compose.runtime.mutableStateOf
 | 
			
		||||
import androidx.compose.ui.text.TextRange
 | 
			
		||||
import androidx.compose.ui.text.input.TextFieldValue
 | 
			
		||||
| 
						 | 
				
			
			@ -11,14 +11,12 @@ import androidx.lifecycle.ViewModel
 | 
			
		|||
import androidx.lifecycle.viewModelScope
 | 
			
		||||
import com.pixelized.desktop.lwa.navigation.screen.destination.CharacterSheetDestination
 | 
			
		||||
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
 | 
			
		||||
import com.pixelized.desktop.lwa.repository.characterSheet.model.CharacterSheet
 | 
			
		||||
import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.CharacterSheetDeleteConfirmationDialogUio
 | 
			
		||||
import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.DiminishedStatDialogUio
 | 
			
		||||
import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.StatChangeDialogUio
 | 
			
		||||
import com.pixelized.desktop.lwa.utils.extention.collectAsState
 | 
			
		||||
import kotlinx.coroutines.flow.SharingStarted
 | 
			
		||||
import kotlinx.coroutines.flow.combine
 | 
			
		||||
import kotlinx.coroutines.flow.stateIn
 | 
			
		||||
import kotlinx.coroutines.runBlocking
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.Res
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__diminished__label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__hit_point
 | 
			
		||||
| 
						 | 
				
			
			@ -49,33 +47,26 @@ class CharacterSheetViewModel(
 | 
			
		|||
    private val _diminishedDialog = mutableStateOf<DiminishedStatDialogUio?>(null)
 | 
			
		||||
    val diminishedDialog: State<DiminishedStatDialogUio?> get() = _diminishedDialog
 | 
			
		||||
 | 
			
		||||
    private val diminishedValueFlow = repository.characterDiminishedFlow(id = argument.id)
 | 
			
		||||
    val diminishedValue: State<Int?>
 | 
			
		||||
        @Composable
 | 
			
		||||
        @Stable
 | 
			
		||||
        get() = repository
 | 
			
		||||
            .characterDiminishedFlow(id = argument.id)
 | 
			
		||||
            .collectAsState { it -> it.takeIf { it > 0 } }
 | 
			
		||||
        get() = diminishedValueFlow.collectAsState { it ->
 | 
			
		||||
            it.takeIf { it > 0 }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    private val sheetFlow = combine(
 | 
			
		||||
        repository.characterSheetFlow(id = argument.id),
 | 
			
		||||
        repository.characterDiminishedFlow(id = argument.id),
 | 
			
		||||
        transform = { sheet, diminished ->
 | 
			
		||||
            factory.convertToUio(sheet = sheet, diminished = diminished)
 | 
			
		||||
        },
 | 
			
		||||
    )
 | 
			
		||||
    val sheet: State<CharacterSheetPageUio?>
 | 
			
		||||
        @Composable
 | 
			
		||||
        @Stable
 | 
			
		||||
        get() = combine(
 | 
			
		||||
            repository.characterSheetFlow(id = argument.id),
 | 
			
		||||
            repository.characterDiminishedFlow(id = argument.id),
 | 
			
		||||
            transform = { sheet, diminished -> sheet to diminished },
 | 
			
		||||
        ).stateIn(
 | 
			
		||||
            scope = viewModelScope,
 | 
			
		||||
            started = SharingStarted.Lazily,
 | 
			
		||||
            initialValue = run {
 | 
			
		||||
                val sheet = repository.characterSheetFlow(id = argument.id).value
 | 
			
		||||
                val diminished = repository.characterDiminishedFlow(id = argument.id).value
 | 
			
		||||
                sheet to diminished
 | 
			
		||||
            }
 | 
			
		||||
        ).collectAsState { (sheet, diminished) ->
 | 
			
		||||
            sheet?.let { model ->
 | 
			
		||||
                runBlocking { factory.convertToUio(sheet = model, diminished = diminished) }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        get() = sheetFlow.collectAsState(
 | 
			
		||||
            initial = null,
 | 
			
		||||
            context = viewModelScope.coroutineContext,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    fun deleteCharacter(id: String) {
 | 
			
		||||
        repository.delete(id = id)
 | 
			
		||||
| 
						 | 
				
			
			@ -120,14 +111,14 @@ class CharacterSheetViewModel(
 | 
			
		|||
    suspend fun showSubCharacteristicDialog(id: String) {
 | 
			
		||||
        repository.characterSheetFlow(id = argument.id).value?.let { sheet ->
 | 
			
		||||
            _statChangeDialog.value = when (id) {
 | 
			
		||||
                CharacterSheetFactory.HP -> {
 | 
			
		||||
                CharacterSheet.CharacteristicId.HP -> {
 | 
			
		||||
                    val value = mutableStateOf(
 | 
			
		||||
                        "${sheet.currentHp}".let {
 | 
			
		||||
                            TextFieldValue(text = it, selection = TextRange(it.length))
 | 
			
		||||
                        }
 | 
			
		||||
                    )
 | 
			
		||||
                    StatChangeDialogUio(
 | 
			
		||||
                        id = CharacterSheetFactory.HP,
 | 
			
		||||
                        id = CharacterSheet.CharacteristicId.HP,
 | 
			
		||||
                        label = getString(resource = Res.string.character_sheet_edit__sub_characteristics__hit_point),
 | 
			
		||||
                        value = { value.value },
 | 
			
		||||
                        onValueChange = { value.value = it },
 | 
			
		||||
| 
						 | 
				
			
			@ -135,14 +126,14 @@ class CharacterSheetViewModel(
 | 
			
		|||
                    )
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                CharacterSheetFactory.PP -> {
 | 
			
		||||
                CharacterSheet.CharacteristicId.PP -> {
 | 
			
		||||
                    val value = mutableStateOf(
 | 
			
		||||
                        "${sheet.currentPp}".let {
 | 
			
		||||
                            TextFieldValue(text = it, selection = TextRange(it.length))
 | 
			
		||||
                        }
 | 
			
		||||
                    )
 | 
			
		||||
                    StatChangeDialogUio(
 | 
			
		||||
                        id = CharacterSheetFactory.PP,
 | 
			
		||||
                        id = CharacterSheet.CharacteristicId.PP,
 | 
			
		||||
                        label = getString(resource = Res.string.character_sheet_edit__sub_characteristics__power_point),
 | 
			
		||||
                        value = { value.value },
 | 
			
		||||
                        onValueChange = { value.value = it },
 | 
			
		||||
| 
						 | 
				
			
			@ -165,8 +156,20 @@ class CharacterSheetViewModel(
 | 
			
		|||
    ) {
 | 
			
		||||
        val sheet = repository.characterSheetFlow(id = argument.id).value
 | 
			
		||||
        val updated = when (characteristicId) {
 | 
			
		||||
            CharacterSheetFactory.HP -> sheet?.copy(currentHp = max(0, min(sheet.maxHp, value)))
 | 
			
		||||
            CharacterSheetFactory.PP -> sheet?.copy(currentPp = max(0, min(sheet.maxPp, value)))
 | 
			
		||||
            CharacterSheet.CharacteristicId.HP -> sheet?.copy(
 | 
			
		||||
                currentHp = max(
 | 
			
		||||
                    0,
 | 
			
		||||
                    min(sheet.maxHp, value)
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            CharacterSheet.CharacteristicId.PP -> sheet?.copy(
 | 
			
		||||
                currentPp = max(
 | 
			
		||||
                    0,
 | 
			
		||||
                    min(sheet.maxPp, value)
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
            else -> null
 | 
			
		||||
        }
 | 
			
		||||
        updated?.let {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -125,8 +125,8 @@ class CharacterSheetEditFactory(
 | 
			
		|||
                    label = editedSkill.label,
 | 
			
		||||
                    description = skillDescriptionFactory.baseSkillDescription(editedSkill.id),
 | 
			
		||||
                    base = "${editedSkill.base.value}",
 | 
			
		||||
                    bonus = editedSkill.bonus.value.value.toIntOrNull(),
 | 
			
		||||
                    level = editedSkill.level.value.value.toIntOrNull(),
 | 
			
		||||
                    bonus = editedSkill.bonus.value.value.takeIf { it.isNotBlank() },
 | 
			
		||||
                    level = editedSkill.level.value.value.takeIf { it.isNotBlank() },
 | 
			
		||||
                    occupation = editedSkill.option.checked.value,
 | 
			
		||||
                    used = currentSkill?.used ?: false,
 | 
			
		||||
                )
 | 
			
		||||
| 
						 | 
				
			
			@ -140,8 +140,8 @@ class CharacterSheetEditFactory(
 | 
			
		|||
                    label = editedSkill.label.value.value,
 | 
			
		||||
                    description = editedSkill.description.value.value,
 | 
			
		||||
                    base = editedSkill.base.value.value,
 | 
			
		||||
                    bonus = editedSkill.bonus.value.value.toIntOrNull(),
 | 
			
		||||
                    level = editedSkill.level.value.value.toIntOrNull(),
 | 
			
		||||
                    bonus = editedSkill.bonus.value.value.takeIf { it.isNotBlank() },
 | 
			
		||||
                    level = editedSkill.level.value.value.takeIf { it.isNotBlank() },
 | 
			
		||||
                    occupation = editedSkill.options.occupation,
 | 
			
		||||
                    used = currentSkill?.used ?: false,
 | 
			
		||||
                )
 | 
			
		||||
| 
						 | 
				
			
			@ -155,8 +155,8 @@ class CharacterSheetEditFactory(
 | 
			
		|||
                    label = editedSkill.label.value.value,
 | 
			
		||||
                    description = editedSkill.description.value.value,
 | 
			
		||||
                    base = editedSkill.base.value.value,
 | 
			
		||||
                    bonus = editedSkill.bonus.value.value.toIntOrNull(),
 | 
			
		||||
                    level = editedSkill.level.value.value.toIntOrNull(),
 | 
			
		||||
                    bonus = editedSkill.bonus.value.value.takeIf { it.isNotBlank() },
 | 
			
		||||
                    level = editedSkill.level.value.value.takeIf { it.isNotBlank() },
 | 
			
		||||
                    occupation = editedSkill.options.occupation,
 | 
			
		||||
                    used = currentSkill?.used ?: false,
 | 
			
		||||
                )
 | 
			
		||||
| 
						 | 
				
			
			@ -423,8 +423,8 @@ class CharacterSheetEditFactory(
 | 
			
		|||
                    descriptionValue = skill.description ?: "",
 | 
			
		||||
                    labelValue = skill.label,
 | 
			
		||||
                    baseValue = skill.base,
 | 
			
		||||
                    bonusValue = skill.bonus?.toString() ?: "",
 | 
			
		||||
                    levelValue = skill.level?.toString() ?: "",
 | 
			
		||||
                    bonusValue = skill.bonus ?: "",
 | 
			
		||||
                    levelValue = skill.level ?: "",
 | 
			
		||||
                    options = run {
 | 
			
		||||
                        val current = sheet.specialSkills.firstOrNull { it.id == skill.id }
 | 
			
		||||
                        listOf(
 | 
			
		||||
| 
						 | 
				
			
			@ -441,12 +441,14 @@ class CharacterSheetEditFactory(
 | 
			
		|||
                    descriptionValue = skill.description ?: "",
 | 
			
		||||
                    labelValue = skill.label,
 | 
			
		||||
                    baseValue = skill.base,
 | 
			
		||||
                    bonusValue = skill.bonus?.toString() ?: "",
 | 
			
		||||
                    levelValue = skill.level?.toString() ?: "",
 | 
			
		||||
                    bonusValue = skill.bonus ?: "",
 | 
			
		||||
                    levelValue = skill.level ?: "",
 | 
			
		||||
                    options = run {
 | 
			
		||||
                        val current = sheet.magicSkills.firstOrNull { it.id == skill.id }
 | 
			
		||||
                        listOf(
 | 
			
		||||
                            skillFieldFactory.occupationOption(checked = current?.occupation ?: false),
 | 
			
		||||
                            skillFieldFactory.occupationOption(
 | 
			
		||||
                                checked = current?.occupation ?: false
 | 
			
		||||
                            ),
 | 
			
		||||
                            skillFieldFactory.deleteOption { onDeleteSkill(skill.id) },
 | 
			
		||||
                        )
 | 
			
		||||
                    },
 | 
			
		||||
| 
						 | 
				
			
			@ -483,11 +485,11 @@ class CharacterSheetEditFactory(
 | 
			
		|||
            base = base,
 | 
			
		||||
            bonus = skillFieldFactory.createWrapper(
 | 
			
		||||
                label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__bonus_label)),
 | 
			
		||||
                value = skill?.bonus?.toString() ?: "",
 | 
			
		||||
                value = skill?.bonus ?: "",
 | 
			
		||||
            ),
 | 
			
		||||
            level = skillFieldFactory.createWrapper(
 | 
			
		||||
                label = mutableStateOf(getString(Res.string.character_sheet_edit__skills__level_label)),
 | 
			
		||||
                value = skill?.level?.toString() ?: "",
 | 
			
		||||
                value = skill?.level ?: "",
 | 
			
		||||
            ),
 | 
			
		||||
            option = skillFieldFactory.occupationOption(skill?.occupation ?: false),
 | 
			
		||||
        )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,11 +3,15 @@ package com.pixelized.desktop.lwa.screen.main
 | 
			
		|||
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.Spacer
 | 
			
		||||
import androidx.compose.foundation.layout.fillMaxSize
 | 
			
		||||
import androidx.compose.foundation.layout.fillMaxWidth
 | 
			
		||||
import androidx.compose.foundation.layout.height
 | 
			
		||||
import androidx.compose.foundation.layout.padding
 | 
			
		||||
import androidx.compose.foundation.rememberScrollState
 | 
			
		||||
import androidx.compose.foundation.verticalScroll
 | 
			
		||||
import androidx.compose.material.Icon
 | 
			
		||||
import androidx.compose.material.Surface
 | 
			
		||||
import androidx.compose.material.Text
 | 
			
		||||
import androidx.compose.material.TextButton
 | 
			
		||||
| 
						 | 
				
			
			@ -28,11 +32,16 @@ import com.pixelized.desktop.lwa.navigation.window.destination.CharacterSheetWin
 | 
			
		|||
import kotlinx.coroutines.runBlocking
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.Res
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__create__title
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.ic_d20_24dp
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.ic_file_24dp
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.ic_folder_24dp
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.ic_table_24dp
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.main_page__create_action
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.main_page__network_action
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.main_page__open_save_directory
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.main_page__roll_history_action
 | 
			
		||||
import org.jetbrains.compose.resources.getString
 | 
			
		||||
import org.jetbrains.compose.resources.painterResource
 | 
			
		||||
import org.jetbrains.compose.resources.stringResource
 | 
			
		||||
import org.koin.compose.viewmodel.koinViewModel
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -103,65 +112,100 @@ fun MainPageContent(
 | 
			
		|||
) {
 | 
			
		||||
    Column(
 | 
			
		||||
        modifier = modifier,
 | 
			
		||||
        verticalArrangement = Arrangement.spacedBy(16.dp),
 | 
			
		||||
        verticalArrangement = Arrangement.spacedBy(4.dp),
 | 
			
		||||
    ) {
 | 
			
		||||
        Column {
 | 
			
		||||
            characters.value.forEach { sheet ->
 | 
			
		||||
                TextButton(
 | 
			
		||||
                    onClick = { onCharacter(sheet) },
 | 
			
		||||
                ) {
 | 
			
		||||
                    Text(
 | 
			
		||||
                        modifier = Modifier.fillMaxWidth(),
 | 
			
		||||
                        overflow = TextOverflow.Ellipsis,
 | 
			
		||||
                        textAlign = TextAlign.Start,
 | 
			
		||||
                        maxLines = 1,
 | 
			
		||||
                        text = sheet.name,
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
        characters.value.forEach { sheet ->
 | 
			
		||||
            TextButton(
 | 
			
		||||
                onClick = { onCharacter(sheet) },
 | 
			
		||||
            ) {
 | 
			
		||||
                Text(
 | 
			
		||||
                    modifier = Modifier.fillMaxWidth(),
 | 
			
		||||
                    overflow = TextOverflow.Ellipsis,
 | 
			
		||||
                    textAlign = TextAlign.Start,
 | 
			
		||||
                    maxLines = 1,
 | 
			
		||||
                    text = sheet.name,
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Spacer(modifier = Modifier.height(height = 24.dp))
 | 
			
		||||
 | 
			
		||||
        TextButton(
 | 
			
		||||
            onClick = onCreateCharacter,
 | 
			
		||||
        ) {
 | 
			
		||||
            Text(
 | 
			
		||||
            Row(
 | 
			
		||||
                modifier = Modifier.fillMaxWidth(),
 | 
			
		||||
                maxLines = 1,
 | 
			
		||||
                overflow = TextOverflow.Ellipsis,
 | 
			
		||||
                textAlign = TextAlign.Start,
 | 
			
		||||
                text = stringResource(Res.string.main_page__create_action),
 | 
			
		||||
            )
 | 
			
		||||
                horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
 | 
			
		||||
                verticalAlignment = Alignment.CenterVertically,
 | 
			
		||||
            ) {
 | 
			
		||||
                Icon(
 | 
			
		||||
                    painter = painterResource(Res.drawable.ic_file_24dp),
 | 
			
		||||
                    contentDescription = null,
 | 
			
		||||
                )
 | 
			
		||||
                Text(
 | 
			
		||||
                    maxLines = 1,
 | 
			
		||||
                    overflow = TextOverflow.Ellipsis,
 | 
			
		||||
                    textAlign = TextAlign.Start,
 | 
			
		||||
                    text = stringResource(Res.string.main_page__create_action),
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        TextButton(
 | 
			
		||||
            onClick = onOpenSaveDirectory,
 | 
			
		||||
        ) {
 | 
			
		||||
            Text(
 | 
			
		||||
            Row(
 | 
			
		||||
                modifier = Modifier.fillMaxWidth(),
 | 
			
		||||
                maxLines = 1,
 | 
			
		||||
                overflow = TextOverflow.Ellipsis,
 | 
			
		||||
                textAlign = TextAlign.Start,
 | 
			
		||||
                text = stringResource(Res.string.main_page__open_save_directory),
 | 
			
		||||
            )
 | 
			
		||||
                horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
 | 
			
		||||
                verticalAlignment = Alignment.CenterVertically,
 | 
			
		||||
            ) {
 | 
			
		||||
                Icon(
 | 
			
		||||
                    painter = painterResource(Res.drawable.ic_folder_24dp),
 | 
			
		||||
                    contentDescription = null,
 | 
			
		||||
                )
 | 
			
		||||
                Text(
 | 
			
		||||
                    maxLines = 1,
 | 
			
		||||
                    overflow = TextOverflow.Ellipsis,
 | 
			
		||||
                    textAlign = TextAlign.Start,
 | 
			
		||||
                    text = stringResource(Res.string.main_page__open_save_directory),
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Column {
 | 
			
		||||
            TextButton(
 | 
			
		||||
                onClick = onRollHistory,
 | 
			
		||||
        TextButton(
 | 
			
		||||
            onClick = onRollHistory,
 | 
			
		||||
        ) {
 | 
			
		||||
            Row(
 | 
			
		||||
                modifier = Modifier.fillMaxWidth(),
 | 
			
		||||
                horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
 | 
			
		||||
                verticalAlignment = Alignment.CenterVertically,
 | 
			
		||||
            ) {
 | 
			
		||||
                Icon(
 | 
			
		||||
                    painter = painterResource(Res.drawable.ic_d20_24dp),
 | 
			
		||||
                    contentDescription = null,
 | 
			
		||||
                )
 | 
			
		||||
                Text(
 | 
			
		||||
                    modifier = Modifier.fillMaxWidth(),
 | 
			
		||||
                    maxLines = 1,
 | 
			
		||||
                    overflow = TextOverflow.Ellipsis,
 | 
			
		||||
                    textAlign = TextAlign.Start,
 | 
			
		||||
                    text = stringResource(Res.string.main_page__roll_history_action),
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
            TextButton(
 | 
			
		||||
                onClick = onNetwork,
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        TextButton(
 | 
			
		||||
            onClick = onNetwork,
 | 
			
		||||
        ) {
 | 
			
		||||
            Row(
 | 
			
		||||
                modifier = Modifier.fillMaxWidth(),
 | 
			
		||||
                horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
 | 
			
		||||
                verticalAlignment = Alignment.CenterVertically,
 | 
			
		||||
            ) {
 | 
			
		||||
                Icon(
 | 
			
		||||
                    painter = painterResource(Res.drawable.ic_table_24dp),
 | 
			
		||||
                    contentDescription = null,
 | 
			
		||||
                )
 | 
			
		||||
                Text(
 | 
			
		||||
                    modifier = Modifier.fillMaxWidth(),
 | 
			
		||||
                    overflow = TextOverflow.Ellipsis,
 | 
			
		||||
                    textAlign = TextAlign.Start,
 | 
			
		||||
                    maxLines = 1,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,7 +48,7 @@ import com.pixelized.desktop.lwa.screen.roll.DifficultyUio.Difficulty
 | 
			
		|||
import com.pixelized.desktop.lwa.utils.DisableInteractionSource
 | 
			
		||||
import kotlinx.coroutines.launch
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.Res
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.ic_d20_32dp
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.ic_d20_24dp
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.roll_page__dc__label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.roll_page__dc_easy__label
 | 
			
		||||
import lwacharactersheet.composeapp.generated.resources.roll_page__dc_hard__label
 | 
			
		||||
| 
						 | 
				
			
			@ -145,7 +145,7 @@ fun RollPage(
 | 
			
		|||
                            this.rotationZ = viewModel.rollRotation.value
 | 
			
		||||
                        },
 | 
			
		||||
                    tint = MaterialTheme.colors.primary,
 | 
			
		||||
                    painter = painterResource(Res.drawable.ic_d20_32dp),
 | 
			
		||||
                    painter = painterResource(Res.drawable.ic_d20_24dp),
 | 
			
		||||
                    contentDescription = null,
 | 
			
		||||
                )
 | 
			
		||||
                AnimatedContent(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue