Initial commit

This commit is contained in:
Thomas Andres Gomez 2024-11-02 08:17:11 +01:00
commit 9ddd6018fd
18 changed files with 931 additions and 0 deletions

View 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"
}
}
}

View file

@ -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>

View file

@ -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
)
}
}
}
}

View file

@ -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")
}
}
}
}

View file

@ -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()
}
}

View file

@ -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",
)
}
}

View file

@ -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,
)
}