feat(connector): add pre-run command before tests

This commit is contained in:
Anthony Berg 2024-05-09 07:16:29 +01:00
parent d551c1b5c5
commit 3e31294b27
4 changed files with 172 additions and 1 deletions

View File

@ -6,6 +6,8 @@ class InterfaceState : KoinComponent {
var projectId: Int? = null
var procedureId: Int? = null
var testId: Int? = null
var altitude: Int? = null
var speed: Int? = null
val projectSelected: Boolean
get() = projectId != null

View File

@ -8,6 +8,8 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollbarAdapter
import androidx.compose.foundation.selection.toggleable
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Add
import androidx.compose.material.icons.outlined.Edit
@ -16,6 +18,9 @@ import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import cafe.adriel.voyager.core.screen.Screen
import cafe.adriel.voyager.koin.getScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator
@ -33,6 +38,8 @@ import tab.test.SimulatorTest
class ListProcedures (
private val procedures: List<Procedure>
) : Screen {
private val optionInput = mutableStateListOf("", "", "")
@Composable
override fun Content() {
val navigator = LocalNavigator.currentOrThrow
@ -132,6 +139,7 @@ class ListProcedures (
onDismissRequest: () -> Unit
) {
val tabNavigator = LocalTabNavigator.current
var openRunDialog by remember { mutableStateOf(false) }
DropdownMenu(
expanded = expanded,
@ -152,12 +160,155 @@ class ListProcedures (
text = { Text("Run Test") },
onClick = {
viewModel.procedureId = procedure.id
tabNavigator.current = SimulatorTest
openRunDialog = true
},
leadingIcon = {
Icon(Icons.Outlined.PlayArrow, "Run Procedure Tests")
},
)
}
when {
openRunDialog -> {
BeforeStartDialog(
onDismissRequest = { openRunDialog = false },
onConfirmation = {
openRunDialog = false
viewModel.altitude = optionInput[0].toIntOrNull()
viewModel.speed = optionInput[1].toIntOrNull()
tabNavigator.current = SimulatorTest
}
)
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun BeforeStartDialog(
onDismissRequest: () -> Unit,
onConfirmation: () -> Unit,
) {
var modeSelect by remember { mutableStateOf(0) }
val modeOptions = listOf("None", "Pre-Configure")
Dialog(onDismissRequest = { onDismissRequest() }) {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
shape = RoundedCornerShape(16.dp),
) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Pre-Run Commands",
style = MaterialTheme.typography.headlineSmall,
modifier = Modifier.padding(16.dp)
)
MultiChoiceSegmentedButtonRow (
modifier = Modifier.padding(8.dp)
) {
modeOptions.forEachIndexed { index, label ->
SegmentedButton(
shape = SegmentedButtonDefaults.itemShape(
index = index,
count = modeOptions.size
),
onCheckedChange = { modeSelect = index },
checked = (index == modeSelect),
) {
Text(label)
}
}
}
when {
modeSelect == 1 -> {
BeforeStartForm()
}
}
Row(
modifier = Modifier
.fillMaxWidth(),
horizontalArrangement = Arrangement.Center,
) {
TextButton(
onClick = { onConfirmation() },
modifier = Modifier.padding(8.dp),
) {
Text("Run")
}
TextButton(
onClick = { onDismissRequest() },
modifier = Modifier.padding(8.dp),
) {
Text("Cancel")
}
}
}
}
}
}
@Composable
private fun BeforeStartForm() {
val checkedListState = remember { mutableStateListOf<Int>() }
val options = listOf("Set Altitude", "Set Speed", "Add Actions")
Column(
modifier = Modifier
.fillMaxWidth(0.9F),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
options.forEachIndexed { index, label ->
Row(
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
.padding(8.dp)
.toggleable(
value = index in checkedListState,
onValueChange = {
if (index in checkedListState) {
checkedListState.remove(index)
} else {
checkedListState.add(index)
}
},
role = Role.Checkbox,
),
verticalAlignment = Alignment.CenterVertically,
) {
Checkbox(
checked = index in checkedListState,
onCheckedChange = null,
)
Text(
text = label,
style = MaterialTheme.typography.bodyLarge,
)
}
if (index in checkedListState) {
OutlinedTextField(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp),
value = optionInput[index],
onValueChange = { optionInput[index] = it },
label = { Text(options[index]) },
singleLine = true
)
}
}
}
}
}

View File

@ -39,6 +39,16 @@ class TestScreenModel (
return@launch
}
val altitude = interfaceState.altitude
if (altitude != null) {
val posi = DoubleArray(7) { -998.0 }
posi[2] = altitude.toDouble()
posi[6] = 0.0
xpc.setPOSI(posi)
}
delay(5000L)
// Starts the test in the database
interfaceState.testId = db.startTest(procedureId)

View File

@ -73,4 +73,12 @@ class XPC {
return result
}
fun getPOSI(): DoubleArray {
return xpc.getPOSI(0)
}
fun setPOSI(posi: DoubleArray) {
xpc.sendPOSI(posi, 0)
}
}