diff --git a/Unit1/Pathway3/BirthdayCard/app/src/main/java/com/example/happybirthday/MainActivity.kt b/Unit1/Pathway3/BirthdayCard/app/src/main/java/com/example/happybirthday/MainActivity.kt
index 8fe0316fb..8f45b0532 100644
--- a/Unit1/Pathway3/BirthdayCard/app/src/main/java/com/example/happybirthday/MainActivity.kt
+++ b/Unit1/Pathway3/BirthdayCard/app/src/main/java/com/example/happybirthday/MainActivity.kt
@@ -38,7 +38,9 @@ import com.example.happybirthday.ui.theme.HappyBirthdayTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContent { }
+ setContent {
+
+ }
}
}
@@ -46,15 +48,51 @@ class MainActivity : ComponentActivity() {
@Composable
fun BirthdayGreetingWithText(message: String, from: String) {
// Create a column so that texts don't overlap
- Column { }
+ Column {
+ Text(
+ text = message,
+ fontSize = 36.sp,
+ modifier = Modifier
+ .fillMaxWidth()
+ .wrapContentWidth(Alignment.CenterHorizontally)
+ .padding(start = 16.dp, top = 16.dp)
+ )
+ Text(
+ text = from,
+ fontSize = 24.sp,
+ modifier = Modifier
+ .fillMaxWidth()
+ .wrapContentWidth(Alignment.CenterHorizontally)
+ .padding(start = 16.dp, end = 16.dp)
+ )
+
+ }
}
// 5. Box 레이아웃 추
@Composable
-fun BirthdayGreetingWithImage(message: String, from: String) { }
+fun BirthdayGreetingWithImage(message: String, from: String) {
+ val image = painterResource(R.drawable.androidparty)
+ Image(
+ painter = image,
+ contentDescription = null,
+ modifier = Modifier
+ .fillMaxHeight()
+ .fillMaxWidth(),
+ contentScale = ContentScale.Crop
+ )
+ BirthdayGreetingWithText(message = message, from = from)
+}
// 4. 이미지 컴포저블 추가
-@Preview(showBackground = false)
+@Preview(showBackground = true)
@Composable
-private fun BirthdayCardPreview() { }
+private fun BirthdayCardPreview() {
+ HappyBirthdayTheme {
+ BirthdayGreetingWithImage(
+ stringResource(R.string.happy_birthday_text),
+ stringResource(R.string.signature_text)
+ )
+ }
+}
diff --git a/Unit1/Pathway3/BirthdayCard/app/src/main/res/drawable-nodpi/androidparty.png b/Unit1/Pathway3/BirthdayCard/app/src/main/res/drawable-nodpi/androidparty.png
new file mode 100644
index 000000000..87124d659
Binary files /dev/null and b/Unit1/Pathway3/BirthdayCard/app/src/main/res/drawable-nodpi/androidparty.png differ
diff --git a/Unit1/Pathway3/BirthdayCard/app/src/main/res/values/strings.xml b/Unit1/Pathway3/BirthdayCard/app/src/main/res/values/strings.xml
index 3a180adfa..3be91d855 100644
--- a/Unit1/Pathway3/BirthdayCard/app/src/main/res/values/strings.xml
+++ b/Unit1/Pathway3/BirthdayCard/app/src/main/res/values/strings.xml
@@ -16,4 +16,6 @@
-->
Happy Birthday
+ Happy Birthday Sam!
+ - from Namju
\ No newline at end of file
diff --git a/Unit1/Pathway3/ComposeArticle/app/src/main/java/com/example/composearticle/MainActivity.kt b/Unit1/Pathway3/ComposeArticle/app/src/main/java/com/example/composearticle/MainActivity.kt
index da2245997..547c40713 100644
--- a/Unit1/Pathway3/ComposeArticle/app/src/main/java/com/example/composearticle/MainActivity.kt
+++ b/Unit1/Pathway3/ComposeArticle/app/src/main/java/com/example/composearticle/MainActivity.kt
@@ -24,12 +24,25 @@ import com.example.composearticle.ui.theme.ComposeArticleTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContent { }
+ setContent {
+ ComposeArticleTheme {
+ Surface(color = MaterialTheme.colors.background) {
+ ComposeArticleApp()
+ }
+ }
+ }
}
}
@Composable
-fun ComposeArticleApp() { }
+fun ComposeArticleApp() {
+ ArticleCard(
+ title = stringResource(R.string.title_jetpack_compose_tutorial),
+ shortDescription = stringResource(R.string.compose_short_desc),
+ longDescription = stringResource(R.string.compose_long_desc),
+ imagePainter = painterResource(id = R.drawable.bg_compose_background)
+ )
+}
@Composable
private fun ArticleCard(
@@ -39,10 +52,39 @@ private fun ArticleCard(
imagePainter: Painter,
modifier: Modifier = Modifier,
) {
- Column() { }
+ Column {
+ Image(
+ painter = imagePainter,
+ contentDescription = null
+ )
+ Text(
+ text = title,
+ fontSize = 24.sp,
+ modifier = Modifier.padding(16.dp)
+ )
+ Text(
+ text = shortDescription,
+ textAlign = TextAlign.Justify,
+ modifier = Modifier.padding(
+ start = 16.dp,
+ end = 16.dp
+ )
+ )
+ Text(
+ text = longDescription,
+ textAlign = TextAlign.Justify,
+ modifier = Modifier.padding(16.dp)
+ )
+ }
}
@Preview(showBackground = true)
@Composable
-fun DefaultPreview() { }
\ No newline at end of file
+fun DefaultPreview() {
+ ComposeArticleTheme() {
+ Surface {
+ ComposeArticleApp()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Unit1/Pathway3/ComposeQuadrant/app/src/main/java/com/example/composequadrant/MainActivity.kt b/Unit1/Pathway3/ComposeQuadrant/app/src/main/java/com/example/composequadrant/MainActivity.kt
index 61b87324c..f64873024 100644
--- a/Unit1/Pathway3/ComposeQuadrant/app/src/main/java/com/example/composequadrant/MainActivity.kt
+++ b/Unit1/Pathway3/ComposeQuadrant/app/src/main/java/com/example/composequadrant/MainActivity.kt
@@ -22,15 +22,47 @@ import com.example.composequadrant.ui.theme.ComposeQuadrantTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContent { }
+ setContent {
+ ComposeQuadrantTheme {
+ Surface(color = MaterialTheme.colors.background) {
+ ComposeQuadrantApp()
+ }
+ }
+ }
}
}
@Composable
fun ComposeQuadrantApp() {
- Column() {
- Row() { }
- Row() { }
+ Column(Modifier.fillMaxWidth()) {
+ Row(Modifier.weight(1f)) {
+ ComposableInfoCard(
+ title = stringResource(R.string.first_title),
+ description = stringResource(R.string.first_description),
+ backgroundColor = Color.Green,
+ modifier = Modifier.weight(1f)
+ )
+ ComposableInfoCard(
+ title = stringResource(R.string.second_title),
+ description = stringResource(R.string.second_description),
+ backgroundColor = Color.Yellow,
+ modifier = Modifier.weight(1f)
+ )
+ }
+ Row(Modifier.weight(1f)) {
+ ComposableInfoCard(
+ title = stringResource(R.string.third_title),
+ description = stringResource(R.string.third_description),
+ backgroundColor = Color.Cyan,
+ modifier = Modifier.weight(1f)
+ )
+ ComposableInfoCard(
+ title = stringResource(R.string.fourth_title),
+ description = stringResource(R.string.fourth_description),
+ backgroundColor = Color.LightGray,
+ modifier = Modifier.weight(1f)
+ )
+ }
}
}
@@ -41,10 +73,33 @@ private fun ComposableInfoCard(
backgroundColor: Color,
modifier: Modifier = Modifier
) {
- Column( ) { }
+ Column(
+ modifier = modifier
+ .fillMaxSize()
+ .background(backgroundColor)
+ .padding(16.dp),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center
+ ) {
+ Text(
+ text = title,
+ fontWeight = FontWeight.Bold,
+ modifier = Modifier.padding(bottom = 16.dp)
+ )
+ Text(
+ text = description,
+ textAlign = TextAlign.Justify
+ )
+ }
}
@Preview(showBackground = true)
@Composable
-fun DefaultPreview() { }
\ No newline at end of file
+fun DefaultPreview() {
+ ComposeQuadrantTheme {
+ Surface {
+ ComposeQuadrantApp()
+ }
+ }
+}
\ No newline at end of file
diff --git a/Unit1/Pathway3/TaskCompleted/app/src/main/java/com/example/taskcompleted/MainActivity.kt b/Unit1/Pathway3/TaskCompleted/app/src/main/java/com/example/taskcompleted/MainActivity.kt
index 840cfd96c..5b86af4f8 100644
--- a/Unit1/Pathway3/TaskCompleted/app/src/main/java/com/example/taskcompleted/MainActivity.kt
+++ b/Unit1/Pathway3/TaskCompleted/app/src/main/java/com/example/taskcompleted/MainActivity.kt
@@ -22,15 +22,43 @@ import com.example.taskcompleted.ui.theme.TaskCompletedTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContent { }
+ setContent {
+ TaskCompletedTheme() {
+ Surface {
+ TaskCompletedScreen()
+ }
+ }
+ }
}
}
@Composable
fun TaskCompletedScreen() {
- Column( ) { }
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .fillMaxHeight(),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center
+ ) {
+ val image = painterResource(R.drawable.ic_task_completed)
+ Image(painter = image, contentDescription = null)
+ Text(
+ text = stringResource(R.string.all_task_completed),
+ fontWeight = FontWeight.Bold,
+ modifier = Modifier.padding(top = 24.dp, bottom = 8.dp)
+ )
+ Text(
+ text = stringResource(R.string.nice_work),
+ fontSize = 16.sp
+ )
+ }
}
@Preview(showBackground = true)
@Composable
-fun DefaultPreview() { }
\ No newline at end of file
+fun DefaultPreview() {
+ Surface {
+ TaskCompletedScreen()
+ }
+}
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/.gitignore b/Unit2/Pathway2/DiceRoller/.gitignore
new file mode 100644
index 000000000..aa724b770
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/Unit2/Pathway2/DiceRoller/app/.gitignore b/Unit2/Pathway2/DiceRoller/app/.gitignore
new file mode 100644
index 000000000..42afabfd2
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/app/build.gradle b/Unit2/Pathway2/DiceRoller/app/build.gradle
new file mode 100644
index 000000000..4d86dc2b7
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/build.gradle
@@ -0,0 +1,63 @@
+plugins {
+ id 'com.android.application'
+ id 'org.jetbrains.kotlin.android'
+}
+
+android {
+ namespace 'com.example.diceroller'
+ compileSdk 32
+
+ defaultConfig {
+ applicationId "com.example.diceroller"
+ minSdk 21
+ targetSdk 32
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ vectorDrawables {
+ useSupportLibrary true
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled 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.1.1'
+ }
+ packagingOptions {
+ resources {
+ excludes += '/META-INF/{AL2.0,LGPL2.1}'
+ }
+ }
+}
+
+dependencies {
+
+ implementation 'androidx.core:core-ktx:1.7.0'
+ implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
+ implementation 'androidx.activity:activity-compose:1.3.1'
+ implementation "androidx.compose.ui:ui:$compose_ui_version"
+ implementation "androidx.compose.ui:ui-tooling-preview:$compose_ui_version"
+ implementation 'androidx.compose.material:material:1.1.1'
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+ androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version"
+ debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version"
+ debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_ui_version"
+}
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/app/proguard-rules.pro b/Unit2/Pathway2/DiceRoller/app/proguard-rules.pro
new file mode 100644
index 000000000..481bb4348
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/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/Unit2/Pathway2/DiceRoller/app/src/androidTest/java/com/example/diceroller/ExampleInstrumentedTest.kt b/Unit2/Pathway2/DiceRoller/app/src/androidTest/java/com/example/diceroller/ExampleInstrumentedTest.kt
new file mode 100644
index 000000000..56697a23d
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/androidTest/java/com/example/diceroller/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.example.diceroller
+
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("com.example.diceroller", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/AndroidManifest.xml b/Unit2/Pathway2/DiceRoller/app/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..6f64e271f
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/AndroidManifest.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/java/com/example/diceroller/MainActivity.kt b/Unit2/Pathway2/DiceRoller/app/src/main/java/com/example/diceroller/MainActivity.kt
new file mode 100644
index 000000000..20cb12524
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/java/com/example/diceroller/MainActivity.kt
@@ -0,0 +1,79 @@
+package com.example.diceroller
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.material.Button
+import androidx.compose.material.Text
+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.painter.Painter
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.example.diceroller.ui.theme.DiceRollerTheme
+
+class MainActivity : ComponentActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent {
+ DiceRollerTheme {
+ DiceRollerApp()
+ }
+ }
+ }
+}
+
+@Preview
+@Composable
+fun DiceRollerApp() {
+ DiceWithButtonAndImage(
+ modifier = Modifier
+ .fillMaxSize()
+ .wrapContentSize(Alignment.Center)
+ )
+
+}
+
+@Composable
+fun DiceWithButtonAndImage(modifier: Modifier = Modifier) {
+ var result by remember { mutableStateOf(1) }
+ val imageResource = when (result) {
+ 1 -> R.drawable.dice_1
+ 2 -> R.drawable.dice_2
+ 3 -> R.drawable.dice_3
+ 4 -> R.drawable.dice_4
+ 5 -> R.drawable.dice_5
+ else -> R.drawable.dice_6
+ }
+ Column(
+ modifier = modifier,
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Image(
+ painter = painterResource(imageResource),
+ contentDescription = result.toString()
+ )
+ Spacer(
+ modifier = Modifier.height(16.dp)
+ )
+ Button(
+ onClick = { result = (1..6).random() }
+ ) {
+ Text(text = stringResource(R.string.roll), fontSize = 24.sp)
+ }
+ }
+}
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/java/com/example/diceroller/ui/theme/Color.kt b/Unit2/Pathway2/DiceRoller/app/src/main/java/com/example/diceroller/ui/theme/Color.kt
new file mode 100644
index 000000000..a15709145
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/java/com/example/diceroller/ui/theme/Color.kt
@@ -0,0 +1,8 @@
+package com.example.diceroller.ui.theme
+
+import androidx.compose.ui.graphics.Color
+
+val Purple200 = Color(0xFFBB86FC)
+val Purple500 = Color(0xFF6200EE)
+val Purple700 = Color(0xFF3700B3)
+val Teal200 = Color(0xFF03DAC5)
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/java/com/example/diceroller/ui/theme/Shape.kt b/Unit2/Pathway2/DiceRoller/app/src/main/java/com/example/diceroller/ui/theme/Shape.kt
new file mode 100644
index 000000000..fc2b35df7
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/java/com/example/diceroller/ui/theme/Shape.kt
@@ -0,0 +1,11 @@
+package com.example.diceroller.ui.theme
+
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Shapes
+import androidx.compose.ui.unit.dp
+
+val Shapes = Shapes(
+ small = RoundedCornerShape(4.dp),
+ medium = RoundedCornerShape(4.dp),
+ large = RoundedCornerShape(0.dp)
+)
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/java/com/example/diceroller/ui/theme/Theme.kt b/Unit2/Pathway2/DiceRoller/app/src/main/java/com/example/diceroller/ui/theme/Theme.kt
new file mode 100644
index 000000000..69e7a8021
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/java/com/example/diceroller/ui/theme/Theme.kt
@@ -0,0 +1,44 @@
+package com.example.diceroller.ui.theme
+
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.darkColors
+import androidx.compose.material.lightColors
+import androidx.compose.runtime.Composable
+
+private val DarkColorPalette = darkColors(
+ primary = Purple200,
+ primaryVariant = Purple700,
+ secondary = Teal200
+)
+
+private val LightColorPalette = lightColors(
+ primary = Purple500,
+ primaryVariant = Purple700,
+ secondary = Teal200
+
+ /* Other default colors to override
+ background = Color.White,
+ surface = Color.White,
+ onPrimary = Color.White,
+ onSecondary = Color.Black,
+ onBackground = Color.Black,
+ onSurface = Color.Black,
+ */
+)
+
+@Composable
+fun DiceRollerTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {
+ val colors = if (darkTheme) {
+ DarkColorPalette
+ } else {
+ LightColorPalette
+ }
+
+ MaterialTheme(
+ colors = colors,
+ typography = Typography,
+ shapes = Shapes,
+ content = content
+ )
+}
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/java/com/example/diceroller/ui/theme/Type.kt b/Unit2/Pathway2/DiceRoller/app/src/main/java/com/example/diceroller/ui/theme/Type.kt
new file mode 100644
index 000000000..9719bbc73
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/java/com/example/diceroller/ui/theme/Type.kt
@@ -0,0 +1,28 @@
+package com.example.diceroller.ui.theme
+
+import androidx.compose.material.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(
+ body1 = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 16.sp
+ )
+ /* Other default text styles to override
+ button = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.W500,
+ fontSize = 14.sp
+ ),
+ caption = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 12.sp
+ )
+ */
+)
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 000000000..2b068d114
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/dice_1.xml b/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/dice_1.xml
new file mode 100644
index 000000000..2bd436bb6
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/dice_1.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/dice_2.xml b/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/dice_2.xml
new file mode 100644
index 000000000..30fb235c0
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/dice_2.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/dice_3.xml b/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/dice_3.xml
new file mode 100644
index 000000000..20bf47221
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/dice_3.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/dice_4.xml b/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/dice_4.xml
new file mode 100644
index 000000000..772737d9c
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/dice_4.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/dice_5.xml b/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/dice_5.xml
new file mode 100644
index 000000000..b1e6afe83
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/dice_5.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/dice_6.xml b/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/dice_6.xml
new file mode 100644
index 000000000..484f92e8a
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/dice_6.xml
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/ic_launcher_background.xml b/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 000000000..07d5da9cb
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 000000000..eca70cfe5
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 000000000..eca70cfe5
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 000000000..c209e78ec
Binary files /dev/null and b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..b2dfe3d1b
Binary files /dev/null and b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 000000000..4f0f1d64e
Binary files /dev/null and b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..62b611da0
Binary files /dev/null and b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 000000000..948a3070f
Binary files /dev/null and b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..1b9a6956b
Binary files /dev/null and b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 000000000..28d4b77f9
Binary files /dev/null and b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..9287f5083
Binary files /dev/null and b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 000000000..aa7d6427e
Binary files /dev/null and b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..9126ae37c
Binary files /dev/null and b/Unit2/Pathway2/DiceRoller/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/values/colors.xml b/Unit2/Pathway2/DiceRoller/app/src/main/res/values/colors.xml
new file mode 100644
index 000000000..f8c6127d3
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/values/strings.xml b/Unit2/Pathway2/DiceRoller/app/src/main/res/values/strings.xml
new file mode 100644
index 000000000..849d007d3
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/res/values/strings.xml
@@ -0,0 +1,4 @@
+
+ Dice Roller
+ Roll
+
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/values/themes.xml b/Unit2/Pathway2/DiceRoller/app/src/main/res/values/themes.xml
new file mode 100644
index 000000000..1d1b2f6c1
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/res/values/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/xml/backup_rules.xml b/Unit2/Pathway2/DiceRoller/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 000000000..fa0f996d2
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/app/src/main/res/xml/data_extraction_rules.xml b/Unit2/Pathway2/DiceRoller/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 000000000..9ee9997b0
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/app/src/test/java/com/example/diceroller/ExampleUnitTest.kt b/Unit2/Pathway2/DiceRoller/app/src/test/java/com/example/diceroller/ExampleUnitTest.kt
new file mode 100644
index 000000000..9136b8558
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/app/src/test/java/com/example/diceroller/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.diceroller
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+ @Test
+ fun addition_isCorrect() {
+ assertEquals(4, 2 + 2)
+ }
+}
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/build.gradle b/Unit2/Pathway2/DiceRoller/build.gradle
new file mode 100644
index 000000000..15dff9ef8
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/build.gradle
@@ -0,0 +1,10 @@
+buildscript {
+ ext {
+ compose_ui_version = '1.1.1'
+ }
+}// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ id 'com.android.application' version '7.3.1' apply false
+ id 'com.android.library' version '7.3.1' apply false
+ id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
+}
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/gradle.properties b/Unit2/Pathway2/DiceRoller/gradle.properties
new file mode 100644
index 000000000..3c5031eb7
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/Unit2/Pathway2/DiceRoller/gradle/wrapper/gradle-wrapper.jar b/Unit2/Pathway2/DiceRoller/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 000000000..e708b1c02
Binary files /dev/null and b/Unit2/Pathway2/DiceRoller/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Unit2/Pathway2/DiceRoller/gradle/wrapper/gradle-wrapper.properties b/Unit2/Pathway2/DiceRoller/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000..68dd7a7f4
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Dec 08 01:23:41 KST 2022
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/Unit2/Pathway2/DiceRoller/gradlew b/Unit2/Pathway2/DiceRoller/gradlew
new file mode 100644
index 000000000..4f906e0c8
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/Unit2/Pathway2/DiceRoller/gradlew.bat b/Unit2/Pathway2/DiceRoller/gradlew.bat
new file mode 100644
index 000000000..107acd32c
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Unit2/Pathway2/DiceRoller/settings.gradle b/Unit2/Pathway2/DiceRoller/settings.gradle
new file mode 100644
index 000000000..63e5f0ead
--- /dev/null
+++ b/Unit2/Pathway2/DiceRoller/settings.gradle
@@ -0,0 +1,16 @@
+pluginManagement {
+ repositories {
+ gradlePluginPortal()
+ google()
+ mavenCentral()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+rootProject.name = "Dice Roller"
+include ':app'
diff --git a/Unit2/Pathway2/Lemonade/.gitignore b/Unit2/Pathway2/Lemonade/.gitignore
new file mode 100644
index 000000000..aa724b770
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/Unit2/Pathway2/Lemonade/app/.gitignore b/Unit2/Pathway2/Lemonade/app/.gitignore
new file mode 100644
index 000000000..42afabfd2
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/app/build.gradle b/Unit2/Pathway2/Lemonade/app/build.gradle
new file mode 100644
index 000000000..d872b8eff
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/build.gradle
@@ -0,0 +1,63 @@
+plugins {
+ id 'com.android.application'
+ id 'org.jetbrains.kotlin.android'
+}
+
+android {
+ namespace 'com.example.lemonade'
+ compileSdk 32
+
+ defaultConfig {
+ applicationId "com.example.lemonade"
+ minSdk 21
+ targetSdk 32
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ vectorDrawables {
+ useSupportLibrary true
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled 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.1.1'
+ }
+ packagingOptions {
+ resources {
+ excludes += '/META-INF/{AL2.0,LGPL2.1}'
+ }
+ }
+}
+
+dependencies {
+
+ implementation 'androidx.core:core-ktx:1.7.0'
+ implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
+ implementation 'androidx.activity:activity-compose:1.3.1'
+ implementation "androidx.compose.ui:ui:$compose_ui_version"
+ implementation "androidx.compose.ui:ui-tooling-preview:$compose_ui_version"
+ implementation 'androidx.compose.material:material:1.1.1'
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+ androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version"
+ debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version"
+ debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_ui_version"
+}
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/app/proguard-rules.pro b/Unit2/Pathway2/Lemonade/app/proguard-rules.pro
new file mode 100644
index 000000000..481bb4348
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/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/Unit2/Pathway2/Lemonade/app/src/androidTest/java/com/example/lemonade/ExampleInstrumentedTest.kt b/Unit2/Pathway2/Lemonade/app/src/androidTest/java/com/example/lemonade/ExampleInstrumentedTest.kt
new file mode 100644
index 000000000..d1cc255b1
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/androidTest/java/com/example/lemonade/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.example.lemonade
+
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("com.example.lemonade", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/AndroidManifest.xml b/Unit2/Pathway2/Lemonade/app/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..2f14b6ee8
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/AndroidManifest.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/java/com/example/lemonade/MainActivity.kt b/Unit2/Pathway2/Lemonade/app/src/main/java/com/example/lemonade/MainActivity.kt
new file mode 100644
index 000000000..f1bd1f1bc
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/java/com/example/lemonade/MainActivity.kt
@@ -0,0 +1,148 @@
+package com.example.lemonade
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.BorderStroke
+import androidx.compose.foundation.Image
+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.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Surface
+import androidx.compose.material.Text
+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.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.example.lemonade.ui.theme.LemonadeTheme
+
+class MainActivity : ComponentActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent {
+ LemonadeTheme {
+ LemonApp()
+ }
+ }
+ }
+}
+
+@Composable
+fun LemonApp() {
+
+ var currentStep by remember { mutableStateOf(1) }
+ var squeezeCount by remember { mutableStateOf(0) }
+
+ Surface(
+ modifier = Modifier.fillMaxSize(),
+ color = MaterialTheme.colors.background
+ ) {
+ when (currentStep) {
+ 1 -> {
+ LemonTextAndImage(
+ textLabelResourceId = R.string.lemon_select,
+ drawableResourceId = R.drawable.lemon_tree,
+ contentDescriptionResourceId = R.string.lemon_tree_content_description,
+ onImageClick = {
+ currentStep = 2
+ squeezeCount = (2..4).random()
+ }
+ )
+ }
+ 2 -> {
+ LemonTextAndImage(
+ textLabelResourceId = R.string.lemon_squeeze,
+ drawableResourceId = R.drawable.lemon_squeeze,
+ contentDescriptionResourceId = R.string.lemon_content_description,
+ onImageClick = {
+ squeezeCount--
+ if (squeezeCount == 0) {
+ currentStep = 3
+ }
+ }
+ )
+ }
+ 3 -> {
+ LemonTextAndImage(
+ textLabelResourceId = R.string.lemon_drink,
+ drawableResourceId = R.drawable.lemon_drink,
+ contentDescriptionResourceId = R.string.lemonade_content_description,
+ onImageClick = {
+ currentStep = 4
+ }
+ )
+ }
+ 4 -> {
+ LemonTextAndImage(
+ textLabelResourceId = R.string.lemon_empty_glass,
+ drawableResourceId = R.drawable.lemon_restart,
+ contentDescriptionResourceId = R.string.empty_glass_content_description,
+ onImageClick = {
+ currentStep = 1
+ }
+ )
+ }
+ }
+ }
+}
+
+@Composable
+fun LemonTextAndImage(
+ textLabelResourceId: Int,
+ drawableResourceId: Int,
+ contentDescriptionResourceId: Int,
+ onImageClick: () -> Unit,
+ modifier: Modifier = Modifier
+) {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center,
+ modifier = modifier.fillMaxSize()
+ ) {
+ Text(
+ text = stringResource(textLabelResourceId),
+ fontSize = 18.sp
+ )
+ Spacer(modifier = Modifier.height(16.dp))
+ Image(
+ painter = painterResource(drawableResourceId),
+ contentDescription = stringResource(contentDescriptionResourceId),
+ modifier = Modifier
+ .wrapContentSize()
+ .clickable(
+ onClick = onImageClick
+ )
+ .border(
+ BorderStroke(2.dp, Color(105, 205, 216)),
+ shape = RoundedCornerShape(4.dp)
+ )
+ .padding(16.dp)
+ )
+ }
+}
+
+@Preview
+@Composable
+fun LemonPreview() {
+ LemonadeTheme() {
+ LemonApp()
+ }
+}
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/java/com/example/lemonade/ui/theme/Color.kt b/Unit2/Pathway2/Lemonade/app/src/main/java/com/example/lemonade/ui/theme/Color.kt
new file mode 100644
index 000000000..7d85d84f9
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/java/com/example/lemonade/ui/theme/Color.kt
@@ -0,0 +1,8 @@
+package com.example.lemonade.ui.theme
+
+import androidx.compose.ui.graphics.Color
+
+val Purple200 = Color(0xFFBB86FC)
+val Purple500 = Color(0xFF6200EE)
+val Purple700 = Color(0xFF3700B3)
+val Teal200 = Color(0xFF03DAC5)
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/java/com/example/lemonade/ui/theme/Shape.kt b/Unit2/Pathway2/Lemonade/app/src/main/java/com/example/lemonade/ui/theme/Shape.kt
new file mode 100644
index 000000000..7493aa03f
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/java/com/example/lemonade/ui/theme/Shape.kt
@@ -0,0 +1,11 @@
+package com.example.lemonade.ui.theme
+
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Shapes
+import androidx.compose.ui.unit.dp
+
+val Shapes = Shapes(
+ small = RoundedCornerShape(4.dp),
+ medium = RoundedCornerShape(4.dp),
+ large = RoundedCornerShape(0.dp)
+)
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/java/com/example/lemonade/ui/theme/Theme.kt b/Unit2/Pathway2/Lemonade/app/src/main/java/com/example/lemonade/ui/theme/Theme.kt
new file mode 100644
index 000000000..3cbd0358d
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/java/com/example/lemonade/ui/theme/Theme.kt
@@ -0,0 +1,44 @@
+package com.example.lemonade.ui.theme
+
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.darkColors
+import androidx.compose.material.lightColors
+import androidx.compose.runtime.Composable
+
+private val DarkColorPalette = darkColors(
+ primary = Purple200,
+ primaryVariant = Purple700,
+ secondary = Teal200
+)
+
+private val LightColorPalette = lightColors(
+ primary = Purple500,
+ primaryVariant = Purple700,
+ secondary = Teal200
+
+ /* Other default colors to override
+ background = Color.White,
+ surface = Color.White,
+ onPrimary = Color.White,
+ onSecondary = Color.Black,
+ onBackground = Color.Black,
+ onSurface = Color.Black,
+ */
+)
+
+@Composable
+fun LemonadeTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {
+ val colors = if (darkTheme) {
+ DarkColorPalette
+ } else {
+ LightColorPalette
+ }
+
+ MaterialTheme(
+ colors = colors,
+ typography = Typography,
+ shapes = Shapes,
+ content = content
+ )
+}
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/java/com/example/lemonade/ui/theme/Type.kt b/Unit2/Pathway2/Lemonade/app/src/main/java/com/example/lemonade/ui/theme/Type.kt
new file mode 100644
index 000000000..7481002c8
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/java/com/example/lemonade/ui/theme/Type.kt
@@ -0,0 +1,28 @@
+package com.example.lemonade.ui.theme
+
+import androidx.compose.material.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(
+ body1 = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 16.sp
+ )
+ /* Other default text styles to override
+ button = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.W500,
+ fontSize = 14.sp
+ ),
+ caption = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 12.sp
+ )
+ */
+)
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/Unit2/Pathway2/Lemonade/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 000000000..2b068d114
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/drawable/ic_launcher_background.xml b/Unit2/Pathway2/Lemonade/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 000000000..07d5da9cb
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/drawable/lemon_drink.xml b/Unit2/Pathway2/Lemonade/app/src/main/res/drawable/lemon_drink.xml
new file mode 100644
index 000000000..1675978b2
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/res/drawable/lemon_drink.xml
@@ -0,0 +1,103 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/drawable/lemon_restart.xml b/Unit2/Pathway2/Lemonade/app/src/main/res/drawable/lemon_restart.xml
new file mode 100644
index 000000000..c5f5379bf
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/res/drawable/lemon_restart.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/drawable/lemon_squeeze.xml b/Unit2/Pathway2/Lemonade/app/src/main/res/drawable/lemon_squeeze.xml
new file mode 100644
index 000000000..cc90a9324
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/res/drawable/lemon_squeeze.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/drawable/lemon_tree.xml b/Unit2/Pathway2/Lemonade/app/src/main/res/drawable/lemon_tree.xml
new file mode 100644
index 000000000..a307871cd
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/res/drawable/lemon_tree.xml
@@ -0,0 +1,156 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 000000000..eca70cfe5
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 000000000..eca70cfe5
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 000000000..c209e78ec
Binary files /dev/null and b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..b2dfe3d1b
Binary files /dev/null and b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 000000000..4f0f1d64e
Binary files /dev/null and b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..62b611da0
Binary files /dev/null and b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 000000000..948a3070f
Binary files /dev/null and b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..1b9a6956b
Binary files /dev/null and b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 000000000..28d4b77f9
Binary files /dev/null and b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..9287f5083
Binary files /dev/null and b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 000000000..aa7d6427e
Binary files /dev/null and b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..9126ae37c
Binary files /dev/null and b/Unit2/Pathway2/Lemonade/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/values/colors.xml b/Unit2/Pathway2/Lemonade/app/src/main/res/values/colors.xml
new file mode 100644
index 000000000..f8c6127d3
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/values/strings.xml b/Unit2/Pathway2/Lemonade/app/src/main/res/values/strings.xml
new file mode 100644
index 000000000..686f6a332
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/res/values/strings.xml
@@ -0,0 +1,11 @@
+
+ Lemonade
+ Tap the lemon tree to select a lemon
+ Keep tapping the lemon to squeeze it
+ Tap the lemonade to drink it
+ Tap the empty glass to start again
+ Lemon tree
+ Lemon
+ Glass of lemonade
+ Empty glass
+
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/values/themes.xml b/Unit2/Pathway2/Lemonade/app/src/main/res/values/themes.xml
new file mode 100644
index 000000000..92e729eed
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/res/values/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/xml/backup_rules.xml b/Unit2/Pathway2/Lemonade/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 000000000..fa0f996d2
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/app/src/main/res/xml/data_extraction_rules.xml b/Unit2/Pathway2/Lemonade/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 000000000..9ee9997b0
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/app/src/test/java/com/example/lemonade/ExampleUnitTest.kt b/Unit2/Pathway2/Lemonade/app/src/test/java/com/example/lemonade/ExampleUnitTest.kt
new file mode 100644
index 000000000..1569bcbe4
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/app/src/test/java/com/example/lemonade/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.lemonade
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+ @Test
+ fun addition_isCorrect() {
+ assertEquals(4, 2 + 2)
+ }
+}
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/build.gradle b/Unit2/Pathway2/Lemonade/build.gradle
new file mode 100644
index 000000000..15dff9ef8
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/build.gradle
@@ -0,0 +1,10 @@
+buildscript {
+ ext {
+ compose_ui_version = '1.1.1'
+ }
+}// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ id 'com.android.application' version '7.3.1' apply false
+ id 'com.android.library' version '7.3.1' apply false
+ id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
+}
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/gradle.properties b/Unit2/Pathway2/Lemonade/gradle.properties
new file mode 100644
index 000000000..3c5031eb7
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/Unit2/Pathway2/Lemonade/gradle/wrapper/gradle-wrapper.jar b/Unit2/Pathway2/Lemonade/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 000000000..e708b1c02
Binary files /dev/null and b/Unit2/Pathway2/Lemonade/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Unit2/Pathway2/Lemonade/gradle/wrapper/gradle-wrapper.properties b/Unit2/Pathway2/Lemonade/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000..0e91a716d
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Thu Dec 08 02:11:55 KST 2022
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/Unit2/Pathway2/Lemonade/gradlew b/Unit2/Pathway2/Lemonade/gradlew
new file mode 100644
index 000000000..4f906e0c8
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/Unit2/Pathway2/Lemonade/gradlew.bat b/Unit2/Pathway2/Lemonade/gradlew.bat
new file mode 100644
index 000000000..107acd32c
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Unit2/Pathway2/Lemonade/settings.gradle b/Unit2/Pathway2/Lemonade/settings.gradle
new file mode 100644
index 000000000..64e1f070d
--- /dev/null
+++ b/Unit2/Pathway2/Lemonade/settings.gradle
@@ -0,0 +1,16 @@
+pluginManagement {
+ repositories {
+ gradlePluginPortal()
+ google()
+ mavenCentral()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+rootProject.name = "Lemonade"
+include ':app'
diff --git a/Unit2/Pathway3/Art Space/.gitignore b/Unit2/Pathway3/Art Space/.gitignore
new file mode 100644
index 000000000..aa724b770
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/Unit2/Pathway3/Art Space/app/.gitignore b/Unit2/Pathway3/Art Space/app/.gitignore
new file mode 100644
index 000000000..42afabfd2
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/app/build.gradle b/Unit2/Pathway3/Art Space/app/build.gradle
new file mode 100644
index 000000000..c9b5fb10f
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/build.gradle
@@ -0,0 +1,63 @@
+plugins {
+ id 'com.android.application'
+ id 'org.jetbrains.kotlin.android'
+}
+
+android {
+ namespace 'com.example.artspace'
+ compileSdk 32
+
+ defaultConfig {
+ applicationId "com.example.artspace"
+ minSdk 21
+ targetSdk 32
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ vectorDrawables {
+ useSupportLibrary true
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled 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.1.1'
+ }
+ packagingOptions {
+ resources {
+ excludes += '/META-INF/{AL2.0,LGPL2.1}'
+ }
+ }
+}
+
+dependencies {
+
+ implementation 'androidx.core:core-ktx:1.7.0'
+ implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
+ implementation 'androidx.activity:activity-compose:1.3.1'
+ implementation "androidx.compose.ui:ui:$compose_ui_version"
+ implementation "androidx.compose.ui:ui-tooling-preview:$compose_ui_version"
+ implementation 'androidx.compose.material:material:1.1.1'
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+ androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version"
+ debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version"
+ debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_ui_version"
+}
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/app/proguard-rules.pro b/Unit2/Pathway3/Art Space/app/proguard-rules.pro
new file mode 100644
index 000000000..481bb4348
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/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/Unit2/Pathway3/Art Space/app/src/androidTest/java/com/example/artspace/ExampleInstrumentedTest.kt b/Unit2/Pathway3/Art Space/app/src/androidTest/java/com/example/artspace/ExampleInstrumentedTest.kt
new file mode 100644
index 000000000..d778e2354
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/src/androidTest/java/com/example/artspace/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.example.artspace
+
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("com.example.artspace", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/app/src/main/AndroidManifest.xml b/Unit2/Pathway3/Art Space/app/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..1769642f7
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/src/main/AndroidManifest.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/app/src/main/java/com/example/artspace/MainActivity.kt b/Unit2/Pathway3/Art Space/app/src/main/java/com/example/artspace/MainActivity.kt
new file mode 100644
index 000000000..b39f2f2ef
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/src/main/java/com/example/artspace/MainActivity.kt
@@ -0,0 +1,204 @@
+package com.example.artspace
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
+import androidx.compose.foundation.border
+import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Button
+import androidx.compose.material.Surface
+import androidx.compose.material.Text
+import androidx.compose.runtime.*
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Alignment.Companion.CenterHorizontally
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.shadow
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.SpanStyle
+import androidx.compose.ui.text.buildAnnotatedString
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.withStyle
+import androidx.compose.ui.tooling.preview.Devices
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.example.artspace.ui.theme.ArtSpaceTheme
+
+class MainActivity : ComponentActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent {
+ ArtSpaceTheme {
+ ArtworkScreen()
+ }
+ }
+ }
+}
+
+
+@Preview(showBackground = true, showSystemUi = true)
+@Composable
+fun DefaultPreview() {
+ ArtSpaceTheme {
+ ArtworkScreen()
+ }
+}
+
+@Preview(showBackground = true, showSystemUi = true, device = Devices.PIXEL_C)
+@Composable
+fun DefaultPreview2() {
+ ArtSpaceTheme {
+ ArtworkScreen()
+ }
+}
+
+@Composable
+fun ArtworkScreen() {
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .padding(16.dp, 32.dp),
+ verticalArrangement = Arrangement.SpaceBetween
+ ) {
+
+ var artworkPK by remember {
+ mutableStateOf(0)
+ }
+
+ val artworkResourceId = when (artworkPK) {
+ 0 -> R.drawable.image1
+ 1 -> R.drawable.image2
+ 2 -> R.drawable.image3
+ 3 -> R.drawable.image4
+ else -> R.drawable.image5
+ }
+
+ val title = when (artworkPK) {
+ 0 -> "Title 1"
+ 1 -> "Title 2"
+ 2 -> "Title 3 "
+ 3 -> "Title 4 "
+ else -> "Title 5"
+ }
+
+ val artist = when (artworkPK) {
+ 0 -> "artist 1"
+ 1 -> "artist 2"
+ 2 -> "artist 3"
+ 3 -> "artist 4"
+ else -> "artist 5"
+ }
+
+ val year = when (artworkPK) {
+ 0 -> 1901
+ 1 -> 1902
+ 2 -> 1903
+ 3 -> 1904
+ else -> 1905
+ }
+
+ Artwork(artworkResourceId, Modifier.align(CenterHorizontally))
+ Spacer(modifier = Modifier.height(32.dp))
+ Description(
+ modifier = Modifier.align(CenterHorizontally),
+ title = title, artist = artist, year = year
+ )
+ Spacer(modifier = Modifier.height(32.dp))
+ NavigationControls(
+ onClickPrevious = {
+ if (artworkPK > 0) {
+ artworkPK--
+ }
+ },
+ onClickNext = {
+ if (artworkPK < 4) {
+ artworkPK++
+ }
+ },
+ modifier = Modifier.weight(1f),
+ )
+ }
+}
+
+@Composable
+fun Artwork(artworkId: Int, modifier: Modifier = Modifier) {
+ val painter = painterResource(id = artworkId)
+ val imageRatio = painter.intrinsicSize.width / painter.intrinsicSize.height
+ Image(
+ painter = painter,
+ contentDescription = null,
+ contentScale = ContentScale.FillBounds,
+ modifier = modifier
+ .shadow(16.dp)
+ .border(2.dp, Color.Gray)
+ .background(Color.White)
+ .padding(16.dp)
+ .fillMaxHeight(.6f)
+ .aspectRatio(imageRatio)
+ )
+}
+
+@Composable
+fun Description(modifier: Modifier = Modifier, title: String, artist: String, year: Int) {
+ Surface(
+ modifier = modifier.shadow(4.dp, RoundedCornerShape(2.dp)),
+ ) {
+ Column(
+ modifier = modifier
+ .padding(16.dp)
+ .wrapContentSize(),
+ verticalArrangement = Arrangement.Bottom
+ ) {
+ Text(text = title, fontSize = 32.sp, color = Color.DarkGray)
+ Text(
+ buildAnnotatedString {
+ withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
+ append(artist)
+ }
+ withStyle(style = SpanStyle(color = Color.Gray)) {
+ append(" ($year)")
+ }
+ }
+ )
+ }
+ }
+}
+
+@Composable
+fun NavigationControls(
+ modifier: Modifier = Modifier,
+ onClickPrevious: () -> Unit,
+ onClickNext: () -> Unit,
+) {
+ Row(
+ modifier = modifier
+ .fillMaxWidth()
+ .fillMaxHeight(),
+ verticalAlignment = Alignment.Bottom
+ ) {
+ Button(
+ onClick = onClickPrevious,
+ modifier = modifier
+ .weight(1.0f)
+ .wrapContentSize()
+ .defaultMinSize(150.dp)
+ ) {
+ Text(text = "Previous")
+ }
+ Spacer(modifier = Modifier.width(16.dp))
+ Button(
+ onClick = onClickNext,
+ modifier = modifier
+ .weight(1f)
+ .wrapContentSize()
+ .defaultMinSize(150.dp)
+ ) {
+ Text(text = "Next")
+ }
+ }
+}
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/app/src/main/java/com/example/artspace/ui/theme/Color.kt b/Unit2/Pathway3/Art Space/app/src/main/java/com/example/artspace/ui/theme/Color.kt
new file mode 100644
index 000000000..51a27509f
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/src/main/java/com/example/artspace/ui/theme/Color.kt
@@ -0,0 +1,8 @@
+package com.example.artspace.ui.theme
+
+import androidx.compose.ui.graphics.Color
+
+val Purple200 = Color(0xFFBB86FC)
+val Purple500 = Color(0xFF6200EE)
+val Purple700 = Color(0xFF3700B3)
+val Teal200 = Color(0xFF03DAC5)
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/app/src/main/java/com/example/artspace/ui/theme/Shape.kt b/Unit2/Pathway3/Art Space/app/src/main/java/com/example/artspace/ui/theme/Shape.kt
new file mode 100644
index 000000000..95b14b077
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/src/main/java/com/example/artspace/ui/theme/Shape.kt
@@ -0,0 +1,11 @@
+package com.example.artspace.ui.theme
+
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Shapes
+import androidx.compose.ui.unit.dp
+
+val Shapes = Shapes(
+ small = RoundedCornerShape(4.dp),
+ medium = RoundedCornerShape(4.dp),
+ large = RoundedCornerShape(0.dp)
+)
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/app/src/main/java/com/example/artspace/ui/theme/Theme.kt b/Unit2/Pathway3/Art Space/app/src/main/java/com/example/artspace/ui/theme/Theme.kt
new file mode 100644
index 000000000..0d48ce512
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/src/main/java/com/example/artspace/ui/theme/Theme.kt
@@ -0,0 +1,44 @@
+package com.example.artspace.ui.theme
+
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.darkColors
+import androidx.compose.material.lightColors
+import androidx.compose.runtime.Composable
+
+private val DarkColorPalette = darkColors(
+ primary = Purple200,
+ primaryVariant = Purple700,
+ secondary = Teal200
+)
+
+private val LightColorPalette = lightColors(
+ primary = Purple500,
+ primaryVariant = Purple700,
+ secondary = Teal200
+
+ /* Other default colors to override
+ background = Color.White,
+ surface = Color.White,
+ onPrimary = Color.White,
+ onSecondary = Color.Black,
+ onBackground = Color.Black,
+ onSurface = Color.Black,
+ */
+)
+
+@Composable
+fun ArtSpaceTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {
+ val colors = if (darkTheme) {
+ DarkColorPalette
+ } else {
+ LightColorPalette
+ }
+
+ MaterialTheme(
+ colors = colors,
+ typography = Typography,
+ shapes = Shapes,
+ content = content
+ )
+}
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/app/src/main/java/com/example/artspace/ui/theme/Type.kt b/Unit2/Pathway3/Art Space/app/src/main/java/com/example/artspace/ui/theme/Type.kt
new file mode 100644
index 000000000..1ada8704e
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/src/main/java/com/example/artspace/ui/theme/Type.kt
@@ -0,0 +1,28 @@
+package com.example.artspace.ui.theme
+
+import androidx.compose.material.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(
+ body1 = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 16.sp
+ )
+ /* Other default text styles to override
+ button = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.W500,
+ fontSize = 14.sp
+ ),
+ caption = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 12.sp
+ )
+ */
+)
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/Unit2/Pathway3/Art Space/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 000000000..2b068d114
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/drawable/ic_launcher_background.xml b/Unit2/Pathway3/Art Space/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 000000000..07d5da9cb
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/drawable/image1.jpg b/Unit2/Pathway3/Art Space/app/src/main/res/drawable/image1.jpg
new file mode 100644
index 000000000..eb992a2d1
Binary files /dev/null and b/Unit2/Pathway3/Art Space/app/src/main/res/drawable/image1.jpg differ
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/drawable/image2.jpg b/Unit2/Pathway3/Art Space/app/src/main/res/drawable/image2.jpg
new file mode 100644
index 000000000..c8cf4e954
Binary files /dev/null and b/Unit2/Pathway3/Art Space/app/src/main/res/drawable/image2.jpg differ
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/drawable/image3.jpg b/Unit2/Pathway3/Art Space/app/src/main/res/drawable/image3.jpg
new file mode 100644
index 000000000..18bb2c5ad
Binary files /dev/null and b/Unit2/Pathway3/Art Space/app/src/main/res/drawable/image3.jpg differ
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/drawable/image4.jpg b/Unit2/Pathway3/Art Space/app/src/main/res/drawable/image4.jpg
new file mode 100644
index 000000000..74b16c6b2
Binary files /dev/null and b/Unit2/Pathway3/Art Space/app/src/main/res/drawable/image4.jpg differ
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/drawable/image5.png b/Unit2/Pathway3/Art Space/app/src/main/res/drawable/image5.png
new file mode 100644
index 000000000..f307eaea3
Binary files /dev/null and b/Unit2/Pathway3/Art Space/app/src/main/res/drawable/image5.png differ
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 000000000..eca70cfe5
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 000000000..eca70cfe5
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 000000000..c209e78ec
Binary files /dev/null and b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..b2dfe3d1b
Binary files /dev/null and b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 000000000..4f0f1d64e
Binary files /dev/null and b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..62b611da0
Binary files /dev/null and b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 000000000..948a3070f
Binary files /dev/null and b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..1b9a6956b
Binary files /dev/null and b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 000000000..28d4b77f9
Binary files /dev/null and b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..9287f5083
Binary files /dev/null and b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 000000000..aa7d6427e
Binary files /dev/null and b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..9126ae37c
Binary files /dev/null and b/Unit2/Pathway3/Art Space/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/values/colors.xml b/Unit2/Pathway3/Art Space/app/src/main/res/values/colors.xml
new file mode 100644
index 000000000..f8c6127d3
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/values/strings.xml b/Unit2/Pathway3/Art Space/app/src/main/res/values/strings.xml
new file mode 100644
index 000000000..410f464d9
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ Art Space
+
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/values/themes.xml b/Unit2/Pathway3/Art Space/app/src/main/res/values/themes.xml
new file mode 100644
index 000000000..23a10bedd
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/src/main/res/values/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/xml/backup_rules.xml b/Unit2/Pathway3/Art Space/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 000000000..fa0f996d2
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/app/src/main/res/xml/data_extraction_rules.xml b/Unit2/Pathway3/Art Space/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 000000000..9ee9997b0
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/app/src/test/java/com/example/artspace/ExampleUnitTest.kt b/Unit2/Pathway3/Art Space/app/src/test/java/com/example/artspace/ExampleUnitTest.kt
new file mode 100644
index 000000000..fde12fe0b
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/app/src/test/java/com/example/artspace/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.example.artspace
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+ @Test
+ fun addition_isCorrect() {
+ assertEquals(4, 2 + 2)
+ }
+}
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/build.gradle b/Unit2/Pathway3/Art Space/build.gradle
new file mode 100644
index 000000000..15dff9ef8
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/build.gradle
@@ -0,0 +1,10 @@
+buildscript {
+ ext {
+ compose_ui_version = '1.1.1'
+ }
+}// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ id 'com.android.application' version '7.3.1' apply false
+ id 'com.android.library' version '7.3.1' apply false
+ id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
+}
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/gradle.properties b/Unit2/Pathway3/Art Space/gradle.properties
new file mode 100644
index 000000000..3c5031eb7
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/Unit2/Pathway3/Art Space/gradle/wrapper/gradle-wrapper.jar b/Unit2/Pathway3/Art Space/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 000000000..e708b1c02
Binary files /dev/null and b/Unit2/Pathway3/Art Space/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Unit2/Pathway3/Art Space/gradle/wrapper/gradle-wrapper.properties b/Unit2/Pathway3/Art Space/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000..3169eb1d0
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Sat Dec 10 12:16:06 KST 2022
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/Unit2/Pathway3/Art Space/gradlew b/Unit2/Pathway3/Art Space/gradlew
new file mode 100755
index 000000000..4f906e0c8
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/Unit2/Pathway3/Art Space/gradlew.bat b/Unit2/Pathway3/Art Space/gradlew.bat
new file mode 100644
index 000000000..ac1b06f93
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Unit2/Pathway3/Art Space/settings.gradle b/Unit2/Pathway3/Art Space/settings.gradle
new file mode 100644
index 000000000..a7ef376e9
--- /dev/null
+++ b/Unit2/Pathway3/Art Space/settings.gradle
@@ -0,0 +1,16 @@
+pluginManagement {
+ repositories {
+ gradlePluginPortal()
+ google()
+ mavenCentral()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+rootProject.name = "Art Space"
+include ':app'
diff --git a/Unit2/Pathway3/Tip Time/.gitignore b/Unit2/Pathway3/Tip Time/.gitignore
new file mode 100644
index 000000000..aa724b770
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/.gitignore
@@ -0,0 +1,15 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
diff --git a/Unit2/Pathway3/Tip Time/app/.gitignore b/Unit2/Pathway3/Tip Time/app/.gitignore
new file mode 100644
index 000000000..42afabfd2
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/app/build.gradle b/Unit2/Pathway3/Tip Time/app/build.gradle
new file mode 100644
index 000000000..5b01497ed
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/build.gradle
@@ -0,0 +1,64 @@
+plugins {
+ id 'com.android.application'
+ id 'org.jetbrains.kotlin.android'
+}
+
+android {
+ namespace 'com.example.tiptime'
+ compileSdk 32
+
+ defaultConfig {
+ applicationId "com.example.tiptime"
+ minSdk 21
+ targetSdk 32
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ vectorDrawables {
+ useSupportLibrary true
+ }
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled 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.1.1'
+ }
+ packagingOptions {
+ resources {
+ excludes += '/META-INF/{AL2.0,LGPL2.1}'
+ }
+ }
+}
+
+dependencies {
+
+ implementation 'androidx.core:core-ktx:1.7.0'
+ implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
+ implementation 'androidx.activity:activity-compose:1.3.1'
+ implementation "androidx.compose.ui:ui:$compose_ui_version"
+ implementation "androidx.compose.ui:ui-tooling-preview:$compose_ui_version"
+ implementation 'androidx.compose.material:material:1.1.1'
+ testImplementation 'junit:junit:4.13.2'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.3'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+ androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version"
+ debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version"
+ debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_ui_version"
+
+}
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/app/proguard-rules.pro b/Unit2/Pathway3/Tip Time/app/proguard-rules.pro
new file mode 100644
index 000000000..481bb4348
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/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/Unit2/Pathway3/Tip Time/app/src/androidTest/java/com/example/tiptime/TipUITests.kt b/Unit2/Pathway3/Tip Time/app/src/androidTest/java/com/example/tiptime/TipUITests.kt
new file mode 100644
index 000000000..390d454e3
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/src/androidTest/java/com/example/tiptime/TipUITests.kt
@@ -0,0 +1,33 @@
+package com.example.tiptime
+
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.material.Surface
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithText
+import androidx.compose.ui.test.performTextInput
+import com.example.tiptime.ui.theme.TipTimeTheme
+import org.junit.Rule
+import org.junit.Test
+
+class TipUITests {
+
+ @get:Rule
+ val composeTestRule = createComposeRule()
+
+ @Test
+ fun calculate_20_percent_tip() {
+ composeTestRule.setContent {
+ TipTimeTheme {
+ Surface (modifier = Modifier.fillMaxSize()){
+ TipTimeScreen()
+ }
+ }
+ }
+ composeTestRule.onNodeWithText("Cost of Service").performTextInput("10")
+ composeTestRule.onNodeWithText("Tip (%)").performTextInput("20")
+ composeTestRule.onNodeWithText("Tip Amount: $2.00").assertExists(
+ "No node with this text was found."
+ )
+ }
+}
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/AndroidManifest.xml b/Unit2/Pathway3/Tip Time/app/src/main/AndroidManifest.xml
new file mode 100644
index 000000000..66c593744
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/src/main/AndroidManifest.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/java/com/example/tiptime/MainActivity.kt b/Unit2/Pathway3/Tip Time/app/src/main/java/com/example/tiptime/MainActivity.kt
new file mode 100644
index 000000000..43f613a38
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/src/main/java/com/example/tiptime/MainActivity.kt
@@ -0,0 +1,174 @@
+package com.example.tiptime
+
+import android.os.Bundle
+import androidx.activity.ComponentActivity
+import androidx.activity.compose.setContent
+import androidx.annotation.StringRes
+import androidx.annotation.VisibleForTesting
+import androidx.compose.foundation.layout.Arrangement
+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.size
+import androidx.compose.foundation.layout.wrapContentWidth
+import androidx.compose.foundation.text.KeyboardActions
+import androidx.compose.foundation.text.KeyboardOptions
+import androidx.compose.material.Surface
+import androidx.compose.material.Switch
+import androidx.compose.material.SwitchDefaults
+import androidx.compose.material.Text
+import androidx.compose.material.TextField
+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.focus.FocusDirection
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalFocusManager
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.font.FontWeight
+import androidx.compose.ui.text.input.ImeAction
+import androidx.compose.ui.text.input.KeyboardType
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+import com.example.tiptime.ui.theme.TipTimeTheme
+import java.text.NumberFormat
+
+class MainActivity : ComponentActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setContent {
+ TipTimeTheme {
+ Surface(modifier = Modifier.fillMaxSize()) {
+ TipTimeScreen()
+ }
+ }
+ }
+ }
+}
+
+@Composable
+fun TipTimeScreen() {
+ var amountInput by remember { mutableStateOf("") }
+ var tipInput by remember { mutableStateOf("") }
+ var roundUp by remember { mutableStateOf(false) }
+
+ val amount = amountInput.toDoubleOrNull() ?: 0.0
+ val tipPercent = tipInput.toDoubleOrNull() ?: 0.0
+ val tip = calculateTip(amount, tipPercent, roundUp)
+
+ val focusManager = LocalFocusManager.current
+
+ Column(
+ modifier = Modifier.padding(32.dp),
+ verticalArrangement = Arrangement.spacedBy(8.dp)
+ ) {
+ Text(
+ text = stringResource(R.string.calculate_tip),
+ fontSize = 24.sp,
+ modifier = Modifier.align(Alignment.CenterHorizontally)
+ )
+ Spacer(Modifier.height(16.dp))
+ EditNumberField(
+ label = R.string.cost_of_service,
+ keyboardOptions = KeyboardOptions.Default.copy(
+ keyboardType = KeyboardType.Number,
+ imeAction = ImeAction.Next
+ ),
+ keyboardActions = KeyboardActions(
+ onNext = { focusManager.moveFocus(FocusDirection.Down) }
+ ),
+ value = amountInput,
+ onValueChanged = { amountInput = it }
+ )
+ EditNumberField(
+ label = R.string.how_was_the_service,
+ keyboardOptions = KeyboardOptions.Default.copy(
+ keyboardType = KeyboardType.Number,
+ imeAction = ImeAction.Done
+ ),
+ keyboardActions = KeyboardActions(
+ onDone = { focusManager.clearFocus() }
+ ),
+ value = tipInput,
+ onValueChanged = { tipInput = it }
+ )
+ RoundTheTipRow(roundUp = roundUp, onRoundUpChanged = { roundUp = it })
+ Spacer(Modifier.height(24.dp))
+ Text(
+ text = stringResource(R.string.tip_amount, tip),
+ modifier = Modifier.align(Alignment.CenterHorizontally),
+ fontSize = 20.sp,
+ fontWeight = FontWeight.Bold
+ )
+ }
+}
+
+@Composable
+fun EditNumberField(
+ @StringRes label: Int,
+ keyboardOptions: KeyboardOptions,
+ keyboardActions: KeyboardActions,
+ value: String,
+ onValueChanged: (String) -> Unit,
+ modifier: Modifier = Modifier
+) {
+ TextField(
+ value = value,
+ singleLine = true,
+ modifier = modifier.fillMaxWidth(),
+ onValueChange = onValueChanged,
+ label = { Text(stringResource(label)) },
+ keyboardOptions = keyboardOptions,
+ keyboardActions = keyboardActions
+ )
+}
+
+@Composable
+fun RoundTheTipRow(
+ roundUp: Boolean,
+ onRoundUpChanged: (Boolean) -> Unit,
+ modifier: Modifier = Modifier
+) {
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .size(48.dp),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Text(text = stringResource(R.string.round_up_tip))
+ Switch(
+ modifier = modifier
+ .fillMaxWidth()
+ .wrapContentWidth(Alignment.End),
+ checked = roundUp,
+ onCheckedChange = onRoundUpChanged,
+ colors = SwitchDefaults.colors(
+ uncheckedThumbColor = Color.DarkGray
+ )
+ )
+ }
+}
+@VisibleForTesting
+internal fun calculateTip(amount: Double, tipPercent: Double, roundUp: Boolean): String {
+ var tip = tipPercent / 100 * amount
+ if (roundUp)
+ tip = kotlin.math.ceil(tip)
+ return NumberFormat.getCurrencyInstance().format(tip)
+}
+
+@Preview
+@Composable
+fun TipTimeScreenPreview() {
+ TipTimeTheme {
+ TipTimeScreen()
+ }
+}
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/java/com/example/tiptime/ui/theme/Color.kt b/Unit2/Pathway3/Tip Time/app/src/main/java/com/example/tiptime/ui/theme/Color.kt
new file mode 100644
index 000000000..d5aa49053
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/src/main/java/com/example/tiptime/ui/theme/Color.kt
@@ -0,0 +1,8 @@
+package com.example.tiptime.ui.theme
+
+import androidx.compose.ui.graphics.Color
+
+val Purple200 = Color(0xFFBB86FC)
+val Purple500 = Color(0xFF6200EE)
+val Purple700 = Color(0xFF3700B3)
+val Teal200 = Color(0xFF03DAC5)
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/java/com/example/tiptime/ui/theme/Shape.kt b/Unit2/Pathway3/Tip Time/app/src/main/java/com/example/tiptime/ui/theme/Shape.kt
new file mode 100644
index 000000000..764529ae6
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/src/main/java/com/example/tiptime/ui/theme/Shape.kt
@@ -0,0 +1,11 @@
+package com.example.tiptime.ui.theme
+
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Shapes
+import androidx.compose.ui.unit.dp
+
+val Shapes = Shapes(
+ small = RoundedCornerShape(4.dp),
+ medium = RoundedCornerShape(4.dp),
+ large = RoundedCornerShape(0.dp)
+)
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/java/com/example/tiptime/ui/theme/Theme.kt b/Unit2/Pathway3/Tip Time/app/src/main/java/com/example/tiptime/ui/theme/Theme.kt
new file mode 100644
index 000000000..27d8d98c8
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/src/main/java/com/example/tiptime/ui/theme/Theme.kt
@@ -0,0 +1,44 @@
+package com.example.tiptime.ui.theme
+
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.darkColors
+import androidx.compose.material.lightColors
+import androidx.compose.runtime.Composable
+
+private val DarkColorPalette = darkColors(
+ primary = Purple200,
+ primaryVariant = Purple700,
+ secondary = Teal200
+)
+
+private val LightColorPalette = lightColors(
+ primary = Purple500,
+ primaryVariant = Purple700,
+ secondary = Teal200
+
+ /* Other default colors to override
+ background = Color.White,
+ surface = Color.White,
+ onPrimary = Color.White,
+ onSecondary = Color.Black,
+ onBackground = Color.Black,
+ onSurface = Color.Black,
+ */
+)
+
+@Composable
+fun TipTimeTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {
+ val colors = if (darkTheme) {
+ DarkColorPalette
+ } else {
+ LightColorPalette
+ }
+
+ MaterialTheme(
+ colors = colors,
+ typography = Typography,
+ shapes = Shapes,
+ content = content
+ )
+}
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/java/com/example/tiptime/ui/theme/Type.kt b/Unit2/Pathway3/Tip Time/app/src/main/java/com/example/tiptime/ui/theme/Type.kt
new file mode 100644
index 000000000..c3259af69
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/src/main/java/com/example/tiptime/ui/theme/Type.kt
@@ -0,0 +1,28 @@
+package com.example.tiptime.ui.theme
+
+import androidx.compose.material.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(
+ body1 = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 16.sp
+ )
+ /* Other default text styles to override
+ button = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.W500,
+ fontSize = 14.sp
+ ),
+ caption = TextStyle(
+ fontFamily = FontFamily.Default,
+ fontWeight = FontWeight.Normal,
+ fontSize = 12.sp
+ )
+ */
+)
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/Unit2/Pathway3/Tip Time/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
new file mode 100644
index 000000000..2b068d114
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/drawable/ic_launcher_background.xml b/Unit2/Pathway3/Tip Time/app/src/main/res/drawable/ic_launcher_background.xml
new file mode 100644
index 000000000..07d5da9cb
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/src/main/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 000000000..eca70cfe5
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 000000000..eca70cfe5
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-hdpi/ic_launcher.webp
new file mode 100644
index 000000000..c209e78ec
Binary files /dev/null and b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..b2dfe3d1b
Binary files /dev/null and b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-mdpi/ic_launcher.webp
new file mode 100644
index 000000000..4f0f1d64e
Binary files /dev/null and b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..62b611da0
Binary files /dev/null and b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
new file mode 100644
index 000000000..948a3070f
Binary files /dev/null and b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..1b9a6956b
Binary files /dev/null and b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
new file mode 100644
index 000000000..28d4b77f9
Binary files /dev/null and b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..9287f5083
Binary files /dev/null and b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
new file mode 100644
index 000000000..aa7d6427e
Binary files /dev/null and b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
new file mode 100644
index 000000000..9126ae37c
Binary files /dev/null and b/Unit2/Pathway3/Tip Time/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/values/colors.xml b/Unit2/Pathway3/Tip Time/app/src/main/res/values/colors.xml
new file mode 100644
index 000000000..f8c6127d3
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/src/main/res/values/colors.xml
@@ -0,0 +1,10 @@
+
+
+ #FFBB86FC
+ #FF6200EE
+ #FF3700B3
+ #FF03DAC5
+ #FF018786
+ #FF000000
+ #FFFFFFFF
+
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/values/strings.xml b/Unit2/Pathway3/Tip Time/app/src/main/res/values/strings.xml
new file mode 100644
index 000000000..d9d23c7df
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/src/main/res/values/strings.xml
@@ -0,0 +1,8 @@
+
+ Tip Time
+ Calculate Tip
+ Cost of Service
+ Tip (%)
+ Round up tip?
+ Tip Amount: %s
+
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/values/themes.xml b/Unit2/Pathway3/Tip Time/app/src/main/res/values/themes.xml
new file mode 100644
index 000000000..941c637ec
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/src/main/res/values/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/xml/backup_rules.xml b/Unit2/Pathway3/Tip Time/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 000000000..fa0f996d2
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1,13 @@
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/app/src/main/res/xml/data_extraction_rules.xml b/Unit2/Pathway3/Tip Time/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 000000000..9ee9997b0
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/app/src/test/java/com/example/tiptime/TipCalculatorTests.kt b/Unit2/Pathway3/Tip Time/app/src/test/java/com/example/tiptime/TipCalculatorTests.kt
new file mode 100644
index 000000000..ba6451a29
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/app/src/test/java/com/example/tiptime/TipCalculatorTests.kt
@@ -0,0 +1,21 @@
+package com.example.tiptime
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class TipCalculatorTests {
+ @Test
+ fun calculate_20_percent_tip_no_roundup() {
+ val amount = 10.00
+ val tipPercent = 20.00
+ val expectedTip = "$2.00"
+ val actualTip = calculateTip(amount = amount, tipPercent = tipPercent, false)
+ assertEquals(expectedTip, actualTip)
+ }
+}
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/build.gradle b/Unit2/Pathway3/Tip Time/build.gradle
new file mode 100644
index 000000000..15dff9ef8
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/build.gradle
@@ -0,0 +1,10 @@
+buildscript {
+ ext {
+ compose_ui_version = '1.1.1'
+ }
+}// Top-level build file where you can add configuration options common to all sub-projects/modules.
+plugins {
+ id 'com.android.application' version '7.3.1' apply false
+ id 'com.android.library' version '7.3.1' apply false
+ id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
+}
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/gradle.properties b/Unit2/Pathway3/Tip Time/gradle.properties
new file mode 100644
index 000000000..3c5031eb7
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true
\ No newline at end of file
diff --git a/Unit2/Pathway3/Tip Time/gradle/wrapper/gradle-wrapper.jar b/Unit2/Pathway3/Tip Time/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 000000000..e708b1c02
Binary files /dev/null and b/Unit2/Pathway3/Tip Time/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/Unit2/Pathway3/Tip Time/gradle/wrapper/gradle-wrapper.properties b/Unit2/Pathway3/Tip Time/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 000000000..a6c6cdc30
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Sat Dec 10 03:44:44 KST 2022
+distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-bin.zip
+distributionPath=wrapper/dists
+zipStorePath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
diff --git a/Unit2/Pathway3/Tip Time/gradlew b/Unit2/Pathway3/Tip Time/gradlew
new file mode 100755
index 000000000..4f906e0c8
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/Unit2/Pathway3/Tip Time/gradlew.bat b/Unit2/Pathway3/Tip Time/gradlew.bat
new file mode 100644
index 000000000..ac1b06f93
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/Unit2/Pathway3/Tip Time/settings.gradle b/Unit2/Pathway3/Tip Time/settings.gradle
new file mode 100644
index 000000000..09edcfc33
--- /dev/null
+++ b/Unit2/Pathway3/Tip Time/settings.gradle
@@ -0,0 +1,16 @@
+pluginManagement {
+ repositories {
+ gradlePluginPortal()
+ google()
+ mavenCentral()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+rootProject.name = "Tip Time"
+include ':app'
diff --git a/Unit3/Pathway2/AffirmationsCodelab/app/src/main/java/com/example/affirmationscodelab/MainActivity.kt b/Unit3/Pathway2/AffirmationsCodelab/app/src/main/java/com/example/affirmationscodelab/MainActivity.kt
index dc2023b3b..7c4d237b3 100644
--- a/Unit3/Pathway2/AffirmationsCodelab/app/src/main/java/com/example/affirmationscodelab/MainActivity.kt
+++ b/Unit3/Pathway2/AffirmationsCodelab/app/src/main/java/com/example/affirmationscodelab/MainActivity.kt
@@ -1,24 +1,29 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
package com.example.affirmationscodelab
+
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.items
+import androidx.compose.material.Card
+import androidx.compose.material.MaterialTheme
import androidx.compose.material.Scaffold
+import androidx.compose.material.Text
import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.layout.ContentScale
+import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.example.affirmationscodelab.data.Datasource
+import com.example.affirmationscodelab.model.Affirmation
import com.example.affirmationscodelab.ui.theme.AffirmationsTheme
class MainActivity : ComponentActivity() {
@@ -33,5 +38,42 @@ class MainActivity : ComponentActivity() {
@Composable
fun AffirmationApp() {
AffirmationsTheme {
+ AffirmationList(affirmationList = Datasource().loadAffirmations())
}
}
+
+@Composable
+fun AffirmationList(affirmationList: List, modifier: Modifier = Modifier) {
+ LazyColumn {
+ items(affirmationList) { affirmation ->
+ AffirmationCard(affirmation)
+ }
+ }
+}
+
+@Composable
+fun AffirmationCard(affirmation: Affirmation, modifier: Modifier = Modifier) {
+ Card(modifier = Modifier.padding(8.dp), elevation = 4.dp) {
+ Column {
+ Image(
+ painter = painterResource(affirmation.imageResourceId),
+ contentDescription = stringResource(affirmation.stringResourceId),
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(194.dp),
+ contentScale = ContentScale.Crop
+ )
+ Text(
+ text = LocalContext.current.getString(affirmation.stringResourceId),
+ modifier = Modifier.padding(16.dp),
+ style = MaterialTheme.typography.h6
+ )
+ }
+ }
+}
+
+@Preview
+@Composable
+private fun AffirmationCardPreview() {
+ AffirmationCard(Affirmation(R.string.affirmation1, R.drawable.image1))
+}
\ No newline at end of file
diff --git a/Unit3/Pathway2/AffirmationsCodelab/app/src/main/java/com/example/affirmationscodelab/data/Datasource.kt b/Unit3/Pathway2/AffirmationsCodelab/app/src/main/java/com/example/affirmationscodelab/data/Datasource.kt
index 7d99d4916..bf396a2a3 100644
--- a/Unit3/Pathway2/AffirmationsCodelab/app/src/main/java/com/example/affirmationscodelab/data/Datasource.kt
+++ b/Unit3/Pathway2/AffirmationsCodelab/app/src/main/java/com/example/affirmationscodelab/data/Datasource.kt
@@ -15,12 +15,11 @@
*/
package com.example.affirmationscodelab.data
import com.example.affirmationscodelab.R
+import com.example.affirmationscodelab.model.Affirmation
+
-/**
- * [Datasource] generates a list of [Affirmation]
- */
class Datasource() {
- /*fun loadAffirmations(): List {
+ fun loadAffirmations(): List {
return listOf(
Affirmation(R.string.affirmation1, R.drawable.image1),
Affirmation(R.string.affirmation2, R.drawable.image2),
@@ -32,5 +31,5 @@ class Datasource() {
Affirmation(R.string.affirmation8, R.drawable.image8),
Affirmation(R.string.affirmation9, R.drawable.image9),
Affirmation(R.string.affirmation10, R.drawable.image10))
- }*/
-}
+ }
+}
\ No newline at end of file
diff --git a/Unit3/Pathway2/AffirmationsCodelab/app/src/main/java/com/example/affirmationscodelab/model/Affirmation.kt b/Unit3/Pathway2/AffirmationsCodelab/app/src/main/java/com/example/affirmationscodelab/model/Affirmation.kt
new file mode 100644
index 000000000..8269e9a94
--- /dev/null
+++ b/Unit3/Pathway2/AffirmationsCodelab/app/src/main/java/com/example/affirmationscodelab/model/Affirmation.kt
@@ -0,0 +1,9 @@
+package com.example.affirmationscodelab.model
+
+import androidx.annotation.DrawableRes
+import androidx.annotation.StringRes
+
+data class Affirmation(
+ @StringRes val stringResourceId: Int,
+ @DrawableRes val imageResourceId: Int
+)
\ No newline at end of file
diff --git a/Unit3/Pathway2/AffirmationsCodelab/app/src/main/res/drawable-v24/ic_launcher_background.xml b/Unit3/Pathway2/AffirmationsCodelab/app/src/main/res/drawable-v24/ic_launcher_background.xml
index 88a65b4b7..ce7505917 100644
--- a/Unit3/Pathway2/AffirmationsCodelab/app/src/main/res/drawable-v24/ic_launcher_background.xml
+++ b/Unit3/Pathway2/AffirmationsCodelab/app/src/main/res/drawable-v24/ic_launcher_background.xml
@@ -1,20 +1,3 @@
-
-
-
-
-
+
\ No newline at end of file
diff --git a/Unit3/Pathway2/AffirmationsCodelab/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/Unit3/Pathway2/AffirmationsCodelab/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
index 2b068d114..8e98d1c7b 100644
--- a/Unit3/Pathway2/AffirmationsCodelab/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
+++ b/Unit3/Pathway2/AffirmationsCodelab/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
@@ -1,30 +1,32 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Unit3/Pathway3/WoofCodelab/app/build.gradle b/Unit3/Pathway3/WoofCodelab/app/build.gradle
index 854a8f86b..99a82ff0e 100644
--- a/Unit3/Pathway3/WoofCodelab/app/build.gradle
+++ b/Unit3/Pathway3/WoofCodelab/app/build.gradle
@@ -71,4 +71,5 @@ dependencies {
implementation "androidx.compose.material:material:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
+ implementation "androidx.compose.material:material-icons-extended:$compose_version"
}
\ No newline at end of file
diff --git a/Unit3/Pathway3/WoofCodelab/app/src/main/java/com/example/woofcodelab/MainActivity.kt b/Unit3/Pathway3/WoofCodelab/app/src/main/java/com/example/woofcodelab/MainActivity.kt
index 26d4256d7..5cc84a3eb 100644
--- a/Unit3/Pathway3/WoofCodelab/app/src/main/java/com/example/woofcodelab/MainActivity.kt
+++ b/Unit3/Pathway3/WoofCodelab/app/src/main/java/com/example/woofcodelab/MainActivity.kt
@@ -20,17 +20,38 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
+import androidx.compose.animation.animateContentSize
+import androidx.compose.animation.core.Spring
+import androidx.compose.animation.core.spring
import androidx.compose.foundation.Image
+import androidx.compose.foundation.background
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.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Card
+import androidx.compose.material.Icon
+import androidx.compose.material.IconButton
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Scaffold
import androidx.compose.material.Text
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.ExpandLess
+import androidx.compose.material.icons.filled.ExpandMore
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.draw.clip
+import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
@@ -38,6 +59,7 @@ import androidx.compose.ui.unit.dp
import com.example.woofcodelab.data.Dog
import com.example.woofcodelab.data.dogs
import com.example.woofcodelab.ui.theme.WoofTheme
+import androidx.compose.ui.tooling.preview.Devices
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
@@ -55,9 +77,15 @@ class MainActivity : ComponentActivity() {
*/
@Composable
fun WoofApp() {
- LazyColumn {
- items(dogs) {
- DogItem(dog = it)
+ Scaffold(
+ topBar = {
+ WoofTopAppBar()
+ }
+ ) {
+ LazyColumn(modifier = Modifier.background(MaterialTheme.colors.background)) {
+ items(dogs) {
+ DogItem(dog = it)
+ }
}
}
}
@@ -70,13 +98,92 @@ fun WoofApp() {
*/
@Composable
fun DogItem(dog: Dog, modifier: Modifier = Modifier) {
+ var expanded by remember { mutableStateOf(false) }
+ Card(
+ elevation = 4.dp,
+ modifier = modifier.padding(8.dp)
+ ) {
+ Column(
+ modifier = Modifier
+ .animateContentSize(
+ animationSpec = spring(
+ dampingRatio = Spring.DampingRatioMediumBouncy,
+ stiffness = Spring.StiffnessLow
+ )
+ )
+ ) {
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(8.dp)
+ ) {
+ DogIcon(dog.imageResourceId)
+ DogInformation(dog.name, dog.age)
+ Spacer(Modifier.weight(1f))
+ DogItemButton(
+ expanded = expanded,
+ onClick = { expanded = !expanded },
+ )
+ }
+ if (expanded) {
+ DogHobby(dog.hobbies)
+ }
+ }
+ }
+}
+
+/**
+ * Composable that displays a button that is clickable and displays an expand more or an expand less
+ * icon.
+ *
+ * @param expanded represents whether the expand more or expand less icon is visible
+ * @param onClick is the action that happens when the button is clicked
+ * @param modifier modifiers to set to this composable
+ */
+@Composable
+private fun DogItemButton(
+ expanded: Boolean,
+ onClick: () -> Unit,
+ modifier: Modifier = Modifier
+) {
+ IconButton(onClick = onClick) {
+ Icon(
+ imageVector = if (expanded) Icons.Filled.ExpandLess else Icons.Filled.ExpandMore,
+ tint = MaterialTheme.colors.secondary,
+ contentDescription = stringResource(R.string.expand_button_content_description),
+ )
+ }
+}
+
+/**
+ * Composable that displays a Top Bar with an icon and text.
+ *
+ * @param modifier modifiers to set to this composable
+ */
+@Composable
+fun WoofTopAppBar(modifier: Modifier = Modifier) {
Row(
- modifier = Modifier
+ modifier = modifier
.fillMaxWidth()
- .padding(8.dp)
+ .background(color = MaterialTheme.colors.primary),
+ verticalAlignment = Alignment.CenterVertically
) {
- DogIcon(dog.imageResourceId)
- DogInformation(dog.name, dog.age)
+ Image(
+ modifier = modifier
+ .size(64.dp)
+ .padding(8.dp),
+ painter = painterResource(R.drawable.ic_woof_logo),
+ /*
+ * Content Description is not needed here - image is decorative, and setting a null
+ * content description allows accessibility services to skip this element during
+ * navigation.
+ */
+ contentDescription = null
+ )
+ Text(
+ text = stringResource(R.string.app_name),
+ style = MaterialTheme.typography.h1
+ )
}
}
@@ -91,7 +198,9 @@ fun DogIcon(@DrawableRes dogIcon: Int, modifier: Modifier = Modifier) {
Image(
modifier = modifier
.size(64.dp)
- .padding(8.dp),
+ .padding(8.dp)
+ .clip(RoundedCornerShape(50)),
+ contentScale = ContentScale.Crop,
painter = painterResource(dogIcon),
/*
* Content Description is not needed here - image is decorative, and setting a null content
@@ -113,10 +222,39 @@ fun DogInformation(@StringRes dogName: Int, dogAge: Int, modifier: Modifier = Mo
Column {
Text(
text = stringResource(dogName),
+ style = MaterialTheme.typography.h2,
modifier = modifier.padding(top = 8.dp)
)
Text(
- text = stringResource(R.string.years_old, dogAge)
+ text = stringResource(R.string.years_old, dogAge),
+ style = MaterialTheme.typography.body1
+ )
+ }
+}
+
+/**
+ * Composable that displays a dog's hobbies.
+ *
+ * @param dogHobby is the resource ID for the text string of the hobby to display
+ * @param modifier modifiers to set to this composable
+ */
+@Composable
+fun DogHobby(@StringRes dogHobby: Int, modifier: Modifier = Modifier) {
+ Column(
+ modifier = modifier.padding(
+ start = 16.dp,
+ top = 8.dp,
+ bottom = 16.dp,
+ end = 16.dp
+ )
+ ) {
+ Text(
+ text = stringResource(R.string.about),
+ style = MaterialTheme.typography.h3
+ )
+ Text(
+ text = stringResource(dogHobby),
+ style = MaterialTheme.typography.body1
)
}
}
@@ -131,3 +269,23 @@ fun WoofPreview() {
WoofApp()
}
}
+
+/**
+ * Composable that displays what the UI of the app looks like in dark theme in the design tab.
+ */
+@Preview
+@Composable
+fun WoofDarkThemePreview() {
+
+ WoofTheme(darkTheme = true) {
+ WoofApp()
+ }
+}
+
+@Preview(showBackground = true, showSystemUi = true, device = Devices.PIXEL_C)
+@Composable
+fun DefaultPreview2() {
+ WoofTheme(darkTheme = true) {
+ WoofApp()
+ }
+}
\ No newline at end of file
diff --git a/Unit3/Pathway3/WoofCodelab/app/src/main/java/com/example/woofcodelab/ui/theme/Color.kt b/Unit3/Pathway3/WoofCodelab/app/src/main/java/com/example/woofcodelab/ui/theme/Color.kt
index 2bb986719..b64eaf79a 100644
--- a/Unit3/Pathway3/WoofCodelab/app/src/main/java/com/example/woofcodelab/ui/theme/Color.kt
+++ b/Unit3/Pathway3/WoofCodelab/app/src/main/java/com/example/woofcodelab/ui/theme/Color.kt
@@ -17,7 +17,14 @@ package com.example.woofcodelab.ui.theme
import androidx.compose.ui.graphics.Color
-val Purple200 = Color(0xFFBB86FC)
-val Purple500 = Color(0xFF6200EE)
-val Purple700 = Color(0xFF3700B3)
-val Teal200 = Color(0xFF03DAC5)
+val White = Color(0xFFFFFFFF)
+val Grey100 = Color(0xFFF1F3F4)
+val Cyan900 = Color(0xFF007B83)
+val Cyan700 = Color(0xFF129EAF)
+
+//Light Theme
+val Grey50 = Color(0xFFF8F9FA)
+val Grey900 = Color(0xFF202124)
+val Grey700 = Color(0xFF5F6368)
+val Green50 = Color(0xFFE6F4EA)
+val Green100 = Color(0xFFCEEAD6)
diff --git a/Unit3/Pathway3/WoofCodelab/app/src/main/java/com/example/woofcodelab/ui/theme/Theme.kt b/Unit3/Pathway3/WoofCodelab/app/src/main/java/com/example/woofcodelab/ui/theme/Theme.kt
index dd94c3134..aa02f2d65 100644
--- a/Unit3/Pathway3/WoofCodelab/app/src/main/java/com/example/woofcodelab/ui/theme/Theme.kt
+++ b/Unit3/Pathway3/WoofCodelab/app/src/main/java/com/example/woofcodelab/ui/theme/Theme.kt
@@ -22,15 +22,21 @@ import androidx.compose.material.lightColors
import androidx.compose.runtime.Composable
private val DarkColorPalette = darkColors(
- primary = Purple200,
- primaryVariant = Purple700,
- secondary = Teal200
+ background = Cyan900,
+ surface = Cyan700,
+ onSurface = White,
+ primary = Grey900,
+ onPrimary = White,
+ secondary = Grey100
)
private val LightColorPalette = lightColors(
- primary = Purple500,
- primaryVariant = Purple700,
- secondary = Teal200
+ background = Green100,
+ surface = Green50,
+ onSurface = Grey900,
+ primary = Grey50,
+ onPrimary = Grey900,
+ secondary = Grey700
/* Other default colors to override
background = Color.White,
diff --git a/Unit3/Pathway3/WoofCodelab/build.gradle b/Unit3/Pathway3/WoofCodelab/build.gradle
index d284ab2f0..813199871 100644
--- a/Unit3/Pathway3/WoofCodelab/build.gradle
+++ b/Unit3/Pathway3/WoofCodelab/build.gradle
@@ -4,7 +4,7 @@ buildscript {
}
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
- id 'com.android.application' version '7.3.1' apply false
- id 'com.android.library' version '7.3.1' apply false
+ id 'com.android.application' version '7.1.3' apply false
+ id 'com.android.library' version '7.1.3' apply false
id 'org.jetbrains.kotlin.android' version '1.7.0' apply false
-}
\ No newline at end of file
+}
diff --git a/Unit4/Pathway1/basic-android-kotlin-compose-training-dessert-clicker/app/build.gradle b/Unit4/Pathway1/basic-android-kotlin-compose-training-dessert-clicker/app/build.gradle
index 8feecee4a..2970be5da 100644
--- a/Unit4/Pathway1/basic-android-kotlin-compose-training-dessert-clicker/app/build.gradle
+++ b/Unit4/Pathway1/basic-android-kotlin-compose-training-dessert-clicker/app/build.gradle
@@ -55,4 +55,5 @@ dependencies {
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.core:core-ktx:1.8.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
+ implementation "androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycle_version"
}
\ No newline at end of file
diff --git a/Unit4/Pathway1/basic-android-kotlin-compose-training-dessert-clicker/app/src/main/java/com/example/dessertclicker/MainActivity.kt b/Unit4/Pathway1/basic-android-kotlin-compose-training-dessert-clicker/app/src/main/java/com/example/dessertclicker/MainActivity.kt
index e267a3264..59fc6ca2a 100644
--- a/Unit4/Pathway1/basic-android-kotlin-compose-training-dessert-clicker/app/src/main/java/com/example/dessertclicker/MainActivity.kt
+++ b/Unit4/Pathway1/basic-android-kotlin-compose-training-dessert-clicker/app/src/main/java/com/example/dessertclicker/MainActivity.kt
@@ -19,6 +19,7 @@ import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.os.Bundle
+import android.util.Log
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
@@ -42,10 +43,10 @@ import androidx.compose.material.MaterialTheme
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Share
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.setValue
-import androidx.compose.runtime.mutableStateOf
-import androidx.compose.runtime.remember
+import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@@ -61,16 +62,49 @@ import com.example.dessertclicker.data.Datasource.dessertList
import com.example.dessertclicker.ui.theme.DessertClickerTheme
import com.example.dessertclicker.model.Dessert
+// tag for logging
+private const val TAG = "MainActivity"
+
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ Log.d(TAG, "onCreate Called")
setContent {
DessertClickerTheme {
DessertClickerApp(desserts = dessertList)
}
}
}
+ override fun onStart() {
+ super.onStart()
+ Log.d(TAG, "onStart Called")
+ }
+
+ override fun onResume() {
+ super.onResume()
+ Log.d(TAG, "onResume Called")
+ }
+
+ override fun onRestart() {
+ super.onRestart()
+ Log.d(TAG, "onRestart Called")
+ }
+
+ override fun onPause() {
+ super.onPause()
+ Log.d(TAG, "onPause Called")
+ }
+
+ override fun onStop() {
+ super.onStop()
+ Log.d(TAG, "onStop Called")
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ Log.d(TAG, "onDestroy Called")
+ }
}
/**
@@ -127,15 +161,15 @@ private fun DessertClickerApp(
desserts: List
) {
- var revenue by remember { mutableStateOf(0) }
- var dessertsSold by remember { mutableStateOf(0) }
+ var revenue by rememberSaveable { mutableStateOf(0) }
+ var dessertsSold by rememberSaveable { mutableStateOf(0) }
- val currentDessertIndex by remember { mutableStateOf(0) }
+ val currentDessertIndex by rememberSaveable { mutableStateOf(0) }
- var currentDessertPrice by remember {
+ var currentDessertPrice by rememberSaveable {
mutableStateOf(desserts[currentDessertIndex].price)
}
- var currentDessertImageId by remember {
+ var currentDessertImageId by rememberSaveable {
mutableStateOf(desserts[currentDessertIndex].imageId)
}
diff --git a/Unit4/Pathway1/basic-android-kotlin-compose-training-dessert-clicker/build.gradle b/Unit4/Pathway1/basic-android-kotlin-compose-training-dessert-clicker/build.gradle
index 1deeec4e4..17e03dbcb 100644
--- a/Unit4/Pathway1/basic-android-kotlin-compose-training-dessert-clicker/build.gradle
+++ b/Unit4/Pathway1/basic-android-kotlin-compose-training-dessert-clicker/build.gradle
@@ -2,6 +2,7 @@ buildscript {
ext {
compose_version = '1.2.0'
compose_compiler_version = '1.2.0'
+ lifecycle_version = '2.5.1'
}
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
diff --git a/Unit4/Pathway1/basic-android-kotlin-compose-training-unscramble/app/build.gradle b/Unit4/Pathway1/basic-android-kotlin-compose-training-unscramble/app/build.gradle
index 5079735d4..ab869fb43 100644
--- a/Unit4/Pathway1/basic-android-kotlin-compose-training-unscramble/app/build.gradle
+++ b/Unit4/Pathway1/basic-android-kotlin-compose-training-unscramble/app/build.gradle
@@ -70,6 +70,7 @@ dependencies {
implementation 'androidx.core:core-ktx:1.8.0'
implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
+ implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"
testImplementation 'junit:junit:4.13.2'
}
\ No newline at end of file
diff --git a/Unit4/Pathway1/basic-android-kotlin-compose-training-unscramble/app/src/main/java/com/example/android/unscramble/MainActivity.kt b/Unit4/Pathway1/basic-android-kotlin-compose-training-unscramble/app/src/main/java/com/example/android/unscramble/MainActivity.kt
index 06a625d72..70636e53c 100644
--- a/Unit4/Pathway1/basic-android-kotlin-compose-training-unscramble/app/src/main/java/com/example/android/unscramble/MainActivity.kt
+++ b/Unit4/Pathway1/basic-android-kotlin-compose-training-unscramble/app/src/main/java/com/example/android/unscramble/MainActivity.kt
@@ -25,6 +25,7 @@ import androidx.compose.ui.Modifier
import com.example.android.unscramble.ui.GameScreen
import com.example.android.unscramble.ui.theme.UnscrambleTheme
+
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -40,5 +41,4 @@ class MainActivity : ComponentActivity() {
}
}
}
-}
-
+}
\ No newline at end of file
diff --git a/Unit4/Pathway1/basic-android-kotlin-compose-training-unscramble/app/src/main/java/com/example/android/unscramble/ui/GameScreen.kt b/Unit4/Pathway1/basic-android-kotlin-compose-training-unscramble/app/src/main/java/com/example/android/unscramble/ui/GameScreen.kt
index 0e14ff1ee..5ab10ea3b 100644
--- a/Unit4/Pathway1/basic-android-kotlin-compose-training-unscramble/app/src/main/java/com/example/android/unscramble/ui/GameScreen.kt
+++ b/Unit4/Pathway1/basic-android-kotlin-compose-training-unscramble/app/src/main/java/com/example/android/unscramble/ui/GameScreen.kt
@@ -19,7 +19,9 @@ import android.app.Activity
import androidx.compose.foundation.layout.Arrangement
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.wrapContentWidth
@@ -34,6 +36,8 @@ import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
@@ -42,21 +46,34 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
+import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.android.unscramble.R
import com.example.android.unscramble.ui.theme.UnscrambleTheme
@Composable
-fun GameScreen(modifier: Modifier = Modifier) {
+fun GameScreen(
+ modifier: Modifier = Modifier,
+ gameViewModel: GameViewModel = viewModel()
+) {
+ val gameUiState by gameViewModel.uiState.collectAsState()
Column(
modifier = modifier
.verticalScroll(rememberScrollState())
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
-
- GameStatus()
- GameLayout()
+ GameStatus(
+ wordCount = gameUiState.currentWordCount,
+ score = gameUiState.score
+ )
+ GameLayout(
+ onUserGuessChanged = { gameViewModel.updateUserGuess(it) },
+ userGuess = gameViewModel.userGuess,
+ onKeyboardDone = { gameViewModel.checkUserGuess() },
+ currentScrambledWord = gameUiState.currentScrambledWord,
+ isGuessWrong = gameUiState.isGuessedWordWrong
+ )
Row(
modifier = modifier
.fillMaxWidth()
@@ -64,29 +81,34 @@ fun GameScreen(modifier: Modifier = Modifier) {
horizontalArrangement = Arrangement.SpaceAround
) {
OutlinedButton(
- onClick = { },
+ onClick = { gameViewModel.skipWord() },
modifier = Modifier
.weight(1f)
.padding(end = 8.dp)
) {
Text(stringResource(R.string.skip))
}
-
Button(
modifier = modifier
.fillMaxWidth()
.weight(1f)
.padding(start = 8.dp),
- onClick = { }
+ onClick = { gameViewModel.checkUserGuess() }
) {
Text(stringResource(R.string.submit))
}
}
+ if (gameUiState.isGameOver) {
+ FinalScoreDialog(
+ score = gameUiState.score,
+ onPlayAgain = { gameViewModel.resetGame() }
+ )
+ }
}
}
@Composable
-fun GameStatus(modifier: Modifier = Modifier) {
+fun GameStatus(wordCount: Int, score: Int, modifier: Modifier = Modifier) {
Row(
modifier = modifier
.fillMaxWidth()
@@ -94,27 +116,33 @@ fun GameStatus(modifier: Modifier = Modifier) {
.size(48.dp),
) {
Text(
- text = stringResource(R.string.word_count, 0),
+ text = stringResource(R.string.word_count, wordCount),
fontSize = 18.sp,
)
Text(
modifier = Modifier
.fillMaxWidth()
.wrapContentWidth(Alignment.End),
- text = stringResource(R.string.score, 0),
+ text = stringResource(R.string.score, score),
fontSize = 18.sp,
)
}
}
@Composable
-fun GameLayout(modifier: Modifier = Modifier) {
+fun GameLayout(
+ currentScrambledWord: String,
+ isGuessWrong: Boolean,
+ userGuess: String,
+ onUserGuessChanged: (String) -> Unit,
+ onKeyboardDone: () -> Unit,
+ modifier: Modifier = Modifier
+) {
Column(
- verticalArrangement = Arrangement.spacedBy(24.dp),
-
- ) {
+ verticalArrangement = Arrangement.spacedBy(24.dp)
+ ) {
Text(
- text = "scrambleun",
+ text = currentScrambledWord,
fontSize = 45.sp,
modifier = modifier.align(Alignment.CenterHorizontally)
)
@@ -124,17 +152,23 @@ fun GameLayout(modifier: Modifier = Modifier) {
modifier = Modifier.align(Alignment.CenterHorizontally)
)
OutlinedTextField(
- value = "",
+ value = userGuess,
singleLine = true,
modifier = Modifier.fillMaxWidth(),
- onValueChange = { },
- label = { Text(stringResource(R.string.enter_your_word)) },
- isError = false,
+ onValueChange = onUserGuessChanged,
+ label = {
+ if (isGuessWrong) {
+ Text(stringResource(R.string.wrong_guess))
+ } else {
+ Text(stringResource(R.string.enter_your_word))
+ }
+ },
+ isError = isGuessWrong,
keyboardOptions = KeyboardOptions.Default.copy(
imeAction = ImeAction.Done
),
keyboardActions = KeyboardActions(
- onDone = { }
+ onDone = { onKeyboardDone() }
),
)
}
@@ -145,6 +179,7 @@ fun GameLayout(modifier: Modifier = Modifier) {
*/
@Composable
private fun FinalScoreDialog(
+ score: Int,
onPlayAgain: () -> Unit,
modifier: Modifier = Modifier
) {
@@ -157,7 +192,7 @@ private fun FinalScoreDialog(
// onCloseRequest.
},
title = { Text(stringResource(R.string.congratulations)) },
- text = { Text(stringResource(R.string.you_scored, 0)) },
+ text = { Text(stringResource(R.string.you_scored, score)) },
modifier = modifier,
dismissButton = {
TextButton(
@@ -169,9 +204,7 @@ private fun FinalScoreDialog(
}
},
confirmButton = {
- TextButton(
- onClick = onPlayAgain
- ) {
+ TextButton(onClick = onPlayAgain) {
Text(text = stringResource(R.string.play_again))
}
}
@@ -180,7 +213,7 @@ private fun FinalScoreDialog(
@Preview(showBackground = true)
@Composable
-fun DefaultPreview() {
+fun GameScreenPreview() {
UnscrambleTheme {
GameScreen()
}
diff --git a/Unit4/Pathway1/basic-android-kotlin-compose-training-unscramble/app/src/main/java/com/example/android/unscramble/ui/GameUiState.kt b/Unit4/Pathway1/basic-android-kotlin-compose-training-unscramble/app/src/main/java/com/example/android/unscramble/ui/GameUiState.kt
new file mode 100644
index 000000000..96029e167
--- /dev/null
+++ b/Unit4/Pathway1/basic-android-kotlin-compose-training-unscramble/app/src/main/java/com/example/android/unscramble/ui/GameUiState.kt
@@ -0,0 +1,9 @@
+package com.example.android.unscramble.ui
+
+data class GameUiState(
+ val currentScrambledWord: String = "",
+ val currentWordCount: Int = 0,
+ val score: Int = 0,
+ val isGuessedWordWrong: Boolean = false,
+ val isGameOver: Boolean = false
+)
\ No newline at end of file
diff --git a/Unit4/Pathway1/basic-android-kotlin-compose-training-unscramble/app/src/main/java/com/example/android/unscramble/ui/GameViewModel.kt b/Unit4/Pathway1/basic-android-kotlin-compose-training-unscramble/app/src/main/java/com/example/android/unscramble/ui/GameViewModel.kt
new file mode 100644
index 000000000..7dfab02a8
--- /dev/null
+++ b/Unit4/Pathway1/basic-android-kotlin-compose-training-unscramble/app/src/main/java/com/example/android/unscramble/ui/GameViewModel.kt
@@ -0,0 +1,124 @@
+package com.example.android.unscramble.ui
+
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.setValue
+import androidx.lifecycle.ViewModel
+import com.example.android.unscramble.data.MAX_NO_OF_WORDS
+import com.example.android.unscramble.data.SCORE_INCREASE
+import com.example.android.unscramble.data.allWords
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.update
+
+class GameViewModel : ViewModel() {
+
+ // Game UI state
+ private val _uiState = MutableStateFlow(GameUiState())
+ val uiState: StateFlow = _uiState.asStateFlow()
+
+ var userGuess by mutableStateOf("")
+ private set
+
+ // Set of words used in the game
+ private var usedWords: MutableSet = mutableSetOf()
+ private lateinit var currentWord: String
+
+ init {
+ resetGame()
+ }
+
+ /*
+ * Re-initializes the game data to restart the game.
+ */
+ fun resetGame() {
+ usedWords.clear()
+ _uiState.value = GameUiState(currentScrambledWord = pickRandomWordAndShuffle())
+ }
+
+ /*
+ * Update the user's guess
+ */
+ fun updateUserGuess(guessedWord: String){
+ userGuess = guessedWord
+ }
+
+ /*
+ * Checks if the user's guess is correct.
+ * Increases the score accordingly.
+ */
+ fun checkUserGuess() {
+ if (userGuess.equals(currentWord, ignoreCase = true)) {
+ // User's guess is correct, increase the score
+ // and call updateGameState() to prepare the game for next round
+ val updatedScore = _uiState.value.score.plus(SCORE_INCREASE)
+ updateGameState(updatedScore)
+ } else {
+ // User's guess is wrong, show an error
+ _uiState.update { currentState ->
+ currentState.copy(isGuessedWordWrong = true)
+ }
+ }
+ // Reset user guess
+ updateUserGuess("")
+ }
+
+ /*
+ * Skip to next word
+ */
+ fun skipWord() {
+ updateGameState(_uiState.value.score)
+ // Reset user guess
+ updateUserGuess("")
+ }
+
+ /*
+ * Picks a new currentWord and currentScrambledWord and updates UiState according to
+ * current game state.
+ */
+ private fun updateGameState(updatedScore: Int) {
+ if (usedWords.size == MAX_NO_OF_WORDS){
+ //Last round in the game, update isGameOver to true, don't pick a new word
+ _uiState.update { currentState ->
+ currentState.copy(
+ isGuessedWordWrong = false,
+ currentWordCount = currentState.currentWordCount.inc(),
+ score = updatedScore,
+ isGameOver = true
+ )
+ }
+ } else{
+ // Normal round in the game
+ _uiState.update { currentState ->
+ currentState.copy(
+ isGuessedWordWrong = false,
+ currentScrambledWord = pickRandomWordAndShuffle(),
+ currentWordCount = currentState.currentWordCount.inc(),
+ score = updatedScore
+ )
+ }
+ }
+ }
+
+ private fun shuffleCurrentWord(word: String): String {
+ val tempWord = word.toCharArray()
+ // Scramble the word
+ tempWord.shuffle()
+ while (String(tempWord).equals(word)) {
+ tempWord.shuffle()
+ }
+ return String(tempWord)
+ }
+
+ private fun pickRandomWordAndShuffle(): String {
+ // Continue picking up a new random word until you get one that hasn't been used before
+ currentWord = allWords.random()
+ if (usedWords.contains(currentWord)) {
+ return pickRandomWordAndShuffle()
+ } else {
+ usedWords.add(currentWord)
+ return shuffleCurrentWord(currentWord)
+ }
+ }
+}
\ No newline at end of file