Skip to content

Commit b71182b

Browse files
feat(settings): Improve settings UI and state management
This commit introduces several improvements to the settings interface, focusing on better state management and a more dynamic user experience. - **Live Update for Flag Settings:** The `SettingsSelect` composable for flag-based options (Context Menu, Home Buttons, App List Buttons) now updates its summary in real-time. Instead of a static description, it now displays a comma-separated list of the currently enabled options. This is achieved by passing a callback from `showFlagSettingsBottomSheet` to update the state in `SettingsFragment`. - **Refactored `SettingsSwitch`:** The `SettingsSwitch` composable has been redesigned. It now uses a standard `Column` layout with a title and a status indicator ("✔" for enabled, "✖" for disabled) instead of a native `SwitchCompat`. The entire component is now clickable to toggle the state. - **Revamped `SettingsSelect` Layout:** The `SettingsSelect` composable is updated to a `Column`-based layout, improving alignment and readability by placing the option text below the title. - **Improved Color Theming:** The color system in `SettingsTheme` has been refined. - The generic `fontColor` parameter in `SettingsSelect` is split into `titleColor` and `optionColor` for more granular control. - New colors (`textEnabled`, `textDisabled`) have been added for status indicators. - Base text colors are now differentiated (`textLightTop`/`textDarkTop` and `textLightBottom`/`textDarkBottom`) to create a subtle visual hierarchy.
1 parent 99fae8b commit b71182b

File tree

24 files changed

+206
-142
lines changed

24 files changed

+206
-142
lines changed
Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
package com.github.droidworksstudio.mlauncher.style
22

33
import androidx.compose.ui.graphics.Color
4+
import androidx.compose.ui.graphics.lerp
45

6+
// Header colors
57
val textLightHeader = Color(0xFFB388FF)
68
val textDarkHeader = Color(0xFF651FFF)
7-
val textLight = Color(0xFFFFFFFF)
8-
val textDark = Color(0xFF000000)
9+
10+
// Base colors
11+
val textLightTop = Color(0xFFFFFFFF) // white
12+
val textDarkTop = Color(0xFF000000) // black
13+
14+
// Adjusted bottom colors
15+
val textLightBottom = lerp(textLightTop, textDarkTop, 0.2f) // slightly darker
16+
val textDarkBottom = lerp(textDarkTop, textLightTop, 0.2f) // slightly lighter
17+
18+
// Gray
919
val textGray = Color(0xFF858585)
20+
21+
// Enabled / Disabled colors
22+
val textEnabled = Color(0xFF98DC9A) // green
23+
val textDisabled = Color(0xFFFF837D) // red

app/src/main/java/com/github/droidworksstudio/mlauncher/style/SettingsTheme.kt

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,11 @@ data class ReplacementTypography(
1717
val header: TextStyle,
1818
val title: TextStyle,
1919
val body: TextStyle,
20-
val item: TextStyle,
20+
val option: TextStyle,
2121
val button: TextStyle,
2222
val buttonDisabled: TextStyle,
23+
val textEnabled: TextStyle = TextStyle.Default,
24+
val textDisabled: TextStyle = TextStyle.Default,
2325
)
2426

2527
@Immutable
@@ -35,9 +37,11 @@ val LocalReplacementTypography = staticCompositionLocalOf {
3537
header = TextStyle.Default,
3638
title = TextStyle.Default,
3739
body = TextStyle.Default,
38-
item = TextStyle.Default,
40+
option = TextStyle.Default,
3941
button = TextStyle.Default,
4042
buttonDisabled = TextStyle.Default,
43+
textEnabled = TextStyle.Default,
44+
textDisabled = TextStyle.Default,
4145
)
4246
}
4347
val LocalReplacementColor = staticCompositionLocalOf {
@@ -63,28 +67,38 @@ fun SettingsTheme(
6367
title = TextStyle(
6468
fontWeight = FontWeight.Light,
6569
fontSize = 32.sp,
66-
color = if (isDark) textLight else textDark,
70+
color = if (isDark) textLightTop else textDarkTop,
6771
),
6872
body = TextStyle(
6973
fontWeight = FontWeight.Light,
7074
fontSize = 16.sp,
71-
color = if (isDark) textLight else textDark,
75+
color = if (isDark) textLightTop else textDarkTop,
7276
),
73-
item = TextStyle(
77+
option = TextStyle(
7478
fontWeight = FontWeight.Light,
75-
fontSize = 16.sp,
76-
color = if (isDark) textLight else textDark,
79+
fontSize = 32.sp,
80+
color = if (isDark) textLightBottom else textDarkBottom,
7781
),
7882
button = TextStyle(
7983
fontWeight = FontWeight.Bold,
8084
fontSize = 16.sp,
81-
color = if (isDark) textLight else textDark,
85+
color = if (isDark) textLightTop else textDarkTop,
8286
),
8387
buttonDisabled = TextStyle(
8488
fontWeight = FontWeight.Bold,
8589
fontSize = 16.sp,
8690
color = textGray,
8791
),
92+
textEnabled = TextStyle(
93+
fontWeight = FontWeight.Light,
94+
fontSize = 16.sp,
95+
color = textEnabled,
96+
),
97+
textDisabled = TextStyle(
98+
fontWeight = FontWeight.Light,
99+
fontSize = 16.sp,
100+
color = textDisabled,
101+
),
88102
)
89103
val replacementColor = ReplacementColor(
90104
settings = colorResource(if (isDark) R.color.blackTrans50 else R.color.blackInverseTrans50),

app/src/main/java/com/github/droidworksstudio/mlauncher/ui/SettingsFragment.kt

Lines changed: 97 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ import androidx.compose.foundation.layout.height
2727
import androidx.compose.foundation.rememberScrollState
2828
import androidx.compose.foundation.verticalScroll
2929
import androidx.compose.runtime.Composable
30+
import androidx.compose.runtime.derivedStateOf
3031
import androidx.compose.runtime.getValue
3132
import androidx.compose.runtime.mutableFloatStateOf
3233
import androidx.compose.runtime.mutableIntStateOf
34+
import androidx.compose.runtime.mutableStateListOf
3335
import androidx.compose.runtime.mutableStateOf
3436
import androidx.compose.runtime.remember
3537
import androidx.compose.runtime.setValue
@@ -882,30 +884,104 @@ class SettingsFragment : BaseFragment() {
882884
fontSize = titleFontSize
883885
)
884886

887+
val currentContextMenuFlags = remember {
888+
mutableStateListOf<Boolean>().apply {
889+
addAll(prefs.getMenuFlags("CONTEXT_MENU_FLAGS", "0011111"))
890+
}
891+
}
892+
893+
val enabledContextMenuOptions by remember {
894+
derivedStateOf {
895+
contextMenuOptionLabels
896+
.take(currentContextMenuFlags.size)
897+
.zip(currentContextMenuFlags)
898+
.filter { it.second }
899+
.joinToString(", ") { it.first }
900+
.ifEmpty { getLocalizedString(R.string.none) }
901+
}
902+
}
903+
885904
SettingsSelect(
886905
title = getLocalizedString(R.string.settings_context_menu_title),
887-
option = getLocalizedString(R.string.settings_context_menu_option),
906+
option = enabledContextMenuOptions,
888907
fontSize = titleFontSize,
889908
onClick = {
890-
dialogBuilder.showFlagSettingsBottomSheet(context, contextMenuOptionLabels, "CONTEXT_MENU_FLAGS", "0011111")
909+
dialogBuilder.showFlagSettingsBottomSheet(
910+
context,
911+
contextMenuOptionLabels,
912+
"CONTEXT_MENU_FLAGS",
913+
"0011111"
914+
) { updatedFlags: List<Boolean> ->
915+
currentContextMenuFlags.clear()
916+
currentContextMenuFlags.addAll(updatedFlags)
917+
}
891918
}
892919
)
893920

921+
val currentAppListFlags = remember {
922+
mutableStateListOf<Boolean>().apply {
923+
addAll(prefs.getMenuFlags("APPLIST_BUTTON_FLAGS", "00"))
924+
}
925+
}
926+
927+
val enabledAppListOptions by remember {
928+
derivedStateOf {
929+
appListButtonOptionLabels
930+
.take(currentAppListFlags.size)
931+
.zip(currentAppListFlags)
932+
.filter { it.second }
933+
.joinToString(", ") { it.first }
934+
.ifEmpty { getLocalizedString(R.string.none) }
935+
}
936+
}
937+
894938
SettingsSelect(
895939
title = getLocalizedString(R.string.settings_applist_buttons_title),
896-
option = getLocalizedString(R.string.settings_applist_buttons_option),
940+
option = enabledAppListOptions,
897941
fontSize = titleFontSize,
898942
onClick = {
899-
dialogBuilder.showFlagSettingsBottomSheet(context, appListButtonOptionLabels, "APPLIST_BUTTON_FLAGS", "00")
943+
dialogBuilder.showFlagSettingsBottomSheet(
944+
context,
945+
appListButtonOptionLabels,
946+
"APPLIST_BUTTON_FLAGS",
947+
"00"
948+
) { updatedFlags: List<Boolean> ->
949+
currentAppListFlags.clear()
950+
currentAppListFlags.addAll(updatedFlags)
951+
}
900952
}
901953
)
902954

955+
val currentHomeButtonFlags = remember {
956+
mutableStateListOf<Boolean>().apply {
957+
addAll(prefs.getMenuFlags("HOME_BUTTON_FLAGS", "0000011"))
958+
}
959+
}
960+
961+
val enabledHomeButtonOptions by remember {
962+
derivedStateOf {
963+
homeButtonOptionLabels
964+
.take(currentHomeButtonFlags.size)
965+
.zip(currentHomeButtonFlags)
966+
.filter { it.second }
967+
.joinToString(", ") { it.first }
968+
.ifEmpty { getLocalizedString(R.string.none) }
969+
}
970+
}
903971
SettingsSelect(
904972
title = getLocalizedString(R.string.settings_home_buttons_title),
905-
option = getLocalizedString(R.string.settings_home_buttons_option),
973+
option = enabledHomeButtonOptions,
906974
fontSize = titleFontSize,
907975
onClick = {
908-
dialogBuilder.showFlagSettingsBottomSheet(context, homeButtonOptionLabels, "HOME_BUTTON_FLAGS", "0000011")
976+
dialogBuilder.showFlagSettingsBottomSheet(
977+
context,
978+
homeButtonOptionLabels,
979+
"HOME_BUTTON_FLAGS",
980+
"0000011"
981+
) { updatedFlags: List<Boolean> ->
982+
currentHomeButtonFlags.clear()
983+
currentHomeButtonFlags.addAll(updatedFlags)
984+
}
909985
}
910986
)
911987

@@ -1394,7 +1470,7 @@ class SettingsFragment : BaseFragment() {
13941470
title = getLocalizedString(R.string.background_color),
13951471
option = hexBackgroundColor,
13961472
fontSize = titleFontSize,
1397-
fontColor = Color(selectedBackgroundColor),
1473+
optionColor = Color(selectedBackgroundColor),
13981474
onClick = {
13991475
dialogBuilder.showColorPickerBottomSheet(
14001476
context = requireContext(),
@@ -1412,7 +1488,7 @@ class SettingsFragment : BaseFragment() {
14121488
title = getLocalizedString(R.string.app_color),
14131489
option = hexAppColor,
14141490
fontSize = titleFontSize,
1415-
fontColor = Color(hexAppColor.toColorInt()),
1491+
optionColor = Color(hexAppColor.toColorInt()),
14161492
onClick = {
14171493
dialogBuilder.showColorPickerBottomSheet(
14181494
context = requireContext(),
@@ -1433,7 +1509,7 @@ class SettingsFragment : BaseFragment() {
14331509
title = getLocalizedString(R.string.date_color),
14341510
option = hexDateColor,
14351511
fontSize = titleFontSize,
1436-
fontColor = Color(hexDateColor.toColorInt()),
1512+
optionColor = Color(hexDateColor.toColorInt()),
14371513
onClick = {
14381514
dialogBuilder.showColorPickerBottomSheet(
14391515
context = requireContext(),
@@ -1451,7 +1527,7 @@ class SettingsFragment : BaseFragment() {
14511527
title = getLocalizedString(R.string.clock_color),
14521528
option = hexClockColor,
14531529
fontSize = titleFontSize,
1454-
fontColor = Color(hexClockColor.toColorInt()),
1530+
optionColor = Color(hexClockColor.toColorInt()),
14551531
onClick = {
14561532
dialogBuilder.showColorPickerBottomSheet(
14571533
context = requireContext(),
@@ -1469,7 +1545,7 @@ class SettingsFragment : BaseFragment() {
14691545
title = getLocalizedString(R.string.alarm_color),
14701546
option = hexAlarmColor,
14711547
fontSize = titleFontSize,
1472-
fontColor = Color(hexAlarmColor.toColorInt()),
1548+
optionColor = Color(hexAlarmColor.toColorInt()),
14731549
onClick = {
14741550
dialogBuilder.showColorPickerBottomSheet(
14751551
context = requireContext(),
@@ -1487,7 +1563,7 @@ class SettingsFragment : BaseFragment() {
14871563
title = getLocalizedString(R.string.daily_word_color),
14881564
option = hexDailyWordColor,
14891565
fontSize = titleFontSize,
1490-
fontColor = Color(hexDailyWordColor.toColorInt()),
1566+
optionColor = Color(hexDailyWordColor.toColorInt()),
14911567
onClick = {
14921568
dialogBuilder.showColorPickerBottomSheet(
14931569
context = requireContext(),
@@ -1505,7 +1581,7 @@ class SettingsFragment : BaseFragment() {
15051581
title = getLocalizedString(R.string.battery_color),
15061582
option = hexBatteryColor,
15071583
fontSize = titleFontSize,
1508-
fontColor = Color(hexBatteryColor.toColorInt()),
1584+
optionColor = Color(hexBatteryColor.toColorInt()),
15091585
onClick = {
15101586
dialogBuilder.showColorPickerBottomSheet(
15111587
context = requireContext(),
@@ -1531,7 +1607,7 @@ class SettingsFragment : BaseFragment() {
15311607
title = getLocalizedString(R.string.shortcuts_color),
15321608
option = String.format("#%06X", (0xFFFFFF and selectedShortcutIconsColor)),
15331609
fontSize = titleFontSize,
1534-
fontColor = Color(String.format("#%06X", (0xFFFFFF and selectedShortcutIconsColor)).toColorInt()),
1610+
optionColor = Color(String.format("#%06X", (0xFFFFFF and selectedShortcutIconsColor)).toColorInt()),
15351611
onClick = {
15361612
dialogBuilder.showColorPickerBottomSheet(
15371613
context = requireContext(),
@@ -2282,7 +2358,7 @@ class SettingsFragment : BaseFragment() {
22822358
title = getLocalizedString(R.string.notes_background_color),
22832359
option = hexBackgroundColor,
22842360
fontSize = titleFontSize,
2285-
fontColor = Color(hexBackgroundColor.toColorInt()),
2361+
optionColor = Color(hexBackgroundColor.toColorInt()),
22862362
onClick = {
22872363
dialogBuilder.showColorPickerBottomSheet(
22882364
context = requireContext(),
@@ -2301,7 +2377,7 @@ class SettingsFragment : BaseFragment() {
23012377
title = getLocalizedString(R.string.bubble_background_color),
23022378
option = hexBubbleBackgroundColor,
23032379
fontSize = titleFontSize,
2304-
fontColor = Color(hexBubbleBackgroundColor.toColorInt()),
2380+
optionColor = Color(hexBubbleBackgroundColor.toColorInt()),
23052381
onClick = {
23062382
dialogBuilder.showColorPickerBottomSheet(
23072383
context = requireContext(),
@@ -2320,7 +2396,7 @@ class SettingsFragment : BaseFragment() {
23202396
title = getLocalizedString(R.string.bubble_message_color),
23212397
option = hexMessageTextColor,
23222398
fontSize = titleFontSize,
2323-
fontColor = Color(hexMessageTextColor.toColorInt()),
2399+
optionColor = Color(hexMessageTextColor.toColorInt()),
23242400
onClick = {
23252401
dialogBuilder.showColorPickerBottomSheet(
23262402
context = requireContext(),
@@ -2339,7 +2415,7 @@ class SettingsFragment : BaseFragment() {
23392415
title = getLocalizedString(R.string.bubble_date_time_color),
23402416
option = hexBubbleTimeDateColor,
23412417
fontSize = titleFontSize,
2342-
fontColor = Color(hexBubbleTimeDateColor.toColorInt()),
2418+
optionColor = Color(hexBubbleTimeDateColor.toColorInt()),
23432419
onClick = {
23442420
dialogBuilder.showColorPickerBottomSheet(
23452421
context = requireContext(),
@@ -2358,7 +2434,7 @@ class SettingsFragment : BaseFragment() {
23582434
title = getLocalizedString(R.string.bubble_category_color),
23592435
option = hexBubbleCategoryColor,
23602436
fontSize = titleFontSize,
2361-
fontColor = Color(hexBubbleCategoryColor.toColorInt()),
2437+
optionColor = Color(hexBubbleCategoryColor.toColorInt()),
23622438
onClick = {
23632439
dialogBuilder.showColorPickerBottomSheet(
23642440
context = requireContext(),
@@ -2385,7 +2461,7 @@ class SettingsFragment : BaseFragment() {
23852461
title = getLocalizedString(R.string.message_input_color),
23862462
option = hexBubbleInputMessageColor,
23872463
fontSize = titleFontSize,
2388-
fontColor = Color(hexBubbleInputMessageColor.toColorInt()),
2464+
optionColor = Color(hexBubbleInputMessageColor.toColorInt()),
23892465
onClick = {
23902466
dialogBuilder.showColorPickerBottomSheet(
23912467
context = requireContext(),
@@ -2404,7 +2480,7 @@ class SettingsFragment : BaseFragment() {
24042480
title = getLocalizedString(R.string.message_input_hint_color),
24052481
option = hexBubbleInputMessageHintColor,
24062482
fontSize = titleFontSize,
2407-
fontColor = Color(hexBubbleInputMessageHintColor.toColorInt()),
2483+
optionColor = Color(hexBubbleInputMessageHintColor.toColorInt()),
24082484
onClick = {
24092485
dialogBuilder.showColorPickerBottomSheet(
24102486
context = requireContext(),

app/src/main/java/com/github/droidworksstudio/mlauncher/ui/components/DialogManager.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,13 @@ class DialogManager(val context: Context, val activity: Activity) {
561561

562562
var flagSettingsBottomSheet: FontBottomSheetDialogLocked? = null
563563

564-
fun showFlagSettingsBottomSheet(context: Context, optionLabels: List<String>, settingFlags: String, default: String = "0") {
564+
fun showFlagSettingsBottomSheet(
565+
context: Context,
566+
optionLabels: List<String>,
567+
settingFlags: String,
568+
default: String = "0",
569+
onFlagsChanged: (List<Boolean>) -> Unit
570+
) {
565571
flagSettingsBottomSheet?.dismiss()
566572

567573
HapticFeedbackService.trigger(
@@ -591,6 +597,7 @@ class DialogManager(val context: Context, val activity: Activity) {
591597
setOnCheckedChangeListener { _, isChecked ->
592598
currentFlags[index] = isChecked
593599
prefs.saveMenuFlags(settingFlags, currentFlags)
600+
onFlagsChanged(currentFlags.toList()) // ✅ notify Compose with new data
594601
HapticFeedbackService.trigger(
595602
context,
596603
HapticFeedbackService.EffectType.SELECT

0 commit comments

Comments
 (0)