commit 7a2c09314dd0a8289e663451c03bb6620096c303 Author: mac Date: Mon Mar 9 20:23:57 2026 -0400 master diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..ab69d4f --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +Play nine score \ No newline at end of file diff --git a/.idea/AndroidProjectSystem.xml b/.idea/AndroidProjectSystem.xml new file mode 100644 index 0000000..4a53bee --- /dev/null +++ b/.idea/AndroidProjectSystem.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..b86273d --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml new file mode 100644 index 0000000..b268ef3 --- /dev/null +++ b/.idea/deploymentTargetSelector.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..02c4aa5 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,18 @@ + + + + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..f0c6ad0 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,50 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..74dd639 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,10 @@ + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..16660f1 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,17 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 0000000..d318874 --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,58 @@ +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.compose) +} + +android { + namespace = "com.example.playninescore" + compileSdk { + version = release(36) { + minorApiLevel = 1 + } + } + + defaultConfig { + applicationId = "com.example.playninescore" + minSdk = 24 + targetSdk = 36 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + buildFeatures { + compose = true + } +} + +dependencies { + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.activity.compose) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.compose.ui) + implementation(libs.androidx.compose.ui.graphics) + implementation(libs.androidx.compose.ui.tooling.preview) + implementation(libs.androidx.compose.material3) + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.junit) + androidTestImplementation(libs.androidx.espresso.core) + androidTestImplementation(platform(libs.androidx.compose.bom)) + androidTestImplementation(libs.androidx.compose.ui.test.junit4) + debugImplementation(libs.androidx.compose.ui.tooling) + debugImplementation(libs.androidx.compose.ui.test.manifest) +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -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 \ No newline at end of file diff --git a/app/src/androidTest/java/com/example/playninescore/ExampleInstrumentedTest.kt b/app/src/androidTest/java/com/example/playninescore/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..f9af8a1 --- /dev/null +++ b/app/src/androidTest/java/com/example/playninescore/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.example.playninescore + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.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.example.playninescore", appContext.packageName) + } +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..bd11c3a --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/com/example/playninescore/MainActivity.kt b/app/src/main/java/com/example/playninescore/MainActivity.kt new file mode 100644 index 0000000..9d315dc --- /dev/null +++ b/app/src/main/java/com/example/playninescore/MainActivity.kt @@ -0,0 +1,438 @@ +package com.example.playninescore + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.horizontalScroll +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Add +import androidx.compose.material.icons.filled.Delete +import androidx.compose.material.icons.filled.Refresh +import androidx.compose.material.icons.filled.Star +import androidx.compose.material3.* +import androidx.compose.runtime.* +import androidx.compose.runtime.getValue +import androidx.compose.runtime.setValue +import androidx.compose.runtime.saveable.Saver +import androidx.compose.runtime.saveable.listSaver +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.focus.onFocusChanged +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Path +import androidx.compose.ui.graphics.TileMode +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.example.playninescore.ui.theme.PlayNineScoreTheme + +// Thème de couleurs Mini Golf +val GolfGreen = Color(0xFF2E7D32) +val FairwayGreen = Color(0xFF4CAF50) +val FairwayGreenDark = Color(0xFF388E3C) +val GrassLight = Color(0xFFE8F5E9) +val FlagRed = Color(0xFFD32F2F) +val GolfBallWhite = Color(0xFFF5F5F5) + +data class Player( + val name: String = "", + val scores: List = List(9) { null } +) + +val PlayerListSaver: Saver, Any> = listSaver( + save = { list -> + list.map { player -> + listOf(player.name) + player.scores.map { it ?: "" } + } + }, + restore = { restored -> + val list = restored as? List<*> + list?.map { item -> + val data = item as List<*> + Player( + name = data[0] as String, + scores = data.drop(1).map { val s = it as String; if (s.isEmpty()) null else s } + ) + } ?: emptyList() + } +) + +@Composable +fun FairwayBackground(content: @Composable () -> Unit) { + Box(modifier = Modifier.fillMaxSize()) { + // Dessin des bandes du fairway + Canvas(modifier = Modifier.fillMaxSize()) { + val stripeWidth = 80.dp.toPx() + var x = 0f + var index = 0 + while (x < size.width) { + drawRect( + color = if (index % 2 == 0) FairwayGreen else FairwayGreenDark, + topLeft = Offset(x, 0f), + size = Size(stripeWidth, size.height) + ) + x += stripeWidth + index++ + } + + // Texture d'herbe légère par-dessus + drawRect( + brush = Brush.verticalGradient( + colors = listOf(Color.Black.copy(alpha = 0.05f), Color.Transparent, Color.Black.copy(alpha = 0.05f)) + ) + ) + } + content() + } +} + +@Composable +fun GolfBallImage(modifier: Modifier = Modifier) { + Canvas(modifier = modifier.size(60.dp)) { + // Ombre portée + drawOval( + color = Color.Black.copy(alpha = 0.2f), + topLeft = Offset(size.width * 0.1f, size.height * 0.75f), + size = Size(size.width * 0.8f, size.height * 0.25f) + ) + // Corps de la balle + drawCircle(color = Color.White) + drawCircle(color = Color.LightGray, radius = size.minDimension / 2f, style = androidx.compose.ui.graphics.drawscope.Stroke(width = 1.dp.toPx())) + + // Petites alvéoles (dimples) + val rows = 5 + val cols = 5 + for (i in 1 until rows) { + for (j in 1 until cols) { + drawCircle( + color = Color.LightGray.copy(alpha = 0.3f), + radius = 2.dp.toPx(), + center = Offset(size.width * (i/rows.toFloat()), size.height * (j/cols.toFloat())) + ) + } + } + } +} + +@Composable +fun GolfFlagImage(modifier: Modifier = Modifier) { + Canvas(modifier = modifier.size(40.dp)) { + val poleWidth = 2.dp.toPx() + // Le trou + drawOval(Color.Black.copy(alpha = 0.3f), Offset(0f, size.height * 0.8f), Size(size.width, size.height * 0.2f)) + // Le mât + drawRect(Color.DarkGray, Offset(size.width/2 - poleWidth/2, 10f), Size(poleWidth, size.height * 0.85f)) + // Le drapeau + val path = Path().apply { + moveTo(size.width/2, 10f) + lineTo(size.width * 0.9f, size.height * 0.25f) + lineTo(size.width/2, size.height * 0.4f) + close() + } + drawPath(path, FlagRed) + } +} + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + setContent { + PlayNineScoreTheme { + FairwayBackground { + PlayNineApp() + } + } + } + } +} + +@Composable +fun PlayNineApp() { + var players by rememberSaveable(stateSaver = PlayerListSaver) { + mutableStateOf(listOf()) + } + var gameStarted by rememberSaveable { mutableStateOf(false) } + + Scaffold( + modifier = Modifier.fillMaxSize(), + containerColor = Color.Transparent + ) { innerPadding -> + val modifier = Modifier.padding(innerPadding) + + if (!gameStarted) { + SetupScreen( + players = players, + onPlayersChange = { players = it }, + onStartGame = { if (players.isNotEmpty()) gameStarted = true }, + modifier = modifier + ) + } else { + ScoreScreen( + players = players, + onScoresChange = { players = it }, + onReset = { + players = emptyList() + gameStarted = false + }, + modifier = modifier + ) + } + } +} + +@Composable +fun SetupScreen( + players: List, + onPlayersChange: (List) -> Unit, + onStartGame: () -> Unit, + modifier: Modifier = Modifier +) { + var newPlayerName by remember { mutableStateOf("") } + + Column( + modifier = modifier.fillMaxSize().padding(24.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + GolfBallImage() + Spacer(modifier = Modifier.height(16.dp)) + Text( + "PLAY NINE", + fontSize = 38.sp, + fontWeight = FontWeight.Black, + color = Color.White, + style = TextStyle( + shadow = androidx.compose.ui.graphics.Shadow(Color.Black, Offset(2f, 2f), 4f) + ) + ) + Text("Le compteur de score ultime", fontSize = 14.sp, color = Color.White.copy(alpha = 0.9f)) + + Spacer(modifier = Modifier.height(32.dp)) + + Card( + modifier = Modifier.fillMaxWidth(), + shape = RoundedCornerShape(16.dp), + colors = CardDefaults.cardColors(containerColor = Color.White.copy(alpha = 0.95f)), + elevation = CardDefaults.cardElevation(8.dp) + ) { + Row( + modifier = Modifier.padding(8.dp), + verticalAlignment = Alignment.CenterVertically + ) { + TextField( + value = newPlayerName, + onValueChange = { newPlayerName = it }, + placeholder = { Text("Nom du joueur...") }, + colors = TextFieldDefaults.colors( + focusedContainerColor = Color.Transparent, + unfocusedContainerColor = Color.Transparent, + focusedIndicatorColor = GolfGreen + ), + modifier = Modifier.weight(1f), + singleLine = true + ) + IconButton( + onClick = { + if (newPlayerName.isNotBlank() && players.size < 6) { + onPlayersChange(players + Player(name = newPlayerName)) + newPlayerName = "" + } + }, + colors = IconButtonDefaults.iconButtonColors(contentColor = GolfGreen) + ) { + Icon(Icons.Default.Add, contentDescription = "Ajouter") + } + } + } + + Spacer(modifier = Modifier.height(24.dp)) + + Box(modifier = Modifier.weight(1f, fill = false).padding(vertical = 8.dp)) { + LazyColumn( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + itemsIndexed(players) { index, player -> + Card( + modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp), + shape = RoundedCornerShape(12.dp), + colors = CardDefaults.cardColors(containerColor = Color.White.copy(alpha = 0.85f)) + ) { + ListItem( + headlineContent = { Text(player.name, fontWeight = FontWeight.Bold, color = GolfGreen) }, + leadingContent = { + Box(Modifier.size(32.dp).background(GolfGreen, CircleShape), contentAlignment = Alignment.Center) { + Text("${index + 1}", color = Color.White, fontSize = 12.sp) + } + }, + trailingContent = { + IconButton(onClick = { + val list = players.toMutableList() + list.removeAt(index) + onPlayersChange(list) + }) { + Icon(Icons.Default.Delete, contentDescription = "Supprimer", tint = FlagRed) + } + }, + colors = ListItemDefaults.colors(containerColor = Color.Transparent) + ) + } + } + } + } + + Spacer(modifier = Modifier.height(16.dp)) + + Button( + onClick = onStartGame, + modifier = Modifier.fillMaxWidth().height(60.dp), + enabled = players.isNotEmpty(), + colors = ButtonDefaults.buttonColors(containerColor = GolfGreen), + shape = RoundedCornerShape(16.dp), + elevation = ButtonDefaults.buttonElevation(4.dp) + ) { + Text("ENTRER SUR LE GREEN", fontSize = 18.sp, fontWeight = FontWeight.Black) + } + } +} + +@Composable +fun ScoreScreen( + players: List, + onScoresChange: (List) -> Unit, + onReset: () -> Unit, + modifier: Modifier = Modifier +) { + val scrollState = rememberScrollState() + val holeW = 60.dp + val playerW = 100.dp + + Column( + modifier = modifier.fillMaxSize().padding(12.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.SpaceBetween + ) { + // En-tête + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Row(verticalAlignment = Alignment.CenterVertically) { + GolfFlagImage(Modifier.size(35.dp)) + Spacer(Modifier.width(8.dp)) + Text( + "Scorecard", + fontSize = 28.sp, + fontWeight = FontWeight.Black, + color = Color.White, + style = TextStyle( + shadow = androidx.compose.ui.graphics.Shadow(Color.Black, Offset(2f, 2f), 4f) + ) + ) + } + IconButton( + onClick = onReset, + colors = IconButtonDefaults.iconButtonColors(containerColor = Color.White.copy(alpha = 0.2f)) + ) { + Icon(Icons.Default.Refresh, contentDescription = "Reset", tint = Color.White) + } + } + + // Centre de l'écran : La Card de score + Box( + modifier = Modifier.weight(1f).fillMaxWidth(), + contentAlignment = Alignment.Center + ) { + Card( + modifier = Modifier.wrapContentHeight().fillMaxWidth(), + shape = RoundedCornerShape(16.dp), + colors = CardDefaults.cardColors(containerColor = Color.White.copy(alpha = 0.95f)), + elevation = CardDefaults.cardElevation(8.dp) + ) { + Box(modifier = Modifier.horizontalScroll(scrollState)) { + Column { + // Header du tableau + Row(modifier = Modifier.background(GolfGreen).padding(vertical = 10.dp)) { + Text("Trou", Modifier.width(holeW), color = Color.White, textAlign = TextAlign.Center, fontWeight = FontWeight.Black) + players.forEach { player -> + Text(player.name, Modifier.width(playerW), color = Color.White, textAlign = TextAlign.Center, fontWeight = FontWeight.Black, maxLines = 1) + } + } + + // Contenu (Scrollable verticalement seulement si nécessaire) + val verticalScrollState = rememberScrollState() + Column(modifier = Modifier.verticalScroll(verticalScrollState)) { + for (hIdx in 0 until 9) { + val isEven = hIdx % 2 == 0 + Row( + modifier = Modifier.background(if (isEven) Color.Transparent else GolfGreen.copy(alpha = 0.05f)), + verticalAlignment = Alignment.CenterVertically + ) { + Text("${hIdx + 1}", Modifier.width(holeW).padding(vertical = 16.dp), textAlign = TextAlign.Center, fontWeight = FontWeight.ExtraBold, color = GolfGreen) + players.forEachIndexed { pIdx, player -> + var isFocused by remember { mutableStateOf(false) } + Box( + modifier = Modifier.width(playerW).height(55.dp) + .background(if (isFocused) FairwayGreen.copy(alpha = 0.2f) else Color.Transparent) + .border(0.5.dp, Color.LightGray.copy(alpha = 0.3f)), + contentAlignment = Alignment.Center + ) { + BasicTextField( + value = player.scores[hIdx] ?: "", + onValueChange = { nv -> + if (nv.isEmpty() || nv == "-" || nv.toIntOrNull() != null) { + val upP = players.toMutableList() + val upS = player.scores.toMutableList() + upS[hIdx] = nv + upP[pIdx] = player.copy(scores = upS) + onScoresChange(upP) + } + }, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), + textStyle = TextStyle(textAlign = TextAlign.Center, fontSize = 20.sp, fontWeight = FontWeight.Bold, color = if(isFocused) GolfGreen else Color.DarkGray), + modifier = Modifier.fillMaxWidth().onFocusChanged { isFocused = it.isFocused }, + singleLine = true + ) + } + } + } + } + + // Total Row + Row(modifier = Modifier.background(FairwayGreen).padding(vertical = 14.dp)) { + Text("TOTAL", Modifier.width(holeW), color = Color.White, textAlign = TextAlign.Center, fontWeight = FontWeight.Black) + players.forEach { player -> + val total = player.scores.sumOf { it?.toIntOrNull() ?: 0 } + Text("$total", Modifier.width(playerW), color = Color.White, textAlign = TextAlign.Center, fontWeight = FontWeight.Black, fontSize = 22.sp) + } + } + } + } + } + } + } + } +} diff --git a/app/src/main/java/com/example/playninescore/ui/theme/Color.kt b/app/src/main/java/com/example/playninescore/ui/theme/Color.kt new file mode 100644 index 0000000..ba12a22 --- /dev/null +++ b/app/src/main/java/com/example/playninescore/ui/theme/Color.kt @@ -0,0 +1,11 @@ +package com.example.playninescore.ui.theme + +import androidx.compose.ui.graphics.Color + +val Purple80 = Color(0xFFD0BCFF) +val PurpleGrey80 = Color(0xFFCCC2DC) +val Pink80 = Color(0xFFEFB8C8) + +val Purple40 = Color(0xFF6650a4) +val PurpleGrey40 = Color(0xFF625b71) +val Pink40 = Color(0xFF7D5260) \ No newline at end of file diff --git a/app/src/main/java/com/example/playninescore/ui/theme/Theme.kt b/app/src/main/java/com/example/playninescore/ui/theme/Theme.kt new file mode 100644 index 0000000..7a3f520 --- /dev/null +++ b/app/src/main/java/com/example/playninescore/ui/theme/Theme.kt @@ -0,0 +1,58 @@ +package com.example.playninescore.ui.theme + +import android.app.Activity +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext + +private val DarkColorScheme = darkColorScheme( + primary = Purple80, + secondary = PurpleGrey80, + tertiary = Pink80 +) + +private val LightColorScheme = lightColorScheme( + primary = Purple40, + secondary = PurpleGrey40, + tertiary = Pink40 + + /* Other default colors to override + background = Color(0xFFFFFBFE), + surface = Color(0xFFFFFBFE), + onPrimary = Color.White, + onSecondary = Color.White, + onTertiary = Color.White, + onBackground = Color(0xFF1C1B1F), + onSurface = Color(0xFF1C1B1F), + */ +) + +@Composable +fun PlayNineScoreTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = true, + content: @Composable () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/example/playninescore/ui/theme/Type.kt b/app/src/main/java/com/example/playninescore/ui/theme/Type.kt new file mode 100644 index 0000000..8cf88f9 --- /dev/null +++ b/app/src/main/java/com/example/playninescore/ui/theme/Type.kt @@ -0,0 +1,34 @@ +package com.example.playninescore.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp + ) + /* Other default text styles to override + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp + ) + */ +) \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..d4eab7c --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,15 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..37fd053 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000..c209e78 Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000..b2dfe3d Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000..4f0f1d6 Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000..62b611d Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000..948a307 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..1b9a695 Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000..28d4b77 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9287f50 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000..aa7d642 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9126ae3 Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..f8c6127 --- /dev/null +++ b/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..54dc5a8 --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Play nine score + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..3bcec82 --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,5 @@ + + + +