Add the ability to roll from the admin screen.
This commit is contained in:
parent
2fb0d3d4cd
commit
ee4445490c
10 changed files with 278 additions and 223 deletions
|
|
@ -9,6 +9,7 @@ import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class CharacterSheetRepository(
|
class CharacterSheetRepository(
|
||||||
private val store: CharacterSheetStore,
|
private val store: CharacterSheetStore,
|
||||||
|
|
@ -47,6 +48,11 @@ class CharacterSheetRepository(
|
||||||
characterSheetId: String?,
|
characterSheetId: String?,
|
||||||
): StateFlow<CharacterSheet?> {
|
): StateFlow<CharacterSheet?> {
|
||||||
val initial = store.detailFlow.value[characterSheetId]
|
val initial = store.detailFlow.value[characterSheetId]
|
||||||
|
|
||||||
|
if (initial == null) {
|
||||||
|
scope.launch { characterDetail(characterSheetId = characterSheetId) }
|
||||||
|
}
|
||||||
|
|
||||||
return store.detailFlow
|
return store.detailFlow
|
||||||
.map { sheets ->
|
.map { sheets ->
|
||||||
sheets[characterSheetId]
|
sheets[characterSheetId]
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,5 @@
|
||||||
package com.pixelized.desktop.lwa.ui.composable.character.characteristic
|
package com.pixelized.desktop.lwa.ui.composable.character.characteristic
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedContent
|
|
||||||
import androidx.compose.animation.SizeTransform
|
|
||||||
import androidx.compose.animation.fadeIn
|
|
||||||
import androidx.compose.animation.fadeOut
|
|
||||||
import androidx.compose.animation.slideInVertically
|
|
||||||
import androidx.compose.animation.slideOutVertically
|
|
||||||
import androidx.compose.animation.togetherWith
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
|
@ -38,6 +31,7 @@ import androidx.compose.ui.text.input.ImeAction
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.window.Dialog
|
||||||
import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox
|
import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox
|
||||||
import com.pixelized.desktop.lwa.utils.extention.onPreviewEscape
|
import com.pixelized.desktop.lwa.utils.extention.onPreviewEscape
|
||||||
import lwacharactersheet.composeapp.generated.resources.Res
|
import lwacharactersheet.composeapp.generated.resources.Res
|
||||||
|
|
@ -67,35 +61,22 @@ fun CharacterSheetCharacteristicDialog(
|
||||||
onConfirm: (CharacterSheetCharacteristicDialogUio) -> Unit,
|
onConfirm: (CharacterSheetCharacteristicDialogUio) -> Unit,
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
) {
|
) {
|
||||||
AnimatedContent(
|
dialog.value?.let {
|
||||||
modifier = Modifier.fillMaxSize(),
|
Dialog(
|
||||||
targetState = dialog.value,
|
onDismissRequest = onDismissRequest,
|
||||||
transitionSpec = {
|
content = {
|
||||||
val enter = fadeIn() + slideInVertically { 32 }
|
CharacterSheetCharacteristicContent(
|
||||||
val exit = fadeOut() + slideOutVertically { 32 }
|
|
||||||
enter togetherWith exit using SizeTransform(clip = false)
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier.fillMaxSize()
|
|
||||||
) {
|
|
||||||
when (it) {
|
|
||||||
null -> Box(
|
|
||||||
modifier = Modifier,
|
|
||||||
)
|
|
||||||
|
|
||||||
else -> Dialog(
|
|
||||||
dialog = it,
|
dialog = it,
|
||||||
onConfirm = onConfirm,
|
onConfirm = onConfirm,
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Dialog(
|
private fun CharacterSheetCharacteristicContent(
|
||||||
dialog: CharacterSheetCharacteristicDialogUio,
|
dialog: CharacterSheetCharacteristicDialogUio,
|
||||||
onConfirm: (CharacterSheetCharacteristicDialogUio) -> Unit,
|
onConfirm: (CharacterSheetCharacteristicDialogUio) -> Unit,
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ fun WindowController.navigateToGameMasterWindow(
|
||||||
window = GameMasterWindow(
|
window = GameMasterWindow(
|
||||||
title = title,
|
title = title,
|
||||||
size = DpSize(
|
size = DpSize(
|
||||||
width = 124.dp * 4 + 64.dp,
|
width = 124.dp * 4 + 108.dp,
|
||||||
height = maxWindowHeight - 32.dp,
|
height = maxWindowHeight - 32.dp,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ import kotlinx.coroutines.flow.stateIn
|
||||||
|
|
||||||
class CharacterDetailViewModel(
|
class CharacterDetailViewModel(
|
||||||
private val characterSheetRepository: CharacterSheetRepository,
|
private val characterSheetRepository: CharacterSheetRepository,
|
||||||
private val campaignRepository: CampaignRepository,
|
|
||||||
private val alterationRepository: AlterationRepository,
|
private val alterationRepository: AlterationRepository,
|
||||||
private val characterDetailFactory: CharacterDetailFactory,
|
private val characterDetailFactory: CharacterDetailFactory,
|
||||||
private val network: NetworkRepository,
|
private val network: NetworkRepository,
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,6 @@ import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.input.key.Key
|
|
||||||
import androidx.compose.ui.input.key.key
|
|
||||||
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox
|
import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox
|
||||||
import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextField
|
import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextField
|
||||||
|
|
@ -51,7 +48,7 @@ import org.jetbrains.compose.resources.stringResource
|
||||||
data class CharacterSheetCopyDialogUio(
|
data class CharacterSheetCopyDialogUio(
|
||||||
val label: String,
|
val label: String,
|
||||||
val value: LwaTextFieldUio,
|
val value: LwaTextFieldUio,
|
||||||
val validate: () -> Boolean
|
val validate: () -> Boolean,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -165,7 +162,11 @@ private fun Dialog(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
TextButton(
|
TextButton(
|
||||||
onClick = { if(dialog.validate()) {onConfirm(dialog)} },
|
onClick = {
|
||||||
|
if (dialog.validate()) {
|
||||||
|
onConfirm(dialog)
|
||||||
|
}
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(Res.string.dialog__confirm_action)
|
text = stringResource(Res.string.dialog__confirm_action)
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,5 @@
|
||||||
package com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.dialog
|
package com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.dialog
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedContent
|
|
||||||
import androidx.compose.animation.SizeTransform
|
|
||||||
import androidx.compose.animation.fadeIn
|
|
||||||
import androidx.compose.animation.fadeOut
|
|
||||||
import androidx.compose.animation.slideInVertically
|
|
||||||
import androidx.compose.animation.slideOutVertically
|
|
||||||
import androidx.compose.animation.togetherWith
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
|
@ -26,14 +19,11 @@ import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.input.key.Key
|
|
||||||
import androidx.compose.ui.input.key.key
|
|
||||||
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.window.Dialog
|
||||||
import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox
|
import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox
|
||||||
import com.pixelized.desktop.lwa.utils.extention.onPreviewEscape
|
import com.pixelized.desktop.lwa.utils.extention.onPreviewEscape
|
||||||
import lwacharactersheet.composeapp.generated.resources.Res
|
import lwacharactersheet.composeapp.generated.resources.Res
|
||||||
|
|
||||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__delete_dialog__description
|
import lwacharactersheet.composeapp.generated.resources.character_sheet__delete_dialog__description
|
||||||
import lwacharactersheet.composeapp.generated.resources.character_sheet__delete_dialog__title
|
import lwacharactersheet.composeapp.generated.resources.character_sheet__delete_dialog__title
|
||||||
import lwacharactersheet.composeapp.generated.resources.dialog__cancel_action
|
import lwacharactersheet.composeapp.generated.resources.dialog__cancel_action
|
||||||
|
|
@ -52,35 +42,22 @@ fun CharacterSheetDeleteConfirmationDialog(
|
||||||
onConfirm: (CharacterSheetDeleteConfirmationDialogUio) -> Unit,
|
onConfirm: (CharacterSheetDeleteConfirmationDialogUio) -> Unit,
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
) {
|
) {
|
||||||
AnimatedContent(
|
dialog.value?.let {
|
||||||
modifier = Modifier.fillMaxSize(),
|
Dialog(
|
||||||
targetState = dialog.value,
|
onDismissRequest = onDismissRequest,
|
||||||
transitionSpec = {
|
content = {
|
||||||
val enter = fadeIn() + slideInVertically { 32 }
|
CharacterSheetDeleteConfirmationContent(
|
||||||
val exit = fadeOut() + slideOutVertically { 32 }
|
|
||||||
enter togetherWith exit using SizeTransform(clip = false)
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier.fillMaxSize()
|
|
||||||
) {
|
|
||||||
when (it) {
|
|
||||||
null -> Box(
|
|
||||||
modifier = Modifier,
|
|
||||||
)
|
|
||||||
|
|
||||||
else -> Dialog(
|
|
||||||
dialog = it,
|
dialog = it,
|
||||||
onConfirm = onConfirm,
|
onConfirm = onConfirm,
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Dialog(
|
private fun CharacterSheetDeleteConfirmationContent(
|
||||||
dialog: CharacterSheetDeleteConfirmationDialogUio,
|
dialog: CharacterSheetDeleteConfirmationDialogUio,
|
||||||
onConfirm: (CharacterSheetDeleteConfirmationDialogUio) -> Unit,
|
onConfirm: (CharacterSheetDeleteConfirmationDialogUio) -> Unit,
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,5 @@
|
||||||
package com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.dialog
|
package com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.dialog
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedContent
|
|
||||||
import androidx.compose.animation.SizeTransform
|
|
||||||
import androidx.compose.animation.fadeIn
|
|
||||||
import androidx.compose.animation.fadeOut
|
|
||||||
import androidx.compose.animation.slideInVertically
|
|
||||||
import androidx.compose.animation.slideOutVertically
|
|
||||||
import androidx.compose.animation.togetherWith
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
|
@ -38,9 +31,9 @@ import androidx.compose.ui.text.input.ImeAction
|
||||||
import androidx.compose.ui.text.input.TextFieldValue
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.window.Dialog
|
||||||
import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox
|
import com.pixelized.desktop.lwa.ui.composable.decoratedBox.DecoratedBox
|
||||||
import com.pixelized.desktop.lwa.utils.extention.onPreviewEscape
|
import com.pixelized.desktop.lwa.utils.extention.onPreviewEscape
|
||||||
import com.pixelized.shared.lwa.model.campaign.Campaign
|
|
||||||
import lwacharactersheet.composeapp.generated.resources.Res
|
import lwacharactersheet.composeapp.generated.resources.Res
|
||||||
import lwacharactersheet.composeapp.generated.resources.dialog__cancel_action
|
import lwacharactersheet.composeapp.generated.resources.dialog__cancel_action
|
||||||
import lwacharactersheet.composeapp.generated.resources.dialog__confirm_action
|
import lwacharactersheet.composeapp.generated.resources.dialog__confirm_action
|
||||||
|
|
@ -60,35 +53,22 @@ fun DiminishedStatDialog(
|
||||||
onConfirm: (CharacterSheetDiminishedStatDialogUio) -> Unit,
|
onConfirm: (CharacterSheetDiminishedStatDialogUio) -> Unit,
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
) {
|
) {
|
||||||
AnimatedContent(
|
dialog.value?.let {
|
||||||
modifier = Modifier.fillMaxSize(),
|
Dialog(
|
||||||
targetState = dialog.value,
|
onDismissRequest = onDismissRequest,
|
||||||
transitionSpec = {
|
content = {
|
||||||
val enter = fadeIn() + slideInVertically { 32 }
|
DiminishedDialogContent(
|
||||||
val exit = fadeOut() + slideOutVertically { 32 }
|
|
||||||
enter togetherWith exit using SizeTransform(clip = false)
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier.fillMaxSize()
|
|
||||||
) {
|
|
||||||
when (it) {
|
|
||||||
null -> Box(
|
|
||||||
modifier = Modifier,
|
|
||||||
)
|
|
||||||
|
|
||||||
else -> Dialog(
|
|
||||||
dialog = it,
|
dialog = it,
|
||||||
onConfirm = onConfirm,
|
onConfirm = onConfirm,
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Dialog(
|
private fun DiminishedDialogContent(
|
||||||
dialog: CharacterSheetDiminishedStatDialogUio,
|
dialog: CharacterSheetDiminishedStatDialogUio,
|
||||||
onConfirm: (CharacterSheetDiminishedStatDialogUio) -> Unit,
|
onConfirm: (CharacterSheetDiminishedStatDialogUio) -> Unit,
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.pixelized.desktop.lwa.ui.screen.gamemaster
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
|
|
@ -19,14 +20,24 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
|
import androidx.compose.runtime.compositionLocalOf
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.input.key.Key
|
||||||
|
import androidx.compose.ui.input.key.KeyEventType
|
||||||
|
import androidx.compose.ui.input.key.key
|
||||||
|
import androidx.compose.ui.input.key.type
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.unit.LayoutDirection
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.navigation.NavHostController
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import com.pixelized.desktop.lwa.LocalBlurController
|
||||||
|
import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterDetailCharacteristicDialogViewModel
|
||||||
|
import com.pixelized.desktop.lwa.ui.composable.character.diminished.CharacterSheetDiminishedViewModel
|
||||||
|
import com.pixelized.desktop.lwa.ui.composable.key.KeyHandler
|
||||||
import com.pixelized.desktop.lwa.ui.navigation.screen.LocalScreenController
|
import com.pixelized.desktop.lwa.ui.navigation.screen.LocalScreenController
|
||||||
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.gamemaster.GMActionDestination
|
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.gamemaster.GMActionDestination
|
||||||
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.gamemaster.composableGameMasterActionPage
|
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.gamemaster.composableGameMasterActionPage
|
||||||
|
|
@ -37,6 +48,9 @@ import com.pixelized.desktop.lwa.ui.navigation.screen.destination.gamemaster.nav
|
||||||
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.gamemaster.navigateToGameMasterAlterationPage
|
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.gamemaster.navigateToGameMasterAlterationPage
|
||||||
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.gamemaster.navigateToGameMasterCharacterPage
|
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.gamemaster.navigateToGameMasterCharacterPage
|
||||||
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.gamemaster.navigateToGameMasterObjectPage
|
import com.pixelized.desktop.lwa.ui.navigation.screen.destination.gamemaster.navigateToGameMasterObjectPage
|
||||||
|
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.CharacterDetailPanel
|
||||||
|
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.CharacterDetailViewModel
|
||||||
|
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.rememberTransitionAnimation
|
||||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMTab
|
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMTab
|
||||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMTabUio
|
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMTabUio
|
||||||
import com.pixelized.desktop.lwa.ui.theme.color.component.LwaSwitchColors
|
import com.pixelized.desktop.lwa.ui.theme.color.component.LwaSwitchColors
|
||||||
|
|
@ -47,34 +61,36 @@ import lwacharactersheet.composeapp.generated.resources.game_master__title
|
||||||
import org.jetbrains.compose.resources.stringResource
|
import org.jetbrains.compose.resources.stringResource
|
||||||
import org.koin.compose.viewmodel.koinViewModel
|
import org.koin.compose.viewmodel.koinViewModel
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun GameMasterScreen(
|
fun GameMasterScreen(
|
||||||
viewModel: GameMasterViewModel = koinViewModel(),
|
gameMasterViewModel: GameMasterViewModel = koinViewModel(),
|
||||||
|
|
||||||
) {
|
) {
|
||||||
val screen = rememberNavController()
|
val screen = rememberNavController()
|
||||||
val gameMaster = viewModel.isGameMaster.collectAsState()
|
val gameMaster = gameMasterViewModel.isGameMaster.collectAsState()
|
||||||
|
|
||||||
Surface(
|
CompositionLocalProvider(
|
||||||
modifier = Modifier.fillMaxSize()
|
LocalScreenController provides screen,
|
||||||
) {
|
) {
|
||||||
CompositionLocalProvider(
|
Surface(
|
||||||
LocalScreenController provides screen,
|
modifier = Modifier.fillMaxSize()
|
||||||
) {
|
) {
|
||||||
GameMasterContent(
|
Box {
|
||||||
modifier = Modifier.fillMaxSize(),
|
GameMasterContent(
|
||||||
controller = screen,
|
modifier = Modifier.fillMaxSize(),
|
||||||
gameMaster = gameMaster,
|
controller = screen,
|
||||||
onGameMaster = viewModel::onGameMaster,
|
gameMaster = gameMaster,
|
||||||
onTab = {
|
onGameMaster = gameMasterViewModel::onGameMaster,
|
||||||
when (it) {
|
onTab = {
|
||||||
GMTabUio.Actions -> screen.navigateToGameMasterActionPage()
|
when (it) {
|
||||||
GMTabUio.Characters -> screen.navigateToGameMasterCharacterPage()
|
GMTabUio.Actions -> screen.navigateToGameMasterActionPage()
|
||||||
GMTabUio.Alterations -> screen.navigateToGameMasterAlterationPage()
|
GMTabUio.Characters -> screen.navigateToGameMasterCharacterPage()
|
||||||
GMTabUio.Objects -> screen.navigateToGameMasterObjectPage()
|
GMTabUio.Alterations -> screen.navigateToGameMasterAlterationPage()
|
||||||
}
|
GMTabUio.Objects -> screen.navigateToGameMasterObjectPage()
|
||||||
},
|
}
|
||||||
)
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -121,44 +137,46 @@ private fun GameMasterContent(
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
content = { paddingValues ->
|
content = { paddingValues ->
|
||||||
Row(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(paddingValues),
|
.padding(paddingValues),
|
||||||
) {
|
) {
|
||||||
Surface(
|
Row {
|
||||||
elevation = 1.dp,
|
Surface(
|
||||||
) {
|
elevation = 1.dp,
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxHeight()
|
|
||||||
.width(width = 64.dp)
|
|
||||||
.padding(vertical = 8.dp),
|
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
|
||||||
verticalArrangement = Arrangement.spacedBy(space = 8.dp),
|
|
||||||
) {
|
) {
|
||||||
GMTabUio.entries.forEach {
|
Column(
|
||||||
GMTab(
|
modifier = Modifier
|
||||||
tab = it,
|
.fillMaxHeight()
|
||||||
onClick = { onTab(it) },
|
.width(width = 64.dp)
|
||||||
)
|
.padding(vertical = 8.dp),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.spacedBy(space = 8.dp),
|
||||||
|
) {
|
||||||
|
GMTabUio.entries.forEach {
|
||||||
|
GMTab(
|
||||||
|
tab = it,
|
||||||
|
onClick = { onTab(it) },
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
Surface(
|
||||||
Surface(
|
modifier = Modifier
|
||||||
modifier = Modifier
|
.fillMaxHeight()
|
||||||
.fillMaxHeight()
|
.weight(weight = 1f),
|
||||||
.weight(weight = 1f),
|
|
||||||
) {
|
|
||||||
NavHost(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
navController = controller,
|
|
||||||
startDestination = GMActionDestination.navigationRoute(),
|
|
||||||
) {
|
) {
|
||||||
composableGameMasterActionPage()
|
NavHost(
|
||||||
composableGameMasterCharacterPage()
|
modifier = Modifier.fillMaxSize(),
|
||||||
composableGameMasterAlterationPage()
|
navController = controller,
|
||||||
composableGameMasterObjectPage()
|
startDestination = GMActionDestination.navigationRoute(),
|
||||||
|
) {
|
||||||
|
composableGameMasterActionPage()
|
||||||
|
composableGameMasterCharacterPage()
|
||||||
|
composableGameMasterAlterationPage()
|
||||||
|
composableGameMasterObjectPage()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,10 @@ import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
|
|
@ -23,17 +25,30 @@ import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.input.key.Key
|
||||||
|
import androidx.compose.ui.input.key.KeyEventType
|
||||||
|
import androidx.compose.ui.input.key.key
|
||||||
|
import androidx.compose.ui.input.key.type
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.LayoutDirection
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.pixelized.desktop.lwa.LocalBlurController
|
||||||
import com.pixelized.desktop.lwa.LocalWindowController
|
import com.pixelized.desktop.lwa.LocalWindowController
|
||||||
|
import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterDetailCharacteristicDialogViewModel
|
||||||
|
import com.pixelized.desktop.lwa.ui.composable.character.characteristic.CharacterSheetCharacteristicDialog
|
||||||
|
import com.pixelized.desktop.lwa.ui.composable.character.diminished.CharacterSheetDiminishedViewModel
|
||||||
|
import com.pixelized.desktop.lwa.ui.composable.key.KeyHandler
|
||||||
import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextFieldUio
|
import com.pixelized.desktop.lwa.ui.composable.textfield.LwaTextFieldUio
|
||||||
import com.pixelized.desktop.lwa.ui.navigation.window.destination.navigateToCharacterSheetEdit
|
import com.pixelized.desktop.lwa.ui.navigation.window.destination.navigateToCharacterSheetEdit
|
||||||
|
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.CharacterDetailPanel
|
||||||
|
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.CharacterDetailViewModel
|
||||||
|
import com.pixelized.desktop.lwa.ui.screen.campaign.player.detail.rememberTransitionAnimation
|
||||||
|
import com.pixelized.desktop.lwa.ui.screen.characterSheet.detail.dialog.DiminishedStatDialog
|
||||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMCharacter
|
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMCharacter
|
||||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMCharacterItemUio
|
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMCharacterItemUio
|
||||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMFilterHeader
|
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMFilterHeader
|
||||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMTagItemUio
|
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMTagItemUio
|
||||||
import com.pixelized.desktop.lwa.ui.theme.color.component.LwaButtonColors
|
import com.pixelized.desktop.lwa.ui.theme.color.component.LwaButtonColors
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import lwacharactersheet.composeapp.generated.resources.Res
|
import lwacharactersheet.composeapp.generated.resources.Res
|
||||||
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__create__title
|
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__create__title
|
||||||
|
|
@ -46,35 +61,99 @@ import org.koin.compose.viewmodel.koinViewModel
|
||||||
@Composable
|
@Composable
|
||||||
fun GMCharacterPage(
|
fun GMCharacterPage(
|
||||||
viewModel: GMCharacterViewModel = koinViewModel(),
|
viewModel: GMCharacterViewModel = koinViewModel(),
|
||||||
|
characterDetailViewModel: CharacterDetailViewModel = koinViewModel(),
|
||||||
|
characteristicDialogViewModel: CharacterDetailCharacteristicDialogViewModel = koinViewModel(),
|
||||||
|
dismissedViewModel: CharacterSheetDiminishedViewModel = koinViewModel(),
|
||||||
) {
|
) {
|
||||||
val windows = LocalWindowController.current
|
val windows = LocalWindowController.current
|
||||||
|
val blurController = LocalBlurController.current
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
val characters = viewModel.characters.collectAsState()
|
val characters = viewModel.characters.collectAsState()
|
||||||
val tags = viewModel.tags.collectAsState()
|
val tags = viewModel.tags.collectAsState()
|
||||||
|
|
||||||
GMCharacterContent(
|
Box {
|
||||||
filter = viewModel.filter,
|
GMCharacterContent(
|
||||||
tags = tags,
|
filter = viewModel.filter,
|
||||||
characters = characters,
|
tags = tags,
|
||||||
onTag = viewModel::onTag,
|
characters = characters,
|
||||||
onCharacterAction = viewModel::onCharacterAction,
|
onTag = viewModel::onTag,
|
||||||
onCharacterSheetEdit = { characterSheetId ->
|
onCharacterAction = viewModel::onCharacterAction,
|
||||||
scope.launch {
|
onCharacterSheetDetail = { characterSheetId ->
|
||||||
windows.navigateToCharacterSheetEdit(
|
characterDetailViewModel.showCharacter(characterSheetId = characterSheetId)
|
||||||
characterId = characterSheetId,
|
},
|
||||||
title = getString(Res.string.character_sheet_edit__edit__title),
|
onCharacterSheetEdit = { characterSheetId ->
|
||||||
)
|
scope.launch {
|
||||||
}
|
windows.navigateToCharacterSheetEdit(
|
||||||
},
|
characterId = characterSheetId,
|
||||||
onCharacterSheetCreate = {
|
title = getString(Res.string.character_sheet_edit__edit__title),
|
||||||
scope.launch {
|
)
|
||||||
windows.navigateToCharacterSheetEdit(
|
}
|
||||||
characterId = null,
|
},
|
||||||
title = getString(Res.string.character_sheet_edit__create__title),
|
onCharacterSheetCreate = {
|
||||||
)
|
scope.launch {
|
||||||
}
|
windows.navigateToCharacterSheetEdit(
|
||||||
},
|
characterId = null,
|
||||||
|
title = getString(Res.string.character_sheet_edit__create__title),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
CharacterDetailPanel(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(alignment = Alignment.TopEnd)
|
||||||
|
.padding(all = 8.dp)
|
||||||
|
.width(width = 128.dp * 4)
|
||||||
|
.fillMaxHeight(),
|
||||||
|
transitionSpec = rememberTransitionAnimation(direction = LayoutDirection.Rtl),
|
||||||
|
blurController = blurController,
|
||||||
|
detailViewModel = characterDetailViewModel,
|
||||||
|
characterDiminishedViewModel = dismissedViewModel,
|
||||||
|
characteristicDialogViewModel = characteristicDialogViewModel,
|
||||||
|
)
|
||||||
|
|
||||||
|
CharacterSheetCharacteristicDialog(
|
||||||
|
dialog = characteristicDialogViewModel.statChangeDialog,
|
||||||
|
onConfirm = { dialog ->
|
||||||
|
scope.launch {
|
||||||
|
characteristicDialogViewModel.changeSubCharacteristic(
|
||||||
|
characterSheetId = dialog.characterSheetId,
|
||||||
|
characteristic = dialog.characteristic,
|
||||||
|
value = dialog.value().text.toIntOrNull() ?: 0,
|
||||||
|
)
|
||||||
|
characteristicDialogViewModel.hideSubCharacteristicDialog()
|
||||||
|
blurController.hide()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onDismissRequest = {
|
||||||
|
characteristicDialogViewModel.hideSubCharacteristicDialog()
|
||||||
|
blurController.hide()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
DiminishedStatDialog(
|
||||||
|
dialog = dismissedViewModel.diminishedDialog,
|
||||||
|
onConfirm = { diminished ->
|
||||||
|
scope.launch {
|
||||||
|
dismissedViewModel.changeDiminished(
|
||||||
|
dialog = diminished
|
||||||
|
)
|
||||||
|
blurController.hide()
|
||||||
|
dismissedViewModel.hideDiminishedDialog()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onDismissRequest = {
|
||||||
|
blurController.hide()
|
||||||
|
dismissedViewModel.hideDiminishedDialog()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
GameMasterCharacterKeyHandler(
|
||||||
|
onDismissRequest = {
|
||||||
|
characterDetailViewModel.hideCharacter()
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,6 +167,7 @@ fun GMCharacterContent(
|
||||||
characters: State<List<GMCharacterItemUio>>,
|
characters: State<List<GMCharacterItemUio>>,
|
||||||
onTag: (GMTagItemUio.TagId) -> Unit,
|
onTag: (GMTagItemUio.TagId) -> Unit,
|
||||||
onCharacterAction: (String, GMCharacterItemUio.Action) -> Unit,
|
onCharacterAction: (String, GMCharacterItemUio.Action) -> Unit,
|
||||||
|
onCharacterSheetDetail: (String) -> Unit,
|
||||||
onCharacterSheetEdit: (String) -> Unit,
|
onCharacterSheetEdit: (String) -> Unit,
|
||||||
onCharacterSheetCreate: () -> Unit,
|
onCharacterSheetCreate: () -> Unit,
|
||||||
) {
|
) {
|
||||||
|
|
@ -129,7 +209,10 @@ fun GMCharacterContent(
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.animateItem(),
|
.animateItem(),
|
||||||
character = character,
|
character = character,
|
||||||
onEdit = {
|
onClick = {
|
||||||
|
onCharacterSheetDetail(character.characterSheetId)
|
||||||
|
},
|
||||||
|
onSecondary = {
|
||||||
onCharacterSheetEdit(character.characterSheetId)
|
onCharacterSheetEdit(character.characterSheetId)
|
||||||
},
|
},
|
||||||
onAction = { action ->
|
onAction = { action ->
|
||||||
|
|
@ -162,4 +245,20 @@ fun GMCharacterContent(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun GameMasterCharacterKeyHandler(
|
||||||
|
onDismissRequest: () -> Unit,
|
||||||
|
) {
|
||||||
|
KeyHandler {
|
||||||
|
when {
|
||||||
|
it.type == KeyEventType.KeyUp && it.key == Key.Escape -> {
|
||||||
|
onDismissRequest()
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package com.pixelized.desktop.lwa.ui.screen.gamemaster.items
|
package com.pixelized.desktop.lwa.ui.screen.gamemaster.items
|
||||||
|
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.PointerMatcher
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
|
@ -8,7 +10,7 @@ import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.calculateStartPadding
|
import androidx.compose.foundation.layout.calculateStartPadding
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.onClick
|
||||||
import androidx.compose.material.DropdownMenu
|
import androidx.compose.material.DropdownMenu
|
||||||
import androidx.compose.material.DropdownMenuItem
|
import androidx.compose.material.DropdownMenuItem
|
||||||
import androidx.compose.material.Icon
|
import androidx.compose.material.Icon
|
||||||
|
|
@ -24,8 +26,8 @@ import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
|
import androidx.compose.ui.input.pointer.PointerButton
|
||||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||||
import androidx.compose.ui.unit.DpOffset
|
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMCharacterItemUio.Action
|
import com.pixelized.desktop.lwa.ui.screen.gamemaster.items.GMCharacterItemUio.Action
|
||||||
import com.pixelized.desktop.lwa.ui.theme.lwa
|
import com.pixelized.desktop.lwa.ui.theme.lwa
|
||||||
|
|
@ -42,6 +44,7 @@ import lwacharactersheet.composeapp.generated.resources.ic_group_24dp
|
||||||
import lwacharactersheet.composeapp.generated.resources.ic_group_off_24dp
|
import lwacharactersheet.composeapp.generated.resources.ic_group_off_24dp
|
||||||
import lwacharactersheet.composeapp.generated.resources.ic_imagesmode_24dp
|
import lwacharactersheet.composeapp.generated.resources.ic_imagesmode_24dp
|
||||||
import org.jetbrains.compose.resources.DrawableResource
|
import org.jetbrains.compose.resources.DrawableResource
|
||||||
|
import org.jetbrains.compose.resources.StringResource
|
||||||
import org.jetbrains.compose.resources.painterResource
|
import org.jetbrains.compose.resources.painterResource
|
||||||
import org.jetbrains.compose.resources.stringResource
|
import org.jetbrains.compose.resources.stringResource
|
||||||
|
|
||||||
|
|
@ -56,30 +59,36 @@ data class GMCharacterItemUio(
|
||||||
@Stable
|
@Stable
|
||||||
sealed class Action(
|
sealed class Action(
|
||||||
val icon: DrawableResource,
|
val icon: DrawableResource,
|
||||||
|
val label: StringResource,
|
||||||
) {
|
) {
|
||||||
@Stable
|
@Stable
|
||||||
data object DisplayPortrait : Action(
|
data object DisplayPortrait : Action(
|
||||||
icon = Res.drawable.ic_imagesmode_24dp,
|
icon = Res.drawable.ic_imagesmode_24dp,
|
||||||
|
label = Res.string.game_master__character_action__display_portrait,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
data object AddToGroup : Action(
|
data object AddToGroup : Action(
|
||||||
icon = Res.drawable.ic_group_24dp,
|
icon = Res.drawable.ic_group_24dp,
|
||||||
|
label = Res.string.game_master__character_action__add_to_group,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
data object RemoveFromGroup : Action(
|
data object RemoveFromGroup : Action(
|
||||||
icon = Res.drawable.ic_group_off_24dp,
|
icon = Res.drawable.ic_group_off_24dp,
|
||||||
|
label = Res.string.game_master__character_action__remove_from_group,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
data object AddToNpc : Action(
|
data object AddToNpc : Action(
|
||||||
icon = Res.drawable.ic_face_24dp,
|
icon = Res.drawable.ic_face_24dp,
|
||||||
|
label = Res.string.game_master__character_action__add_to_npc,
|
||||||
)
|
)
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
data object RemoveFromNpc : Action(
|
data object RemoveFromNpc : Action(
|
||||||
icon = Res.drawable.ic_face_retouching_off_24dp,
|
icon = Res.drawable.ic_face_retouching_off_24dp,
|
||||||
|
label = Res.string.game_master__character_action__remove_from_npc,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -88,12 +97,14 @@ object GMCharacterPreviewDefault {
|
||||||
val padding = PaddingValues(horizontal = 16.dp)
|
val padding = PaddingValues(horizontal = 16.dp)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun GMCharacter(
|
fun GMCharacter(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
padding: PaddingValues = GMCharacterPreviewDefault.padding,
|
padding: PaddingValues = GMCharacterPreviewDefault.padding,
|
||||||
character: GMCharacterItemUio,
|
character: GMCharacterItemUio,
|
||||||
onEdit: () -> Unit,
|
onClick: () -> Unit,
|
||||||
|
onSecondary: () -> Unit,
|
||||||
onAction: (Action) -> Unit,
|
onAction: (Action) -> Unit,
|
||||||
onTag: (GMTagItemUio.TagId) -> Unit,
|
onTag: (GMTagItemUio.TagId) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
|
@ -103,7 +114,11 @@ fun GMCharacter(
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.clip(shape = MaterialTheme.lwa.shapes.gameMaster)
|
.clip(shape = MaterialTheme.lwa.shapes.gameMaster)
|
||||||
.clickable(onClick = onEdit)
|
.onClick(
|
||||||
|
matcher = PointerMatcher.mouse(PointerButton.Secondary),
|
||||||
|
onClick = onSecondary,
|
||||||
|
)
|
||||||
|
.clickable(onClick = onClick)
|
||||||
.background(color = MaterialTheme.lwa.colorScheme.elevated.base1dp)
|
.background(color = MaterialTheme.lwa.colorScheme.elevated.base1dp)
|
||||||
.then(other = modifier),
|
.then(other = modifier),
|
||||||
) {
|
) {
|
||||||
|
|
@ -167,58 +182,37 @@ private fun OverflowActionMenu(
|
||||||
tint = MaterialTheme.colors.primary,
|
tint = MaterialTheme.colors.primary,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
)
|
)
|
||||||
}
|
DropdownMenu(
|
||||||
DropdownMenu(
|
expanded = overflowMenu.value,
|
||||||
offset = remember { DpOffset(x = -(48.dp + 8.dp), y = -(48.dp)) },
|
onDismissRequest = {
|
||||||
expanded = overflowMenu.value,
|
overflowMenu.value = false
|
||||||
onDismissRequest = {
|
},
|
||||||
overflowMenu.value = false
|
content = {
|
||||||
},
|
character.actions.forEach { action ->
|
||||||
content = {
|
DropdownMenuItem(
|
||||||
character.actions.forEach { action ->
|
onClick = {
|
||||||
DropdownMenuItem(
|
overflowMenu.value = false
|
||||||
onClick = {
|
onAction(action)
|
||||||
overflowMenu.value = false
|
},
|
||||||
onAction(action)
|
|
||||||
},
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
|
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
|
||||||
) {
|
) {
|
||||||
Icon(
|
Row(
|
||||||
painter = painterResource(action.icon),
|
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
|
||||||
tint = MaterialTheme.lwa.colorScheme.base.primary,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
contentDescription = null,
|
) {
|
||||||
)
|
Icon(
|
||||||
Text(
|
painter = painterResource(action.icon),
|
||||||
style = MaterialTheme.lwa.typography.base.body1,
|
tint = MaterialTheme.lwa.colorScheme.base.primary,
|
||||||
color = MaterialTheme.lwa.colorScheme.base.primary,
|
contentDescription = null,
|
||||||
text = when (action) {
|
)
|
||||||
Action.DisplayPortrait -> stringResource(
|
Text(
|
||||||
Res.string.game_master__character_action__display_portrait,
|
style = MaterialTheme.lwa.typography.base.body1,
|
||||||
)
|
color = MaterialTheme.lwa.colorScheme.base.primary,
|
||||||
|
text = stringResource(action.label),
|
||||||
Action.AddToGroup -> stringResource(
|
)
|
||||||
Res.string.game_master__character_action__add_to_group,
|
}
|
||||||
)
|
|
||||||
|
|
||||||
Action.AddToNpc -> stringResource(
|
|
||||||
Res.string.game_master__character_action__add_to_npc,
|
|
||||||
)
|
|
||||||
|
|
||||||
Action.RemoveFromGroup -> stringResource(
|
|
||||||
Res.string.game_master__character_action__remove_from_group,
|
|
||||||
)
|
|
||||||
|
|
||||||
Action.RemoveFromNpc -> stringResource(
|
|
||||||
Res.string.game_master__character_action__remove_from_npc,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
},
|
)
|
||||||
)
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue