diff --git a/composeApp/src/commonMain/composeResources/drawable/ic_fan_focus_24dp.xml b/composeApp/src/commonMain/composeResources/drawable/ic_fan_focus_24dp.xml
new file mode 100644
index 0000000..7ae04e6
--- /dev/null
+++ b/composeApp/src/commonMain/composeResources/drawable/ic_fan_focus_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/composeApp/src/commonMain/composeResources/drawable/ic_ifl_24dp.xml b/composeApp/src/commonMain/composeResources/drawable/ic_ifl_24dp.xml
new file mode 100644
index 0000000..d91598a
--- /dev/null
+++ b/composeApp/src/commonMain/composeResources/drawable/ic_ifl_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/composeApp/src/commonMain/composeResources/drawable/ic_timer_24dp.xml b/composeApp/src/commonMain/composeResources/drawable/ic_timer_24dp.xml
new file mode 100644
index 0000000..793edb2
--- /dev/null
+++ b/composeApp/src/commonMain/composeResources/drawable/ic_timer_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/composeApp/src/commonMain/composeResources/drawable/ic_visibility_24dp.xml b/composeApp/src/commonMain/composeResources/drawable/ic_visibility_24dp.xml
new file mode 100644
index 0000000..c22b6d7
--- /dev/null
+++ b/composeApp/src/commonMain/composeResources/drawable/ic_visibility_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/composeApp/src/commonMain/composeResources/drawable/ic_visibility_off_24dp.xml b/composeApp/src/commonMain/composeResources/drawable/ic_visibility_off_24dp.xml
new file mode 100644
index 0000000..b758ece
--- /dev/null
+++ b/composeApp/src/commonMain/composeResources/drawable/ic_visibility_off_24dp.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml
index 1c3b949..352544a 100644
--- a/composeApp/src/commonMain/composeResources/values/strings.xml
+++ b/composeApp/src/commonMain/composeResources/values/strings.xml
@@ -158,8 +158,24 @@
lance
Difficulté
- %1$s passe à %2$d d\'état diminuée
+ %1$s passe à %2$d d'état diminuée
%1$s passe à %2$d %3$s
Hp
Pp
+
+ Paramètres de l'application
+ Paramètres par défault
+ Portrait joueur
+ Dés dynamiques
+ Affiche un dé à côté du portrait d'un personnage lorsqu'un jet est fait par ce dernier.
+ Chatlog options
+ Afficher automatiquement le chat
+ Affiche automatiquement le chat lors de la réception d'un message
+ Cacher automatiquement le chat
+ Cache automatiquement le chat au bout d'un certain temps
+ Délai pour cacher le chat
+ Délai après lequel le chat disparaît
+ Défilement automatique
+ Défilement automatique du chat vers le dernier message reçu lors de la réception de ce dernier.
+
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/settings/SettingsFactory.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/settings/SettingsFactory.kt
index b5a5916..9c8c92b 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/settings/SettingsFactory.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/settings/SettingsFactory.kt
@@ -18,6 +18,7 @@ class SettingsFactory(
playerName = settings.playerName,
dynamicDice = settings.dynamicDice,
autoHideChat = settings.autoHideChat,
+ autoHideDelay = settings.autoHideDelay,
autoShowChat = settings.autoShowChat,
autoScrollChat = settings.autoScrollChat,
)
@@ -41,6 +42,7 @@ class SettingsFactory(
playerName = json.playerName ?: default.playerName,
dynamicDice = json.dynamicDice ?: default.dynamicDice,
autoHideChat = json.autoHideChat ?: default.autoHideChat,
+ autoHideDelay = json.autoHideDelay ?: default.autoHideDelay,
autoShowChat = json.autoShowChat ?: default.autoShowChat,
autoScrollChat = json.autoScrollChat ?: default.autoScrollChat,
)
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/settings/model/Settings.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/settings/model/Settings.kt
index 7af6816..2693887 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/settings/model/Settings.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/settings/model/Settings.kt
@@ -6,6 +6,7 @@ data class Settings(
val playerName: String,
val dynamicDice: Boolean,
val autoHideChat: Boolean,
+ val autoHideDelay: Int,
val autoShowChat: Boolean,
val autoScrollChat: Boolean,
) {
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/settings/model/SettingsJsonV1.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/settings/model/SettingsJsonV1.kt
index bbc4f26..b83937e 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/settings/model/SettingsJsonV1.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/repository/settings/model/SettingsJsonV1.kt
@@ -9,6 +9,7 @@ data class SettingsJsonV1(
val playerName: String?,
val dynamicDice: Boolean?,
val autoHideChat: Boolean?,
+ val autoHideDelay: Int?,
val autoShowChat: Boolean?,
val autoScrollChat: Boolean?,
) : SettingsJson
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/chat/CampaignChatViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/chat/CampaignChatViewModel.kt
index 8c8e72e..43267e2 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/chat/CampaignChatViewModel.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/chat/CampaignChatViewModel.kt
@@ -42,10 +42,18 @@ class CampaignChatViewModel(
)
suspend fun displayChat() {
- chatAnimatedVisibility.animateTo(1f)
+ chatAnimatedVisibility.animateTo(
+ targetValue = 1f,
+ )
}
suspend fun hideChat() {
- chatAnimatedVisibility.animateTo(0f, animationSpec = tween(2000, delayMillis = 8000))
+ chatAnimatedVisibility.animateTo(
+ targetValue = 0f,
+ animationSpec = tween(
+ durationMillis = 2000,
+ delayMillis = settings.value.autoHideDelay * 1000,
+ )
+ )
}
}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/PlayerRibbonViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/PlayerRibbonViewModel.kt
index 964c95d..77705cf 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/PlayerRibbonViewModel.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/campaign/player/ribbon/PlayerRibbonViewModel.kt
@@ -12,6 +12,7 @@ import com.pixelized.desktop.lwa.repository.alteration.AlterationRepository
import com.pixelized.desktop.lwa.repository.campaign.CampaignRepository
import com.pixelized.desktop.lwa.repository.characterSheet.CharacterSheetRepository
import com.pixelized.desktop.lwa.repository.roll_history.RollHistoryRepository
+import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
@@ -24,6 +25,7 @@ import java.text.Collator
class PlayerRibbonViewModel(
private val rollHistoryRepository: RollHistoryRepository,
+ private val settingsRepository: SettingsRepository,
characterRepository: CharacterSheetRepository,
alterationRepository: AlterationRepository,
private val ribbonFactory: PlayerRibbonFactory,
@@ -68,12 +70,14 @@ class PlayerRibbonViewModel(
val state = rolls.getOrPut(characterSheetId) { mutableStateOf(null) }
LaunchedEffect(characterSheetId) {
rollHistoryRepository.rolls.collect { roll ->
- if (roll.characterId == characterSheetId) {
- state.value = PlayerPortraitRollUio(
- characterId = characterSheetId,
- value = roll.rollValue,
- label = roll.resultLabel?.split(" ")?.joinToString(separator = "\n") { it }
- )
+ if (settingsRepository.settings().dynamicDice) {
+ if (roll.characterId == characterSheetId) {
+ state.value = PlayerPortraitRollUio(
+ characterId = characterSheetId,
+ value = roll.rollValue,
+ label = roll.resultLabel?.split(" ")?.joinToString(separator = "\n") { it }
+ )
+ }
}
}
}
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/SettingsScreen.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/SettingsScreen.kt
index 0391b5b..a41d28a 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/SettingsScreen.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/SettingsScreen.kt
@@ -3,6 +3,7 @@ package com.pixelized.desktop.lwa.ui.screen.settings
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
@@ -12,21 +13,38 @@ import androidx.compose.material.IconButton
import androidx.compose.material.Scaffold
import androidx.compose.material.Surface
import androidx.compose.material.Text
+import androidx.compose.material.TextButton
import androidx.compose.material.TopAppBar
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.runtime.Composable
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 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.destination.SettingsDestination
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingItemUio
+import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingNumberItem
+import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingNumberItemUio
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingSection
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingSectionUio
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingToggleItem
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingToggleItemUio
+import lwacharactersheet.composeapp.generated.resources.Res
+import lwacharactersheet.composeapp.generated.resources.settings__reset_action
+import lwacharactersheet.composeapp.generated.resources.settings__title
+import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel
+object SettingsScreenDefault {
+ val margin: PaddingValues = PaddingValues(horizontal = 16.dp)
+ val padding: PaddingValues = PaddingValues(start = 16.dp, top = 8.dp, end = 8.dp, bottom = 8.dp)
+}
@Composable
fun SettingsScreen(
@@ -34,13 +52,25 @@ fun SettingsScreen(
) {
val screen = LocalScreenController.current
+ KeyHandler {
+ when {
+ it.type == KeyEventType.KeyUp && it.key == Key.Escape -> {
+ screen.popBackStack(route = SettingsDestination.baseRoute(), inclusive = true)
+ true
+ }
+
+ else -> false
+ }
+ }
+
Surface {
SettingsContent(
modifier = Modifier.fillMaxSize(),
items = viewModel.items,
onBack = {
- screen.popBackStack()
+ screen.popBackStack(route = SettingsDestination.baseRoute(), inclusive = true)
},
+ onReset = viewModel::onReset
)
}
}
@@ -52,13 +82,14 @@ private fun SettingsContent(
spacing: Dp = 8.dp,
items: List,
onBack: () -> Unit,
+ onReset: () -> Unit,
) {
Scaffold(
modifier = modifier,
topBar = {
TopAppBar(
title = {
- Text(text = "Paramètres de l\'application")
+ Text(text = stringResource(Res.string.settings__title))
},
navigationIcon = {
IconButton(
@@ -69,7 +100,14 @@ private fun SettingsContent(
contentDescription = null,
)
}
- }
+ },
+ actions = {
+ TextButton(
+ onClick = onReset,
+ ) {
+ Text(text = stringResource(Res.string.settings__reset_action))
+ }
+ },
)
},
content = { paddingValues ->
@@ -81,17 +119,12 @@ private fun SettingsContent(
) {
items.forEach {
when (it) {
- is SettingSectionUio -> {
- SettingSection(item = it)
- }
-
- is SettingToggleItemUio -> {
- SettingToggleItem(item = it)
- }
+ is SettingSectionUio -> SettingSection(item = it)
+ is SettingToggleItemUio -> SettingToggleItem(item = it)
+ is SettingNumberItemUio -> SettingNumberItem(item = it)
}
}
}
}
)
-}
-
+}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/SettingsViewModel.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/SettingsViewModel.kt
index 2f728b3..56b3926 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/SettingsViewModel.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/SettingsViewModel.kt
@@ -5,51 +5,90 @@ import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.pixelized.desktop.lwa.repository.settings.SettingsRepository
+import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingNumberItemUio
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingSectionUio
import com.pixelized.desktop.lwa.ui.screen.settings.composable.SettingToggleItemUio
+import com.pixelized.desktop.lwa.usecase.SettingsUseCase
import kotlinx.coroutines.launch
+import lwacharactersheet.composeapp.generated.resources.Res
+import lwacharactersheet.composeapp.generated.resources.ic_fan_focus_24dp
+import lwacharactersheet.composeapp.generated.resources.ic_ifl_24dp
+import lwacharactersheet.composeapp.generated.resources.ic_timer_24dp
+import lwacharactersheet.composeapp.generated.resources.ic_visibility_24dp
+import lwacharactersheet.composeapp.generated.resources.ic_visibility_off_24dp
+import lwacharactersheet.composeapp.generated.resources.settings__chat_log__auto_hide_delay_description
+import lwacharactersheet.composeapp.generated.resources.settings__chat_log__auto_hide_delay_title
+import lwacharactersheet.composeapp.generated.resources.settings__chat_log__auto_hide_description
+import lwacharactersheet.composeapp.generated.resources.settings__chat_log__auto_hide_title
+import lwacharactersheet.composeapp.generated.resources.settings__chat_log__auto_scroll_description
+import lwacharactersheet.composeapp.generated.resources.settings__chat_log__auto_scroll_title
+import lwacharactersheet.composeapp.generated.resources.settings__chat_log__auto_show_description
+import lwacharactersheet.composeapp.generated.resources.settings__chat_log__auto_show_title
+import lwacharactersheet.composeapp.generated.resources.settings__chat_log__section
+import lwacharactersheet.composeapp.generated.resources.settings__player_portrait__dyn_dice_description
+import lwacharactersheet.composeapp.generated.resources.settings__player_portrait__dyn_dice_tile
+import lwacharactersheet.composeapp.generated.resources.settings__player_portrait__section
+
class SettingsViewModel(
private val settingsRepository: SettingsRepository,
+ private val settingsUseCase: SettingsUseCase,
) : ViewModel() {
private val settings = settingsRepository.settingsFlow()
- private val states = hashMapOf>()
+ private val booleanStates = hashMapOf>()
+ private val intStates = hashMapOf>()
val items = listOf(
SettingSectionUio(
- title = "Portrait joueurs."
+ title = Res.string.settings__player_portrait__section,
),
SettingToggleItemUio(
- title = "Dés dynamiques",
- description = "Affiche un dés à côté du portrait d'un personnage lorsqu\'un jet est fait par ce dernier.",
- checked = states.dynamicDice,
+ icon = Res.drawable.ic_ifl_24dp,
+ title = Res.string.settings__player_portrait__dyn_dice_tile,
+ description = Res.string.settings__player_portrait__dyn_dice_description,
+ checked = booleanStates.dynamicDice,
onToggle = {
settingsRepository.update(settings = settings.value.copy(dynamicDice = it))
},
),
SettingSectionUio(
- title = "Chatlog options."
+ title = Res.string.settings__chat_log__section,
),
SettingToggleItemUio(
- title = "Afficher automatiquement",
- description = "Affiche automatiquement le chat lors de la réception d'un message.",
- checked = states.autoShowChat,
+ icon = Res.drawable.ic_visibility_24dp,
+ title = Res.string.settings__chat_log__auto_show_title,
+ description = Res.string.settings__chat_log__auto_show_description,
+ checked = booleanStates.autoShowChat,
onToggle = {
settingsRepository.update(settings = settings.value.copy(autoShowChat = it))
},
),
SettingToggleItemUio(
- title = "Cacher automatiquement",
- description = "Cache automatiquement le chat au bout d'un certain temps.",
- checked = states.autoHideChat,
+ icon = Res.drawable.ic_visibility_off_24dp,
+ title = Res.string.settings__chat_log__auto_hide_title,
+ description = Res.string.settings__chat_log__auto_hide_description,
+ checked = booleanStates.autoHideChat,
onToggle = {
settingsRepository.update(settings = settings.value.copy(autoHideChat = it))
},
),
+ SettingNumberItemUio(
+ icon = Res.drawable.ic_timer_24dp,
+ title = Res.string.settings__chat_log__auto_hide_delay_title,
+ description = Res.string.settings__chat_log__auto_hide_delay_description,
+ enable = booleanStates.autoHideChat,
+ value = intStates.autoHideDelay,
+ onValueChange = {
+ if (it in 0..999) {
+ settingsRepository.update(settings = settings.value.copy(autoHideDelay = it))
+ }
+ }
+ ),
SettingToggleItemUio(
- title = "Défilement automatique",
- description = "Défilement automatique de chat vers le dernier message reçu lors de la réception de ce dernier.",
- checked = states.autoScrollChat,
+ icon = Res.drawable.ic_fan_focus_24dp,
+ title = Res.string.settings__chat_log__auto_scroll_title,
+ description = Res.string.settings__chat_log__auto_scroll_description,
+ checked = booleanStates.autoScrollChat,
onToggle = {
settingsRepository.update(settings = settings.value.copy(autoScrollChat = it))
},
@@ -59,14 +98,19 @@ class SettingsViewModel(
init {
viewModelScope.launch {
settingsRepository.settingsFlow().collect { settings ->
- states.dynamicDice.value = settings.dynamicDice
- states.autoShowChat.value = settings.autoShowChat
- states.autoHideChat.value = settings.autoHideChat
- states.autoScrollChat.value = settings.autoScrollChat
+ booleanStates.dynamicDice.value = settings.dynamicDice
+ booleanStates.autoShowChat.value = settings.autoShowChat
+ booleanStates.autoHideChat.value = settings.autoHideChat
+ intStates.autoHideDelay.value = settings.autoHideDelay
+ booleanStates.autoScrollChat.value = settings.autoScrollChat
}
}
}
+ fun onReset() {
+ settingsRepository.update(settings = settingsUseCase.defaultSettings())
+ }
+
private val HashMap>.dynamicDice
get() = getOrPut("DYNAMIC_DICE") { mutableStateOf(settings.value.dynamicDice) }
@@ -76,6 +120,9 @@ class SettingsViewModel(
private val HashMap>.autoHideChat
get() = getOrPut("AUTO_HIDE_CHAT") { mutableStateOf(settings.value.autoHideChat) }
+ private val HashMap>.autoHideDelay
+ get() = getOrPut("AUTO_HIDE_DELAY") { mutableStateOf(settings.value.autoHideDelay) }
+
private val HashMap>.autoScrollChat
get() = getOrPut("AUTO_SCROLL_CHAT") { mutableStateOf(settings.value.autoScrollChat) }
}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/composable/SettingNumberItem.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/composable/SettingNumberItem.kt
new file mode 100644
index 0000000..dbbd591
--- /dev/null
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/composable/SettingNumberItem.kt
@@ -0,0 +1,138 @@
+package com.pixelized.desktop.lwa.ui.screen.settings.composable
+
+import androidx.compose.foundation.background
+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.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.foundation.text.BasicTextField
+import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.material.Icon
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Surface
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Stable
+import androidx.compose.runtime.State
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.focus.onFocusChanged
+import androidx.compose.ui.graphics.SolidColor
+import androidx.compose.ui.text.font.FontStyle
+import androidx.compose.ui.text.input.ImeAction
+import androidx.compose.ui.unit.DpSize
+import androidx.compose.ui.unit.dp
+import com.pixelized.desktop.lwa.ui.screen.settings.SettingsScreenDefault
+import com.pixelized.desktop.lwa.ui.theme.lwa
+import org.jetbrains.compose.resources.DrawableResource
+import org.jetbrains.compose.resources.StringResource
+import org.jetbrains.compose.resources.painterResource
+import org.jetbrains.compose.resources.stringResource
+
+@Stable
+data class SettingNumberItemUio(
+ val icon: DrawableResource,
+ val title: StringResource,
+ val description: StringResource,
+ val enable: State,
+ val value: State,
+ val onValueChange: (Int) -> Unit,
+) : SettingItemUio
+
+@Composable
+fun SettingNumberItem(
+ modifier: Modifier = Modifier,
+ margin: PaddingValues = SettingsScreenDefault.margin,
+ padding: PaddingValues = SettingsScreenDefault.padding,
+ spacing: DpSize = DpSize(width = 16.dp, height = 8.dp),
+ item: SettingNumberItemUio,
+) {
+ val colorScheme = MaterialTheme.lwa.colorScheme
+
+ Surface(
+ modifier = modifier.padding(paddingValues = margin),
+ shape = MaterialTheme.lwa.shapes.settings,
+ elevation = 1.dp,
+ ) {
+ Row(
+ modifier = Modifier.padding(paddingValues = padding),
+ horizontalArrangement = Arrangement.spacedBy(space = spacing.width),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Icon(
+ modifier = Modifier.size(size = 24.dp),
+ painter = painterResource(item.icon),
+ contentDescription = null,
+ )
+
+ Column(
+ modifier = Modifier.weight(weight = 1f),
+ verticalArrangement = Arrangement.spacedBy(space = spacing.height),
+ ) {
+ Text(
+ style = MaterialTheme.lwa.typography.settings.title,
+ maxLines = 1,
+ text = stringResource(resource = item.title),
+ )
+ Text(
+ style = MaterialTheme.lwa.typography.settings.description,
+ fontStyle = FontStyle.Italic,
+ text = stringResource(resource = item.description),
+ )
+ }
+
+ Column(
+ modifier = Modifier.padding(end = 8.dp),
+ verticalArrangement = Arrangement.spacedBy(space = 4.dp),
+ ) {
+ val focused = remember {
+ mutableStateOf(false)
+ }
+ val textColor = remember(item) {
+ derivedStateOf {
+ when (item.enable.value) {
+ true -> colorScheme.base.primary
+ else -> colorScheme.base.onSurface.copy(alpha = 0.3f)
+ }
+ }
+ }
+ val borderColor = remember(item, focused) {
+ derivedStateOf {
+ when (focused.value) {
+ true -> colorScheme.base.primary
+ else -> colorScheme.base.onSurface.copy(alpha = 0.3f)
+ }
+ }
+ }
+ BasicTextField(
+ modifier = Modifier
+ .onFocusChanged { focused.value = it.isFocused }
+ .width(width = 44.dp)
+ .padding(horizontal = 2.dp),
+ textStyle = MaterialTheme.lwa.typography.settings.input.copy(
+ color = textColor.value,
+ ),
+ cursorBrush = SolidColor(MaterialTheme.colors.primary),
+ keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
+ singleLine = true,
+ enabled = item.enable.value,
+ value = "${item.value.value}",
+ onValueChange = { item.onValueChange(it.toIntOrNull() ?: 0) },
+ )
+ Box(
+ modifier = Modifier
+ .background(color = borderColor.value)
+ .size(width = 48.dp, height = 2.dp),
+ )
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/composable/SettingSection.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/composable/SettingSection.kt
index 6086799..c02674b 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/composable/SettingSection.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/composable/SettingSection.kt
@@ -8,23 +8,26 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
+import com.pixelized.desktop.lwa.ui.screen.settings.SettingsScreenDefault
import com.pixelized.desktop.lwa.ui.theme.lwa
+import org.jetbrains.compose.resources.StringResource
+import org.jetbrains.compose.resources.stringResource
@Stable
data class SettingSectionUio(
- val title: String,
+ val title: StringResource,
) : SettingItemUio
@Composable
fun SettingSection(
modifier: Modifier = Modifier,
- padding: PaddingValues = PaddingValues(start = 16.dp, top = 32.dp, end = 16.dp),
+ padding: PaddingValues = PaddingValues(start = 16.dp, top = 32.dp, end = 16.dp, bottom = 16.dp),
item: SettingSectionUio,
) {
Text(
modifier = modifier.padding(paddingValues = padding),
- style = MaterialTheme.lwa.typography.base.h6,
+ style = MaterialTheme.lwa.typography.settings.section,
maxLines = 1,
- text = item.title,
+ text = stringResource(resource = item.title),
)
}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/composable/SettingToggleItem.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/composable/SettingToggleItem.kt
index 514415e..a760175 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/composable/SettingToggleItem.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/screen/settings/composable/SettingToggleItem.kt
@@ -5,23 +5,34 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Surface
import androidx.compose.material.Switch
import androidx.compose.material.SwitchDefaults
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Stable
import androidx.compose.runtime.State
+import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.text.font.FontStyle
-import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
+import com.pixelized.desktop.lwa.ui.screen.settings.SettingsScreenDefault
import com.pixelized.desktop.lwa.ui.theme.lwa
+import org.jetbrains.compose.resources.DrawableResource
+import org.jetbrains.compose.resources.StringResource
+import org.jetbrains.compose.resources.painterResource
+import org.jetbrains.compose.resources.stringResource
@Stable
data class SettingToggleItemUio(
- val title: String,
- val description: String,
+ val icon: DrawableResource,
+ val title: StringResource,
+ val description: StringResource,
val checked: State,
val onToggle: (Boolean) -> Unit,
) : SettingItemUio
@@ -29,36 +40,49 @@ data class SettingToggleItemUio(
@Composable
fun SettingToggleItem(
modifier: Modifier = Modifier,
- padding: PaddingValues = PaddingValues(start = 16.dp, top = 8.dp, end = 16.dp),
- spacing: Dp = 8.dp,
+ margin: PaddingValues = SettingsScreenDefault.margin,
+ padding: PaddingValues = SettingsScreenDefault.padding,
+ spacing: DpSize = DpSize(width = 16.dp, height = 8.dp),
item: SettingToggleItemUio,
) {
- Row(
- modifier = modifier.padding(paddingValues = padding),
- horizontalArrangement = Arrangement.spacedBy(space = spacing),
+ Surface(
+ modifier = modifier.padding(paddingValues = margin),
+ shape = MaterialTheme.lwa.shapes.settings,
+ elevation = 1.dp,
) {
- Column(
- modifier = Modifier.weight(weight = 1f),
- verticalArrangement = Arrangement.spacedBy(space = spacing),
+ Row(
+ modifier = Modifier.padding(paddingValues = padding),
+ horizontalArrangement = Arrangement.spacedBy(space = spacing.width),
+ verticalAlignment = Alignment.CenterVertically,
) {
- Text(
- style = MaterialTheme.lwa.typography.base.body1,
- maxLines = 1,
- text = item.title,
+ Icon(
+ modifier = Modifier.size(size = 24.dp),
+ painter = painterResource(item.icon),
+ contentDescription = null,
)
- Text(
- style = MaterialTheme.lwa.typography.base.caption,
- fontStyle = FontStyle.Italic,
- text = item.description,
+ Column(
+ modifier = Modifier.weight(weight = 1f),
+ verticalArrangement = Arrangement.spacedBy(space = spacing.height),
+ ) {
+ Text(
+ style = MaterialTheme.lwa.typography.settings.title,
+ maxLines = 1,
+ text = stringResource(resource = item.title),
+ )
+ Text(
+ style = MaterialTheme.lwa.typography.settings.description,
+ fontStyle = FontStyle.Italic,
+ text = stringResource(resource = item.description),
+ )
+ }
+
+ Switch(
+ colors = SwitchDefaults.colors(
+ checkedThumbColor = MaterialTheme.lwa.colorScheme.base.primary,
+ ),
+ onCheckedChange = item.onToggle,
+ checked = item.checked.value
)
}
-
- Switch(
- colors = SwitchDefaults.colors(
- checkedThumbColor = MaterialTheme.lwa.colorScheme.base.primary,
- ),
- onCheckedChange = item.onToggle,
- checked = item.checked.value
- )
}
}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/theme/LwaTheme.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/theme/LwaTheme.kt
index 73ca61e..97ef035 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/theme/LwaTheme.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/theme/LwaTheme.kt
@@ -8,6 +8,8 @@ import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.remember
import com.pixelized.desktop.lwa.ui.theme.color.LwaColors
import com.pixelized.desktop.lwa.ui.theme.color.darkLwaColorTheme
+import com.pixelized.desktop.lwa.ui.theme.shapes.LwaShapes
+import com.pixelized.desktop.lwa.ui.theme.shapes.lwaShapes
import com.pixelized.desktop.lwa.ui.theme.typography.LwaTypography
import com.pixelized.desktop.lwa.ui.theme.typography.lwaTypography
@@ -24,6 +26,7 @@ val MaterialTheme.lwa: LwaTheme
data class LwaTheme(
val colorScheme: LwaColors,
val typography: LwaTypography,
+ val shapes: LwaShapes,
)
@Composable
@@ -32,11 +35,13 @@ fun LwaTheme(
) {
val lwaColors = darkLwaColorTheme()
val lwaTypography = lwaTypography(colors = lwaColors)
+ val lwaShapes = lwaShapes()
val theme = remember {
LwaTheme(
colorScheme = lwaColors,
typography = lwaTypography,
+ shapes = lwaShapes,
)
}
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/theme/shapes/LwaShapes.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/theme/shapes/LwaShapes.kt
new file mode 100644
index 0000000..a139ba1
--- /dev/null
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/theme/shapes/LwaShapes.kt
@@ -0,0 +1,23 @@
+package com.pixelized.desktop.lwa.ui.theme.shapes
+
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.Stable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.unit.dp
+
+@Stable
+data class LwaShapes(
+ val settings: Shape,
+)
+
+@Stable
+@Composable
+fun lwaShapes(
+ settings: Shape = RoundedCornerShape(8.dp),
+): LwaShapes = remember {
+ LwaShapes(
+ settings = settings,
+ )
+}
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/theme/typography/LwaTypography.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/theme/typography/LwaTypography.kt
index affabe4..a550f0f 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/theme/typography/LwaTypography.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/ui/theme/typography/LwaTypography.kt
@@ -6,9 +6,12 @@ import androidx.compose.runtime.Stable
import androidx.compose.runtime.remember
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
+import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.sp
import com.pixelized.desktop.lwa.ui.theme.color.LwaColors
+import com.pixelized.desktop.lwa.ui.theme.typography.LwaTypography.Settings
import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.consola_mono_bold
import lwacharactersheet.composeapp.generated.resources.consola_mono_book
@@ -18,12 +21,21 @@ import org.jetbrains.compose.resources.Font
data class LwaTypography(
val base: Typography,
val chat: Chat,
+ val settings: Settings,
) {
@Stable
data class Chat(
val timestamp: TextStyle,
val text: TextStyle,
)
+
+ @Stable
+ data class Settings(
+ val section: TextStyle,
+ val title: TextStyle,
+ val input: TextStyle,
+ val description: TextStyle,
+ )
}
@Composable
@@ -62,6 +74,22 @@ fun lwaTypography(
letterSpacing = 0.4.sp,
color = colors.chat.text,
),
+ ),
+ settings = Settings(
+ section = base.h6,
+ title = base.body1.copy(
+ fontWeight = FontWeight.SemiBold,
+ ),
+ input = base.body1.copy(
+ fontWeight = FontWeight.SemiBold,
+ fontSize = 18.sp,
+ lineHeight = 26.sp,
+ textAlign = TextAlign.End,
+ ),
+ description = base.caption.copy(
+ fontStyle = FontStyle.Italic,
+ color = colors.base.onSurface.copy(alpha = 0.7f),
+ ),
)
)
}
diff --git a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/usecase/SettingsUseCase.kt b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/usecase/SettingsUseCase.kt
index df53702..7d46183 100644
--- a/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/usecase/SettingsUseCase.kt
+++ b/composeApp/src/commonMain/kotlin/com/pixelized/desktop/lwa/usecase/SettingsUseCase.kt
@@ -10,6 +10,7 @@ class SettingsUseCase {
playerName = "",
dynamicDice = true,
autoHideChat = true,
+ autoHideDelay = 8,
autoShowChat = true,
autoScrollChat = true,
)