diff --git a/compose/compose/.gradle/8.0/checksums/checksums.lock b/compose/compose/.gradle/8.0/checksums/checksums.lock new file mode 100644 index 0000000..3c23ff4 Binary files /dev/null and b/compose/compose/.gradle/8.0/checksums/checksums.lock differ diff --git a/compose/compose/.gradle/8.0/checksums/md5-checksums.bin b/compose/compose/.gradle/8.0/checksums/md5-checksums.bin new file mode 100644 index 0000000..a7d021d Binary files /dev/null and b/compose/compose/.gradle/8.0/checksums/md5-checksums.bin differ diff --git a/compose/compose/.gradle/8.0/checksums/sha1-checksums.bin b/compose/compose/.gradle/8.0/checksums/sha1-checksums.bin new file mode 100644 index 0000000..c4ef32a Binary files /dev/null and b/compose/compose/.gradle/8.0/checksums/sha1-checksums.bin differ diff --git a/compose/compose/.gradle/8.0/dependencies-accessors/dependencies-accessors.lock b/compose/compose/.gradle/8.0/dependencies-accessors/dependencies-accessors.lock new file mode 100644 index 0000000..49fafcc Binary files /dev/null and b/compose/compose/.gradle/8.0/dependencies-accessors/dependencies-accessors.lock differ diff --git a/compose/compose/.gradle/8.0/dependencies-accessors/gc.properties b/compose/compose/.gradle/8.0/dependencies-accessors/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/compose/compose/.gradle/8.0/executionHistory/executionHistory.bin b/compose/compose/.gradle/8.0/executionHistory/executionHistory.bin new file mode 100644 index 0000000..61a7459 Binary files /dev/null and b/compose/compose/.gradle/8.0/executionHistory/executionHistory.bin differ diff --git a/compose/compose/.gradle/8.0/executionHistory/executionHistory.lock b/compose/compose/.gradle/8.0/executionHistory/executionHistory.lock new file mode 100644 index 0000000..3890b60 Binary files /dev/null and b/compose/compose/.gradle/8.0/executionHistory/executionHistory.lock differ diff --git a/compose/compose/.gradle/8.0/fileChanges/last-build.bin b/compose/compose/.gradle/8.0/fileChanges/last-build.bin new file mode 100644 index 0000000..f76dd23 Binary files /dev/null and b/compose/compose/.gradle/8.0/fileChanges/last-build.bin differ diff --git a/compose/compose/.gradle/8.0/fileHashes/fileHashes.bin b/compose/compose/.gradle/8.0/fileHashes/fileHashes.bin new file mode 100644 index 0000000..c9cc0f9 Binary files /dev/null and b/compose/compose/.gradle/8.0/fileHashes/fileHashes.bin differ diff --git a/compose/compose/.gradle/8.0/fileHashes/fileHashes.lock b/compose/compose/.gradle/8.0/fileHashes/fileHashes.lock new file mode 100644 index 0000000..528f8c8 Binary files /dev/null and b/compose/compose/.gradle/8.0/fileHashes/fileHashes.lock differ diff --git a/compose/compose/.gradle/8.0/fileHashes/resourceHashesCache.bin b/compose/compose/.gradle/8.0/fileHashes/resourceHashesCache.bin new file mode 100644 index 0000000..19e2424 Binary files /dev/null and b/compose/compose/.gradle/8.0/fileHashes/resourceHashesCache.bin differ diff --git a/compose/compose/.gradle/8.0/gc.properties b/compose/compose/.gradle/8.0/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/compose/compose/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/compose/compose/.gradle/buildOutputCleanup/buildOutputCleanup.lock new file mode 100644 index 0000000..0168532 Binary files /dev/null and b/compose/compose/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/compose/compose/.gradle/buildOutputCleanup/cache.properties b/compose/compose/.gradle/buildOutputCleanup/cache.properties new file mode 100644 index 0000000..83e559e --- /dev/null +++ b/compose/compose/.gradle/buildOutputCleanup/cache.properties @@ -0,0 +1,2 @@ +#Mon Oct 02 21:58:30 GMT+04:00 2023 +gradle.version=8.0 diff --git a/compose/compose/.gradle/buildOutputCleanup/outputFiles.bin b/compose/compose/.gradle/buildOutputCleanup/outputFiles.bin new file mode 100644 index 0000000..6914fe6 Binary files /dev/null and b/compose/compose/.gradle/buildOutputCleanup/outputFiles.bin differ diff --git a/compose/compose/.gradle/file-system.probe b/compose/compose/.gradle/file-system.probe new file mode 100644 index 0000000..9a4d2d9 Binary files /dev/null and b/compose/compose/.gradle/file-system.probe differ diff --git a/compose/compose/.gradle/vcs-1/gc.properties b/compose/compose/.gradle/vcs-1/gc.properties new file mode 100644 index 0000000..e69de29 diff --git a/compose/compose/.idea/.gitignore b/compose/compose/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/compose/compose/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/compose/compose/.idea/.name b/compose/compose/.idea/.name new file mode 100644 index 0000000..06c0b50 --- /dev/null +++ b/compose/compose/.idea/.name @@ -0,0 +1 @@ +pmu-demo \ No newline at end of file diff --git a/compose/compose/.idea/compiler.xml b/compose/compose/.idea/compiler.xml new file mode 100644 index 0000000..b589d56 --- /dev/null +++ b/compose/compose/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/compose/compose/.idea/gradle.xml b/compose/compose/.idea/gradle.xml new file mode 100644 index 0000000..ae388c2 --- /dev/null +++ b/compose/compose/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/compose/compose/.idea/inspectionProfiles/Project_Default.xml b/compose/compose/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..44ca2d9 --- /dev/null +++ b/compose/compose/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,41 @@ + + + + \ No newline at end of file diff --git a/compose/compose/.idea/kotlinc.xml b/compose/compose/.idea/kotlinc.xml new file mode 100644 index 0000000..0fc3113 --- /dev/null +++ b/compose/compose/.idea/kotlinc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/compose/compose/.idea/misc.xml b/compose/compose/.idea/misc.xml new file mode 100644 index 0000000..8978d23 --- /dev/null +++ b/compose/compose/.idea/misc.xml @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/compose/compose/app/.gitignore b/compose/compose/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/compose/compose/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/compose/compose/app/build.gradle.kts b/compose/compose/app/build.gradle.kts new file mode 100644 index 0000000..ebac06a --- /dev/null +++ b/compose/compose/app/build.gradle.kts @@ -0,0 +1,71 @@ +plugins { + id("com.android.application") + id("org.jetbrains.kotlin.android") +} + +android { + namespace = "ru.ulstu.is.pmu" + compileSdk = 34 + + defaultConfig { + applicationId = "ru.ulstu.is.pmu" + minSdk = 24 + targetSdk = 33 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables { + useSupportLibrary = true + } + } + + 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" + } + buildFeatures { + compose = true + } + composeOptions { + kotlinCompilerExtensionVersion = "1.4.3" + } + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } + } +} + +dependencies { + + implementation("androidx.core:core-ktx:1.9.0") + implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2") + implementation("androidx.activity:activity-compose:1.7.2") + implementation(platform("androidx.compose:compose-bom:2023.03.00")) + implementation("androidx.navigation:navigation-compose:2.6.0") + implementation("androidx.compose.ui:ui") + implementation("androidx.compose.ui:ui-graphics") + implementation("androidx.compose.ui:ui-tooling-preview") + implementation("androidx.compose.material3:material3") + implementation("androidx.datastore:datastore-core-android:1.1.0-alpha05") + testImplementation("junit:junit:4.13.2") + androidTestImplementation("androidx.test.ext:junit:1.1.5") + androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") + androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00")) + androidTestImplementation("androidx.compose.ui:ui-test-junit4") + debugImplementation("androidx.compose.ui:ui-tooling") + debugImplementation("androidx.compose.ui:ui-test-manifest") +} \ No newline at end of file diff --git a/compose/compose/app/proguard-rules.pro b/compose/compose/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/compose/compose/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/compose/compose/app/src/androidTest/java/ru/ulstu/is/pmu/ExampleInstrumentedTest.kt b/compose/compose/app/src/androidTest/java/ru/ulstu/is/pmu/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..abd2614 --- /dev/null +++ b/compose/compose/app/src/androidTest/java/ru/ulstu/is/pmu/ExampleInstrumentedTest.kt @@ -0,0 +1,22 @@ +package ru.ulstu.`is`.pmu + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.platform.app.InstrumentationRegistry +import org.junit.Assert.* +import org.junit.Test +import org.junit.runner.RunWith + +/** + * 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("ru.ulstu.is.pmu", appContext.packageName) + } +} \ No newline at end of file diff --git a/compose/compose/app/src/main/AndroidManifest.xml b/compose/compose/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..2900ac3 --- /dev/null +++ b/compose/compose/app/src/main/AndroidManifest.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/MainComposeActivity.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/MainComposeActivity.kt new file mode 100644 index 0000000..5dc3f1b --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/MainComposeActivity.kt @@ -0,0 +1,48 @@ +package ru.ulstu.`is`.pmu + +import android.content.res.Configuration +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.navigation.compose.rememberNavController +import ru.ulstu.`is`.pmu.tanks.composeui.Login +import ru.ulstu.`is`.pmu.composeui.navigation.MainNavbar +import ru.ulstu.`is`.pmu.composeui.navigation.NavGraph +import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme + +class MainComposeActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + PmudemoTheme { + Surface( + modifier = Modifier.fillMaxSize(), + color = MaterialTheme.colorScheme.background + ) { + val navController = rememberNavController() + NavGraph(navController = navController) + } + } + } + } +} + +@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +fun MainNavbarPreview() { + PmudemoTheme { + Surface( + color = MaterialTheme.colorScheme.background + ) { + val navController = rememberNavController() + NavGraph(navController = navController) + } + } +} \ No newline at end of file diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/composeui/About.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/composeui/About.kt new file mode 100644 index 0000000..008a2ed --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/composeui/About.kt @@ -0,0 +1,66 @@ +package ru.ulstu.`is`.pmu.composeui + +import android.content.Intent +import android.content.res.Configuration +import android.net.Uri +import android.widget.TextView +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.viewinterop.AndroidView +import ru.ulstu.`is`.pmu.R +import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme + +@Composable +fun About() { + val localContext = LocalContext.current + val aboutText = localContext.resources.getText(R.string.about_text) + + val urlOnClick = { + val openURL = Intent(Intent.ACTION_VIEW) + openURL.data = Uri.parse("https://ulstu.ru/") + localContext.startActivity(openURL) + } + + Column(Modifier.padding(all = 10.dp)) { + AndroidView( + modifier = Modifier + .fillMaxWidth() + .clickable(onClick = urlOnClick), + factory = { context -> TextView(context) }, + update = { it.text = aboutText } + ) + Spacer(Modifier.padding(bottom = 10.dp)) + Button( + modifier = Modifier.fillMaxWidth(), + onClick = urlOnClick + ) { + Text(stringResource(id = R.string.generator)) + } + } +} + +@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +fun AboutPreview() { + PmudemoTheme { + Surface( + color = MaterialTheme.colorScheme.background + ) { + About() + } + } +} \ No newline at end of file diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/composeui/navigation/MainNavbar.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/composeui/navigation/MainNavbar.kt new file mode 100644 index 0000000..029be29 --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/composeui/navigation/MainNavbar.kt @@ -0,0 +1,281 @@ +package ru.ulstu.`is`.pmu.composeui.navigation + +import android.annotation.SuppressLint +import android.content.res.Configuration +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxHeight +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.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBack +import androidx.compose.material.icons.filled.KeyboardArrowDown +import androidx.compose.material.icons.filled.KeyboardArrowUp +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExposedDropdownMenuBox +import androidx.compose.material3.ExposedDropdownMenuDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.NavigationBar +import androidx.compose.material3.NavigationBarItem +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavDestination +import androidx.navigation.NavDestination.Companion.hierarchy +import androidx.navigation.NavGraph.Companion.findStartDestination +import androidx.navigation.NavHostController +import androidx.navigation.NavType +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.currentBackStackEntryAsState +import androidx.navigation.compose.rememberNavController +import androidx.navigation.navArgument +import ru.ulstu.`is`.pmu.R +import ru.ulstu.`is`.pmu.student.composeui.StudentView +import ru.ulstu.`is`.pmu.ui.theme.CustomDark +import ru.ulstu.`is`.pmu.ui.theme.CustomOrange +import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalConfiguration +import androidx.navigation.NavController +import ru.ulstu.`is`.pmu.student.composeui.TankList +import ru.ulstu.`is`.pmu.tanks.composeui.Account +import ru.ulstu.`is`.pmu.tanks.composeui.Constructor +import ru.ulstu.`is`.pmu.tanks.composeui.Hangar +import ru.ulstu.`is`.pmu.ui.theme.CustomRed + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun Topbar( + navController: NavHostController, + currentScreen: Screen? +) { + TopAppBar( + colors = TopAppBarDefaults.smallTopAppBarColors( + containerColor = CustomOrange, + titleContentColor = CustomDark, + ), + title = { + Text( + stringResource(currentScreen?.resourceId ?: R.string.app_name), + fontSize = 40.sp, + fontWeight = FontWeight.Bold, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth() + ) + }, + navigationIcon = { + if ( + navController.previousBackStackEntry != null + && (currentScreen == null || !currentScreen.showInBottomBar) + ) { + IconButton(onClick = { navController.navigateUp() }) { + Icon( + imageVector = Icons.Filled.ArrowBack, + contentDescription = null, + tint = MaterialTheme.colorScheme.onPrimary + ) + } + } + } + ) +} + +@Composable +fun Navbar( + navController: NavHostController, + currentDestination: NavDestination?, + modifier: Modifier = Modifier.background(CustomOrange) +) { + NavigationBar( + modifier, + containerColor = CustomOrange + ) + { + Screen.bottomBarItems.forEach { screen -> + NavigationBarItem( + modifier = Modifier.background(CustomOrange), + icon = { Icon(screen.icon, contentDescription = null, tint = CustomDark, modifier = Modifier.size(50.dp)) }, + selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true, + onClick = { + navController.navigate(screen.route) { + popUpTo(navController.graph.findStartDestination().id) { + saveState = true + } + launchSingleTop = true + restoreState = true + } + } + ) + } + } +} + +@Composable +fun Navhost( + navController: NavHostController, +) { + NavHost( + navController, + startDestination = Screen.TankList.route, + ) { + composable(Screen.TankList.route) { TankList(navController) } + composable(Screen.Constructor.route) { Constructor(navController) } + composable(Screen.Hangar.route) { Hangar(navController) } + composable(Screen.Account.route) { Account(navController) } + composable( + Screen.StudentView.route, + arguments = listOf(navArgument("id") { type = NavType.IntType }) + ) { backStackEntry -> + backStackEntry.arguments?.let { StudentView(it.getInt("id")) } + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun DropDownList( + navController: NavHostController, +){ + //для работы выпадающего списка уровней + val optionsList = listOf( + "Нациям", + "Уровням" + ) + var expandedOptions by remember { mutableStateOf(false) } + var mySelectedOption by remember { mutableStateOf(optionsList[0]) } + + Row( + horizontalArrangement = Arrangement.spacedBy(40.dp), + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .padding(10.dp, 10.dp, 10.dp, 0.dp) + .height(70.dp) + ){ + Text(text = stringResource(id = R.string.main_label), color = Color.White, textAlign = TextAlign.Center) + // Выпадающий список вариантов показа + ExposedDropdownMenuBox( + expanded = expandedOptions, + onExpandedChange = { + expandedOptions = !expandedOptions + } + ) { + // textfield + TextField( + modifier = Modifier + .menuAnchor() // menuAnchor modifier must be passed to the text field for correctness. + .width(200.dp), + readOnly = true, + value = mySelectedOption, + onValueChange = {}, + label = { Text("") }, + trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expandedOptions) }, + colors = ExposedDropdownMenuDefaults.textFieldColors(), + ) + + // menu + ExposedDropdownMenu( + expanded = expandedOptions, + onDismissRequest = { + expandedOptions = false + }, + ) { + // menu items + optionsList.forEach { selectionOption -> + DropdownMenuItem( + text = { Text(selectionOption) }, + onClick = { + mySelectedOption = selectionOption + expandedOptions = false + }, + contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding, + ) + } + } + } + } +} + +@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MainNavbar(navController: NavController) { + val navController = rememberNavController() + val navBackStackEntry by navController.currentBackStackEntryAsState() + val currentDestination = navBackStackEntry?.destination + val currentScreen = currentDestination?.route?.let { Screen.getItem(it) } + + Scaffold( + topBar = { + Topbar(navController, currentScreen) + }, + bottomBar = { + if (currentScreen == null || currentScreen.showInBottomBar) { + Navbar(navController, currentDestination) + } + }, + ) { + Column( + modifier = Modifier + .verticalScroll(rememberScrollState()) + .background(CustomDark) + .fillMaxSize() + .padding(0.dp, 70.dp, 0.dp, 170.dp), + ){ + if(currentScreen?.route == Screen.TankList.route){ + DropDownList(navController) + } + Navhost(navController) + } + } +} + +@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +fun MainNavbarPreview() { + PmudemoTheme { + Surface( + color = CustomDark + ) { + val navController = rememberNavController() + NavGraph(navController = navController) + } + } +} \ No newline at end of file diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/composeui/navigation/NavGraph.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/composeui/navigation/NavGraph.kt new file mode 100644 index 0000000..656994e --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/composeui/navigation/NavGraph.kt @@ -0,0 +1,27 @@ +package ru.ulstu.`is`.pmu.composeui.navigation + +import androidx.compose.runtime.Composable +import androidx.navigation.NavHostController +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import ru.ulstu.`is`.pmu.tanks.composeui.Hangar +import ru.ulstu.`is`.pmu.tanks.composeui.Login +import ru.ulstu.`is`.pmu.tanks.composeui.Register + +@Composable +fun NavGraph (navController: NavHostController){ + NavHost( + navController = navController, + startDestination = Screen.Login.route) + { + composable(route = Screen.Login.route){ + Login(navController) + } + composable(route = Screen.Register.route){ + Register(navController) + } + composable(route = Screen.TankList.route){ + MainNavbar(navController) + } + } +} \ No newline at end of file diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/composeui/navigation/Screen.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/composeui/navigation/Screen.kt new file mode 100644 index 0000000..d4587aa --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/composeui/navigation/Screen.kt @@ -0,0 +1,54 @@ +package ru.ulstu.`is`.pmu.composeui.navigation + +import androidx.annotation.StringRes +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.AccountCircle +import androidx.compose.material.icons.filled.Add +import androidx.compose.material.icons.filled.Favorite +import androidx.compose.material.icons.filled.Home +import androidx.compose.material.icons.filled.List +import androidx.compose.ui.graphics.vector.ImageVector +import ru.ulstu.`is`.pmu.R + +enum class Screen( + val route: String, + @StringRes val resourceId: Int, + val icon: ImageVector = Icons.Filled.Favorite, + val showInBottomBar: Boolean = true +) { + TankList( + "tank-list", R.string.tanks_main_title, Icons.Filled.Home + ), + Login( + "login", R.string.login, showInBottomBar = false + ), + Register( + "register", R.string.register, showInBottomBar = false + ), + Constructor( + "constructor", R.string.constructor, Icons.Filled.Add + ), + Hangar( + "hangar", R.string.hangar, Icons.Filled.List + ), + Account( + "account", R.string.account, Icons.Filled.AccountCircle + ), + StudentView( + "student-view/{id}", R.string.student_view_title, showInBottomBar = false + ); + + companion object { + val bottomBarItems = listOf( + TankList, + Constructor, + Hangar, + Account + ) + + fun getItem(route: String): Screen? { + val findRoute = route.split("/").first() + return values().find { value -> value.route.startsWith(findRoute) } + } + } +} \ No newline at end of file diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/student/composeui/StudentView.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/student/composeui/StudentView.kt new file mode 100644 index 0000000..e6a5513 --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/student/composeui/StudentView.kt @@ -0,0 +1,74 @@ +package ru.ulstu.`is`.pmu.student.composeui + +import android.content.res.Configuration +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import ru.ulstu.`is`.pmu.R +import ru.ulstu.`is`.pmu.student.model.getStudents +import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun StudentView(id: Int) { + val student = getStudents()[id] + Column( + Modifier + .fillMaxWidth() + .padding(all = 10.dp) + ) { + OutlinedTextField(modifier = Modifier.fillMaxWidth(), + value = student.firstName, onValueChange = {}, readOnly = true, + label = { + Text(stringResource(id = R.string.student_firstname)) + } + ) + OutlinedTextField(modifier = Modifier.fillMaxWidth(), + value = student.lastName, onValueChange = {}, readOnly = true, + label = { + Text(stringResource(id = R.string.student_lastname)) + } + ) + OutlinedTextField(modifier = Modifier.fillMaxWidth(), + value = student.group, onValueChange = {}, readOnly = true, + label = { + Text(stringResource(id = R.string.student_group)) + } + ) + OutlinedTextField(modifier = Modifier.fillMaxWidth(), + value = student.phone, onValueChange = {}, readOnly = true, + label = { + Text(stringResource(id = R.string.student_phone)) + } + ) + OutlinedTextField(modifier = Modifier.fillMaxWidth(), + value = student.email, onValueChange = {}, readOnly = true, + label = { + Text(stringResource(id = R.string.student_email)) + } + ) + } +} + +@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +fun StudentViewPreview() { + PmudemoTheme { + Surface( + color = MaterialTheme.colorScheme.background + ) { + StudentView(id = 0) + } + } +} \ No newline at end of file diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/student/composeui/TankList.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/student/composeui/TankList.kt new file mode 100644 index 0000000..acc4047 --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/student/composeui/TankList.kt @@ -0,0 +1,196 @@ +package ru.ulstu.`is`.pmu.student.composeui + +import android.content.res.Configuration +import androidx.annotation.StringRes +import androidx.compose.foundation.Image +import androidx.compose.foundation.ScrollState +import androidx.compose.foundation.background +import androidx.compose.foundation.horizontalScroll +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxHeight +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.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.rememberScrollState +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavController +import ru.ulstu.`is`.pmu.R +import ru.ulstu.`is`.pmu.composeui.navigation.Screen +import ru.ulstu.`is`.pmu.student.model.getStudents +import ru.ulstu.`is`.pmu.ui.theme.CustomDark +import ru.ulstu.`is`.pmu.ui.theme.CustomOrange +import ru.ulstu.`is`.pmu.ui.theme.CustomRed +import ru.ulstu.`is`.pmu.ui.theme.CustomYellow +import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme + +@Composable +fun TankList(navController: NavController?) { + val listIds = listOf( + R.string.ussr_list, + R.string.germany_list, + R.string.usa_list + ) + + // Lazy Column, Pass the numbers array + LazyColumnExample(numbers = listIds) +} + +@Composable +fun ColumnItem( + number: Int +) { + Column( + modifier = Modifier.padding(0.dp, 10.dp) + ) { + Box( + Modifier + .background(CustomYellow) + .fillMaxWidth() + .height(40.dp), + ){ + Text( + text = stringResource(id = number), + fontSize = 30.sp, + fontWeight = FontWeight.Bold, + color = CustomDark, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth() + ) + } + Box( + Modifier + .background(CustomYellow) + .height(260.dp), + ) + { + Row ( + modifier = Modifier.horizontalScroll(ScrollState(0)) + ) + { + getStudents().forEachIndexed() { index, student -> + val studentId = Screen.StudentView.route.replace("{id}", index.toString()) + Card( + colors = CardDefaults.cardColors( + containerColor = CustomDark, + ), + modifier = Modifier + .size(width = 200.dp, height = 250.dp) + .padding(all = 5.dp) + ) { + var imageId = R.drawable.t_34_85 + var textId = R.string.t_34_85 + + if(number == R.string.ussr_list){ + //ничего + } else if (number == R.string.germany_list){ + imageId = R.drawable.tiger_1 + textId = R.string.tiger_1 + } else if (number == R.string.usa_list) { + imageId = R.drawable.sherman + textId = R.string.sherman + } + + Image( + painter = painterResource(id = imageId), + contentDescription = stringResource(id = R.string.tanks_main_title), + modifier = Modifier + .height(150.dp) + .padding(all = 5.dp) + ) + Text( + text = stringResource(id = textId), + fontSize = 30.sp, + fontWeight = FontWeight.Bold, + color = CustomOrange, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth() + ) + Button( + modifier = Modifier + .fillMaxWidth() + .padding(10.dp, 0.dp, 10.dp, 10.dp), + colors = ButtonDefaults.buttonColors( + containerColor = CustomRed, + contentColor = CustomDark), + onClick = { }) { + //navController?.navigate(Screen.Hangar.route) + //navController?.navigate(studentId) + //"${student.firstName} ${student.lastName}" + Text(text = stringResource(id = R.string.purchase_button)) + } + } + } + } + } + } +} + +@Composable +fun LazyColumnExample(numbers: List) { + LazyColumn( + verticalArrangement = Arrangement.Bottom, + modifier = Modifier.height(300.dp * numbers.size) + ) { + // item places one item on the LazyScope + item { + //ColumnItem(number = 0) + } + + // items(count) places number of items supplied + // as count and gives current count in the lazyItemScope + items(10) {currentCount-> + //ColumnItem(number = currentCount) + } + + // items(list/array) places number of items + // same as the size of list/array and gives + // current list/array item in the lazyItemScope + items(numbers) {arrayItem-> + ColumnItem(number = arrayItem) + } + + // items(list/array) places number of + // items same as the size of list/array + // and gives current list/array item and + // currentIndex in the lazyItemScope + itemsIndexed(numbers) { index, item -> + //ColumnItem(number = index) + } + } +} + +@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +fun StudentListPreview() { + PmudemoTheme { + Surface( + color = CustomDark + ) { + TankList(navController = null) + } + } +} \ No newline at end of file diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/student/model/Level.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/student/model/Level.kt new file mode 100644 index 0000000..0b2fe94 --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/student/model/Level.kt @@ -0,0 +1,23 @@ +package ru.ulstu.`is`.pmu.student.model + +import java.io.Serializable + +data class Level( + val level: Int, +) : Serializable + +fun getLevels(): List { + return listOf( + Level(1), + Level(2), + Level(3), + Level(4), + Level(5), + Level(6), + Level(7), + Level(8), + Level(9), + Level(10) + ) +} + diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/student/model/Nation.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/student/model/Nation.kt new file mode 100644 index 0000000..d20ec48 --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/student/model/Nation.kt @@ -0,0 +1,23 @@ +package ru.ulstu.`is`.pmu.student.model + +import java.io.Serializable + +data class Nation( + val name: String, +) : Serializable + +fun getNations(): List { + return listOf( + Nation("СССР"), + Nation("Германия"), + Nation("США"), + Nation("Великобритания"), + Nation("Франция"), + Nation("Китай"), + Nation("Япония"), + Nation("Италия"), + Nation("Польша"), + Nation("Швеция") + ) +} + diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/student/model/Student.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/student/model/Student.kt new file mode 100644 index 0000000..566e5a2 --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/student/model/Student.kt @@ -0,0 +1,19 @@ +package ru.ulstu.`is`.pmu.student.model + +import java.io.Serializable + +data class Student( + val firstName: String, + val lastName: String, + val group: String, + val phone: String, + val email: String +) : Serializable + +fun getStudents(): List { + return listOf( + Student("First1", "Last1", "Group1", "+79998887766", "email1@mail.ru"), + Student("First2", "Last2", "Group1", "+79995553322", "email2@mail.ru"), + Student("First3", "Last3", "Group2", "+79991114466", "email3@mail.ru") + ) +} diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/student/model/Tank.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/student/model/Tank.kt new file mode 100644 index 0000000..e17a44e --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/student/model/Tank.kt @@ -0,0 +1,19 @@ +package ru.ulstu.`is`.pmu.student.model + +import java.io.Serializable + +data class Tank( + val name: String, + val price: Int, + val level: Int, + val nation: String +) : Serializable + +fun getTanks(): List { + return listOf( + Tank("T-38-85", 970000, 6, "СССР"), + Tank("M3 Lee", 140000, 4, "США"), + Tank("Foch B", 6100000, 10, "Франция") + ) +} + diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Account.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Account.kt new file mode 100644 index 0000000..cac000a --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Account.kt @@ -0,0 +1,178 @@ +package ru.ulstu.`is`.pmu.tanks.composeui + +import android.content.res.Configuration +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +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.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.material3.TextField +import androidx.compose.material3.TextFieldDefaults +import androidx.compose.runtime.Composable +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.graphics.Color +import androidx.compose.ui.graphics.StrokeJoin +import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.modifier.modifierLocalConsumer +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.ExperimentalTextApi +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavController +import androidx.navigation.compose.currentBackStackEntryAsState +import androidx.navigation.compose.rememberNavController +import ru.ulstu.`is`.pmu.R +import ru.ulstu.`is`.pmu.composeui.navigation.Screen +import ru.ulstu.`is`.pmu.ui.theme.CustomBackground +import ru.ulstu.`is`.pmu.ui.theme.CustomDark +import ru.ulstu.`is`.pmu.ui.theme.CustomOrange +import ru.ulstu.`is`.pmu.ui.theme.CustomRed +import ru.ulstu.`is`.pmu.ui.theme.CustomYellow +import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme + +@OptIn(ExperimentalMaterial3Api::class, ExperimentalTextApi::class) +@Composable +fun Account(navController: NavController) { + val navBackStackEntry by navController.currentBackStackEntryAsState() + val currentDestination = navBackStackEntry?.destination + val currentScreen = currentDestination?.route?.let { Screen.getItem(it) } + + //для работы текстовых полей + var nickname by remember { mutableStateOf("") } + + var password by remember { mutableStateOf("") } + + var balance by remember { mutableStateOf("") } + + Column( + verticalArrangement = Arrangement.spacedBy(35.dp), + modifier = Modifier.fillMaxHeight(1f).padding(0.dp, 15.dp) + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier + .fillMaxWidth() + .background(CustomYellow) + ){ + Column { + Spacer(Modifier.height(15.dp)) + Row( + horizontalArrangement = Arrangement.Center, + modifier = Modifier.fillMaxWidth() + ){ + Text(text="Личные данные", fontSize = 30.sp, color = Color.Black, fontWeight = FontWeight.Bold) + } + Spacer(Modifier.height(15.dp)) + Row( + horizontalArrangement = Arrangement.SpaceAround, + modifier = Modifier.fillMaxWidth() + ){ + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier.padding(0.dp, 5.dp) + ) { + Text(text="Логин:", fontSize = 30.sp, color = Color.Black, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(30.dp)) + Text(text="Пароль:", fontSize = 30.sp, color = Color.Black, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(30.dp)) + Text(text="Баланс:", fontSize = 30.sp, color = Color.Black, fontWeight = FontWeight.Bold) + } + Column { + TextField( + value = nickname, + placeholder = { Text(text = "Логин", color = CustomDark) }, + onValueChange = { nickname = it }, + modifier = Modifier + .width(200.dp), + ) + Spacer(Modifier.height(10.dp)) + TextField( + value = password, + placeholder = { Text(text = "Пароль", color = CustomDark) }, + onValueChange = { password = it }, + modifier = Modifier + .width(200.dp), + ) + Spacer(Modifier.height(10.dp)) + TextField( + value = balance, + placeholder = { Text(text = "Баланс", color = CustomDark) }, + onValueChange = { balance = it }, + modifier = Modifier + .width(200.dp), + colors = TextFieldDefaults.textFieldColors( + focusedLabelColor = CustomOrange, + cursorColor = CustomOrange + ) + ) + } + } + Spacer(Modifier.height(25.dp)) + } + } + Row( + horizontalArrangement = Arrangement.Center, + modifier = Modifier + .fillMaxWidth() + .padding(10.dp, 10.dp) + ){ + Button( + modifier = Modifier + .width(200.dp) + .height(50.dp), + colors = ButtonDefaults.buttonColors( + containerColor = CustomRed, + contentColor = Color.White + ), + onClick = { navController.navigate(Screen.TankList.route) }) { + //"${student.firstName} ${student.lastName}" + Text(text = stringResource(id = R.string.save_account_button), fontSize = 20.sp, fontWeight = FontWeight.Bold) + } + } + Spacer(Modifier.weight(1.0f)) + } +} + +@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +fun AccountPreview() { + PmudemoTheme { + Surface( + color = CustomDark + ) { + val navController = rememberNavController() + Account(navController) + } + } +} \ No newline at end of file diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Constructor.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Constructor.kt new file mode 100644 index 0000000..24dae7b --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Constructor.kt @@ -0,0 +1,362 @@ +package ru.ulstu.`is`.pmu.tanks.composeui + +import android.content.res.Configuration +import android.graphics.drawable.Icon +import android.widget.Toast +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +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.width +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.MoreVert +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExposedDropdownMenuBox +import androidx.compose.material3.ExposedDropdownMenuDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.material3.TextField +import androidx.compose.material3.TextFieldDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +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.graphics.Color +import androidx.compose.ui.graphics.StrokeJoin +import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.modifier.modifierLocalConsumer +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.ExperimentalTextApi +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavController +import androidx.navigation.compose.currentBackStackEntryAsState +import androidx.navigation.compose.rememberNavController +import ru.ulstu.`is`.pmu.R +import ru.ulstu.`is`.pmu.composeui.navigation.Screen +import ru.ulstu.`is`.pmu.student.model.getLevels +import ru.ulstu.`is`.pmu.student.model.getNations +import ru.ulstu.`is`.pmu.ui.theme.CustomBackground +import ru.ulstu.`is`.pmu.ui.theme.CustomDark +import ru.ulstu.`is`.pmu.ui.theme.CustomOrange +import ru.ulstu.`is`.pmu.ui.theme.CustomRed +import ru.ulstu.`is`.pmu.ui.theme.CustomYellow +import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme + +@OptIn(ExperimentalMaterial3Api::class, ExperimentalTextApi::class) +@Composable +fun Constructor(navController: NavController) { + val navBackStackEntry by navController.currentBackStackEntryAsState() + val currentDestination = navBackStackEntry?.destination + val currentScreen = currentDestination?.route?.let { Screen.getItem(it) } + + var name by remember { mutableStateOf("") } + var price by remember { mutableStateOf("") } + + //для работы выпадающего списка уровней + var expandedLevels by remember { mutableStateOf(false) } + var selectedLevel by remember { mutableStateOf(getLevels()[0].level) } + + //для работы выпадающего списка наций + var expandedNation by remember { mutableStateOf(false) } + var selectedNation by remember { mutableStateOf(getNations()[0].name) } + + Column( + verticalArrangement = Arrangement.spacedBy(35.dp), + modifier = Modifier.padding(0.dp, 15.dp) + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth().background(CustomYellow) + ){ + Column { + Row( + horizontalArrangement = Arrangement.Center, + modifier = Modifier.fillMaxWidth() + ){ + Text(text="Добавить танк", fontSize = 30.sp, color = Color.Black, fontWeight = FontWeight.Bold) + } + Row( + horizontalArrangement = Arrangement.SpaceAround, + modifier = Modifier.fillMaxWidth() + ){ + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier.padding(0.dp, 5.dp) + ) { + Text(text="Название:", fontSize = 30.sp, color = Color.Black, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(30.dp)) + Text(text="Уровень:", fontSize = 30.sp, color = Color.Black, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(30.dp)) + Text(text="Нация:", fontSize = 30.sp, color = Color.Black, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(25.dp)) + Text(text="Стоимость:", fontSize = 30.sp, color = Color.Black, fontWeight = FontWeight.Bold) + } + Column { + TextField( + value = name, + placeholder = { Text(text = "Название", color = CustomDark) }, + onValueChange = { name = it }, + modifier = Modifier + .width(200.dp), + ) + Spacer(Modifier.height(10.dp)) + // Выпадающий список уровней + ExposedDropdownMenuBox( + expanded = expandedLevels, + onExpandedChange = { + expandedLevels = !expandedLevels + } + ) { + // textfield + TextField( + modifier = Modifier + .menuAnchor() // menuAnchor modifier must be passed to the text field for correctness. + .width(200.dp), + readOnly = true, + value = selectedLevel.toString(), + onValueChange = {}, + label = { Text("") }, + trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expandedLevels) }, + colors = ExposedDropdownMenuDefaults.textFieldColors(), + ) + + // menu + ExposedDropdownMenu( + expanded = expandedLevels, + onDismissRequest = { + expandedLevels = false + }, + ) { + // menu items + getLevels().forEach { selectionOption -> + DropdownMenuItem( + text = { Text(selectionOption.level.toString()) }, + onClick = { + selectedLevel = selectionOption.level + expandedLevels = false + }, + contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding, + ) + } + } + } + Spacer(Modifier.height(10.dp)) + // Выпадающий список наций + ExposedDropdownMenuBox( + expanded = expandedNation, + onExpandedChange = { + expandedNation = !expandedNation + } + ) { + // textfield + TextField( + modifier = Modifier + .menuAnchor() // menuAnchor modifier must be passed to the text field for correctness. + .width(200.dp), + readOnly = true, + value = selectedNation, + onValueChange = {}, + label = { Text("") }, + trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expandedNation) }, + colors = ExposedDropdownMenuDefaults.textFieldColors(), + ) + + // menu + ExposedDropdownMenu( + expanded = expandedNation, + onDismissRequest = { + expandedNation = false + }, + ) { + // menu items + getNations().forEach { selectionOption -> + DropdownMenuItem( + text = { Text(selectionOption.name) }, + onClick = { + selectedNation = selectionOption.name + expandedNation = false + }, + contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding, + ) + } + } + } + Spacer(Modifier.height(10.dp)) + TextField( + value = price, + placeholder = { Text(text = "Стоимость", color = CustomDark) }, + onValueChange = { price = it }, + modifier = Modifier + .width(200.dp), + ) + } + } + Row( + horizontalArrangement = Arrangement.Center, + modifier = Modifier.fillMaxWidth().padding(10.dp, 10.dp) + ){ + Button( + modifier = Modifier + .width(200.dp) + .height(50.dp), + colors = ButtonDefaults.buttonColors( + containerColor = CustomOrange, + contentColor = Color.Black + ), + onClick = { }) { + //"${student.firstName} ${student.lastName}" + Text(text = stringResource(id = R.string.create_account_button), fontSize = 20.sp, fontWeight = FontWeight.Bold) + } + } + } + } + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth().background(CustomYellow) + ){ + Column { + Row( + horizontalArrangement = Arrangement.Center, + modifier = Modifier.fillMaxWidth() + ){ + Text(text="Добавить уровень", fontSize = 30.sp, color = Color.Black, fontWeight = FontWeight.Bold) + } + Row( + horizontalArrangement = Arrangement.SpaceAround, + modifier = Modifier.fillMaxWidth() + ){ + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier.padding(0.dp, 5.dp) + ) { + Text(text="Уровень:", fontSize = 30.sp, color = Color.Black, fontWeight = FontWeight.Bold) + } + Column { + TextField( + value = "", + placeholder = { Text(text = "Уровень", color = CustomDark) }, + onValueChange = { }, + modifier = Modifier + .width(200.dp), + ) + } + } + Row( + horizontalArrangement = Arrangement.Center, + modifier = Modifier.fillMaxWidth().padding(10.dp, 10.dp) + ){ + Button( + modifier = Modifier + .width(200.dp) + .height(50.dp), + colors = ButtonDefaults.buttonColors( + containerColor = CustomOrange, + contentColor = Color.Black + ), + onClick = { }) { + //"${student.firstName} ${student.lastName}" + Text(text = stringResource(id = R.string.create_account_button), fontSize = 20.sp, fontWeight = FontWeight.Bold) + } + } + } + } + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth().background(CustomYellow) + ){ + Column { + Row( + horizontalArrangement = Arrangement.Center, + modifier = Modifier.fillMaxWidth() + ){ + Text(text="Добавить нацию", fontSize = 30.sp, color = Color.Black, fontWeight = FontWeight.Bold) + } + Row( + horizontalArrangement = Arrangement.SpaceAround, + modifier = Modifier.fillMaxWidth() + ){ + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier.padding(0.dp, 5.dp) + ) { + Text(text="Нация:", fontSize = 30.sp, color = Color.Black, fontWeight = FontWeight.Bold) + } + Column { + TextField( + value = "", + placeholder = { Text(text = "Нация", color = CustomDark) }, + onValueChange = { }, + modifier = Modifier + .width(200.dp), + ) + } + } + Row( + horizontalArrangement = Arrangement.Center, + modifier = Modifier.fillMaxWidth().padding(10.dp, 10.dp) + ){ + Button( + modifier = Modifier + .width(200.dp) + .height(50.dp), + colors = ButtonDefaults.buttonColors( + containerColor = CustomOrange, + contentColor = Color.Black + ), + onClick = { }) { + //"${student.firstName} ${student.lastName}" + Text(text = stringResource(id = R.string.create_account_button), fontSize = 20.sp, fontWeight = FontWeight.Bold) + } + } + } + } + Spacer(Modifier.height(20.dp)) + } +} + +@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +fun ConstructorPreview() { + PmudemoTheme { + Surface( + color = CustomDark + ) { + val navController = rememberNavController() + Constructor(navController) + } + } +} \ No newline at end of file diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Hangar.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Hangar.kt new file mode 100644 index 0000000..5bc51a4 --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Hangar.kt @@ -0,0 +1,202 @@ +package ru.ulstu.`is`.pmu.tanks.composeui + +import android.content.res.Configuration +import androidx.compose.foundation.Image +import androidx.compose.foundation.ScrollState +import androidx.compose.foundation.background +import androidx.compose.foundation.horizontalScroll +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +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.layout.width +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavController +import androidx.navigation.compose.currentBackStackEntryAsState +import androidx.navigation.compose.rememberNavController +import ru.ulstu.`is`.pmu.R +import ru.ulstu.`is`.pmu.composeui.navigation.Screen +import ru.ulstu.`is`.pmu.student.model.getStudents +import ru.ulstu.`is`.pmu.ui.theme.CustomDark +import ru.ulstu.`is`.pmu.ui.theme.CustomOrange +import ru.ulstu.`is`.pmu.ui.theme.CustomRed +import ru.ulstu.`is`.pmu.ui.theme.CustomYellow +import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun Hangar(navController: NavController){ + val navBackStackEntry by navController.currentBackStackEntryAsState() + val currentDestination = navBackStackEntry?.destination + val currentScreen = currentDestination?.route?.let { Screen.getItem(it) } + + Column( + verticalArrangement = Arrangement.spacedBy(15.dp) + ) { + for(n in 1..3){ + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceAround, + modifier = Modifier + .fillMaxWidth() + .padding(10.dp, 0.dp, 10.dp, 0.dp) + ) { + Column( + modifier = Modifier.background(CustomYellow) + ) { + Box( + Modifier + .background(CustomYellow) + .height(260.dp), + ) + { + Card( + colors = CardDefaults.cardColors( + containerColor = CustomYellow, + ), + modifier = Modifier + .size(width = 170.dp, height = 250.dp) + .padding(10.dp, 0.dp, 10.dp, 0.dp) + ) { + Image( + painter = painterResource(id = R.drawable.t_34_85), + contentDescription = stringResource(id = R.string.tanks_main_title), + modifier = Modifier + .height(130.dp) + ) + Text( + text = stringResource(id = R.string.t_34_85), + fontSize = 20.sp, + fontWeight = FontWeight.Bold, + color = Color.Black, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth() + ) + Text( + text = "Нация: СССР", + fontSize = 17.sp, + fontWeight = FontWeight.Bold, + color = Color.Black, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth() + ) + Text( + text = "Уровень: 6", + fontSize = 17.sp, + fontWeight = FontWeight.Bold, + color = Color.Black, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth() + ) + Text( + text = "Стоимость: 965000", + fontSize = 17.sp, + fontWeight = FontWeight.Bold, + color = Color.Black, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth() + ) + } + } + } + Column( + modifier = Modifier.background(CustomYellow) + ) { + Box( + Modifier + .background(CustomYellow) + .height(260.dp), + ) + { + Card( + colors = CardDefaults.cardColors( + containerColor = CustomYellow, + ), + modifier = Modifier + .size(width = 170.dp, height = 250.dp) + .padding(10.dp, 0.dp, 10.dp, 0.dp) + ) { + Image( + painter = painterResource(id = R.drawable.tiger_1), + contentDescription = stringResource(id = R.string.tanks_main_title), + modifier = Modifier + .height(130.dp) + ) + Text( + text = stringResource(id = R.string.tiger_1), + fontSize = 20.sp, + fontWeight = FontWeight.Bold, + color = Color.Black, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth() + ) + Text( + text = "Нация: Германия", + fontSize = 17.sp, + fontWeight = FontWeight.Bold, + color = Color.Black, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth() + ) + Text( + text = "Уровень: 7", + fontSize = 17.sp, + fontWeight = FontWeight.Bold, + color = Color.Black, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth() + ) + Text( + text = "Стоимость: 1350000", + fontSize = 17.sp, + fontWeight = FontWeight.Bold, + color = Color.Black, + textAlign = TextAlign.Center, + modifier = Modifier.fillMaxWidth() + ) + } + } + } + } + } + Spacer(Modifier.height(20.dp)) + } +} + +@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +fun HangarPreview() { + PmudemoTheme { + Surface( + color = CustomDark + ) { + val navController = rememberNavController() + Hangar(navController) + } + } +} \ No newline at end of file diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Login.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Login.kt new file mode 100644 index 0000000..c0d3bd6 --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Login.kt @@ -0,0 +1,218 @@ +package ru.ulstu.`is`.pmu.tanks.composeui + +import android.content.res.Configuration +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +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.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.material3.TextFieldDefaults +import androidx.compose.runtime.Composable +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.graphics.Paint +import androidx.compose.ui.graphics.StrokeJoin +import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.graphics.drawscope.drawIntoCanvas +import androidx.compose.ui.graphics.nativeCanvas +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.ExperimentalTextApi +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavController +import androidx.navigation.compose.currentBackStackEntryAsState +import androidx.navigation.compose.rememberNavController +import ru.ulstu.`is`.pmu.R +import ru.ulstu.`is`.pmu.composeui.navigation.Screen +import ru.ulstu.`is`.pmu.ui.theme.CustomBackground +import ru.ulstu.`is`.pmu.ui.theme.CustomDark +import ru.ulstu.`is`.pmu.ui.theme.CustomOrange +import ru.ulstu.`is`.pmu.ui.theme.CustomRed +import ru.ulstu.`is`.pmu.ui.theme.CustomYellow +import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme + +@OptIn(ExperimentalMaterial3Api::class, ExperimentalTextApi::class) +@Composable +fun Login(navController: NavController) { + val navBackStackEntry by navController.currentBackStackEntryAsState() + val currentDestination = navBackStackEntry?.destination + val currentScreen = currentDestination?.route?.let { Screen.getItem(it) } + + //для букв с рамками + // Create a Paint that has black stroke + val textPaintStroke = Paint().asFrameworkPaint().apply { + isAntiAlias = true + style = android.graphics.Paint.Style.STROKE + textSize = 200f + color = android.graphics.Color.BLACK + strokeWidth = 40f + strokeMiter= 15f + strokeJoin = android.graphics.Paint.Join.ROUND + } + + // Create a Paint that has white fill + val textPaint = Paint().asFrameworkPaint().apply { + isAntiAlias = true + style = android.graphics.Paint.Style.FILL + textSize = 200f + color = CustomOrange.hashCode() + } + + var userName by remember { mutableStateOf("") } + var userPassword by remember { mutableStateOf("") } + + Box( + contentAlignment = Alignment.BottomCenter, + modifier = Modifier.fillMaxSize() + ){ + Image( + painter = painterResource(id = R.drawable.login), + contentDescription = stringResource(id = R.string.tanks_main_title), + contentScale = ContentScale.Crop, + modifier = Modifier.fillMaxSize() + ) + Column( + modifier = Modifier.fillMaxSize() + .padding(0.dp, 40.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Column( + verticalArrangement = Arrangement.spacedBy(70.dp) + ){ + Canvas( + modifier = Modifier.fillMaxWidth(), + onDraw = { + drawIntoCanvas { + it.nativeCanvas.drawText( + "TANKS", + 240f, + 80.dp.toPx(), + textPaintStroke + ) + it.nativeCanvas.drawText( + "TANKS", + 240f, + 80.dp.toPx(), + textPaint + ) + } + } + ) + Canvas( + modifier = Modifier.fillMaxWidth(), + onDraw = { + drawIntoCanvas { + it.nativeCanvas.drawText( + "MOBILE", + 200f, + 80.dp.toPx(), + textPaintStroke + ) + it.nativeCanvas.drawText( + "MOBILE", + 200f, + 80.dp.toPx(), + textPaint + ) + } + } + ) + } + Spacer(modifier = Modifier.weight(1.0f)) + OutlinedTextField( + shape = RoundedCornerShape(50.dp), + value = userName, + placeholder = {Text(text = "Логин", color = CustomYellow)}, + onValueChange = { userName = it }, + modifier = Modifier + .width(200.dp) + .border(2.dp, CustomOrange, RoundedCornerShape(50.dp)), + colors = TextFieldDefaults.outlinedTextFieldColors( + containerColor = CustomBackground, + focusedBorderColor = CustomOrange, + unfocusedBorderColor = CustomOrange + ), + ) + Spacer(Modifier.height(10.dp)) + OutlinedTextField( + shape = RoundedCornerShape(50.dp), + value = userPassword, + placeholder = {Text(text = "Пароль", color = CustomYellow)}, + onValueChange = { userPassword = it }, + modifier = Modifier + .width(200.dp) + .border(2.dp, CustomOrange, RoundedCornerShape(50.dp)), + colors = TextFieldDefaults.outlinedTextFieldColors( + containerColor = CustomBackground, + focusedBorderColor = CustomOrange, + unfocusedBorderColor = CustomOrange + ), + ) + Spacer(Modifier.height(50.dp)) + Button( + modifier = Modifier + .width(200.dp) + .height(50.dp), + colors = ButtonDefaults.buttonColors( + containerColor = CustomYellow, + contentColor = CustomDark), + onClick = { navController.navigate(Screen.TankList.route) }) { + //"${student.firstName} ${student.lastName}" + Text(text = stringResource(id = R.string.login_button), fontSize = 20.sp) + } + Spacer(Modifier.height(25.dp)) + TextButton( + onClick={ navController.navigate(Screen.Register.route) } + ) { + Text( + text = stringResource(id = R.string.register_button), + color = CustomOrange, + fontSize = 20.sp + ) + } + } + } +} + +@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +fun LoginPreview() { + PmudemoTheme { + Surface( + color = CustomDark + ) { + val navController = rememberNavController() + Login(navController) + } + } +} \ No newline at end of file diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Register.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Register.kt new file mode 100644 index 0000000..6be38dd --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/tanks/composeui/Register.kt @@ -0,0 +1,155 @@ +package ru.ulstu.`is`.pmu.tanks.composeui + +import android.content.res.Configuration +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +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.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.material3.TextField +import androidx.compose.material3.TextFieldDefaults +import androidx.compose.runtime.Composable +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.graphics.Color +import androidx.compose.ui.graphics.StrokeJoin +import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.ExperimentalTextApi +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.navigation.NavController +import androidx.navigation.compose.currentBackStackEntryAsState +import androidx.navigation.compose.rememberNavController +import ru.ulstu.`is`.pmu.R +import ru.ulstu.`is`.pmu.composeui.navigation.Screen +import ru.ulstu.`is`.pmu.ui.theme.CustomBackground +import ru.ulstu.`is`.pmu.ui.theme.CustomDark +import ru.ulstu.`is`.pmu.ui.theme.CustomOrange +import ru.ulstu.`is`.pmu.ui.theme.CustomRed +import ru.ulstu.`is`.pmu.ui.theme.CustomYellow +import ru.ulstu.`is`.pmu.ui.theme.PmudemoTheme + +@OptIn(ExperimentalMaterial3Api::class, ExperimentalTextApi::class) +@Composable +fun Register(navController: NavController) { + val navBackStackEntry by navController.currentBackStackEntryAsState() + val currentDestination = navBackStackEntry?.destination + val currentScreen = currentDestination?.route?.let { Screen.getItem(it) } + + var userName by remember { mutableStateOf("") } + var userPassword by remember { mutableStateOf("") } + + Column( + modifier = Modifier + .fillMaxSize() + .background(CustomDark) + .padding(0.dp, 70.dp) + ){ + Image( + painter = painterResource(id = R.drawable.logo), + contentDescription = stringResource(id = R.string.tanks_main_title), + modifier = Modifier + .fillMaxWidth() + .height(150.dp) + ) + Column( + modifier = Modifier + .fillMaxSize() + .padding(0.dp, 40.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Text( + text = stringResource(id = R.string.register_button), + textAlign = TextAlign.Center, + fontWeight = FontWeight.Bold, + fontSize = 40.sp, + color = CustomOrange, + ) + Spacer(modifier = Modifier.weight(0.2f)) + Row( + horizontalArrangement = Arrangement.SpaceAround, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth() + ){ + Column( + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text(text="Логин:", fontSize = 30.sp, color = Color.White, fontWeight = FontWeight.Bold) + Spacer(Modifier.height(10.dp)) + Text(text="Пароль:", fontSize = 30.sp, color = Color.White, fontWeight = FontWeight.Bold) + } + Column { + TextField( + value = userName, + placeholder = { Text(text = "Логин", color = CustomDark) }, + onValueChange = { userName = it }, + modifier = Modifier + .width(200.dp), + ) + Spacer(Modifier.height(10.dp)) + TextField( + value = userPassword, + placeholder = { Text(text = "Пароль", color = CustomDark) }, + onValueChange = { userPassword = it }, + modifier = Modifier + .width(200.dp), + ) + } + } + Spacer(Modifier.weight(1.0f)) + Button( + modifier = Modifier + .width(200.dp) + .height(50.dp), + colors = ButtonDefaults.buttonColors( + containerColor = CustomRed, + contentColor = Color.White + ), + onClick = { navController.navigate(Screen.Login.route) }) { + //"${student.firstName} ${student.lastName}" + Text(text = stringResource(id = R.string.create_account_button), fontSize = 20.sp) + } + } + } +} + +@Preview(name = "Light Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_NO) +@Preview(name = "Dark Mode", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES) +@Composable +fun RegisterPreview() { + PmudemoTheme { + Surface( + + ) { + val navController = rememberNavController() + Register(navController) + } + } +} \ No newline at end of file diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/ui/theme/Color.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/ui/theme/Color.kt new file mode 100644 index 0000000..8b668e0 --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/ui/theme/Color.kt @@ -0,0 +1,10 @@ +package ru.ulstu.`is`.pmu.ui.theme + +import androidx.compose.ui.graphics.Color + +val CustomYellow = Color(0xFFFAB81B) +val CustomOrange = Color(0xFFF25322) +val CustomDark = Color(0xFF212121) +val CustomRed = Color(0xFFA61C00) + +val CustomBackground = Color(0x00FAB81B) \ No newline at end of file diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/ui/theme/Theme.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/ui/theme/Theme.kt new file mode 100644 index 0000000..8cd41fd --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/ui/theme/Theme.kt @@ -0,0 +1,72 @@ +package ru.ulstu.`is`.pmu.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.runtime.SideEffect +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalView +import androidx.core.view.WindowCompat + +private val DarkColorScheme = darkColorScheme( + primary = CustomYellow, + secondary = CustomOrange, + tertiary = CustomRed, + background = CustomDark +) + +private val LightColorScheme = lightColorScheme( + primary = CustomYellow, + secondary = CustomOrange, + tertiary = CustomRed, + background = CustomDark + + /* 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 PmudemoTheme( + 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 + } + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as Activity).window + window.statusBarColor = colorScheme.primary.toArgb() + WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme + } + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) +} \ No newline at end of file diff --git a/compose/compose/app/src/main/java/ru/ulstu/is/pmu/ui/theme/Type.kt b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/ui/theme/Type.kt new file mode 100644 index 0000000..40dc6ca --- /dev/null +++ b/compose/compose/app/src/main/java/ru/ulstu/is/pmu/ui/theme/Type.kt @@ -0,0 +1,34 @@ +package ru.ulstu.`is`.pmu.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/compose/compose/app/src/main/res/drawable/ic_launcher_background.xml b/compose/compose/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/compose/compose/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/compose/compose/app/src/main/res/drawable/ic_launcher_foreground.xml b/compose/compose/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/compose/compose/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/compose/compose/app/src/main/res/drawable/login.jpg b/compose/compose/app/src/main/res/drawable/login.jpg new file mode 100644 index 0000000..96b4fd6 Binary files /dev/null and b/compose/compose/app/src/main/res/drawable/login.jpg differ diff --git a/compose/compose/app/src/main/res/drawable/logo.png b/compose/compose/app/src/main/res/drawable/logo.png new file mode 100644 index 0000000..7316adf Binary files /dev/null and b/compose/compose/app/src/main/res/drawable/logo.png differ diff --git a/compose/compose/app/src/main/res/drawable/sherman.jpg b/compose/compose/app/src/main/res/drawable/sherman.jpg new file mode 100644 index 0000000..4fbe54c Binary files /dev/null and b/compose/compose/app/src/main/res/drawable/sherman.jpg differ diff --git a/compose/compose/app/src/main/res/drawable/t_34_85.jpeg b/compose/compose/app/src/main/res/drawable/t_34_85.jpeg new file mode 100644 index 0000000..c50d054 Binary files /dev/null and b/compose/compose/app/src/main/res/drawable/t_34_85.jpeg differ diff --git a/compose/compose/app/src/main/res/drawable/tanks_mobile_main_logo.png b/compose/compose/app/src/main/res/drawable/tanks_mobile_main_logo.png new file mode 100644 index 0000000..c4beb31 Binary files /dev/null and b/compose/compose/app/src/main/res/drawable/tanks_mobile_main_logo.png differ diff --git a/compose/compose/app/src/main/res/drawable/tiger_1.jpg b/compose/compose/app/src/main/res/drawable/tiger_1.jpg new file mode 100644 index 0000000..3e5b52b Binary files /dev/null and b/compose/compose/app/src/main/res/drawable/tiger_1.jpg differ diff --git a/compose/compose/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/compose/compose/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/compose/compose/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/compose/compose/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/compose/compose/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/compose/compose/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/compose/compose/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/compose/compose/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000..c209e78 Binary files /dev/null and b/compose/compose/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/compose/compose/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/compose/compose/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000..b2dfe3d Binary files /dev/null and b/compose/compose/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/compose/compose/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/compose/compose/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000..4f0f1d6 Binary files /dev/null and b/compose/compose/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/compose/compose/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/compose/compose/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000..62b611d Binary files /dev/null and b/compose/compose/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/compose/compose/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/compose/compose/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000..948a307 Binary files /dev/null and b/compose/compose/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/compose/compose/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/compose/compose/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..1b9a695 Binary files /dev/null and b/compose/compose/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/compose/compose/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/compose/compose/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000..28d4b77 Binary files /dev/null and b/compose/compose/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/compose/compose/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/compose/compose/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9287f50 Binary files /dev/null and b/compose/compose/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/compose/compose/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/compose/compose/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000..aa7d642 Binary files /dev/null and b/compose/compose/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/compose/compose/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/compose/compose/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9126ae3 Binary files /dev/null and b/compose/compose/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/compose/compose/app/src/main/res/values/colors.xml b/compose/compose/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..f7e4ae9 --- /dev/null +++ b/compose/compose/app/src/main/res/values/colors.xml @@ -0,0 +1,14 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + #FFFAB81B + #FFF25322 + #FF212121 + #FFA61C00 + \ No newline at end of file diff --git a/compose/compose/app/src/main/res/values/strings.xml b/compose/compose/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..aca823a --- /dev/null +++ b/compose/compose/app/src/main/res/values/strings.xml @@ -0,0 +1,34 @@ + + TANKS MOBILE + Login + Register + Генератор + Ангар + Аккаунт + Главная + СССР + Германия + США + Купить + Войти + Создать + Сохранить + Регистрация + Имя + Фамилия + Группа + Телефон + e-mail + Главная + Профиль студента + Генератор + Список техники по: + T-34-85 + Sherman + Tiger 1 + +

Это текст о нас!

\n\n +

Здесь могла быть Ваша реклама!

\n\n +

Наш сайт ulstu.ru

+
+
\ No newline at end of file diff --git a/compose/compose/app/src/main/res/values/themes.xml b/compose/compose/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..bf6a6ee --- /dev/null +++ b/compose/compose/app/src/main/res/values/themes.xml @@ -0,0 +1,5 @@ + + + +