Initial commit
This commit is contained in:
commit
9ddd6018fd
18 changed files with 931 additions and 0 deletions
45
composeApp/build.gradle.kts
Normal file
45
composeApp/build.gradle.kts
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
|
||||
|
||||
plugins {
|
||||
alias(libs.plugins.kotlinMultiplatform)
|
||||
alias(libs.plugins.composeMultiplatform)
|
||||
alias(libs.plugins.composeCompiler)
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm("desktop")
|
||||
|
||||
sourceSets {
|
||||
val desktopMain by getting
|
||||
|
||||
commonMain.dependencies {
|
||||
implementation(compose.runtime)
|
||||
implementation(compose.foundation)
|
||||
implementation(compose.material)
|
||||
implementation(compose.ui)
|
||||
implementation(compose.components.resources)
|
||||
implementation(compose.components.uiToolingPreview)
|
||||
implementation(libs.androidx.lifecycle.viewmodel)
|
||||
implementation(libs.androidx.lifecycle.runtime.compose)
|
||||
|
||||
implementation("org.jetbrains.androidx.navigation:navigation-compose:2.8.0-alpha10")
|
||||
}
|
||||
desktopMain.dependencies {
|
||||
implementation(compose.desktop.currentOs)
|
||||
implementation(libs.kotlinx.coroutines.swing)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
compose.desktop {
|
||||
application {
|
||||
mainClass = "com.pixelized.desktop.lwa.MainKt"
|
||||
|
||||
nativeDistributions {
|
||||
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
|
||||
packageName = "com.pixelized.desktop.lwa"
|
||||
packageVersion = "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="600dp"
|
||||
android:height="600dp"
|
||||
android:viewportWidth="600"
|
||||
android:viewportHeight="600">
|
||||
<path
|
||||
android:pathData="M301.21,418.53C300.97,418.54 300.73,418.56 300.49,418.56C297.09,418.59 293.74,417.72 290.79,416.05L222.6,377.54C220.63,376.43 219,374.82 217.85,372.88C216.7,370.94 216.09,368.73 216.07,366.47L216.07,288.16C216.06,287.32 216.09,286.49 216.17,285.67C216.38,283.54 216.91,281.5 217.71,279.6L199.29,268.27L177.74,256.19C175.72,260.43 174.73,265.23 174.78,270.22L174.79,387.05C174.85,393.89 178.57,400.2 184.53,403.56L286.26,461.02C290.67,463.51 295.66,464.8 300.73,464.76C300.91,464.76 301.09,464.74 301.27,464.74C301.24,449.84 301.22,439.23 301.22,439.23L301.21,418.53Z"
|
||||
android:fillColor="#041619"
|
||||
android:fillType="nonZero"/>
|
||||
<path
|
||||
android:pathData="M409.45,242.91L312.64,188.23C303.64,183.15 292.58,183.26 283.68,188.51L187.92,245C183.31,247.73 179.93,251.62 177.75,256.17L177.74,256.19L199.29,268.27L217.71,279.6C217.83,279.32 217.92,279.02 218.05,278.74C218.24,278.36 218.43,277.98 218.64,277.62C219.06,276.88 219.52,276.18 220.04,275.51C221.37,273.8 223.01,272.35 224.87,271.25L289.06,233.39C290.42,232.59 291.87,231.96 293.39,231.51C295.53,230.87 297.77,230.6 300,230.72C302.98,230.88 305.88,231.73 308.47,233.2L373.37,269.85C375.54,271.08 377.49,272.68 379.13,274.57C379.68,275.19 380.18,275.85 380.65,276.53C380.86,276.84 381.05,277.15 381.24,277.47L397.79,266.39L420.34,252.93L420.31,252.88C417.55,248.8 413.77,245.35 409.45,242.91Z"
|
||||
android:fillColor="#37BF6E"
|
||||
android:fillType="nonZero"/>
|
||||
<path
|
||||
android:pathData="M381.24,277.47C381.51,277.92 381.77,278.38 382.01,278.84C382.21,279.24 382.39,279.65 382.57,280.06C382.91,280.88 383.19,281.73 383.41,282.59C383.74,283.88 383.92,285.21 383.93,286.57L383.93,361.1C383.96,363.95 383.35,366.77 382.16,369.36C381.93,369.86 381.69,370.35 381.42,370.83C379.75,373.79 377.32,376.27 374.39,378L310.2,415.87C307.47,417.48 304.38,418.39 301.21,418.53L301.22,439.23C301.22,439.23 301.24,449.84 301.27,464.74C306.1,464.61 310.91,463.3 315.21,460.75L410.98,404.25C419.88,399 425.31,389.37 425.22,379.03L425.22,267.85C425.17,262.48 423.34,257.34 420.34,252.93L397.79,266.39L381.24,277.47Z"
|
||||
android:fillColor="#3870B2"
|
||||
android:fillType="nonZero"/>
|
||||
<path
|
||||
android:pathData="M177.75,256.17C179.93,251.62 183.31,247.73 187.92,245L283.68,188.51C292.58,183.26 303.64,183.15 312.64,188.23L409.45,242.91C413.77,245.35 417.55,248.8 420.31,252.88L420.34,252.93L498.59,206.19C494.03,199.46 487.79,193.78 480.67,189.75L320.86,99.49C306.01,91.1 287.75,91.27 273.07,99.95L114.99,193.2C107.39,197.69 101.81,204.11 98.21,211.63L177.74,256.19L177.75,256.17ZM301.27,464.74C301.09,464.74 300.91,464.76 300.73,464.76C295.66,464.8 290.67,463.51 286.26,461.02L184.53,403.56C178.57,400.2 174.85,393.89 174.79,387.05L174.78,270.22C174.73,265.23 175.72,260.43 177.74,256.19L98.21,211.63C94.86,218.63 93.23,226.58 93.31,234.82L93.31,427.67C93.42,438.97 99.54,449.37 109.4,454.92L277.31,549.77C284.6,553.88 292.84,556.01 301.2,555.94L301.2,555.8C301.39,543.78 301.33,495.26 301.27,464.74Z"
|
||||
android:strokeWidth="10"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#083042"
|
||||
android:fillType="nonZero"/>
|
||||
<path
|
||||
android:pathData="M498.59,206.19L420.34,252.93C423.34,257.34 425.17,262.48 425.22,267.85L425.22,379.03C425.31,389.37 419.88,399 410.98,404.25L315.21,460.75C310.91,463.3 306.1,464.61 301.27,464.74C301.33,495.26 301.39,543.78 301.2,555.8L301.2,555.94C309.48,555.87 317.74,553.68 325.11,549.32L483.18,456.06C497.87,447.39 506.85,431.49 506.69,414.43L506.69,230.91C506.6,222.02 503.57,213.5 498.59,206.19Z"
|
||||
android:strokeWidth="10"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#083042"
|
||||
android:fillType="nonZero"/>
|
||||
<path
|
||||
android:pathData="M301.2,555.94C292.84,556.01 284.6,553.88 277.31,549.76L109.4,454.92C99.54,449.37 93.42,438.97 93.31,427.67L93.31,234.82C93.23,226.58 94.86,218.63 98.21,211.63C101.81,204.11 107.39,197.69 114.99,193.2L273.07,99.95C287.75,91.27 306.01,91.1 320.86,99.49L480.67,189.75C487.79,193.78 494.03,199.46 498.59,206.19C503.57,213.5 506.6,222.02 506.69,230.91L506.69,414.43C506.85,431.49 497.87,447.39 483.18,456.06L325.11,549.32C317.74,553.68 309.48,555.87 301.2,555.94Z"
|
||||
android:strokeWidth="10"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#083042"
|
||||
android:fillType="nonZero"/>
|
||||
</vector>
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package com.pixelized.desktop.lwa
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.rememberWindowState
|
||||
import com.pixelized.desktop.lwa.screen.CharacterSheet
|
||||
import com.pixelized.desktop.lwa.screen.CharacterSheetUio
|
||||
import com.pixelized.desktop.lwa.theme.LwaTheme
|
||||
import org.jetbrains.compose.ui.tooling.preview.Preview
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
fun App() {
|
||||
LwaTheme {
|
||||
val characterSheet = remember { mutableStateOf<CharacterSheetUio?>(null) }
|
||||
|
||||
Column(
|
||||
modifier = Modifier.padding(all = 16.dp),
|
||||
) {
|
||||
Button(
|
||||
onClick = {
|
||||
characterSheet.value = CharacterSheetUio.Koryas
|
||||
}
|
||||
) {
|
||||
Text(text = "Koryas Tissenpa")
|
||||
}
|
||||
}
|
||||
|
||||
characterSheet.value?.let { sheet ->
|
||||
Window(
|
||||
onCloseRequest = { characterSheet.value = null },
|
||||
// state = rememberWindowState(size = DpSize(width = 320.dp + 32.dp, height = 800.dp)),
|
||||
title = "LwaCharacterSheet",
|
||||
) {
|
||||
CharacterSheet(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
width = 320.dp,
|
||||
characterSheet = sheet
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package com.pixelized.desktop.lwa.composable
|
||||
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxScope
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.RectangleShape
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.theme.LwaTheme
|
||||
import org.jetbrains.compose.ui.tooling.preview.Preview
|
||||
|
||||
@Composable
|
||||
fun DecoratedBox(
|
||||
modifier: Modifier = Modifier,
|
||||
border: Color = Color(0xFFDFDFDF),
|
||||
paddingValues: PaddingValues = PaddingValues(all = 8.dp),
|
||||
content: @Composable BoxScope.() -> Unit,
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.border(width = 1.dp, color = border, shape = RoundedCornerShape(16.dp))
|
||||
.padding(all = 2.dp)
|
||||
.border(width = 1.dp, color = border, shape = RectangleShape)
|
||||
.padding(paddingValues = paddingValues),
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
private fun DecoratedBoxPreview() {
|
||||
LwaTheme {
|
||||
Surface {
|
||||
DecoratedBox {
|
||||
Text("test")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.pixelized.desktop.lwa
|
||||
|
||||
import androidx.compose.ui.window.Window
|
||||
import androidx.compose.ui.window.application
|
||||
|
||||
fun main() = application {
|
||||
Window(
|
||||
onCloseRequest = ::exitApplication,
|
||||
title = "LwaCharacterSheet",
|
||||
) {
|
||||
App()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,260 @@
|
|||
package com.pixelized.desktop.lwa.screen
|
||||
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||
import androidx.compose.foundation.layout.FlowRow
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.desktop.lwa.composable.DecoratedBox
|
||||
|
||||
@Stable
|
||||
data class CharacterSheetUio(
|
||||
val name: String,
|
||||
val characteristics: List<Node>,
|
||||
val subCharacteristics: List<Node>,
|
||||
val skills: List<Node>,
|
||||
val occupations: List<Node>,
|
||||
val magics: List<Node>,
|
||||
) {
|
||||
@Stable
|
||||
class Node(
|
||||
val label: String,
|
||||
val value: Any,
|
||||
)
|
||||
|
||||
companion object {
|
||||
val Koryas = CharacterSheetUio(
|
||||
name = "Koryas Tissenpa",
|
||||
characteristics = listOf(
|
||||
Node(label = "Force", value = 10),
|
||||
Node(label = "Dextérité", value = 11),
|
||||
Node(label = "Constitution", value = 15),
|
||||
Node(label = "Taille", value = 13),
|
||||
Node(label = "Intelligence", value = 9),
|
||||
Node(label = "Pouvoir", value = 15),
|
||||
Node(label = "Charisme", value = 7),
|
||||
),
|
||||
subCharacteristics = listOf(
|
||||
Node(label = "Déplacement ", value = 10),
|
||||
Node(label = "Points de vie", value = "14/14"),
|
||||
Node(label = "Points de pouvoir", value = "13/13"),
|
||||
Node(label = "Bonus aux dégâts", value = "1d4"),
|
||||
Node(label = "Armure", value = 0),
|
||||
),
|
||||
skills = listOf(
|
||||
Node(label = "Bagarre", value = 75),
|
||||
Node(label = "Esquive", value = 60),
|
||||
Node(label = "Saisie", value = 20),
|
||||
Node(label = "Lancer", value = 20),
|
||||
Node(label = "Athlétisme", value = 60),
|
||||
Node(label = "Acrobatie", value = 50),
|
||||
Node(label = "Perception", value = 55),
|
||||
Node(label = "Recherche", value = 25),
|
||||
Node(label = "Empathie", value = 15),
|
||||
Node(label = "Persuasion", value = 20),
|
||||
Node(label = "Intimidation", value = 50),
|
||||
Node(label = "Baratin", value = 20),
|
||||
Node(label = "Marchandage", value = 10),
|
||||
Node(label = "Escamotage", value = 20),
|
||||
Node(label = "Premiers soins", value = 20),
|
||||
),
|
||||
occupations = listOf(
|
||||
Node(label = "Survie", value = 80),
|
||||
Node(label = "Empathie (Animal)", value = 60),
|
||||
Node(label = "Pistage", value = 60),
|
||||
Node(label = "Discrétion", value = 60),
|
||||
Node(label = "Connaissance (Herboristerie)", value = 40),
|
||||
Node(label = "Artisanat (Onguent)", value = 60),
|
||||
),
|
||||
magics = listOf(
|
||||
Node(label = "Métamorphose (Loup)", value = 100),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalLayoutApi::class)
|
||||
@Composable
|
||||
fun CharacterSheet(
|
||||
modifier: Modifier,
|
||||
scrollState: ScrollState = rememberScrollState(),
|
||||
width: Dp = 320.dp,
|
||||
characterSheet: CharacterSheetUio = CharacterSheetUio.Koryas,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.verticalScroll(state = scrollState)
|
||||
.padding(all = 16.dp)
|
||||
.then(other = modifier),
|
||||
verticalArrangement = Arrangement.spacedBy(space = 16.dp),
|
||||
) {
|
||||
Text(
|
||||
style = MaterialTheme.typography.h4,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = characterSheet.name,
|
||||
)
|
||||
FlowRow(
|
||||
maxItemsInEachRow = 3,
|
||||
horizontalArrangement = Arrangement.spacedBy(
|
||||
space = 16.dp,
|
||||
alignment = Alignment.CenterHorizontally,
|
||||
),
|
||||
verticalArrangement = Arrangement.spacedBy(space = 16.dp),
|
||||
) {
|
||||
characterSheet.characteristics.forEach {
|
||||
Stat(
|
||||
modifier = Modifier
|
||||
.width(width = (width - 32.dp) / 3)
|
||||
.height(height = 120.dp),
|
||||
label = it.label,
|
||||
value = it.value as? Int ?: 0,
|
||||
)
|
||||
}
|
||||
}
|
||||
DecoratedBox(
|
||||
modifier = Modifier.width(width = width),
|
||||
) {
|
||||
Column {
|
||||
Text(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
style = MaterialTheme.typography.caption,
|
||||
textAlign = TextAlign.Center,
|
||||
text = "Charactéristiques dérivées"
|
||||
)
|
||||
characterSheet.subCharacteristics.forEach {
|
||||
Characteristics(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
label = it.label,
|
||||
value = it.value,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
DecoratedBox(
|
||||
modifier = Modifier.width(width = width),
|
||||
) {
|
||||
Column {
|
||||
Text(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
style = MaterialTheme.typography.caption,
|
||||
textAlign = TextAlign.Center,
|
||||
text = "Compétences"
|
||||
)
|
||||
characterSheet.skills.forEach {
|
||||
Characteristics(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
label = it.label,
|
||||
value = it.value,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
DecoratedBox(
|
||||
modifier = Modifier.width(width = width),
|
||||
) {
|
||||
Column {
|
||||
Text(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
style = MaterialTheme.typography.caption,
|
||||
textAlign = TextAlign.Center,
|
||||
text = "Occupations"
|
||||
)
|
||||
characterSheet.occupations.forEach {
|
||||
Characteristics(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
label = it.label,
|
||||
value = it.value,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
DecoratedBox(
|
||||
modifier = Modifier.width(width = width),
|
||||
) {
|
||||
Column {
|
||||
Text(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
style = MaterialTheme.typography.caption,
|
||||
textAlign = TextAlign.Center,
|
||||
text = "Compétences magiques"
|
||||
)
|
||||
characterSheet.magics.forEach {
|
||||
Characteristics(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
label = it.label,
|
||||
value = it.value,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Stat(
|
||||
modifier: Modifier = Modifier,
|
||||
label: String,
|
||||
value: Int,
|
||||
) {
|
||||
DecoratedBox(
|
||||
modifier = modifier,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.align(alignment = Alignment.TopCenter),
|
||||
style = MaterialTheme.typography.caption,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = label,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.align(alignment = Alignment.Center),
|
||||
style = MaterialTheme.typography.h4,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
maxLines = 1,
|
||||
text = "$value"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Characteristics(
|
||||
modifier: Modifier = Modifier,
|
||||
label: String,
|
||||
value: Any,
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier,
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.typography.body1,
|
||||
text = label
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier.alignByBaseline(),
|
||||
style = MaterialTheme.typography.body1,
|
||||
fontWeight = FontWeight.Bold,
|
||||
text = "$value",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.pixelized.desktop.lwa.theme
|
||||
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.darkColors
|
||||
import androidx.compose.runtime.Composable
|
||||
|
||||
@Composable
|
||||
fun LwaTheme(
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
MaterialTheme(
|
||||
colors = darkColors(),
|
||||
typography = MaterialTheme.typography,
|
||||
shapes = MaterialTheme.shapes,
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue