Skip to content

Commit ba05741

Browse files
committed
#397 feat: add switch to enable/disable all the key maps in a subgroup
1 parent d679113 commit ba05741

File tree

13 files changed

+160
-54
lines changed

13 files changed

+160
-54
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
- Shortcuts on the trigger screen that guide you how to set up different types of buttons.
1111
- #1788 dismiss lockscreen when launching app action from lockscreen
1212
- Show tips for parallel and sequence triggers, and constraints in the trigger screen
13+
- #397 enable/disable all key maps in a group
1314

1415
## Removed
1516

app/version.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
VERSION_NAME=4.0.0-beta.1
2-
VERSION_CODE=161
2+
VERSION_CODE=163
33
VERSION_NUM=0

base/src/main/assets/whats-new.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Version 4.0! 🎉
44

55
⏻ Remap your power button and more
66

7+
Enable/disable all the key maps in a group
8+
79
Many other bug fixes and optimisations
810

911
See all the changes at http://changelog.keymapper.club.

base/src/main/java/io/github/sds100/keymapper/base/home/HomeKeyMapListScreen.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ fun HomeKeyMapListScreen(
234234
onRemoveConstraintClick = viewModel::onRemoveGroupConstraintClick,
235235
onConstraintModeChanged = viewModel::onGroupConstraintModeChanged,
236236
onFixConstraintClick = viewModel::onFixClick,
237+
onKeyMapsEnabledChange = viewModel::onGroupKeyMapsEnabledChanged
237238
)
238239
},
239240
selectionBottomSheet = {

base/src/main/java/io/github/sds100/keymapper/base/home/KeyMapAppBarState.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ sealed class KeyMapAppBarState {
2020
val breadcrumbs: List<GroupListItemModel>,
2121
val isEditingGroupName: Boolean,
2222
val isNewGroup: Boolean,
23+
/**
24+
* If it is null then the Switch should be disabled.
25+
*/
26+
val keyMapsEnabled: SelectedKeyMapsEnabled?,
2327
) : KeyMapAppBarState()
2428

2529
data class Selecting(

base/src/main/java/io/github/sds100/keymapper/base/home/KeyMapListAppBar.kt

Lines changed: 76 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import androidx.compose.animation.slideInVertically
1414
import androidx.compose.animation.slideOutVertically
1515
import androidx.compose.animation.togetherWith
1616
import androidx.compose.foundation.interaction.MutableInteractionSource
17+
import androidx.compose.foundation.layout.Arrangement
1718
import androidx.compose.foundation.layout.Box
1819
import androidx.compose.foundation.layout.Column
1920
import androidx.compose.foundation.layout.IntrinsicSize
@@ -60,11 +61,13 @@ import androidx.compose.material3.MaterialTheme
6061
import androidx.compose.material3.OutlinedButton
6162
import androidx.compose.material3.OutlinedTextFieldDefaults
6263
import androidx.compose.material3.Surface
64+
import androidx.compose.material3.Switch
6365
import androidx.compose.material3.Text
6466
import androidx.compose.material3.TextFieldDefaults
6567
import androidx.compose.material3.TopAppBarColors
6668
import androidx.compose.material3.TopAppBarDefaults
6769
import androidx.compose.material3.TopAppBarScrollBehavior
70+
import androidx.compose.material3.VerticalDivider
6871
import androidx.compose.runtime.Composable
6972
import androidx.compose.runtime.LaunchedEffect
7073
import 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
955992
private 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
9741012
private 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
9931032
private 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
10181058
private 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
10451086
private 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
11501192
private 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
11671209
private fun HomeStateSelectingDisabledPreview() {
11681210
val state = KeyMapAppBarState.Selecting(

base/src/main/java/io/github/sds100/keymapper/base/home/KeyMapListViewModel.kt

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -354,27 +354,10 @@ class KeyMapListViewModel(
354354
breadcrumbListItems: List<GroupListItemModel>,
355355
showThisGroup: Boolean,
356356
): KeyMapAppBarState.Selecting {
357-
var selectedKeyMapsEnabled: SelectedKeyMapsEnabled? = null
358357
val keyMaps = keyMapGroup.keyMaps.dataOrNull() ?: emptyList()
359358

360-
for (keyMap in keyMaps) {
361-
if (keyMap.uid in selectionState.selectedIds) {
362-
if (selectedKeyMapsEnabled == null) {
363-
selectedKeyMapsEnabled = if (keyMap.isEnabled) {
364-
SelectedKeyMapsEnabled.ALL
365-
} else {
366-
SelectedKeyMapsEnabled.NONE
367-
}
368-
} else {
369-
if ((keyMap.isEnabled && selectedKeyMapsEnabled == SelectedKeyMapsEnabled.NONE) ||
370-
(!keyMap.isEnabled && selectedKeyMapsEnabled == SelectedKeyMapsEnabled.ALL)
371-
) {
372-
selectedKeyMapsEnabled = SelectedKeyMapsEnabled.MIXED
373-
break
374-
}
375-
}
376-
}
377-
}
359+
val selectedKeyMapsEnabled: SelectedKeyMapsEnabled? =
360+
getKeyMapSelectedState(keyMaps.filter { it.uid in selectionState.selectedIds })
378361

379362
return KeyMapAppBarState.Selecting(
380363
selectionCount = selectionState.selectedIds.size,
@@ -386,6 +369,31 @@ class KeyMapListViewModel(
386369
)
387370
}
388371

372+
private fun getKeyMapSelectedState(
373+
keyMaps: List<KeyMap>,
374+
): SelectedKeyMapsEnabled? {
375+
var selectedKeyMapsEnabled: SelectedKeyMapsEnabled? = null
376+
377+
for (keyMap in keyMaps) {
378+
if (selectedKeyMapsEnabled == null) {
379+
selectedKeyMapsEnabled = if (keyMap.isEnabled) {
380+
SelectedKeyMapsEnabled.ALL
381+
} else {
382+
SelectedKeyMapsEnabled.NONE
383+
}
384+
} else {
385+
if ((keyMap.isEnabled && selectedKeyMapsEnabled == SelectedKeyMapsEnabled.NONE) ||
386+
(!keyMap.isEnabled && selectedKeyMapsEnabled == SelectedKeyMapsEnabled.ALL)
387+
) {
388+
selectedKeyMapsEnabled = SelectedKeyMapsEnabled.MIXED
389+
break
390+
}
391+
}
392+
}
393+
394+
return selectedKeyMapsEnabled
395+
}
396+
389397
private fun buildGroupAppBarState(
390398
keyMapGroup: KeyMapGroup,
391399
warnings: List<HomeWarningListItem>,
@@ -412,6 +420,9 @@ class KeyMapListViewModel(
412420
isPaused = isPaused,
413421
)
414422
} else {
423+
val selectedKeyMapsEnabled: SelectedKeyMapsEnabled? =
424+
getKeyMapSelectedState(keyMapGroup.keyMaps.dataOrNull() ?: emptyList())
425+
415426
return KeyMapAppBarState.ChildGroup(
416427
groupName = keyMapGroup.group.name,
417428
constraints = listItemCreator.buildConstraintChipList(
@@ -424,6 +435,7 @@ class KeyMapListViewModel(
424435
breadcrumbs = breadcrumbs,
425436
isEditingGroupName = isEditingGroupName,
426437
isNewGroup = isNewGroup,
438+
keyMapsEnabled = selectedKeyMapsEnabled
427439
)
428440
}
429441
}
@@ -857,6 +869,14 @@ class KeyMapListViewModel(
857869
}
858870
}
859871

872+
fun onGroupKeyMapsEnabledChanged(enabled: Boolean) {
873+
if (enabled) {
874+
listKeyMaps.enableGroupKeyMaps()
875+
} else {
876+
listKeyMaps.disableGroupKeyMaps()
877+
}
878+
}
879+
860880
fun onNewKeyMapClick() {
861881
coroutineScope.launch {
862882
val groupUid = listKeyMaps.keyMapGroup.first().group?.uid

0 commit comments

Comments
 (0)