diff --git a/Android/app/build.gradle.kts b/Android/app/build.gradle.kts index a23ba30..35844c1 100644 --- a/Android/app/build.gradle.kts +++ b/Android/app/build.gradle.kts @@ -59,6 +59,7 @@ dependencies { implementation("androidx.compose.ui:ui-graphics") implementation("androidx.compose.ui:ui-tooling-preview") implementation("androidx.compose.material3:material3") + implementation("androidx.compose.ui:ui-graphics-android:1.6.3") testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.5") androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") diff --git a/Android/app/src/main/AndroidManifest.xml b/Android/app/src/main/AndroidManifest.xml index 576e266..f8c1bf6 100644 --- a/Android/app/src/main/AndroidManifest.xml +++ b/Android/app/src/main/AndroidManifest.xml @@ -2,6 +2,8 @@ + + - diff --git a/Android/app/src/main/java/com/example/mathseduc/ConnexionPlayerActivity.kt b/Android/app/src/main/java/com/example/mathseduc/ConnexionPlayerActivity.kt new file mode 100644 index 0000000..eb9cff8 --- /dev/null +++ b/Android/app/src/main/java/com/example/mathseduc/ConnexionPlayerActivity.kt @@ -0,0 +1,189 @@ +package com.example.mathseduc + +import android.os.Bundle +import android.widget.Toast +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.PasswordVisualTransformation +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.example.mathseduc.controllers.ControllerPlayer +import com.example.mathseduc.ui.theme.MathsEducTheme + + +class ConnexionPlayerActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + MathsEducTheme { + ConnexionPlayerContent() + } + } + } +} + +@Composable +fun ConnexionPlayerContent() { + var nickname by remember { mutableStateOf("") } + var password by remember { mutableStateOf("") } + var showDialog by remember { mutableStateOf(false) } + + val context = LocalContext.current + + Column( + modifier = Modifier + .fillMaxSize() + .padding(16.dp), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Image( + painter = painterResource(id = R.drawable.logo), + contentDescription = null, + modifier = Modifier + .size(160.dp, 130.dp) + .background(Color.Gray) // Replace with your background color + ) + + Spacer(modifier = Modifier.height(16.dp)) + + OutlinedTextField( + value = nickname, + onValueChange = { nickname = it }, + label = { Text("Nickname") }, + modifier = Modifier + .fillMaxWidth() + .padding(8.dp) + ) + + OutlinedTextField( + value = password, + onValueChange = { password = it }, + label = { Text("Password") }, + visualTransformation = PasswordVisualTransformation(), + keyboardOptions = KeyboardOptions.Default.copy( + keyboardType = KeyboardType.Password + ), + modifier = Modifier + .fillMaxWidth() + .padding(8.dp) + ) + + Spacer(modifier = Modifier.height(16.dp)) + + Button( + onClick = { + val isAuthenticated = ControllerPlayer.authenticateUser(nickname, password) + if (isAuthenticated != -1) { + MainActivity.idPlayerConnected = isAuthenticated + Toast.makeText(context, "Connexion réussie, bienvenue $nickname !", Toast.LENGTH_SHORT).show() + } else { + Toast.makeText(context, "Connexion échouée. Veuillez réessayer.", Toast.LENGTH_SHORT).show() + } + }, + modifier = Modifier + .fillMaxWidth() + .height(48.dp) + ) { + Text("Login") + } + + Spacer(modifier = Modifier.height(16.dp)) + + Button( + onClick = { showDialog = true }, + modifier = Modifier + .fillMaxWidth() + .height(48.dp) + ) { + Text("Register") + } + + if (showDialog) { + RegisterDialog(onDismiss = { showDialog = false }) + } + } +} + +@Composable +fun RegisterDialog(onDismiss: () -> Unit) { + val context = LocalContext.current + + var nickname by remember { mutableStateOf("") } + var password by remember { mutableStateOf("") } + + AlertDialog( + onDismissRequest = { + onDismiss() + }, + title = { Text("Register") }, + confirmButton = { + Button( + onClick = { + // Save the user information or perform registration + onDismiss() + } + ) { + Text("Save") + } + }, + dismissButton = { + Button( + onClick = { + onDismiss() + } + ) { + Text("Dismiss") + } + }, + text = { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(8.dp) + ) { + OutlinedTextField( + value = nickname, + onValueChange = { nickname = it }, + label = { Text("Nickname") }, + modifier = Modifier + .fillMaxWidth() + .padding(8.dp) + ) + + OutlinedTextField( + value = password, + onValueChange = { password = it }, + label = { Text("Password") }, + visualTransformation = PasswordVisualTransformation(), + keyboardOptions = KeyboardOptions.Default.copy( + keyboardType = KeyboardType.Password + ), + modifier = Modifier + .fillMaxWidth() + .padding(8.dp) + ) + } + } + ) +} + +@Preview(showBackground = true) +@Composable +fun ConnexionPlayerPreview() { + MathsEducTheme { + ConnexionPlayerContent() + } +} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/mathseduc/CreateLobbyActivity.kt b/Android/app/src/main/java/com/example/mathseduc/CreateLobbyActivity.kt new file mode 100644 index 0000000..1ce1046 --- /dev/null +++ b/Android/app/src/main/java/com/example/mathseduc/CreateLobbyActivity.kt @@ -0,0 +1,4 @@ +package com.example.mathseduc.ui + +class CreateLobbyActivity { +} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/mathseduc/MainActivity.kt b/Android/app/src/main/java/com/example/mathseduc/MainActivity.kt index b86de44..5ed91fc 100644 --- a/Android/app/src/main/java/com/example/mathseduc/MainActivity.kt +++ b/Android/app/src/main/java/com/example/mathseduc/MainActivity.kt @@ -3,113 +3,29 @@ package com.example.mathseduc import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.* import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import com.example.mathseduc.ui.theme.Colors +import com.example.mathseduc.ui.HomePage import com.example.mathseduc.ui.theme.MathsEducTheme class MainActivity : ComponentActivity() { + companion object { + var idPlayerConnected: Int = -1 + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { MathsEducTheme { - MainActivityContent() + HomePage() } } } } -@Composable -fun MainActivityContent() { - val modifier = Modifier - .fillMaxSize() - .padding(16.dp) - - Column( - modifier = modifier, - verticalArrangement = Arrangement.Center, - horizontalAlignment = Alignment.CenterHorizontally - ) { - Image( - painter = painterResource(id = R.drawable.logo), - contentDescription = null, - modifier = Modifier - .size(160.dp, 130.dp) - .clip(RoundedCornerShape(8.dp)) - ) - - Spacer(modifier = Modifier.height(16.dp)) - - Button( - onClick = { /* Handle solo button click */ }, - shape = RoundedCornerShape(15), - colors = ButtonDefaults.buttonColors(Colors.Green), - modifier = Modifier - .fillMaxWidth() - .height(48.dp) - - ) { - Text( - text = "Solo", - color = Color.White, - fontWeight = FontWeight.Bold - ) - } - - Spacer(modifier = Modifier.height(16.dp)) - - Button( - onClick = { /* Handle multi button click */ }, - shape = RoundedCornerShape(15), - colors = ButtonDefaults.buttonColors(Colors.Orange), - modifier = Modifier - .fillMaxWidth() - .height(48.dp) - ) { - Text( - text = "Multiplayer", - color = Color.White, - fontWeight = FontWeight.Bold - ) - } - - Spacer(modifier = Modifier.height(16.dp)) - - Button( - onClick = { /* Handle connexion button click */ }, - shape = RoundedCornerShape(15), - colors = ButtonDefaults.buttonColors(Colors.Grey), - modifier = Modifier - .fillMaxWidth() - .height(48.dp) - .padding(horizontal = 16.dp) - ) { - Text( - text = "Connexion", - color = Color.White - ) - } - } -} - @Preview(showBackground = true) @Composable -fun DefaultPreview() { - MathsEducTheme { - MainActivityContent() - } +fun MainActivityPreview() { + MainActivity() } \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/mathseduc/MultiActivity.kt b/Android/app/src/main/java/com/example/mathseduc/MultiActivity.kt new file mode 100644 index 0000000..f56166b --- /dev/null +++ b/Android/app/src/main/java/com/example/mathseduc/MultiActivity.kt @@ -0,0 +1,27 @@ +package com.example.mathseduc + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.runtime.Composable +import androidx.compose.ui.tooling.preview.Preview +import com.example.mathseduc.ui.MultiPage +import com.example.mathseduc.ui.theme.MathsEducTheme + + +class MultiActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + MultiPage() + } + } +} + +@Preview(showBackground = true) +@Composable +fun MultiPreview() { + MathsEducTheme { + MultiPage() + } +} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/mathseduc/ui/activity_create_lobby.kt b/Android/app/src/main/java/com/example/mathseduc/ui/activity_create_lobby.kt new file mode 100644 index 0000000..a9f6aa3 --- /dev/null +++ b/Android/app/src/main/java/com/example/mathseduc/ui/activity_create_lobby.kt @@ -0,0 +1,2 @@ +package com.example.mathseduc.ui + diff --git a/Android/app/src/main/java/com/example/mathseduc/ui/activity_main.kt b/Android/app/src/main/java/com/example/mathseduc/ui/activity_main.kt new file mode 100644 index 0000000..edc16f2 --- /dev/null +++ b/Android/app/src/main/java/com/example/mathseduc/ui/activity_main.kt @@ -0,0 +1,116 @@ +package com.example.mathseduc.ui + +import android.content.Intent +import android.widget.Toast +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import com.example.mathseduc.ConnexionPlayerActivity +import com.example.mathseduc.MainActivity +import com.example.mathseduc.MultiActivity +import com.example.mathseduc.R +import com.example.mathseduc.ui.theme.Colors + + +@Composable +fun HomePage() { + val context = LocalContext.current + val modifier = Modifier + .fillMaxSize() + .padding(16.dp) + + Column( + modifier = modifier, + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Image( + painter = painterResource(id = R.drawable.logo), + contentDescription = null, + modifier = Modifier + .size(160.dp, 130.dp) + .clip(RoundedCornerShape(8.dp)) + ) + + Spacer(modifier = Modifier.height(16.dp)) + + Button( + onClick = { /* Handle solo button click */ }, + shape = RoundedCornerShape(15), + colors = ButtonDefaults.buttonColors(Colors.Green), + modifier = Modifier + .fillMaxWidth() + .height(48.dp) + + ) { + Text( + text = "Solo", + color = Color.White, + fontWeight = FontWeight.Bold + ) + } + + Spacer(modifier = Modifier.height(16.dp)) + + Button( + onClick = { + if (MainActivity.idPlayerConnected != -1){ + val intent = Intent(context, MultiActivity::class.java) + context.startActivity(intent) + } + else { + Toast.makeText(context, "Vous n'êtes pas connecté", Toast.LENGTH_SHORT).show() + val intent = Intent(context, ConnexionPlayerActivity::class.java) + context.startActivity(intent) + } + }, + shape = RoundedCornerShape(15), + colors = ButtonDefaults.buttonColors(Colors.Orange), + modifier = Modifier + .fillMaxWidth() + .height(48.dp) + ) { + Text( + text = "Multiplayer", + color = Color.White, + fontWeight = FontWeight.Bold + ) + } + + Spacer(modifier = Modifier.height(16.dp)) + + Button( + onClick = { /* Handle connexion button click */ }, + shape = RoundedCornerShape(15), + colors = ButtonDefaults.buttonColors(Colors.Grey), + modifier = Modifier + .fillMaxWidth() + .height(48.dp) + .padding(horizontal = 16.dp) + ) { + Text( + text = "Connexion", + color = Color.White + ) + } + } +} \ No newline at end of file diff --git a/Android/app/src/main/java/com/example/mathseduc/ui/activity_multi.kt b/Android/app/src/main/java/com/example/mathseduc/ui/activity_multi.kt new file mode 100644 index 0000000..967ec87 --- /dev/null +++ b/Android/app/src/main/java/com/example/mathseduc/ui/activity_multi.kt @@ -0,0 +1,177 @@ +package com.example.mathseduc.ui +import android.content.Intent +import android.os.Handler +import android.os.Looper +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.ArrowBack +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.example.mathseduc.CreateLobbyActivity +import com.example.mathseduc.MainActivity +import com.example.mathseduc.controllers.ControllerChapter +import com.example.mathseduc.controllers.ControllerLobby +import com.example.mathseduc.models.Lobby +import com.example.mathseduc.ui.theme.Colors + + +@Composable +fun MultiPage() { + val context = LocalContext.current + var selectedItem by remember { mutableStateOf(null) } + + var lobbyList by remember { mutableStateOf(ControllerLobby.getLobbies() ?: emptyList()) } + var refreshState by remember { mutableStateOf(true) } + + DisposableEffect(refreshState) { + val handler = Handler(Looper.getMainLooper()) + val refreshRunnable = object : Runnable { + override fun run() { + lobbyList = ControllerLobby.getLobbies()!! + selectedItem = null + handler.postDelayed(this, 3000) + } + } + + handler.postDelayed(refreshRunnable, 3000) + + onDispose { + handler.removeCallbacks(refreshRunnable) + } + } + + Box( + modifier = Modifier + .fillMaxSize() + .padding(16.dp) + ) { + IconButton( + onClick = { + val intent = Intent(context, MainActivity::class.java) + context.startActivity(intent) + }, + modifier = Modifier + .align(Alignment.TopStart) + ) { + Icon( + Icons.Rounded.ArrowBack, + "arrow_back", + tint = Colors.White + ) + } + + Column( + modifier = Modifier + .fillMaxSize() + .padding(top = 48.dp) + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 10.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = "Liste des lobbies", + color = Colors.White, + modifier = Modifier + .weight(1f) + .padding(start = 20.dp) + ) + + Button( + onClick = { + val intent = Intent(context, CreateLobbyActivity::class.java) + context.startActivity(intent) + }, + shape = RoundedCornerShape(15), + modifier = Modifier + .weight(1f) + .padding(end = 20.dp), + colors = ButtonDefaults.buttonColors(Colors.Blue) + ) { + Text(text = "Ajouter un lobby") + } + } + + LazyColumn( + modifier = Modifier + .fillMaxSize() + .weight(0.85f) + ) { + items(lobbyList ?: emptyList()) { lobby -> + LobbyItem(lobby, selectedItem == lobby) { + selectedItem = it + } + } + } + } + } +} + +@Composable +fun LobbyItem(lobby: Lobby, isSelected: Boolean, onItemClick: (Lobby) -> Unit) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(8.dp) + .clickable { + onItemClick(lobby) + } + .background(if (isSelected) Colors.Orange else Colors.Grey) + .padding(16.dp) + .clip(RoundedCornerShape(8.dp)) + ) { + Text( + text = lobby.name, + fontSize = 18.sp, + color = Colors.White, + modifier = Modifier.weight(1f) + + ) + Text( + text = "${ControllerLobby.getNbPlayerInLobby(lobby.id)}/${lobby.nbplayers}", + fontSize = 18.sp, + color = Colors.White, + modifier = Modifier.weight(1f) + ) + Text( + text = ControllerChapter.getChapterNameById(lobby.idchapter).toString(), + fontSize = 18.sp, + color = Colors.White, + modifier = Modifier.weight(1f) + ) + Text( + text = lobby.difficulty.toString(), + fontSize = 18.sp, + color = Colors.White, + modifier = Modifier.weight(1f) + ) + } +} +