@@ -14,6 +14,7 @@ import androidx.compose.animation.slideInVertically
1414import androidx.compose.animation.slideOutVertically
1515import androidx.compose.animation.togetherWith
1616import androidx.compose.foundation.interaction.MutableInteractionSource
17+ import androidx.compose.foundation.layout.Arrangement
1718import androidx.compose.foundation.layout.Box
1819import androidx.compose.foundation.layout.Column
1920import androidx.compose.foundation.layout.IntrinsicSize
@@ -60,11 +61,13 @@ import androidx.compose.material3.MaterialTheme
6061import androidx.compose.material3.OutlinedButton
6162import androidx.compose.material3.OutlinedTextFieldDefaults
6263import androidx.compose.material3.Surface
64+ import androidx.compose.material3.Switch
6365import androidx.compose.material3.Text
6466import androidx.compose.material3.TextFieldDefaults
6567import androidx.compose.material3.TopAppBarColors
6668import androidx.compose.material3.TopAppBarDefaults
6769import androidx.compose.material3.TopAppBarScrollBehavior
70+ import androidx.compose.material3.VerticalDivider
6871import androidx.compose.runtime.Composable
6972import androidx.compose.runtime.LaunchedEffect
7073import androidx.compose.runtime.derivedStateOf
@@ -134,6 +137,7 @@ fun KeyMapListAppBar(
134137 onRemoveConstraintClick : (String ) -> Unit = {},
135138 onConstraintModeChanged : (ConstraintMode ) -> Unit = {},
136139 onFixConstraintClick : (KMError ) -> Unit = {},
140+ onKeyMapsEnabledChange : (Boolean ) -> Unit = {}
137141) {
138142 BackHandler (onBack = onBackClick)
139143
@@ -278,6 +282,8 @@ fun KeyMapListAppBar(
278282 onRemoveConstraintClick = onRemoveConstraintClick,
279283 onConstraintModeChanged = onConstraintModeChanged,
280284 onFixConstraintClick = onFixConstraintClick,
285+ keyMapsEnabled = state.keyMapsEnabled,
286+ onKeyMapsEnabledChange = onKeyMapsEnabledChange,
281287 actions = {
282288 AnimatedVisibility (! state.isEditingGroupName) {
283289 var expandedDropdown by rememberSaveable { mutableStateOf(false ) }
@@ -343,13 +349,13 @@ private fun RootGroupAppBar(
343349) {
344350 // This is taken from the AppBar color code.
345351 val colorTransitionFraction by
346- remember(scrollBehavior) {
347- // derivedStateOf to prevent redundant recompositions when the content scrolls.
348- derivedStateOf {
349- val overlappingFraction = scrollBehavior.state.overlappedFraction
350- if (overlappingFraction > 0.01f ) 1f else 0f
351- }
352+ remember(scrollBehavior) {
353+ // derivedStateOf to prevent redundant recompositions when the content scrolls.
354+ derivedStateOf {
355+ val overlappingFraction = scrollBehavior.state.overlappedFraction
356+ if (overlappingFraction > 0.01f ) 1f else 0f
352357 }
358+ }
353359
354360 val appBarColors = TopAppBarDefaults .centerAlignedTopAppBarColors()
355361
@@ -383,7 +389,7 @@ private fun RootGroupAppBar(
383389 Surface (color = appBarContainerColor) {
384390 HomeWarningList (
385391 modifier = Modifier .padding(bottom = 8 .dp),
386- warnings = ( state as ? KeyMapAppBarState . RootGroup )?. warnings ? : emptyList() ,
392+ warnings = state. warnings,
387393 onFixClick = onFixWarningClick,
388394 )
389395 }
@@ -426,6 +432,8 @@ private fun ChildGroupAppBar(
426432 onRemoveConstraintClick : (String ) -> Unit = {},
427433 onConstraintModeChanged : (ConstraintMode ) -> Unit = {},
428434 onFixConstraintClick : (KMError ) -> Unit = {},
435+ keyMapsEnabled : SelectedKeyMapsEnabled ? ,
436+ onKeyMapsEnabledChange : (Boolean ) -> Unit = {},
429437 actions : @Composable RowScope .() -> Unit = {},
430438) {
431439 // Make custom top app bar because the height can not be set to fix the text field error in.
@@ -483,29 +491,58 @@ private fun ChildGroupAppBar(
483491
484492 Spacer (Modifier .height(8 .dp))
485493
486- androidx.compose.animation. AnimatedVisibility (
487- modifier = Modifier .align( Alignment .End ) ,
488- visible = constraints.size > 1 ,
494+ Row (
495+ modifier = Modifier .fillMaxWidth(), horizontalArrangement = Arrangement .End ,
496+ verticalAlignment = Alignment . CenterVertically
489497 ) {
490- Row {
491- RadioButtonText (
492- text = stringResource(R .string.constraint_mode_and),
493- isSelected = constraintMode == ConstraintMode .AND ,
494- isEnabled = ! isEditingGroupName,
495- onSelected = {
496- onConstraintModeChanged(ConstraintMode .AND )
497- },
498- )
498+ androidx.compose.animation.AnimatedVisibility (
499+ visible = constraints.size > 1 ,
500+ ) {
501+ Row (verticalAlignment = Alignment .CenterVertically ) {
502+ RadioButtonText (
503+ text = stringResource(R .string.constraint_mode_and),
504+ isSelected = constraintMode == ConstraintMode .AND ,
505+ isEnabled = ! isEditingGroupName,
506+ onSelected = {
507+ onConstraintModeChanged(ConstraintMode .AND )
508+ },
509+ )
499510
500- RadioButtonText (
501- text = stringResource(R .string.constraint_mode_or),
502- isSelected = constraintMode == ConstraintMode .OR ,
503- isEnabled = ! isEditingGroupName,
504- onSelected = {
505- onConstraintModeChanged(ConstraintMode .OR )
506- },
507- )
511+ RadioButtonText (
512+ text = stringResource(R .string.constraint_mode_or),
513+ isSelected = constraintMode == ConstraintMode .OR ,
514+ isEnabled = ! isEditingGroupName,
515+ onSelected = {
516+ onConstraintModeChanged(ConstraintMode .OR )
517+ },
518+ )
519+
520+ VerticalDivider (
521+ modifier = Modifier .height(24 .dp),
522+ color = MaterialTheme .colorScheme.onPrimaryContainer
523+ )
524+ }
525+ }
526+
527+ Spacer (Modifier .width(16 .dp))
528+
529+ val text = when (keyMapsEnabled) {
530+ SelectedKeyMapsEnabled .ALL -> stringResource(R .string.home_enabled_key_maps_enabled)
531+ SelectedKeyMapsEnabled .MIXED -> stringResource(R .string.home_enabled_key_maps_mixed)
532+ SelectedKeyMapsEnabled .NONE , null -> stringResource(R .string.home_enabled_key_maps_disabled)
508533 }
534+
535+ Switch (
536+ checked = keyMapsEnabled == SelectedKeyMapsEnabled .ALL ,
537+ onCheckedChange = onKeyMapsEnabledChange,
538+ enabled = keyMapsEnabled != null ,
539+ )
540+
541+ Spacer (Modifier .width(16 .dp))
542+
543+ Text (text = text, style = MaterialTheme .typography.bodyMedium)
544+
545+ Spacer (Modifier .width(16 .dp))
509546 }
510547 }
511548 }
@@ -950,7 +987,7 @@ private fun groupSampleList(): List<GroupListItemModel> {
950987}
951988
952989@OptIn(ExperimentalMaterial3Api ::class )
953- @Preview(showSystemUi = true )
990+ @Preview
954991@Composable
955992private fun KeyMapsChildGroupPreview () {
956993 val state = KeyMapAppBarState .ChildGroup (
@@ -962,14 +999,15 @@ private fun KeyMapsChildGroupPreview() {
962999 breadcrumbs = groupSampleList(),
9631000 isEditingGroupName = false ,
9641001 isNewGroup = false ,
1002+ keyMapsEnabled = SelectedKeyMapsEnabled .ALL
9651003 )
9661004 KeyMapperTheme {
9671005 KeyMapListAppBar (modifier = Modifier .fillMaxWidth(), state = state)
9681006 }
9691007}
9701008
9711009@OptIn(ExperimentalMaterial3Api ::class )
972- @Preview(showSystemUi = true )
1010+ @Preview
9731011@Composable
9741012private fun KeyMapsChildGroupDarkPreview () {
9751013 val state = KeyMapAppBarState .ChildGroup (
@@ -981,14 +1019,15 @@ private fun KeyMapsChildGroupDarkPreview() {
9811019 breadcrumbs = emptyList(),
9821020 isEditingGroupName = false ,
9831021 isNewGroup = false ,
1022+ keyMapsEnabled = SelectedKeyMapsEnabled .MIXED
9841023 )
9851024 KeyMapperTheme (darkTheme = true ) {
9861025 KeyMapListAppBar (modifier = Modifier .fillMaxWidth(), state = state)
9871026 }
9881027}
9891028
9901029@OptIn(ExperimentalMaterial3Api ::class )
991- @Preview(showSystemUi = true )
1030+ @Preview
9921031@Composable
9931032private fun KeyMapsChildGroupEditingPreview () {
9941033 val focusRequester = FocusRequester ()
@@ -1008,12 +1047,13 @@ private fun KeyMapsChildGroupEditingPreview() {
10081047 constraints = emptyList(),
10091048 constraintMode = ConstraintMode .AND ,
10101049 parentConstraintCount = 1 ,
1050+ keyMapsEnabled = SelectedKeyMapsEnabled .NONE
10111051 )
10121052 }
10131053}
10141054
10151055@OptIn(ExperimentalMaterial3Api ::class )
1016- @Preview(showSystemUi = true )
1056+ @Preview
10171057@Composable
10181058private fun KeyMapsChildGroupEditingDarkPreview () {
10191059 val state = KeyMapAppBarState .ChildGroup (
@@ -1025,6 +1065,7 @@ private fun KeyMapsChildGroupEditingDarkPreview() {
10251065 breadcrumbs = emptyList(),
10261066 isEditingGroupName = true ,
10271067 isNewGroup = true ,
1068+ keyMapsEnabled = SelectedKeyMapsEnabled .ALL
10281069 )
10291070
10301071 val focusRequester = FocusRequester ()
@@ -1040,7 +1081,7 @@ private fun KeyMapsChildGroupEditingDarkPreview() {
10401081 }
10411082}
10421083
1043- @Preview(showSystemUi = true )
1084+ @Preview
10441085@Composable
10451086private fun KeyMapsChildGroupErrorPreview () {
10461087 val focusRequester = FocusRequester ()
@@ -1060,6 +1101,7 @@ private fun KeyMapsChildGroupErrorPreview() {
10601101 constraints = emptyList(),
10611102 constraintMode = ConstraintMode .AND ,
10621103 parentConstraintCount = 0 ,
1104+ keyMapsEnabled = null
10631105 )
10641106 }
10651107}
@@ -1145,7 +1187,7 @@ private fun HomeStateWarningsDarkPreview() {
11451187}
11461188
11471189@OptIn(ExperimentalMaterial3Api ::class )
1148- @Preview(showSystemUi = true )
1190+ @Preview
11491191@Composable
11501192private fun HomeStateSelectingPreview () {
11511193 val state = KeyMapAppBarState .Selecting (
@@ -1162,7 +1204,7 @@ private fun HomeStateSelectingPreview() {
11621204}
11631205
11641206@OptIn(ExperimentalMaterial3Api ::class )
1165- @Preview(showSystemUi = true )
1207+ @Preview
11661208@Composable
11671209private fun HomeStateSelectingDisabledPreview () {
11681210 val state = KeyMapAppBarState .Selecting (
0 commit comments