Modify UART screen

This commit is contained in:
Sylwester Zieliński
2022-05-06 14:36:56 +02:00
parent 742d854b8b
commit c7b2cae6a3
20 changed files with 119 additions and 134 deletions

View File

@@ -2,7 +2,6 @@ package no.nordicsemi.android.nrftoolbox
import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
@@ -13,7 +12,6 @@ import no.nordicsemi.android.material.you.NordicActivity
import no.nordicsemi.android.material.you.NordicTheme
import no.nordicsemi.android.navigation.NavigationView
import no.nordicsemi.android.nrftoolbox.repository.ActivitySignals
import no.nordicsemi.android.nrftoolbox.viewmodel.HomeViewModel
import no.nordicsemi.ui.scanner.ScannerDestinations
import javax.inject.Inject

View File

@@ -4,16 +4,9 @@ import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SmallTopAppBar
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
@@ -80,7 +73,7 @@ fun BackIconAppBar(text: String, onClick: () -> Unit) {
IconButton(onClick = { onClick() }) {
Icon(
painterResource(id = R.drawable.ic_logger),
contentDescription = stringResource(id = R.string.back_screen),
contentDescription = stringResource(id = R.string.open_logger),
tint = MaterialTheme.colorScheme.onPrimary,
modifier = Modifier.size(24.dp)
)
@@ -90,7 +83,7 @@ fun BackIconAppBar(text: String, onClick: () -> Unit) {
}
@Composable
fun LoggerIconAppBar(text: String, onClick: () -> Unit, onLoggerClick: () -> Unit) {
fun LoggerIconAppBar(text: String, onClick: () -> Unit, onDisconnectClick: () -> Unit, onLoggerClick: () -> Unit) {
SmallTopAppBar(
title = { Text(text) },
colors = TopAppBarDefaults.smallTopAppBarColors(
@@ -110,10 +103,13 @@ fun LoggerIconAppBar(text: String, onClick: () -> Unit, onLoggerClick: () -> Uni
}
},
actions = {
Button(onClick = { onDisconnectClick() }) {
Text(stringResource(id = R.string.disconnect))
}
IconButton(onClick = { onLoggerClick() }) {
Icon(
painterResource(id = R.drawable.ic_logger),
contentDescription = stringResource(id = R.string.back_screen),
contentDescription = stringResource(id = R.string.open_logger),
tint = MaterialTheme.colorScheme.onPrimary,
modifier = Modifier.size(24.dp)
)

View File

@@ -9,6 +9,7 @@
<string name="close_app">Close the application.</string>
<string name="back_screen">Close the current screen.</string>
<string name="open_logger">Open logger application.</string>
<string name="disconnect">Disconnect</string>
<string name="field_battery">Battery</string>

View File

@@ -28,7 +28,7 @@ fun BPSScreen() {
LoggerIconAppBar(stringResource(id = R.string.bps_title), {
viewModel.onEvent(DisconnectEvent)
}) {
}, { viewModel.onEvent(DisconnectEvent) }) {
viewModel.onEvent(OpenLoggerEvent)
}

View File

@@ -26,7 +26,7 @@ fun CGMScreen() {
Column {
val navigateUp = { viewModel.onEvent(NavigateUp) }
LoggerIconAppBar(stringResource(id = R.string.cgms_title), navigateUp) {
LoggerIconAppBar(stringResource(id = R.string.cgms_title), navigateUp, { viewModel.onEvent(DisconnectEvent)}) {
viewModel.onEvent(OpenLoggerEvent)
}

View File

@@ -26,7 +26,7 @@ fun CSCScreen() {
Column {
val navigateUp = { viewModel.onEvent(NavigateUp) }
LoggerIconAppBar(stringResource(id = R.string.csc_title), navigateUp) {
LoggerIconAppBar(stringResource(id = R.string.csc_title), navigateUp, { viewModel.onEvent(OnDisconnectButtonClick) }) {
viewModel.onEvent(OpenLogger)
}

View File

@@ -28,7 +28,7 @@ fun GLSScreen() {
LoggerIconAppBar(stringResource(id = R.string.gls_title), {
viewModel.onEvent(DisconnectEvent)
}) {
}, { viewModel.onEvent(DisconnectEvent) }) {
viewModel.onEvent(OpenLoggerEvent)
}

View File

@@ -26,7 +26,7 @@ fun HRSScreen() {
Column {
val navigateUp = { viewModel.onEvent(NavigateUpEvent) }
LoggerIconAppBar(stringResource(id = R.string.hrs_title), navigateUp) {
LoggerIconAppBar(stringResource(id = R.string.hrs_title), navigateUp, { viewModel.onEvent(DisconnectEvent) }) {
viewModel.onEvent(OpenLoggerEvent)
}

View File

@@ -26,7 +26,7 @@ fun HTSScreen() {
Column {
val navigateUp = { viewModel.onEvent(NavigateUp) }
LoggerIconAppBar(stringResource(id = R.string.hts_title), navigateUp) {
LoggerIconAppBar(stringResource(id = R.string.hts_title), navigateUp, { viewModel.onEvent(DisconnectEvent) }) {
viewModel.onEvent(OpenLoggerEvent)
}

View File

@@ -27,7 +27,7 @@ fun PRXScreen() {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
val navigateUp = { viewModel.onEvent(NavigateUpEvent) }
LoggerIconAppBar(stringResource(id = R.string.prx_title), navigateUp) {
LoggerIconAppBar(stringResource(id = R.string.prx_title), navigateUp, { viewModel.onEvent(DisconnectEvent) }) {
viewModel.onEvent(OpenLoggerEvent)
}

View File

@@ -26,7 +26,7 @@ fun RSCSScreen() {
Column {
val navigateUp = { viewModel.onEvent(NavigateUpEvent) }
LoggerIconAppBar(stringResource(id = R.string.rscs_title), navigateUp) {
LoggerIconAppBar(stringResource(id = R.string.rscs_title), navigateUp, { viewModel.onEvent(DisconnectEvent) }) {
viewModel.onEvent(OpenLoggerEvent)
}

View File

@@ -4,7 +4,7 @@ apply plugin: 'com.google.protobuf'
protobuf {
protoc {
artifact = 'com.google.protobuf:protoc:3.14.0:osx-x86_64'
artifact = 'com.google.protobuf:protoc:3.14.0'
}
// Generates the java Protobuf-lite code for the Protobufs in this project. See

View File

@@ -1,8 +1,6 @@
package no.nordicsemi.android.uart.view
import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
@@ -24,6 +22,28 @@ internal fun InputSection(onEvent: (UARTViewEvent) -> Unit) {
val hint = stringResource(id = R.string.uart_input_hint)
val checkedItem = rememberSaveable { mutableStateOf(MacroEol.values()[0]) }
Row(verticalAlignment = Alignment.CenterVertically) {
Box(modifier = Modifier.weight(1f)) {
TextField(text = text.value, hint = hint) {
text.value = it
}
}
Spacer(modifier = Modifier.size(16.dp))
Button(
onClick = { onEvent(OnRunInput(text.value, checkedItem.value)) },
modifier = Modifier.padding(top = 6.dp)
) {
Text(text = stringResource(id = R.string.uart_send))
}
}
}
@Composable
internal fun EditInputSection(onEvent: (UARTViewEvent) -> Unit) {
val checkedItem = rememberSaveable { mutableStateOf(MacroEol.values()[0]) }
val items = MacroEol.values().map {
RadioButtonItem(it.toDisplayString(), it == checkedItem.value)
}
@@ -59,23 +79,6 @@ internal fun InputSection(onEvent: (UARTViewEvent) -> Unit) {
}
Spacer(modifier = Modifier.size(16.dp))
Row(verticalAlignment = Alignment.CenterVertically) {
Box(modifier = Modifier.weight(1f)) {
TextField(text = text.value, hint = hint) {
text.value = it
}
}
Spacer(modifier = Modifier.size(16.dp))
Button(
onClick = { onEvent(OnRunInput(text.value, checkedItem.value)) },
modifier = Modifier.padding(top = 6.dp)
) {
Text(text = stringResource(id = R.string.uart_send))
}
}
}
}
}

View File

@@ -31,66 +31,70 @@ internal fun MacroSection(viewState: UARTViewState, onEvent: (UARTViewEvent) ->
DeleteConfigurationDialog(onEvent) { showDeleteDialog.value = false }
}
ScreenSection {
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
SectionTitle(
resId = R.drawable.ic_macro,
title = stringResource(R.string.uart_macros),
menu = {
IconButton(onClick = { onEvent(MacroInputSwitchClick) }) {
if (viewState.showEditDialog) {
UARTAddMacroDialog(viewState.selectedMacro) { onEvent(it) }
}
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(16.dp).fillMaxSize()
) {
ScreenSection {
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
SectionTitle(
resId = R.drawable.ic_macro,
title = stringResource(R.string.uart_macros),
)
Spacer(modifier = Modifier.height(16.dp))
Row {
Box(modifier = Modifier.weight(1f)) {
UARTConfigurationPicker(viewState, onEvent)
}
IconButton(onClick = { showAddDialog.value = true }) {
Icon(
painterResource(id = R.drawable.ic_input),
contentDescription = stringResource(id = R.string.uart_input_macro),
Icons.Default.Add,
stringResource(id = R.string.uart_configuration_add)
)
}
}
)
Spacer(modifier = Modifier.height(16.dp))
viewState.selectedConfiguration?.let {
Row {
Box(modifier = Modifier.weight(1f)) {
UARTConfigurationPicker(viewState, onEvent)
}
if (!viewState.isConfigurationEdited) {
IconButton(onClick = { onEvent(OnEditConfiguration) }) {
Icon(
Icons.Default.Edit,
stringResource(id = R.string.uart_configuration_edit)
)
}
} else {
IconButton(onClick = { onEvent(OnEditConfiguration) }) {
Icon(
painterResource(id = R.drawable.ic_pencil_off),
stringResource(id = R.string.uart_configuration_edit)
)
}
}
IconButton(onClick = { showAddDialog.value = true }) {
Icon(Icons.Default.Add, stringResource(id = R.string.uart_configuration_add))
IconButton(onClick = { showDeleteDialog.value = true }) {
Icon(
Icons.Default.Delete,
stringResource(id = R.string.uart_configuration_delete)
)
}
}
}
viewState.selectedConfiguration?.let {
Spacer(modifier = Modifier.height(16.dp))
if (!viewState.isConfigurationEdited) {
IconButton(onClick = { onEvent(OnEditConfiguration) }) {
Icon(
Icons.Default.Edit,
stringResource(id = R.string.uart_configuration_edit)
)
}
} else {
IconButton(onClick = { onEvent(OnEditConfiguration) }) {
Icon(
painterResource(id = R.drawable.ic_pencil_off),
stringResource(id = R.string.uart_configuration_edit)
)
}
}
IconButton(onClick = { showDeleteDialog.value = true }) {
Icon(
Icons.Default.Delete,
stringResource(id = R.string.uart_configuration_delete)
)
}
UARTMacroView(it, viewState.isConfigurationEdited, onEvent)
}
}
viewState.selectedConfiguration?.let {
Spacer(modifier = Modifier.height(16.dp))
UARTMacroView(it, viewState.isConfigurationEdited, onEvent)
}
}
}
}

View File

@@ -1,9 +0,0 @@
package no.nordicsemi.android.uart.view
import androidx.compose.runtime.Composable
@Composable
fun SettingsScreen() {
}

View File

@@ -1,23 +1,16 @@
package no.nordicsemi.android.uart.view
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import no.nordicsemi.android.material.you.ScreenSection
import no.nordicsemi.android.uart.R
import no.nordicsemi.android.uart.data.UARTData
@Composable
internal fun UARTContentView(
state: UARTData,
viewState: UARTViewState,
onEvent: (UARTViewEvent) -> Unit
) {
Column(
@@ -33,18 +26,8 @@ internal fun UARTContentView(
Spacer(modifier = Modifier.size(16.dp))
if (viewState.isInputVisible) {
InputSection(onEvent = onEvent)
} else {
MacroSection(viewState, onEvent)
}
InputSection(onEvent = onEvent)
Spacer(modifier = Modifier.size(16.dp))
Button(
onClick = { onEvent(DisconnectEvent) }
) {
Text(text = stringResource(id = R.string.disconnect))
}
}
}

View File

@@ -19,7 +19,7 @@ import no.nordicsemi.android.uart.data.UARTConfiguration
import no.nordicsemi.android.uart.data.UARTMacro
private val divider = 4.dp
private val buttonSize = 80.dp
private val buttonSize = 80.dp //Minimum touch area
@Composable
internal fun UARTMacroView(

View File

@@ -8,9 +8,13 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import no.nordicsemi.android.material.you.PagerView
import no.nordicsemi.android.material.you.PagerViewEntity
import no.nordicsemi.android.material.you.PagerViewItem
import no.nordicsemi.android.service.*
import no.nordicsemi.android.theme.view.LoggerIconAppBar
import no.nordicsemi.android.uart.R
import no.nordicsemi.android.uart.data.UARTData
import no.nordicsemi.android.uart.viewmodel.UARTViewModel
import no.nordicsemi.android.utils.exhaustive
import no.nordicsemi.ui.scanner.ui.DeviceConnectingView
@@ -23,14 +27,10 @@ fun UARTScreen() {
val viewModel: UARTViewModel = hiltViewModel()
val state = viewModel.state.collectAsState().value
if (state.showEditDialog) {
UARTAddMacroDialog(state.selectedMacro) { viewModel.onEvent(it) }
}
Column {
val navigateUp = { viewModel.onEvent(NavigateUp) }
LoggerIconAppBar(stringResource(id = R.string.uart_title), navigateUp) {
LoggerIconAppBar(stringResource(id = R.string.uart_title), navigateUp, { viewModel.onEvent(DisconnectEvent) }) {
viewModel.onEvent(OpenLogger)
}
@@ -44,16 +44,7 @@ fun UARTScreen() {
is LinkLossResult -> Scroll { DeviceDisconnectedView(Reason.LINK_LOSS, navigateUp) }
is MissingServiceResult -> Scroll { DeviceDisconnectedView(Reason.MISSING_SERVICE, navigateUp) }
is UnknownErrorResult -> Scroll { DeviceDisconnectedView(Reason.UNKNOWN, navigateUp) }
is SuccessResult -> {
// val i1 = PagerViewEntity(
// listOf(
// PagerViewItem("aaa") { Text("aa") },
// PagerViewItem("bbb") { Text("bb") }
// )
// )
// PagerView(i1)
UARTContentView(state.uartManagerState.result.data, state) { viewModel.onEvent(it) }
}
is SuccessResult -> SuccessScreen(state.uartManagerState.result.data, state, viewModel)
}
TutorialState -> TutorialScreen(viewModel)
}.exhaustive
@@ -61,6 +52,21 @@ fun UARTScreen() {
}
}
@Composable
private fun SuccessScreen(data: UARTData, state: UARTViewState, viewModel: UARTViewModel) {
val viewEntity = PagerViewEntity(
listOf(
PagerViewItem(stringResource(id = R.string.uart_input)) {
UARTContentView(data) { viewModel.onEvent(it) }
},
PagerViewItem(stringResource(id = R.string.uart_macros)) {
MacroSection(state) { viewModel.onEvent(it) }
}
)
)
PagerView(viewEntity)
}
@Composable
fun Scroll(content: @Composable () -> Unit) {
Column(modifier = Modifier.verticalScroll(rememberScrollState())) {

View File

@@ -58,4 +58,7 @@
<string name="uart_scroll_down">Click to constantly scroll view to the latest available log.</string>
<string name="uart_input_log">--&gt; %s</string>
<string name="uart_output_log" tools:ignore="TypographyDashes">&lt;-- %s</string>
<string name="uart_settings">Settings</string>
<string name="uart_settings_button">Go to settings screen.</string>
</resources>

View File

@@ -37,9 +37,9 @@ dependencyResolutionManagement {
library('datastore-protobuf', 'com.google.protobuf:protobuf-javalite:3.18.0')
bundle('datastore', ['datastore-core', 'datastore-prefs', 'datastore-protobuf'])
version('compose', '1.1.0')
version('compose', '1.2.0-alpha07')
library('compose-ui', 'androidx.compose.ui', 'ui').versionRef('compose')
library('compose-material', 'androidx.compose.material3:material3:1.0.0-alpha10')
library('compose-material', 'androidx.compose.material3:material3:1.0.0-alpha09')
library('compose-tooling-preview', 'androidx.compose.ui', 'ui-tooling-preview').versionRef('compose')
library('compose-navigation', 'androidx.navigation:navigation-compose:2.4.1')
bundle('compose', ['compose-ui', 'compose-material', 'compose-tooling-preview', 'compose-navigation'])