Skip to content

Commit c38f014

Browse files
committed
Sensing intervals/sampling period can now be set between 4 values. Reset Data button added to clear the data from the orientation_data table.
Improved UI using modern designs. Added a visualizer for the orientation data.
1 parent a03424a commit c38f014

File tree

15 files changed

+937
-103
lines changed

15 files changed

+937
-103
lines changed

Assignment3/Axelero/app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ android {
5252

5353
dependencies {
5454
implementation(libs.androidx.lifecycle.viewmodel.compose)
55+
implementation(libs.androidx.navigation.runtime.ktx)
5556
val room_version = "2.6.1"
5657
kapt("androidx.room:room-compiler:$room_version")
5758
implementation(libs.androidx.core.ktx)

Assignment3/Axelero/app/src/main/java/com/example/axelero/HistoryActivity.kt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@ import android.util.Log
66
import androidx.activity.ComponentActivity
77
import androidx.activity.compose.setContent
88
import androidx.activity.result.contract.ActivityResultContracts
9+
import androidx.compose.foundation.layout.fillMaxSize
10+
import androidx.compose.material3.MaterialTheme
11+
import androidx.compose.material3.Surface
12+
import androidx.compose.ui.Modifier
913
import androidx.lifecycle.lifecycleScope
1014
import com.example.axelero.repository.OrientationDataRepository
1115
import com.example.axelero.ui.HistoryContent
16+
import com.example.axelero.ui.theme.AxeleroTheme
1217
import kotlinx.coroutines.launch
1318

1419
class HistoryActivity : ComponentActivity() {
@@ -32,7 +37,15 @@ class HistoryActivity : ComponentActivity() {
3237
super.onCreate(savedInstanceState)
3338
Log.d("HistoryActivity: orientationDataRepository", orientationDataRepository.toString())
3439
setContent {
35-
HistoryContent(orientationDataRepository, createDocumentResult)
40+
AxeleroTheme {
41+
// A surface container using the 'background' color from the theme
42+
Surface(
43+
modifier = Modifier.fillMaxSize(),
44+
color = MaterialTheme.colorScheme.background
45+
) {
46+
HistoryContent(orientationDataRepository, createDocumentResult)
47+
}
48+
}
3649
}
3750
}
3851

Assignment3/Axelero/app/src/main/java/com/example/axelero/MainActivity.kt

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
package com.example.axelero
22

3+
import android.os.Build
34
import android.os.Bundle
45
import android.util.Log
56
import androidx.activity.ComponentActivity
67
import androidx.activity.compose.setContent
8+
import androidx.annotation.RequiresApi
9+
import androidx.compose.foundation.layout.fillMaxSize
10+
import androidx.compose.material3.MaterialTheme
11+
import androidx.compose.material3.Surface
712
import androidx.compose.runtime.getValue
813
import androidx.compose.runtime.mutableFloatStateOf
914
import androidx.compose.runtime.setValue
15+
import androidx.compose.ui.Modifier
1016
import com.example.axelero.repository.OrientationDataRepository
1117
import com.example.axelero.ui.MainContent
18+
import com.example.axelero.ui.theme.AxeleroTheme
1219

1320
class MainActivity : ComponentActivity() {
1421
private val orientationDataRepository by lazy {
@@ -17,10 +24,19 @@ class MainActivity : ComponentActivity() {
1724
private var xAngle by mutableFloatStateOf(0f)
1825
private var yAngle by mutableFloatStateOf(0f)
1926
private var zAngle by mutableFloatStateOf(0f)
27+
@RequiresApi(Build.VERSION_CODES.O)
2028
override fun onCreate(savedInstanceState: Bundle?) {
2129
super.onCreate(savedInstanceState)
2230
setContent {
23-
MainContent(xAngle, yAngle, zAngle, orientationDataRepository)
31+
AxeleroTheme {
32+
// A surface container using the 'background' color from the theme
33+
Surface(
34+
modifier = Modifier.fillMaxSize(),
35+
color = MaterialTheme.colorScheme.background
36+
) {
37+
MainContent(xAngle, yAngle, zAngle, orientationDataRepository)
38+
}
39+
}
2440
}
2541
}
2642

Assignment3/Axelero/app/src/main/java/com/example/axelero/ui/HistoryContent.kt

Lines changed: 98 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,40 @@
11
package com.example.axelero.ui
22

3+
import android.app.Activity
34
import android.content.Intent
45
import androidx.activity.result.ActivityResultLauncher
56
import androidx.compose.foundation.layout.Arrangement
67
import androidx.compose.foundation.layout.Column
78
import androidx.compose.foundation.layout.Spacer
89
import androidx.compose.foundation.layout.fillMaxSize
10+
import androidx.compose.foundation.layout.fillMaxWidth
911
import androidx.compose.foundation.layout.height
12+
import androidx.compose.foundation.layout.padding
13+
import androidx.compose.foundation.rememberScrollState
14+
import androidx.compose.foundation.shape.RoundedCornerShape
15+
import androidx.compose.foundation.verticalScroll
16+
import androidx.compose.material.icons.Icons
17+
import androidx.compose.material.icons.automirrored.filled.ArrowBack
18+
import androidx.compose.material.icons.filled.ArrowBack
1019
import androidx.compose.material3.Button
20+
import androidx.compose.material3.CardDefaults
21+
import androidx.compose.material3.ExperimentalMaterial3Api
22+
import androidx.compose.material3.Icon
23+
import androidx.compose.material3.IconButton
24+
import androidx.compose.material3.MaterialTheme
25+
import androidx.compose.material3.OutlinedButton
26+
import androidx.compose.material3.OutlinedCard
27+
import androidx.compose.material3.Scaffold
28+
import androidx.compose.material3.SmallTopAppBar
1129
import androidx.compose.material3.Text
30+
import androidx.compose.material3.TopAppBar
1231
import androidx.compose.runtime.Composable
1332
import androidx.compose.runtime.produceState
1433
import androidx.compose.runtime.remember
34+
import androidx.compose.runtime.rememberCoroutineScope
1535
import androidx.compose.ui.Alignment
1636
import androidx.compose.ui.Modifier
37+
import androidx.compose.ui.platform.LocalContext
1738
import androidx.compose.ui.unit.dp
1839
import com.example.axelero.db.OrientationData
1940
import com.example.axelero.repository.OrientationDataRepository
@@ -23,70 +44,98 @@ import kotlinx.coroutines.CoroutineScope
2344
import kotlinx.coroutines.Dispatchers
2445
import kotlinx.coroutines.launch
2546

47+
@OptIn(ExperimentalMaterial3Api::class)
2648
@Composable
27-
fun HistoryContent(orientationDataRepository: OrientationDataRepository, createDocumentResult: ActivityResultLauncher<Intent>) {
49+
fun HistoryContent(
50+
orientationDataRepository: OrientationDataRepository,
51+
createDocumentResult: ActivityResultLauncher<Intent>
52+
) {
53+
val context = LocalContext.current
2854
val orientationData = produceState<List<OrientationData>>(initialValue = emptyList()) {
2955
value = orientationDataRepository.getOrientationData()
3056
}
31-
3257
val modelProducer1 = remember { CartesianChartModelProducer.build() }
3358
val modelProducer2 = remember { CartesianChartModelProducer.build() }
3459
val modelProducer3 = remember { CartesianChartModelProducer.build() }
60+
val coroutineScope = rememberCoroutineScope()
61+
val scrollState = rememberScrollState()
3562

36-
Column(
37-
modifier = Modifier.fillMaxSize(),
38-
verticalArrangement = Arrangement.Center,
39-
horizontalAlignment = Alignment.CenterHorizontally
40-
) {
41-
Text("Orientation Data History")
42-
Spacer(modifier = Modifier.height(16.dp))
43-
44-
// Display the three line charts for the actual orientation angles
45-
LineChart(
46-
"X Angle",
47-
orientationData.value.map { it.xAngle },
48-
modelProducer1
49-
)
50-
Spacer(modifier = Modifier.height(16.dp))
51-
LineChart(
52-
"Y Angle",
53-
orientationData.value.map { it.yAngle },
54-
modelProducer2
55-
)
56-
Spacer(modifier = Modifier.height(16.dp))
57-
LineChart(
58-
"Z Angle",
59-
orientationData.value.map { it.zAngle },
60-
modelProducer3
61-
)
63+
Scaffold(
64+
topBar = {
65+
TopAppBar(title = { Text("Orientation Data History") },
66+
navigationIcon = {
67+
IconButton(onClick = {(context as? Activity)?.onBackPressed() }) {
68+
Icon(Icons.AutoMirrored.Filled.ArrowBack, contentDescription = "Back")
69+
}
70+
}
71+
)
72+
}
73+
) { padding ->
74+
Column(
75+
modifier = Modifier
76+
.fillMaxSize()
77+
.padding(padding)
78+
.padding(horizontal = 16.dp)
79+
.verticalScroll(scrollState),
80+
verticalArrangement = Arrangement.Center,
81+
horizontalAlignment = Alignment.CenterHorizontally
82+
) {
83+
Spacer(Modifier.height(16.dp))
84+
OutlinedCard(modifier = Modifier.fillMaxWidth(), elevation = CardDefaults.outlinedCardElevation(defaultElevation = 4.dp)) {
85+
Column(modifier = Modifier.padding(16.dp)) {
86+
Text("X Angle", style = MaterialTheme.typography.titleMedium)
87+
Spacer(Modifier.height(8.dp))
88+
LineChart("X Angle", orientationData.value.map { it.xAngle }, modelProducer1)
89+
}
90+
}
6291

63-
Spacer(modifier = Modifier.height(16.dp))
64-
Button(
65-
onClick = {
66-
// Save the orientation data to a text file on the device
67-
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
68-
addCategory(Intent.CATEGORY_OPENABLE)
69-
type = "text/plain"
70-
putExtra(Intent.EXTRA_TITLE, "orientation_data_" + {orientationDataRepository.sensingInterval.toString()} + ".txt")
92+
Spacer(Modifier.height(16.dp))
93+
OutlinedCard(modifier = Modifier.fillMaxWidth(), elevation = CardDefaults.outlinedCardElevation(defaultElevation = 4.dp)) {
94+
Column(modifier = Modifier.padding(16.dp)) {
95+
Text("Y Angle", style = MaterialTheme.typography.titleMedium)
96+
Spacer(Modifier.height(8.dp))
97+
LineChart("Y Angle", orientationData.value.map { it.yAngle }, modelProducer2)
7198
}
72-
createDocumentResult.launch(intent)
7399
}
74-
) {
75-
Text("Export Data")
76-
}
77-
Spacer(modifier = Modifier.height(16.dp))
78-
Button(
79-
onClick = {
80-
// Reset the orientation data in the database
81-
CoroutineScope(Dispatchers.IO).launch {
82-
orientationDataRepository.clearOrientationData()
100+
101+
Spacer(Modifier.height(16.dp))
102+
OutlinedCard(modifier = Modifier.fillMaxWidth(), elevation = CardDefaults.outlinedCardElevation(defaultElevation = 4.dp)) {
103+
Column(modifier = Modifier.padding(16.dp)) {
104+
Text("Z Angle", style = MaterialTheme.typography.titleMedium)
105+
Spacer(Modifier.height(8.dp))
106+
LineChart("Z Angle", orientationData.value.map { it.zAngle }, modelProducer3)
83107
}
84108
}
85-
) {
86-
Text("Reset Data")
109+
110+
Spacer(Modifier.height(24.dp))
111+
OutlinedButton(
112+
onClick = {
113+
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
114+
addCategory(Intent.CATEGORY_OPENABLE)
115+
type = "text/plain"
116+
putExtra(Intent.EXTRA_TITLE, "orientation_data_" + orientationDataRepository.sensingInterval.toString() + ".txt")
117+
}
118+
createDocumentResult.launch(intent)
119+
},
120+
modifier = Modifier.fillMaxWidth(0.6f),
121+
shape = RoundedCornerShape(8.dp)
122+
) {
123+
Text("Export Data")
124+
}
125+
Spacer(Modifier.height(16.dp))
126+
OutlinedButton(
127+
onClick = {
128+
coroutineScope.launch {
129+
orientationDataRepository.clearOrientationData()
130+
}
131+
},
132+
modifier = Modifier.fillMaxWidth(0.6f),
133+
shape = RoundedCornerShape(8.dp)
134+
) {
135+
Text("Reset Data")
136+
}
87137
}
88138
}
89139
}
90140

91141

92-

0 commit comments

Comments
 (0)