Fix windows management by introducting key()

This commit is contained in:
Thomas Andres Gomez 2024-11-27 11:36:53 +01:00
parent 51021d41d5
commit f8168a8997
32 changed files with 420 additions and 59 deletions

View file

@ -17,7 +17,8 @@
<string name="roll_page__dc_hard__label">Difficile</string> <string name="roll_page__dc_hard__label">Difficile</string>
<string name="roll_page__dc_impossible__label">Impossible</string> <string name="roll_page__dc_impossible__label">Impossible</string>
<string name="character_sheet_edit__title">Création de personnage</string> <string name="character_sheet_edit__create__title">Création de personnage</string>
<string name="character_sheet_edit__edit__title">Édition de personnage</string>
<string name="character_sheet_edit__name_placeholder">Nom</string> <string name="character_sheet_edit__name_placeholder">Nom</string>
<string name="character_sheet_edit__add_roll_action">Ajouter une action</string> <string name="character_sheet_edit__add_roll_action">Ajouter une action</string>
<string name="character_sheet_edit__save_action">Sauvegarder</string> <string name="character_sheet_edit__save_action">Sauvegarder</string>
@ -67,7 +68,6 @@
<string name="character_sheet_edit__delete__label">Supprimer</string> <string name="character_sheet_edit__delete__label">Supprimer</string>
<string name="character_sheet_edit__occupation__label">Compétence d'occupation</string> <string name="character_sheet_edit__occupation__label">Compétence d'occupation</string>
<string name="character_sheet__diminished__label">État diminuer</string> <string name="character_sheet__diminished__label">État diminuer</string>
<string name="character_sheet__edit__label">Modifier</string> <string name="character_sheet__edit__label">Modifier</string>
<string name="character_sheet__delete__label">Supprimer</string> <string name="character_sheet__delete__label">Supprimer</string>

View file

@ -143,7 +143,7 @@ private fun WindowsHandler(
is CharacterSheetCreateWindow -> CharacterSheetMainNavHost( is CharacterSheetCreateWindow -> CharacterSheetMainNavHost(
startDestination = CharacterSheetEditDestination.navigationRoute( startDestination = CharacterSheetEditDestination.navigationRoute(
id = null, id = window.sheetId,
enableBack = false, enableBack = false,
), ),
) )

View file

@ -5,21 +5,27 @@ import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.runtime.compositionLocalOf import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.window.Window import androidx.compose.ui.window.Window
import androidx.compose.ui.window.WindowState
import androidx.compose.ui.window.rememberWindowState
import com.pixelized.desktop.lwa.navigation.window.destination.Window import com.pixelized.desktop.lwa.navigation.window.destination.Window
val LocalWindow = compositionLocalOf<Window> { val LocalWindow = compositionLocalOf<Window> {
error("Local Window is not yet ready") error("Local Window is not yet ready")
} }
val LocalWindowState = compositionLocalOf<WindowState> {
error("Local Window state is not yet ready")
}
@Stable @Stable
class WindowController { class WindowController {
private val _windows = mutableStateOf<Set<Window>>(emptySet()) private val _windows = mutableStateOf<Map<String, Window>>(emptyMap())
val windows: State<Set<Window>> get() = _windows val windows: State<Map<String, Window>> get() = _windows
fun showWindow(window: Window) { fun showWindow(window: Window) {
_windows.value = _windows.value.toMutableSet().apply { add(window) } _windows.value = _windows.value.toMutableMap().apply { this[window.id] = window }
} }
fun hideWindow(window: Window) { fun hideWindow(window: Window) {
@ -27,7 +33,7 @@ class WindowController {
} }
fun hideWindow(id: String) { fun hideWindow(id: String) {
_windows.value = _windows.value.toMutableSet().apply { removeIf { it.id == id } } _windows.value = _windows.value.toMutableMap().apply { this.remove(id) }
} }
} }
@ -36,16 +42,20 @@ fun WindowsNavHost(
controller: WindowController, controller: WindowController,
content: @Composable (Window) -> Unit, content: @Composable (Window) -> Unit,
) { ) {
controller.windows.value.forEach { window -> controller.windows.value.forEach { (id, window) ->
CompositionLocalProvider( key(id) {
LocalWindow provides window, val state = rememberWindowState(size = window.size)
) { CompositionLocalProvider(
Window( LocalWindow provides window,
onCloseRequest = { controller.hideWindow(id = window.id) }, LocalWindowState provides state,
state = window.state,
title = window.title,
) { ) {
content.invoke(window) Window(
onCloseRequest = { controller.hideWindow(id = window.id) },
state = state,
title = window.title,
) {
content.invoke(window)
}
} }
} }
} }

View file

@ -5,8 +5,11 @@ import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@Stable @Stable
class CharacterSheetCreateWindow : Window( class CharacterSheetCreateWindow(
title = "", title: String,
val sheetId: String?,
) : Window(
title = title,
size = size, size = size,
) { ) {
companion object { companion object {

View file

@ -1,32 +1,12 @@
package com.pixelized.desktop.lwa.navigation.window.destination package com.pixelized.desktop.lwa.navigation.window.destination
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.window.WindowPlacement
import androidx.compose.ui.window.WindowPosition
import androidx.compose.ui.window.WindowState
import java.util.UUID import java.util.UUID
@Stable @Stable
sealed class Window( sealed class Window(
val id: String = UUID.randomUUID().toString(), val id: String = UUID.randomUUID().toString(),
val title: String, val title: String,
size: DpSize, val size: DpSize,
) { )
val state = WindowState(
placement = WindowPlacement.Floating,
isMinimized = false,
position = WindowPosition.PlatformDefault,
width = size.width,
height = size.height,
)
val width: Dp get() = state.size.width
val height: Dp get() = state.size.height
val size: DpSize get() = state.size
suspend fun resize(size: DpSize) {
state.size = size
}
}

View file

@ -41,7 +41,6 @@ import androidx.compose.material.icons.filled.Delete
import androidx.compose.material.icons.filled.Edit import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.MoreVert import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
@ -60,15 +59,15 @@ import com.pixelized.desktop.lwa.composable.decoratedBox.DecoratedBox
import com.pixelized.desktop.lwa.composable.tooltip.TooltipLayout import com.pixelized.desktop.lwa.composable.tooltip.TooltipLayout
import com.pixelized.desktop.lwa.composable.tooltip.TooltipUio import com.pixelized.desktop.lwa.composable.tooltip.TooltipUio
import com.pixelized.desktop.lwa.navigation.screen.LocalScreenController import com.pixelized.desktop.lwa.navigation.screen.LocalScreenController
import com.pixelized.desktop.lwa.navigation.screen.destination.navigateToCharacterSheetEdit
import com.pixelized.desktop.lwa.navigation.window.LocalWindow import com.pixelized.desktop.lwa.navigation.window.LocalWindow
import com.pixelized.desktop.lwa.navigation.window.destination.CharacterSheetWindow import com.pixelized.desktop.lwa.navigation.window.destination.CharacterSheetCreateWindow
import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.CharacterSheetDeleteConfirmationDialog import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.CharacterSheetDeleteConfirmationDialog
import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.CharacterSheetStatDialog import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.CharacterSheetStatDialog
import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.DiminishedStatDialog import com.pixelized.desktop.lwa.screen.characterSheet.detail.dialog.DiminishedStatDialog
import com.pixelized.desktop.lwa.screen.roll.RollPage import com.pixelized.desktop.lwa.screen.roll.RollPage
import com.pixelized.desktop.lwa.screen.roll.RollViewModel import com.pixelized.desktop.lwa.screen.roll.RollViewModel
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import lwacharactersheet.composeapp.generated.resources.Res import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.character_sheet__delete__label import lwacharactersheet.composeapp.generated.resources.character_sheet__delete__label
import lwacharactersheet.composeapp.generated.resources.character_sheet__edit__label import lwacharactersheet.composeapp.generated.resources.character_sheet__edit__label
@ -76,8 +75,10 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet__skills_
import lwacharactersheet.composeapp.generated.resources.character_sheet__skills__magic_title import lwacharactersheet.composeapp.generated.resources.character_sheet__skills__magic_title
import lwacharactersheet.composeapp.generated.resources.character_sheet__skills__special_title import lwacharactersheet.composeapp.generated.resources.character_sheet__skills__special_title
import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__title import lwacharactersheet.composeapp.generated.resources.character_sheet__sub_characteristics__title
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__edit__title
import lwacharactersheet.composeapp.generated.resources.ic_d20_32dp import lwacharactersheet.composeapp.generated.resources.ic_d20_32dp
import lwacharactersheet.composeapp.generated.resources.ic_skull_32dp import lwacharactersheet.composeapp.generated.resources.ic_skull_32dp
import org.jetbrains.compose.resources.getString
import org.jetbrains.compose.resources.painterResource import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel
@ -128,10 +129,6 @@ fun CharacterSheetPage(
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val blurController = remember { BlurContentController() } val blurController = remember { BlurContentController() }
LaunchedEffect(Unit) {
window.resize(size = CharacterSheetWindow.size)
}
Surface( Surface(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
) { ) {
@ -150,9 +147,11 @@ fun CharacterSheetPage(
} }
}, },
onEdit = { onEdit = {
screen.navigateToCharacterSheetEdit( windowController.showWindow(
id = sheet.id, window = CharacterSheetCreateWindow(
enableBack = true, title = runBlocking { getString(Res.string.character_sheet_edit__edit__title) },
sheetId = sheet.id,
),
) )
}, },
onDelete = { onDelete = {

View file

@ -21,7 +21,6 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Add
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.Stable import androidx.compose.runtime.Stable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
@ -33,7 +32,6 @@ import com.pixelized.desktop.lwa.LocalWindowController
import com.pixelized.desktop.lwa.composable.decoratedBox.DecoratedBox import com.pixelized.desktop.lwa.composable.decoratedBox.DecoratedBox
import com.pixelized.desktop.lwa.navigation.screen.LocalScreenController import com.pixelized.desktop.lwa.navigation.screen.LocalScreenController
import com.pixelized.desktop.lwa.navigation.window.LocalWindow import com.pixelized.desktop.lwa.navigation.window.LocalWindow
import com.pixelized.desktop.lwa.navigation.window.destination.CharacterSheetCreateWindow
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.BaseSkillFieldUio import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.BaseSkillFieldUio
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.BaseSkillForm import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.BaseSkillForm
import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.FieldUio import com.pixelized.desktop.lwa.screen.characterSheet.edit.composable.FieldUio
@ -51,7 +49,6 @@ import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sa
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__magic_action import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__magic_action
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__special_action import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__skills__special_action
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__title import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__sub_characteristics__title
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__title
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel
@ -106,14 +103,11 @@ fun CharacterSheetEditPage(
val screen = LocalScreenController.current val screen = LocalScreenController.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
LaunchedEffect(Unit) {
window.resize(size = CharacterSheetCreateWindow.size)
}
Surface( Surface(
modifier = Modifier.fillMaxSize(), modifier = Modifier.fillMaxSize(),
) { ) {
CharacterSheetEdit( CharacterSheetEdit(
title = window.title,
form = viewModel.characterSheet.value, form = viewModel.characterSheet.value,
onBack = remember { onBack = remember {
if (viewModel.enableBack) { if (viewModel.enableBack) {
@ -151,6 +145,8 @@ fun CharacterSheetEditPage(
@Composable @Composable
fun CharacterSheetEdit( fun CharacterSheetEdit(
modifier: Modifier = Modifier,
title: String,
form: CharacterSheetEditPageUio, form: CharacterSheetEditPageUio,
onBack: (() -> Unit)?, onBack: (() -> Unit)?,
onNewSpecialSkill: () -> Unit, onNewSpecialSkill: () -> Unit,
@ -159,13 +155,14 @@ fun CharacterSheetEdit(
onSave: () -> Unit, onSave: () -> Unit,
) { ) {
Scaffold( Scaffold(
modifier = modifier,
topBar = { topBar = {
TopAppBar( TopAppBar(
title = { title = {
Text( Text(
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
maxLines = 1, maxLines = 1,
text = stringResource(Res.string.character_sheet_edit__title), text = title,
) )
}, },
navigationIcon = onBack?.let { action: () -> Unit -> navigationIcon = onBack?.let { action: () -> Unit ->

View file

@ -25,10 +25,13 @@ import com.pixelized.desktop.lwa.navigation.screen.destination.navigateToNetwork
import com.pixelized.desktop.lwa.navigation.screen.destination.navigateToRollHistory import com.pixelized.desktop.lwa.navigation.screen.destination.navigateToRollHistory
import com.pixelized.desktop.lwa.navigation.window.destination.CharacterSheetCreateWindow import com.pixelized.desktop.lwa.navigation.window.destination.CharacterSheetCreateWindow
import com.pixelized.desktop.lwa.navigation.window.destination.CharacterSheetWindow import com.pixelized.desktop.lwa.navigation.window.destination.CharacterSheetWindow
import kotlinx.coroutines.runBlocking
import lwacharactersheet.composeapp.generated.resources.Res import lwacharactersheet.composeapp.generated.resources.Res
import lwacharactersheet.composeapp.generated.resources.character_sheet_edit__create__title
import lwacharactersheet.composeapp.generated.resources.main_page__create_action import lwacharactersheet.composeapp.generated.resources.main_page__create_action
import lwacharactersheet.composeapp.generated.resources.main_page__network_action import lwacharactersheet.composeapp.generated.resources.main_page__network_action
import lwacharactersheet.composeapp.generated.resources.main_page__roll_history_action import lwacharactersheet.composeapp.generated.resources.main_page__roll_history_action
import org.jetbrains.compose.resources.getString
import org.jetbrains.compose.resources.stringResource import org.jetbrains.compose.resources.stringResource
import org.koin.compose.viewmodel.koinViewModel import org.koin.compose.viewmodel.koinViewModel
@ -66,7 +69,12 @@ fun MainPage(
) )
}, },
onCreateCharacter = { onCreateCharacter = {
window.showWindow(window = CharacterSheetCreateWindow()) window.showWindow(
window = CharacterSheetCreateWindow(
title = runBlocking { getString(Res.string.character_sheet_edit__create__title) },
sheetId = null,
)
)
}, },
onRollHistory = { onRollHistory = {
screen.navigateToRollHistory() screen.navigateToRollHistory()

1
server/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

44
server/build.gradle.kts Normal file
View file

@ -0,0 +1,44 @@
plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.kotlinAndroid)
}
android {
namespace = "com.pixelized.server"
compileSdk = 34
defaultConfig {
applicationId = "com.pixelized.server"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
implementation(libs.appcompat.v7)
testImplementation(libs.junit)
androidTestImplementation(libs.runner)
androidTestImplementation(libs.espresso.core)
}

21
server/proguard-rules.pro vendored Normal file
View file

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View file

@ -0,0 +1,24 @@
package com.pixelized.server
import android.support.test.InstrumentationRegistry
import android.support.test.runner.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.pixelized.server", appContext.packageName)
}
}

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.LwaCharacterSheet" />
</manifest>

View file

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

View file

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View file

@ -0,0 +1,10 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.LwaCharacterSheet" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_200</item>
<item name="colorPrimaryDark">@color/purple_700</item>
<item name="colorAccent">@color/teal_200</item>
<!-- Customize your theme here. -->
</style>
</resources>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>

View file

@ -0,0 +1,3 @@
<resources>
<string name="app_name">server</string>
</resources>

View file

@ -0,0 +1,10 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.LwaCharacterSheet" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryDark">@color/purple_700</item>
<item name="colorAccent">@color/teal_200</item>
<!-- Customize your theme here. -->
</style>
</resources>

View file

@ -0,0 +1,17 @@
package com.pixelized.server
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}