Add an item screen.
|
|
@ -7,6 +7,8 @@ import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.platform.LocalInspectionMode
|
||||||
import androidx.compose.ui.platform.LocalView
|
import androidx.compose.ui.platform.LocalView
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
|
|
@ -42,8 +44,9 @@ class ThemeViewModel @Inject constructor(
|
||||||
@Composable
|
@Composable
|
||||||
@Stable
|
@Stable
|
||||||
fun isInDarkTheme(): Boolean {
|
fun isInDarkTheme(): Boolean {
|
||||||
|
val preview = LocalContext.current !is MainActivity
|
||||||
val view = LocalView.current
|
val view = LocalView.current
|
||||||
return if (view.isInEditMode) {
|
return if (view.isInEditMode || preview) {
|
||||||
isSystemInDarkTheme()
|
isSystemInDarkTheme()
|
||||||
} else {
|
} else {
|
||||||
val themeViewModel: ThemeViewModel = hiltViewModel()
|
val themeViewModel: ThemeViewModel = hiltViewModel()
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ class ItemLexiconParser @Inject constructor(
|
||||||
name = name,
|
name = name,
|
||||||
isContainer = container,
|
isContainer = container,
|
||||||
effect = throwParser.parse(value = row.parse(column = EFFECT)),
|
effect = throwParser.parse(value = row.parse(column = EFFECT)),
|
||||||
icon = BaldurGageImageCache.cache(url = row.parseUri(column = ICON)),
|
icon = BaldurGageImageCache.cache(uri = row.parseUri(column = ICON)),
|
||||||
)
|
)
|
||||||
inventories[item.id] = item
|
inventories[item.id] = item
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
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.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalFocusManager
|
import androidx.compose.ui.platform.LocalFocusManager
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
|
|
@ -54,6 +56,7 @@ data class TextFieldUio(
|
||||||
@Composable
|
@Composable
|
||||||
fun TextFieldAppBar(
|
fun TextFieldAppBar(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
|
focusRequester: FocusRequester = remember { FocusRequester() },
|
||||||
field: TextFieldUio,
|
field: TextFieldUio,
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
onClear: () -> Unit,
|
onClear: () -> Unit,
|
||||||
|
|
@ -62,7 +65,9 @@ fun TextFieldAppBar(
|
||||||
val focus = LocalFocusManager.current
|
val focus = LocalFocusManager.current
|
||||||
|
|
||||||
androidx.compose.material3.TextField(
|
androidx.compose.material3.TextField(
|
||||||
modifier = modifier.height(height = 64.dp),
|
modifier = modifier
|
||||||
|
.height(height = 64.dp)
|
||||||
|
.focusRequester(focusRequester = focusRequester),
|
||||||
shape = MaterialTheme.lexicon.shapes.textField,
|
shape = MaterialTheme.lexicon.shapes.textField,
|
||||||
colors = TextFieldDefaults.colors(
|
colors = TextFieldDefaults.colors(
|
||||||
focusedContainerColor = Color.Transparent,
|
focusedContainerColor = Color.Transparent,
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,6 @@ import kotlinx.coroutines.launch
|
||||||
fun InventoryPage(
|
fun InventoryPage(
|
||||||
viewModel: InventoryViewModel,
|
viewModel: InventoryViewModel,
|
||||||
) {
|
) {
|
||||||
val view = LocalView.current
|
|
||||||
val snack = LocalSnack.current
|
val snack = LocalSnack.current
|
||||||
val snackJob = remember { mutableStateOf<Job?>(null) }
|
val snackJob = remember { mutableStateOf<Job?>(null) }
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,111 @@
|
||||||
|
package com.pixelized.rplexicon.ui.screens.character.pages.inventory.item
|
||||||
|
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.IntrinsicSize
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.minimumInteractiveComponentSize
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.Stable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||||
|
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.pixelized.rplexicon.ui.composable.images.AsyncImage
|
||||||
|
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||||
|
import com.pixelized.rplexicon.utilitary.extentions.string.BaldurGageImageCache.cache
|
||||||
|
|
||||||
|
@Stable
|
||||||
|
data class ItemUio(
|
||||||
|
val id: String,
|
||||||
|
val name: String,
|
||||||
|
val description: String?,
|
||||||
|
val icon: Any?,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Item(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
paddingValues: PaddingValues = PaddingValues(horizontal = 16.dp),
|
||||||
|
item: ItemUio,
|
||||||
|
onClick: (() -> Unit)? = null,
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.clickable(enabled = onClick != null) { onClick?.invoke() }
|
||||||
|
.minimumInteractiveComponentSize()
|
||||||
|
.height(intrinsicSize = IntrinsicSize.Min)
|
||||||
|
.padding(paddingValues)
|
||||||
|
.then(other = modifier),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(space = 8.dp),
|
||||||
|
) {
|
||||||
|
AsyncImage(
|
||||||
|
model = item.icon,
|
||||||
|
)
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(
|
||||||
|
space = 4.dp,
|
||||||
|
alignment = Alignment.CenterVertically
|
||||||
|
),
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
style = MaterialTheme.typography.bodyMedium,
|
||||||
|
text = item.name,
|
||||||
|
)
|
||||||
|
item.description?.let {
|
||||||
|
Text(
|
||||||
|
style = MaterialTheme.typography.labelSmall,
|
||||||
|
text = it,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||||
|
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||||
|
private fun ItemPreview(
|
||||||
|
@PreviewParameter(ItemProvider::class) preview: ItemUio,
|
||||||
|
) {
|
||||||
|
LexiconTheme {
|
||||||
|
Surface {
|
||||||
|
Item(item = preview)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ItemProvider : PreviewParameterProvider<ItemUio> {
|
||||||
|
override val values: Sequence<ItemUio> = sequenceOf(
|
||||||
|
ItemUio(
|
||||||
|
id = "7d27561b-f2f4-4899-a2fc-df3501b1b66b",
|
||||||
|
name = "Bourse",
|
||||||
|
description = "Un petite bourse.",
|
||||||
|
icon = cache(uri = "https://bg3.wiki/w/images/c/c6/Pouch_A_Unfaded.webp"),
|
||||||
|
),
|
||||||
|
ItemUio(
|
||||||
|
id = "43424bbc-0117-44f8-b512-6d469a05e6c2",
|
||||||
|
name = "Sac à dos",
|
||||||
|
description = "Sac à dos pour aventurier.",
|
||||||
|
icon = cache(uri = "https://bg3.wiki/w/images/6/6d/Backpack_B_Unfaded.webp"),
|
||||||
|
),
|
||||||
|
ItemUio(
|
||||||
|
id = "2ecf41c2-06b1-4f2d-a6d9-b6adcaf05aba",
|
||||||
|
name = "Sac à dos",
|
||||||
|
description = "Sac à dos pour aventurier.",
|
||||||
|
icon = cache(uri = "https://bg3.wiki/w/images/3/39/Backpack_A_Unfaded.webp"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,129 @@
|
||||||
|
package com.pixelized.rplexicon.ui.screens.character.pages.inventory.item
|
||||||
|
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
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.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Surface
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.Stable
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.pixelized.rplexicon.R
|
||||||
|
import com.pixelized.rplexicon.ui.composable.form.TextFieldAppBar
|
||||||
|
import com.pixelized.rplexicon.ui.composable.form.TextFieldUio
|
||||||
|
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||||
|
import com.pixelized.rplexicon.utilitary.extentions.modifier.lexiconShadow
|
||||||
|
import com.pixelized.rplexicon.utilitary.extentions.string.BaldurGageImageCache.cache
|
||||||
|
|
||||||
|
@Stable
|
||||||
|
data class ItemListUio(
|
||||||
|
val search: TextFieldUio,
|
||||||
|
val items: List<ItemUio>,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ItemListPage() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ItemListContent(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
page: ItemListUio,
|
||||||
|
onBack: () -> Unit,
|
||||||
|
onClear: () -> Unit,
|
||||||
|
onSearchChange: (String) -> Unit,
|
||||||
|
) {
|
||||||
|
Scaffold(
|
||||||
|
modifier = modifier,
|
||||||
|
topBar = {
|
||||||
|
Surface(
|
||||||
|
modifier = Modifier.lexiconShadow(),
|
||||||
|
) {
|
||||||
|
TextFieldAppBar(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(height = 64.dp),
|
||||||
|
field = page.search,
|
||||||
|
onBack = onBack,
|
||||||
|
onClear = onClear,
|
||||||
|
onValueChange = onSearchChange,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
content = { paddings ->
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier.padding(paddingValues = paddings),
|
||||||
|
contentPadding = PaddingValues(vertical = 16.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(space = 8.dp),
|
||||||
|
) {
|
||||||
|
items(
|
||||||
|
items = page.items,
|
||||||
|
key = { it.id },
|
||||||
|
) {
|
||||||
|
Item(item = it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||||
|
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||||
|
private fun ItemLisPreview() {
|
||||||
|
LexiconTheme {
|
||||||
|
Surface {
|
||||||
|
ItemListContent(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
page = remember {
|
||||||
|
ItemListUio(
|
||||||
|
search = TextFieldUio(
|
||||||
|
label = R.string.search_field_title,
|
||||||
|
value = mutableStateOf("")
|
||||||
|
),
|
||||||
|
items = listOf(
|
||||||
|
ItemUio(
|
||||||
|
id = "70d0bcbe-47af-48ba-a9e5-9f9b97bc25a1",
|
||||||
|
name = "Bourse",
|
||||||
|
description = "Une petite bourse en cuir.",
|
||||||
|
icon = cache("https://bg3.wiki/w/images/5/5b/Leather_Pouch_A_Unfaded.webp"),
|
||||||
|
),
|
||||||
|
ItemUio(
|
||||||
|
id = "7d27561b-f2f4-4899-a2fc-df3501b1b66b",
|
||||||
|
name = "Bourse",
|
||||||
|
description = "Une petite bourse.",
|
||||||
|
icon = cache(uri = "https://bg3.wiki/w/images/c/c6/Pouch_A_Unfaded.webp"),
|
||||||
|
),
|
||||||
|
ItemUio(
|
||||||
|
id = "43424bbc-0117-44f8-b512-6d469a05e6c2",
|
||||||
|
name = "Sac à dos",
|
||||||
|
description = "Sac à dos pour aventurier.",
|
||||||
|
icon = cache(uri = "https://bg3.wiki/w/images/6/6d/Backpack_B_Unfaded.webp"),
|
||||||
|
),
|
||||||
|
ItemUio(
|
||||||
|
id = "2ecf41c2-06b1-4f2d-a6d9-b6adcaf05aba",
|
||||||
|
name = "Sac à dos",
|
||||||
|
description = "Sac à dos pour aventurier.",
|
||||||
|
icon = cache(uri = "https://bg3.wiki/w/images/3/39/Backpack_A_Unfaded.webp"),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
onBack = {},
|
||||||
|
onClear = {},
|
||||||
|
onSearchChange = {},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,13 +7,14 @@ import com.pixelized.rplexicon.R
|
||||||
object BaldurGageImageCache {
|
object BaldurGageImageCache {
|
||||||
// https://bg3.wiki/wiki/Category:Controller_UI_Icons
|
// https://bg3.wiki/wiki/Category:Controller_UI_Icons
|
||||||
private val uri = mapOf(
|
private val uri = mapOf(
|
||||||
// Default.
|
|
||||||
null to R.drawable.icbg_generic_darkness_icon,
|
|
||||||
// Category:Generic Controller Icons
|
// Category:Generic Controller Icons
|
||||||
"https://bg3.wiki/w/images/5/56/Generic_Darkness_Icon.webp" to R.drawable.icbg_generic_darkness_icon,
|
"https://bg3.wiki/w/images/5/56/Generic_Darkness_Icon.webp" to R.drawable.icbg_generic_darkness_icon,
|
||||||
// Category:Container Controller Icons
|
// Category:Container Controller Icons
|
||||||
|
"https://bg3.wiki/w/images/5/5b/Leather_Pouch_A_Unfaded.webp" to R.drawable.icbg_leather_pouch_a_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/c/c6/Pouch_A_Unfaded.webp" to R.drawable.icbg_pouch_a_unfaded,
|
||||||
"https://bg3.wiki/w/images/3/39/Backpack_A_Unfaded.webp" to R.drawable.icbg_backpack_a_unfaded,
|
"https://bg3.wiki/w/images/3/39/Backpack_A_Unfaded.webp" to R.drawable.icbg_backpack_a_unfaded,
|
||||||
"https://bg3.wiki/w/images/6/6d/Backpack_B_Unfaded.webp" to R.drawable.icbg_backpack_b_unfaded,
|
"https://bg3.wiki/w/images/6/6d/Backpack_B_Unfaded.webp" to R.drawable.icbg_backpack_b_unfaded,
|
||||||
|
"https://bg3.wiki/w/images/c/c0/Keychain_Unfaded.png" to R.drawable.icbg_keychain_unfaded,
|
||||||
// Category:Potion Controller Icons
|
// Category:Potion Controller Icons
|
||||||
"https://bg3.wiki/w/images/c/ce/POT_Potion_of_Healing_Unfaded.png" to R.drawable.icbg_pot_potion_of_healing_unfaded,
|
"https://bg3.wiki/w/images/c/ce/POT_Potion_of_Healing_Unfaded.png" to R.drawable.icbg_pot_potion_of_healing_unfaded,
|
||||||
"https://bg3.wiki/w/images/7/73/POT_Potion_of_Superior_Healing_Unfaded.png" to R.drawable.icbg_potion_of_superior_healing_unfaded,
|
"https://bg3.wiki/w/images/7/73/POT_Potion_of_Superior_Healing_Unfaded.png" to R.drawable.icbg_potion_of_superior_healing_unfaded,
|
||||||
|
|
@ -286,5 +287,7 @@ object BaldurGageImageCache {
|
||||||
@DrawableRes
|
@DrawableRes
|
||||||
fun spellIcon(name: String): Int? = spells[name]
|
fun spellIcon(name: String): Int? = spells[name]
|
||||||
|
|
||||||
fun cache(url: Uri?): Any = uri[url.toString()] ?: uri[null]!!
|
fun cache(uri: Uri?): Any = cache(uri = uri.toString())
|
||||||
|
|
||||||
|
fun cache(uri: String?): Any = this.uri[uri.toString()] ?: R.drawable.icbg_generic_darkness_icon
|
||||||
}
|
}
|
||||||
|
Before Width: | Height: | Size: 30 KiB |
BIN
app/src/main/res/drawable/icbg_book_generic_c_unfaded.webp
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 37 KiB |
BIN
app/src/main/res/drawable/icbg_hand_crossbow_unfaded.webp
Normal file
|
After Width: | Height: | Size: 9.9 KiB |
|
Before Width: | Height: | Size: 35 KiB |
BIN
app/src/main/res/drawable/icbg_haste_spore_grenade_unfaded.webp
Normal file
|
After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 45 KiB |
BIN
app/src/main/res/drawable/icbg_item_foundry_misc_gear_a.webp
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
app/src/main/res/drawable/icbg_keychain_unfaded.webp
Normal file
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 20 KiB |
BIN
app/src/main/res/drawable/icbg_lantern_of_revealing.webp
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
app/src/main/res/drawable/icbg_leather_pouch_a_unfaded.webp
Normal file
|
After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 42 KiB |
BIN
app/src/main/res/drawable/icbg_light_crossbow_unfaded.webp
Normal file
|
After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 6.1 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 35 KiB |
BIN
app/src/main/res/drawable/icbg_rapier_unfaded.webp
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 37 KiB |
BIN
app/src/main/res/drawable/icbg_shortsword_unfaded.webp
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 31 KiB |
BIN
app/src/main/res/drawable/icbg_worg_fang_unfaded.webp
Normal file
|
After Width: | Height: | Size: 6.3 KiB |