more structure to forms and views
shared ui got an interface to demo the components
This commit is contained in:
@@ -22,12 +22,25 @@ kotlin {
|
||||
implementation(libs.compose.runtime)
|
||||
implementation(libs.compose.foundation)
|
||||
implementation(libs.compose.ui)
|
||||
implementation("org.jetbrains.compose.ui:ui-tooling-preview:1.10.0")
|
||||
implementation(libs.kotlinx.datetime)
|
||||
api("br.com.devsrsouza.compose.icons:feather:1.1.1")
|
||||
|
||||
}
|
||||
|
||||
wasmJsMain.dependencies {
|
||||
implementation(libs.wrappers.browser)
|
||||
}
|
||||
|
||||
jvmMain.dependencies {}
|
||||
jvmMain.dependencies {
|
||||
implementation(compose.desktop.currentOs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compose.desktop {
|
||||
application {
|
||||
mainClass = "dev.geekback.dopewars.DemoMain3Kt"
|
||||
// mainClass = "dev.geekback.dopewars.ComposeTimestampControlDemoKt"
|
||||
}
|
||||
}
|
||||
@@ -3,8 +3,10 @@ package dev.geekback.dopewars.ui
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
@@ -40,3 +42,46 @@ fun BorderedCard(title: String, content: @Composable () -> Unit) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ViewFrame(
|
||||
title: String,
|
||||
onRequestEdit: () -> Unit,
|
||||
content: @Composable () -> Unit) {
|
||||
BorderedCard(title) {
|
||||
Column {
|
||||
content()
|
||||
|
||||
Row {
|
||||
Button(onClick = onRequestEdit) { Text("Edit") }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun FormFrame(
|
||||
title: String,
|
||||
onModelUpdate: () -> Unit,
|
||||
onModelReset: () -> Unit,
|
||||
onCancelEdit: () -> Unit,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
BorderedCard(title) {
|
||||
Column {
|
||||
content()
|
||||
|
||||
Row {
|
||||
Button(onClick = onModelUpdate) {
|
||||
Text("Update")
|
||||
}
|
||||
Button(onClick = onModelReset) {
|
||||
Text("Reset")
|
||||
}
|
||||
Button(onClick = onCancelEdit) {
|
||||
Text("Cancel")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,43 @@
|
||||
package dev.geekback.dopewars.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.geekback.dopewars.shared.Player
|
||||
import dev.geekback.dopewars.ui.api.ApiUi
|
||||
|
||||
interface DopeWarsModelUi<T> {
|
||||
@Composable
|
||||
fun view(model: T);
|
||||
fun view(model: T, onRequestEdit: () -> Unit)
|
||||
|
||||
@Composable
|
||||
fun form(model: T, onModelUpdate: (T) -> Unit)
|
||||
|
||||
@Composable
|
||||
fun field(model: T, onChanged: (T) -> Unit) {
|
||||
var displayModel by remember { mutableStateOf(model) }
|
||||
var isEditing by remember { mutableStateOf(false) }
|
||||
|
||||
Column {
|
||||
Text("IsEditing -> $isEditing")
|
||||
|
||||
if (isEditing) {
|
||||
form(displayModel) {
|
||||
displayModel = it
|
||||
isEditing = false
|
||||
onChanged(it)
|
||||
}
|
||||
} else {
|
||||
view(displayModel) {
|
||||
isEditing = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class DopeWarsUi(
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package dev.geekback.dopewars.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -16,7 +18,10 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import dev.geekback.dopewars.shared.Locations
|
||||
import compose.icons.FeatherIcons
|
||||
import compose.icons.feathericons.LogIn
|
||||
import compose.icons.feathericons.Menu
|
||||
import dev.geekback.dopewars.shared.Location
|
||||
import dev.geekback.dopewars.shared.Player
|
||||
import dev.geekback.dopewars.shared.api.TravelRequest
|
||||
|
||||
@@ -30,19 +35,21 @@ class TravelUi {
|
||||
fun wizard(current: Player, onTicketPunched: (TravelRequest) -> Unit) {
|
||||
var stage by remember { mutableStateOf(0) }
|
||||
var pickedLocation by remember { mutableStateOf(0) }
|
||||
val locations = Locations.all
|
||||
val locations = Location.all()
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
// Window(onCloseRequest = { onTicketPunched(TravelRequest(destination = current.location)) }, title = "Select New Location") {
|
||||
/*
|
||||
|
||||
Card(modifier = Modifier.padding(16.dp).fillMaxSize()) {
|
||||
Column {
|
||||
Text("Wizard")
|
||||
var index = 0;
|
||||
var index = 0
|
||||
when (stage) {
|
||||
0 -> {
|
||||
Text(text = locations[pickedLocation].name)
|
||||
IconButton(onClick = { expanded = !expanded }) {
|
||||
// Icon(MaterialIcons.Filled.Menu, contentDescription = "More options")
|
||||
Row {
|
||||
Text(text = locations[pickedLocation].name)
|
||||
IconButton(onClick = { expanded = !expanded }) {
|
||||
Icon(imageVector = FeatherIcons.Menu, contentDescription = "Login")
|
||||
// Icon(MaterialIcons.Filled.Menu, contentDescription = "More options")
|
||||
}
|
||||
}
|
||||
DropdownMenu(
|
||||
expanded = expanded,
|
||||
@@ -57,7 +64,7 @@ class TravelUi {
|
||||
println("location index to $index")
|
||||
}
|
||||
)
|
||||
index += 1;
|
||||
index += 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +86,5 @@ class TravelUi {
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ data class ApiUi(
|
||||
val playerNameUpdateRequest: PlayerNameUpdateRequestUi,
|
||||
val playerNameUpdateResponse: PlayerNameUpdateResponseUi,
|
||||
val tradeRequest: TradeRequestUi,
|
||||
// TODO: tradeResponse
|
||||
val travelRequest: TravelRequestUi,
|
||||
val travelResponse: TravelResponseUi,
|
||||
) {
|
||||
|
||||
@@ -16,9 +16,11 @@ import dev.geekback.dopewars.ui.LocationUi
|
||||
|
||||
class MarketRequestUi: DopeWarsModelUi<MarketRequest> {
|
||||
@Composable
|
||||
override fun view(model: MarketRequest) {
|
||||
override fun view(model: MarketRequest, onRequestEdit: () -> Unit) {
|
||||
BorderedCard("Market Request for ${model.location.name}") {
|
||||
LocationUi().view(model.location)
|
||||
LocationUi().view(model.location) {
|
||||
println("location edit requested")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,4 +46,9 @@ class MarketRequestUi: DopeWarsModelUi<MarketRequest> {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun <T>form_skeleton(model: T, onModelUpdate: (T) -> Unit, onFieldUpdate: (T) -> Unit) {
|
||||
|
||||
}
|
||||
@@ -5,12 +5,14 @@ import dev.geekback.dopewars.shared.api.MarketResult
|
||||
import dev.geekback.dopewars.ui.BorderedCard
|
||||
import dev.geekback.dopewars.ui.DopeWarsModelUi
|
||||
import dev.geekback.dopewars.ui.MarketUi
|
||||
import dev.geekback.dopewars.ui.ViewFrame
|
||||
|
||||
class MarketResponseUi: DopeWarsModelUi<MarketResult> {
|
||||
@Composable
|
||||
override fun view(model: MarketResult) {
|
||||
BorderedCard("Market Result for ${model.market.location.name}") {
|
||||
MarketUi().view(model.market)
|
||||
override fun view(model: MarketResult, onRequestEdit: () -> Unit) {
|
||||
ViewFrame(title = "Market Result for ${model.market.location.name}",
|
||||
onRequestEdit = onRequestEdit) {
|
||||
println("On Request Edit")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,5 +27,4 @@ class MarketResponseUi: DopeWarsModelUi<MarketResult> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -7,9 +7,9 @@ import dev.geekback.dopewars.ui.DopeWarsModelUi
|
||||
import dev.geekback.dopewars.shared.api.PlayerNameUpdateRequest
|
||||
import dev.geekback.dopewars.ui.BorderedCard
|
||||
|
||||
class PlayerNameUpdateRequestUi(): DopeWarsModelUi<PlayerNameUpdateRequest> {
|
||||
class PlayerNameUpdateRequestUi : DopeWarsModelUi<PlayerNameUpdateRequest> {
|
||||
@Composable
|
||||
override fun view(model: PlayerNameUpdateRequest) {
|
||||
override fun view(model: PlayerNameUpdateRequest, onRequestEdit: () -> Unit) {
|
||||
BorderedCard("Player Name Update Request for ${model.newName}") {
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -8,9 +8,9 @@ import dev.geekback.dopewars.ui.BorderedCard
|
||||
|
||||
class PlayerNameUpdateResponseUi: DopeWarsModelUi<PlayerNameUpdateResponse> {
|
||||
@Composable
|
||||
override fun view(model: PlayerNameUpdateResponse) {
|
||||
override fun view(model: PlayerNameUpdateResponse, onRequestEdit: () -> Unit) {
|
||||
BorderedCard("Player Name Update Response") {
|
||||
PlayerUi().view(model.updatedPlayer)
|
||||
PlayerUi().view(model.updatedPlayer) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import dev.geekback.dopewars.ui.DopeWarsModelUi
|
||||
|
||||
class TradeRequestUi: DopeWarsModelUi<TradeRequest> {
|
||||
@Composable
|
||||
override fun view(model: TradeRequest) {
|
||||
override fun view(model: TradeRequest, onRequestEdit: () -> Unit) {
|
||||
BorderedCard("Trade Request for ${model.drug.name} / ${model.action} / ${model.quantity}") {
|
||||
|
||||
}
|
||||
@@ -26,9 +26,6 @@ class TradeRequestUi: DopeWarsModelUi<TradeRequest> {
|
||||
onModelUpdate: (TradeRequest) -> Unit
|
||||
) {
|
||||
var localModel by remember { mutableStateOf(model) }
|
||||
var actionIndex by remember { mutableStateOf(0) }
|
||||
var quantity by remember { mutableStateOf(model.quantity) }
|
||||
var drug by remember { mutableStateOf(model.drug) }
|
||||
|
||||
BorderedCard("Trade Requesst Form") {
|
||||
Row {
|
||||
|
||||
@@ -8,7 +8,7 @@ import dev.geekback.dopewars.ui.BorderedCard
|
||||
|
||||
class TravelRequestUi: DopeWarsModelUi<TravelRequest> {
|
||||
@Composable
|
||||
override fun view(model: TravelRequest) {
|
||||
override fun view(model: TravelRequest, onRequestEdit: () -> Unit) {
|
||||
BorderedCard("Travel Request to ${model.destination.name}") {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,27 +17,24 @@ import dev.geekback.dopewars.ui.MarketUi
|
||||
class TravelResponseUi: DopeWarsModelUi<TravelResult> {
|
||||
|
||||
@Composable
|
||||
override fun view(model: TravelResult) {
|
||||
override fun view(model: TravelResult, onRequestEdit: () -> Unit) {
|
||||
BorderedCard("Travel Result ${model.location.name}") {
|
||||
LocationUi().view(model.location)
|
||||
LocationUi().view(model.location) {}
|
||||
Text("Day: ${model.day}")
|
||||
MarketUi().view(model.market)
|
||||
MarketUi().view(model.market) {}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun form(model: TravelResult, onModelUpdate: (TravelResult) -> Unit) {
|
||||
var day by remember { mutableStateOf(model.day) }
|
||||
var location by remember { mutableStateOf(model.location) }
|
||||
var market by remember { mutableStateOf(model.market) }
|
||||
var localModel by remember { mutableStateOf(model) }
|
||||
|
||||
BorderedCard("Travel Result Form") {
|
||||
LocationUi().form(model.location) {
|
||||
println("Update location to $it")
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// Row {
|
||||
@@ -53,4 +50,22 @@ class TravelResponseUi: DopeWarsModelUi<TravelResult> {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
fun ViewFormButtons(onRequestEdit: () -> Unit) {
|
||||
Row {
|
||||
Button(onClick = onRequestEdit) {
|
||||
Text("Edit")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun FormButtons(onModelUpdate: () -> Unit, onModelReset: () -> Unit) {
|
||||
Row {
|
||||
Button(onClick = onModelUpdate) { Text("Apply") }
|
||||
Button(onClick = onModelReset) { Text("Reset") }
|
||||
}
|
||||
}
|
||||
@@ -1,92 +1,110 @@
|
||||
package dev.geekback.dopewars.ui
|
||||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.onClick
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.RangeSlider
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableFloatStateOf
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import dev.geekback.dopewars.shared.DRUG_MAX_PRICE
|
||||
import dev.geekback.dopewars.shared.Drug
|
||||
import dev.geekback.dopewars.shared.DrugInfo
|
||||
|
||||
class DrugInfoUi: DopeWarsModelUi<DrugInfo> {
|
||||
@Composable
|
||||
override fun view(model: DrugInfo) {
|
||||
BorderedCard(model.drug.name) {
|
||||
Column {
|
||||
Text("Price: ${model.minValue} - ${model.maxValue}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun form(
|
||||
model: DrugInfo,
|
||||
onModelUpdate: (DrugInfo) -> Unit
|
||||
) {
|
||||
var drug by remember { mutableStateOf(model) }
|
||||
var name by remember { mutableStateOf(model.drug.name) }
|
||||
var minPrice by remember { mutableFloatStateOf(model.minValue) }
|
||||
var maxPrice by remember { mutableFloatStateOf(model.maxValue) }
|
||||
|
||||
BorderedCard("Drug Form") {
|
||||
Column {
|
||||
// Name
|
||||
TextField(
|
||||
value = name,
|
||||
onValueChange = { name = it },
|
||||
label = { Text("Name") },
|
||||
)
|
||||
|
||||
Row {
|
||||
TextField(
|
||||
value = minPrice.toString(),
|
||||
onValueChange = { minPrice = it.toFloatOrNull() ?: minPrice },
|
||||
label = { Text("Min Price") },
|
||||
class DrugInfoUi : DopeWarsModelUi<DrugInfo> {
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun picker(default: Drug, onSelect: (Drug) -> Unit) {
|
||||
var showOptions by remember { mutableStateOf(false) }
|
||||
Column {
|
||||
Row {
|
||||
Text(
|
||||
modifier = Modifier.onClick {
|
||||
showOptions = true
|
||||
},
|
||||
text = default.name
|
||||
)
|
||||
DropdownMenu(
|
||||
expanded = showOptions,
|
||||
onDismissRequest = { showOptions = false },
|
||||
) {
|
||||
Drug.all().forEach { localDrug ->
|
||||
DropdownMenuItem(
|
||||
onClick = {
|
||||
showOptions = false
|
||||
onSelect(localDrug)
|
||||
},
|
||||
text = { Text(localDrug.name) }
|
||||
)
|
||||
|
||||
TextField(
|
||||
value = maxPrice.toString(),
|
||||
onValueChange = { maxPrice = it.toFloatOrNull() ?: maxPrice },
|
||||
label = { Text("Max Price") },
|
||||
)
|
||||
}
|
||||
|
||||
RangeSlider(
|
||||
value = (minPrice)..(maxPrice),
|
||||
onValueChangeFinished = { },
|
||||
valueRange = 1f..DRUG_MAX_PRICE,
|
||||
onValueChange = { it ->
|
||||
minPrice = it.start
|
||||
maxPrice = it.endInclusive
|
||||
}
|
||||
)
|
||||
|
||||
Row {
|
||||
Button(onClick = {
|
||||
drug = DrugInfo(Drug.WEED , minPrice, maxPrice)
|
||||
onModelUpdate(drug)
|
||||
}) {
|
||||
Text("Apply")
|
||||
}
|
||||
|
||||
Button(onClick = {
|
||||
name = Drug.WEED.name
|
||||
minPrice = drug.minValue
|
||||
maxPrice = drug.maxValue
|
||||
}) {
|
||||
Text("Cancel")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun view(model: DrugInfo, onRequestEdit: () -> Unit) {
|
||||
ViewFrame(title = model.drug.name, onRequestEdit = onRequestEdit) {
|
||||
Text("Price: ${model.minValue} - ${model.maxValue}")
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun form(
|
||||
model: DrugInfo,
|
||||
onModelUpdate: (DrugInfo) -> Unit
|
||||
) {
|
||||
var drug by remember { mutableStateOf(model.drug) }
|
||||
var minPrice by remember { mutableIntStateOf(model.minValue) }
|
||||
var maxPrice by remember { mutableIntStateOf(model.maxValue) }
|
||||
|
||||
FormFrame(
|
||||
title = "Drug Form",
|
||||
onModelUpdate = { onModelUpdate(DrugInfo(drug, minPrice, maxPrice)) },
|
||||
onModelReset = {
|
||||
drug = model.drug
|
||||
minPrice = model.minValue
|
||||
maxPrice = model.maxValue
|
||||
},
|
||||
onCancelEdit = { onModelUpdate(model) }) {
|
||||
picker(drug) {
|
||||
drug = it
|
||||
}
|
||||
|
||||
Row {
|
||||
TextField(
|
||||
value = minPrice.toString(),
|
||||
onValueChange = { minPrice = it.toIntOrNull() ?: minPrice },
|
||||
label = { Text("Min Price") },
|
||||
)
|
||||
|
||||
TextField(
|
||||
value = maxPrice.toString(),
|
||||
onValueChange = { maxPrice = it.toIntOrNull() ?: maxPrice },
|
||||
label = { Text("Max Price") },
|
||||
)
|
||||
}
|
||||
|
||||
RangeSlider(
|
||||
value = (minPrice.toFloat())..(maxPrice.toFloat()),
|
||||
onValueChangeFinished = { },
|
||||
valueRange = 1f..DRUG_MAX_PRICE,
|
||||
onValueChange = {
|
||||
minPrice = it.start.toInt()
|
||||
maxPrice = it.endInclusive.toInt()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package dev.geekback.dopewars.ui
|
||||
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
@@ -7,9 +8,17 @@ import dev.geekback.dopewars.shared.InventoryItem
|
||||
|
||||
class InventoryUi: DopeWarsModelUi<List<InventoryItem>> {
|
||||
@Composable
|
||||
override fun view(model: List<InventoryItem>) {
|
||||
BorderedCard("Inventory Items") {
|
||||
|
||||
override fun view(model: List<InventoryItem>, onRequestEdit: () -> Unit) {
|
||||
ViewFrame("Inventory",
|
||||
onRequestEdit = onRequestEdit) {
|
||||
LazyColumn {
|
||||
items(model.size) { index ->
|
||||
val item = model[index]
|
||||
InventoryItemUi().view(item) {
|
||||
println("Item Edit Request")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,5 +33,4 @@ class InventoryUi: DopeWarsModelUi<List<InventoryItem>> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,12 +1,28 @@
|
||||
package dev.geekback.dopewars.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.geekback.dopewars.shared.InventoryItem
|
||||
|
||||
class InventoryItemUi: DopeWarsModelUi<InventoryItem> {
|
||||
@Composable
|
||||
override fun view(model: InventoryItem) {
|
||||
private val drugInfoUi = DrugInfoUi()
|
||||
|
||||
@Composable
|
||||
override fun view(model: InventoryItem, onRequestEdit: () -> Unit) {
|
||||
BorderedCard("") {
|
||||
Text("${model.drug.name} / ${model.quantity}g")
|
||||
|
||||
Button(onClick = onRequestEdit) {
|
||||
Text("Edit")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -14,6 +30,34 @@ class InventoryItemUi: DopeWarsModelUi<InventoryItem> {
|
||||
model: InventoryItem,
|
||||
onModelUpdate: (InventoryItem) -> Unit
|
||||
) {
|
||||
TODO("Not yet implemented")
|
||||
var drug by remember { mutableStateOf(model.drug) }
|
||||
var quantity by remember { mutableStateOf(model.quantity) }
|
||||
|
||||
ViewFrame("Inventory Item",
|
||||
onRequestEdit = {}) {
|
||||
drugInfoUi.picker(drug) {
|
||||
drug = it
|
||||
}
|
||||
|
||||
TextField(
|
||||
value = quantity.toString(),
|
||||
label = { Text("Quantity in g") },
|
||||
onValueChange = {
|
||||
quantity = it.toInt()
|
||||
})
|
||||
|
||||
Row {
|
||||
Button(onClick = { onModelUpdate(InventoryItem(drug, quantity)) }) {
|
||||
Text("Apply")
|
||||
}
|
||||
|
||||
Button(onClick = {
|
||||
drug = model.drug
|
||||
quantity = model.quantity
|
||||
} ) {
|
||||
Text("Reset")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +1,78 @@
|
||||
package dev.geekback.dopewars.ui
|
||||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.foundation.onClick
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import dev.geekback.dopewars.shared.Location
|
||||
|
||||
class LocationUi: DopeWarsModelUi<Location> {
|
||||
class LocationUi : DopeWarsModelUi<Location> {
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
override fun view(model: Location) {
|
||||
BorderedCard("Location - ${model.name}") {
|
||||
fun picker(default: Location, onSelect: (Location) -> Unit) {
|
||||
var showOptions by remember { mutableStateOf(false) }
|
||||
Column {
|
||||
Row {
|
||||
Text(
|
||||
text = default.name,
|
||||
modifier = Modifier.onClick { showOptions = true }
|
||||
)
|
||||
|
||||
DropdownMenu(
|
||||
expanded = showOptions,
|
||||
onDismissRequest = { showOptions = false }
|
||||
) {
|
||||
Location.all().forEach { localLocation ->
|
||||
DropdownMenuItem(onClick = {
|
||||
showOptions = false
|
||||
onSelect(localLocation)
|
||||
}, text = { Text(localLocation.name) })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
override fun view(model: Location, onRequestEdit: () -> Unit) {
|
||||
ViewFrame(title = "Location",
|
||||
onRequestEdit = onRequestEdit) {
|
||||
Text(model.name)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
override fun form(
|
||||
model: Location,
|
||||
onModelUpdate: (Location) -> Unit
|
||||
) {
|
||||
var name by remember { mutableStateOf(model.name) }
|
||||
var location by remember { mutableStateOf(model)}
|
||||
var localModel by remember { mutableStateOf(model) }
|
||||
|
||||
BorderedCard("Location") {
|
||||
TextField(value = name, label = {
|
||||
Text("Location Name")
|
||||
}, onValueChange = {
|
||||
name = it
|
||||
})
|
||||
val title = if (localModel == model) { "Location" } else { "Location *" }
|
||||
|
||||
Row {
|
||||
Button(onClick = {
|
||||
location.name = name;
|
||||
onModelUpdate(location)
|
||||
}) {
|
||||
Text("Apply")
|
||||
}
|
||||
|
||||
Button(onClick = {
|
||||
name = location.name
|
||||
}) {
|
||||
Text("Cancel")
|
||||
}
|
||||
FormFrame(title = title,
|
||||
onModelUpdate = {
|
||||
onModelUpdate(localModel)
|
||||
},
|
||||
onModelReset = {
|
||||
localModel = model
|
||||
},
|
||||
onCancelEdit = {
|
||||
onModelUpdate(model)
|
||||
}) {
|
||||
picker(localModel) {
|
||||
localModel = it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,24 +2,34 @@ package dev.geekback.dopewars.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import dev.geekback.dopewars.shared.Market
|
||||
import dev.geekback.dopewars.shared.Player
|
||||
|
||||
class MarketUi: DopeWarsModelUi<Market> {
|
||||
@Composable
|
||||
override fun view(model: Market) {
|
||||
override fun view(model: Market, onRequestEdit: () -> Unit) {
|
||||
val prices = model.prices.toList()
|
||||
BorderedCard("Market for ${model.location.name}") {
|
||||
Column {
|
||||
LazyColumn {
|
||||
items(prices.size) { index ->
|
||||
val item = prices[index];
|
||||
|
||||
val item = prices[index]
|
||||
val name = item.first.name
|
||||
val price = item.second.toFloat()
|
||||
val price = item.second
|
||||
Text("Drug $name $${price}")
|
||||
}
|
||||
}
|
||||
Button(onClick = onRequestEdit) {
|
||||
Text("Edit")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,33 @@
|
||||
package dev.geekback.dopewars.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.*
|
||||
import dev.geekback.dopewars.shared.Player
|
||||
import kotlin.time.Instant
|
||||
|
||||
class PlayerUi: DopeWarsModelUi<Player> {
|
||||
class PlayerUi : DopeWarsModelUi<Player> {
|
||||
private val inventoryUi = InventoryUi()
|
||||
private val marketUi = MarketUi()
|
||||
private val locationUi = LocationUi()
|
||||
|
||||
@Composable
|
||||
override fun view(model: Player) {
|
||||
BorderedCard(model.name) {
|
||||
Column {
|
||||
Text("ID: ${model.id}")
|
||||
Text("Cash: $${model.cash}")
|
||||
Text("Debt: $${model.debt}")
|
||||
Text("Health: ${model.health}")
|
||||
Text("Location: ${model.location.name}")
|
||||
// TODO: this is an ugly memory hack
|
||||
InventoryUi().view(model.inventory)
|
||||
// marketView(model.lastMarket ?: Market(location = Location("Unknown"), prices = mapOf()))
|
||||
val lastTime = Instant.fromEpochSeconds(model.lastActionTime)
|
||||
Text("Last Action: $lastTime")
|
||||
override fun view(model: Player, onRequestEdit: () -> Unit) {
|
||||
ViewFrame(
|
||||
title = model.name,
|
||||
onRequestEdit = onRequestEdit
|
||||
) {
|
||||
Text("ID: ${model.id}")
|
||||
Text("Cash: $${model.cash}")
|
||||
Text("Debt: $${model.debt}")
|
||||
Text("Health: ${model.health}")
|
||||
Text("Location: ${model.location.name}")
|
||||
this.inventoryUi.view(model.inventory) {
|
||||
println("Inventory Edit request")
|
||||
}
|
||||
// marketView(model.lastMarket ?: Market(location = Location("Unknown"), prices = mapOf()))
|
||||
val lastTime = Instant.fromEpochSeconds(model.lastActionTime)
|
||||
Text("Last Action: $lastTime")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,14 +36,64 @@ class PlayerUi: DopeWarsModelUi<Player> {
|
||||
model: Player,
|
||||
onModelUpdate: (Player) -> Unit
|
||||
) {
|
||||
BorderedCard("Player ${model.name}") {
|
||||
Button(onClick = { onModelUpdate(model) }) {
|
||||
Text("Update")
|
||||
var uuid by remember { mutableStateOf(model.id) }
|
||||
var name by remember { mutableStateOf(model.name) }
|
||||
var day by remember { mutableStateOf(model.day) }
|
||||
var cash by remember { mutableStateOf(model.cash) }
|
||||
var debt by remember { mutableStateOf(model.debt) }
|
||||
var health by remember { mutableStateOf(model.health) }
|
||||
var location by remember { mutableStateOf(model.location) }
|
||||
var inventory by remember { mutableStateOf(model.inventory) }
|
||||
var lastActionTime by remember { mutableStateOf(model.lastActionTime) }
|
||||
var lastMarket by remember { mutableStateOf(model.lastMarket) }
|
||||
|
||||
FormFrame(
|
||||
title = "Player ${model.name} Form",
|
||||
onModelUpdate = {
|
||||
onModelUpdate(
|
||||
Player(
|
||||
id = uuid,
|
||||
cash = cash,
|
||||
debt = debt,
|
||||
health = health,
|
||||
location = location,
|
||||
inventory = inventory,
|
||||
name = name,
|
||||
day = day,
|
||||
lastMarket = lastMarket,
|
||||
lastActionTime = lastActionTime,
|
||||
)
|
||||
)
|
||||
},
|
||||
onModelReset = {
|
||||
uuid = model.id
|
||||
name = model.name
|
||||
day = model.day
|
||||
cash = model.cash
|
||||
debt = model.debt
|
||||
health = model.health
|
||||
location = model.location
|
||||
inventory = model.inventory
|
||||
lastActionTime = model.lastActionTime
|
||||
lastMarket = model.lastMarket
|
||||
},
|
||||
onCancelEdit = {
|
||||
onModelUpdate(model)
|
||||
}) {
|
||||
TextField(value = uuid, onValueChange = { uuid = it })
|
||||
TextField(value = name, onValueChange = { name = it })
|
||||
TextField(value = day.toString(), onValueChange = { day = it.toInt() })
|
||||
TextField(value = cash.toString(), onValueChange = { cash = it.toInt() })
|
||||
TextField(value = debt.toString(), onValueChange = { debt = it.toInt() })
|
||||
TextField(value = health.toString(), onValueChange = { health = it.toInt() })
|
||||
this.locationUi.picker(location) { location = it }
|
||||
TextField(value = lastActionTime.toString(), onValueChange = { lastActionTime = it.toLong() })
|
||||
|
||||
if (lastMarket == null) {
|
||||
Text("No Market")
|
||||
} else {
|
||||
this.marketUi.view(lastMarket!!) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun playerView(player: Player) {
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package dev.geekback.util
|
||||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.onClick
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import kotlinx.datetime.TimeZone
|
||||
import kotlinx.datetime.toLocalDateTime
|
||||
import kotlin.time.Instant
|
||||
|
||||
data class ComposeTimestampConfiguration(
|
||||
val minimumDate: Long,
|
||||
val maximumDate: Long,
|
||||
)
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
fun ComposableTimestampControlPreview() {
|
||||
Box {
|
||||
ComposeTimestampControl(
|
||||
initialValue = 123456789,
|
||||
configuration = ComposeTimestampConfiguration(minimumDate = 0, maximumDate = 1234567890),
|
||||
onValueUpdated = { println("Updated to $it") },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun ComposeTimestampControl(initialValue: Long, configuration: ComposeTimestampConfiguration, onValueUpdated: (Long) -> Unit) {
|
||||
var currentValue by remember { mutableStateOf(initialValue) }
|
||||
|
||||
val currentDate = Instant.fromEpochSeconds(currentValue).toLocalDateTime(TimeZone.currentSystemDefault()).date
|
||||
val currentTime = Instant.fromEpochSeconds(currentValue).toLocalDateTime(TimeZone.currentSystemDefault()).time
|
||||
|
||||
var showingDatePicker by remember { mutableStateOf(false) }
|
||||
var showingTimePicker by remember { mutableStateOf(false) }
|
||||
|
||||
var datePickerState = rememberDatePickerState(
|
||||
initialSelectedDateMillis = initialValue,
|
||||
)
|
||||
|
||||
Column {
|
||||
Row {
|
||||
Text("$currentDate", modifier = Modifier.onClick(enabled = true, onClick = {
|
||||
showingDatePicker = true
|
||||
}))
|
||||
Text("$currentTime", modifier = Modifier.onClick(enabled = true, onClick = {
|
||||
showingTimePicker = true
|
||||
}))
|
||||
}
|
||||
|
||||
Row {
|
||||
Text("Date Visible $showingDatePicker")
|
||||
Text("Time Visible $showingTimePicker")
|
||||
}
|
||||
|
||||
HorizontalDivider()
|
||||
|
||||
if (showingDatePicker) {
|
||||
DatePicker(
|
||||
state = datePickerState
|
||||
)
|
||||
}
|
||||
|
||||
if (showingTimePicker) {
|
||||
|
||||
}
|
||||
|
||||
// Controls
|
||||
Row {
|
||||
Button(onClick = { currentValue = initialValue }) { Text("Reset") }
|
||||
Button(onClick = { onValueUpdated(currentValue) }) { Text("Set") }
|
||||
Button(onClick = { onValueUpdated(initialValue + currentValue) }) { Text("Cancel") }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package dev.geekback.dopewars
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
import dev.geekback.util.ComposeTimestampConfiguration
|
||||
import dev.geekback.util.ComposeTimestampControl
|
||||
|
||||
fun main() = application {
|
||||
Window(
|
||||
onCloseRequest = ::exitApplication,
|
||||
title = "ComposeTimestampControlDemoApp"
|
||||
) {
|
||||
ComposeTimestampControlDemoApp()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ComposeTimestampControlDemoApp() {
|
||||
var currentValue by remember { mutableStateOf(1234567890L )}
|
||||
|
||||
ComposeTimestampControl(
|
||||
initialValue = currentValue,
|
||||
configuration = ComposeTimestampConfiguration(minimumDate = 0, maximumDate = 12345678900),
|
||||
) {
|
||||
println("Updated from $currentValue to $it")
|
||||
currentValue = it
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
package dev.geekback.dopewars
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.DrawerValue
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ModalDrawerSheet
|
||||
import androidx.compose.material3.ModalNavigationDrawer
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.rememberDrawerState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
import dev.geekback.dopewars.shared.Drug
|
||||
import dev.geekback.dopewars.shared.DrugInfo
|
||||
import dev.geekback.dopewars.shared.Location
|
||||
import dev.geekback.dopewars.shared.Market
|
||||
import dev.geekback.dopewars.shared.Player
|
||||
import dev.geekback.dopewars.shared.api.MarketRequest
|
||||
import dev.geekback.dopewars.shared.api.MarketResult
|
||||
import dev.geekback.dopewars.shared.api.PlayerNameUpdateRequest
|
||||
import dev.geekback.dopewars.shared.api.PlayerNameUpdateResponse
|
||||
import dev.geekback.dopewars.shared.api.TradeAction
|
||||
import dev.geekback.dopewars.shared.api.TradeRequest
|
||||
import dev.geekback.dopewars.shared.api.TravelRequest
|
||||
import dev.geekback.dopewars.shared.api.TravelResult
|
||||
import dev.geekback.dopewars.ui.DopeWarsUi
|
||||
|
||||
fun main() = application {
|
||||
Window(
|
||||
onCloseRequest = ::exitApplication,
|
||||
title = "DopeWars Dev Client"
|
||||
) {
|
||||
DemoApp()
|
||||
}
|
||||
}
|
||||
|
||||
data class ApiData(
|
||||
var marketRequest: MarketRequest,
|
||||
var marketResult: MarketResult,
|
||||
var playerNameUpdateRequest: PlayerNameUpdateRequest,
|
||||
var playerNameUpdateResponse: PlayerNameUpdateResponse,
|
||||
var tradeAction: TradeAction,
|
||||
var tradeRequest: TradeRequest,
|
||||
var travelRequest: TravelRequest,
|
||||
var travelResult: TravelResult
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun DemoApp() {
|
||||
val drawerState = rememberDrawerState(DrawerValue.Closed)
|
||||
val scope = rememberCoroutineScope()
|
||||
var currentScreen by remember { mutableStateOf(Screens.HOME) }
|
||||
var drug by remember { mutableStateOf(DrugInfo(drug = Drug.random(), minValue = 10000, maxValue = 100000)) }
|
||||
var player by remember { mutableStateOf(Player.new()) }
|
||||
var location by remember { mutableStateOf(Location.random()) }
|
||||
var market by remember {
|
||||
mutableStateOf(
|
||||
Market(
|
||||
location = Location.random(),
|
||||
prices = mapOf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val ui = DopeWarsUi.new()
|
||||
|
||||
val travelResultLocation = Location.random()
|
||||
|
||||
var api by remember {
|
||||
mutableStateOf(
|
||||
ApiData(
|
||||
marketRequest = MarketRequest(
|
||||
location = Location.random()
|
||||
),
|
||||
marketResult = MarketResult(
|
||||
market = Market(
|
||||
location = Location.random(),
|
||||
prices = emptyMap()
|
||||
)
|
||||
),
|
||||
playerNameUpdateRequest = PlayerNameUpdateRequest("newPlayerName"),
|
||||
playerNameUpdateResponse = PlayerNameUpdateResponse(
|
||||
updatedPlayer = Player.new()
|
||||
),
|
||||
tradeAction = TradeAction.BUY,
|
||||
tradeRequest = TradeRequest(
|
||||
action = TradeAction.BUY,
|
||||
drug = Drug.random(),
|
||||
quantity = 10
|
||||
),
|
||||
travelRequest = TravelRequest(
|
||||
destination = Location.random()
|
||||
),
|
||||
travelResult = TravelResult(
|
||||
location = travelResultLocation,
|
||||
day = 1,
|
||||
market = Market(location = travelResultLocation, mapOf())
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
MaterialTheme {
|
||||
ModalNavigationDrawer(
|
||||
drawerState = drawerState,
|
||||
drawerContent = {
|
||||
ModalDrawerSheet {
|
||||
val buttons = listOf(
|
||||
Pair(Screens.HOME, "Home"),
|
||||
Pair(Screens.DRUG, "Drugs"),
|
||||
Pair(Screens.PLAYER, "Player"),
|
||||
Pair(Screens.LOCATION, "Location"),
|
||||
Pair(Screens.API, "API")
|
||||
)
|
||||
|
||||
buttons.forEach { pair ->
|
||||
Button(onClick = {
|
||||
currentScreen = pair.first
|
||||
}) {
|
||||
Text(pair.second)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
) {
|
||||
Column { // Main content
|
||||
when (currentScreen) {
|
||||
Screens.HOME -> {
|
||||
Row {
|
||||
Box(modifier = Modifier.width(400.dp)) {
|
||||
ui.player.field(player) {
|
||||
println("Player changed -> $it")
|
||||
}
|
||||
}
|
||||
ui.location.field(location) {
|
||||
println("Location changed -> $it")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Screens.DRUG -> {
|
||||
ui.drug.field(drug) {
|
||||
println("Drug Updated -> $it")
|
||||
}
|
||||
}
|
||||
|
||||
Screens.PLAYER -> {
|
||||
ui.player.form(player) {
|
||||
player = it
|
||||
}
|
||||
}
|
||||
|
||||
Screens.LOCATION -> {
|
||||
ui.location.form(location) {
|
||||
println("Location updated from $location to $it")
|
||||
location = it
|
||||
}
|
||||
}
|
||||
|
||||
Screens.MARKET -> {
|
||||
ui.market.form(market) {
|
||||
market = it
|
||||
}
|
||||
}
|
||||
|
||||
Screens.API -> {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) {
|
||||
SizeBox(250.dp, 250.dp) {
|
||||
ui.api.marketRequest.form(api.marketRequest) { api.marketRequest = it }
|
||||
}
|
||||
|
||||
SizeBox(250.dp, 250.dp) {
|
||||
ui.api.marketResponse.form(api.marketResult) { api.marketResult = it }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(10.dp)) {
|
||||
SizeBox(250.dp, 250.dp) {
|
||||
ui.api.playerNameUpdateRequest.form(api.playerNameUpdateRequest) {
|
||||
api.playerNameUpdateRequest = it
|
||||
}
|
||||
}
|
||||
|
||||
SizeBox(250.dp, 250.dp) {
|
||||
ui.api.playerNameUpdateResponse.form(api.playerNameUpdateResponse) {
|
||||
api.playerNameUpdateResponse = it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ui.api.travelRequest.form(api.travelRequest) { api.travelRequest = it }
|
||||
ui.api.travelResponse.form(api.travelResult) { api.travelResult = it }
|
||||
ui.api.tradeRequest.form(api.tradeRequest) { api.tradeRequest = it }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
fun SizeBox(width: Dp, height: Dp, body: @Composable () -> Unit) {
|
||||
Box(modifier = Modifier.width(width).height(height)) {
|
||||
body()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.geekback.dopewars
|
||||
|
||||
enum class Screens {
|
||||
HOME,
|
||||
DRUG,
|
||||
PLAYER,
|
||||
LOCATION,
|
||||
MARKET,
|
||||
API
|
||||
}
|
||||
Reference in New Issue
Block a user