[优化] 新增Compose下的亮暗色种子色设置

This commit is contained in:
HapeLee
2026-04-20 00:09:27 +08:00
parent c3dd1f90c6
commit 0d1a374e6e
3 changed files with 118 additions and 45 deletions
@@ -60,6 +60,10 @@ object ThemeConfig {
postEvent(EventBus.RECREATE, "") postEvent(EventBus.RECREATE, "")
} }
var cNPrimary by prefDelegate(PreferKey.cNPrimary, 0) {
postEvent(EventBus.RECREATE, "")
}
var customContrast by prefDelegate(PreferKey.customContrast, "Default") { var customContrast by prefDelegate(PreferKey.customContrast, "Default") {
postEvent(EventBus.RECREATE, "") postEvent(EventBus.RECREATE, "")
} }
@@ -115,6 +115,7 @@ fun ThemeConfigScreen(
var useMiuixMonet by remember { mutableStateOf(ThemeConfig.useMiuixMonet) } var useMiuixMonet by remember { mutableStateOf(ThemeConfig.useMiuixMonet) }
var showRestartDialog by remember { mutableStateOf(false) } var showRestartDialog by remember { mutableStateOf(false) }
var showColorPicker by remember { mutableStateOf(false) } var showColorPicker by remember { mutableStateOf(false) }
var pickNightSeedColor by remember { mutableStateOf(false) }
var showLauncherIconPicker by remember { mutableStateOf(false) } var showLauncherIconPicker by remember { mutableStateOf(false) }
var showThemeListDialog by remember { mutableStateOf(false) } var showThemeListDialog by remember { mutableStateOf(false) }
var saveThemeKey by remember { mutableStateOf<String?>(null) } var saveThemeKey by remember { mutableStateOf<String?>(null) }
@@ -122,6 +123,7 @@ fun ThemeConfigScreen(
val fontScaleValue = remember { mutableFloatStateOf(ThemeConfig.fontScale.toFloat()) } val fontScaleValue = remember { mutableFloatStateOf(ThemeConfig.fontScale.toFloat()) }
val primaryColorValue = remember { mutableIntStateOf(ThemeConfig.cPrimary) } val primaryColorValue = remember { mutableIntStateOf(ThemeConfig.cPrimary) }
val nightPrimaryColorValue = remember { mutableIntStateOf(ThemeConfig.cNPrimary) }
AppScaffold( AppScaffold(
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
@@ -163,7 +165,9 @@ fun ThemeConfigScreen(
value = selectedTheme, value = selectedTheme,
isDark = isDarkTheme, isDark = isDarkTheme,
isAmoled = ThemeConfig.isPureBlack, isAmoled = ThemeConfig.isPureBlack,
paletteStyle = ThemeConfig.paletteStyle paletteStyle = ThemeConfig.paletteStyle,
customLightSeedColor = primaryColorValue.intValue,
customNightSeedColor = nightPrimaryColorValue.intValue
) )
} }
} }
@@ -255,6 +259,8 @@ fun ThemeConfigScreen(
isDark = isDarkTheme, isDark = isDarkTheme,
isAmoled = ThemeConfig.isPureBlack, isAmoled = ThemeConfig.isPureBlack,
paletteStyle = ThemeConfig.paletteStyle, paletteStyle = ThemeConfig.paletteStyle,
customLightSeedColor = primaryColorValue.intValue,
customNightSeedColor = nightPrimaryColorValue.intValue,
onThemeSelected = { theme -> onThemeSelected = { theme ->
if (theme == "13") { if (theme == "13") {
val hasLightBg = !ThemeConfig.bgImageLight.isNullOrEmpty() val hasLightBg = !ThemeConfig.bgImageLight.isNullOrEmpty()
@@ -326,27 +332,25 @@ fun ThemeConfigScreen(
SplicedColumnGroup(title = stringResource(R.string.custom_theme)) { SplicedColumnGroup(title = stringResource(R.string.custom_theme)) {
ClickableSettingItem( ClickableSettingItem(
title = stringResource(R.string.seed_color), title = stringResource(R.string.seed_color),
option = if (primaryColorValue.intValue != 0) "#${ description = stringResource(R.string.day),
Integer.toHexString( option = formatColorOption(primaryColorValue.intValue)
primaryColorValue.intValue ?: stringResource(R.string.click_to_select),
).uppercase() onClick = {
}" else stringResource(R.string.click_to_select), pickNightSeedColor = false
onClick = { showColorPicker = true }, showColorPicker = true
trailingContent = { },
if (primaryColorValue.intValue != 0) { trailingContent = { ColorSwatch(colorValue = primaryColorValue.intValue) }
Box(
modifier = Modifier
.size(28.dp)
.clip(CircleShape)
.background(Color(primaryColorValue.intValue))
.border(
1.dp,
MaterialTheme.colorScheme.outlineVariant,
CircleShape
) )
) ClickableSettingItem(
} title = stringResource(R.string.seed_color),
} description = stringResource(R.string.night),
option = formatColorOption(nightPrimaryColorValue.intValue)
?: stringResource(R.string.click_to_select),
onClick = {
pickNightSeedColor = true
showColorPicker = true
},
trailingContent = { ColorSwatch(colorValue = nightPrimaryColorValue.intValue) }
) )
DropdownListSettingItem( DropdownListSettingItem(
title = stringResource(R.string.palette_style), title = stringResource(R.string.palette_style),
@@ -609,9 +613,17 @@ fun ThemeConfigScreen(
ColorPickerSheet( ColorPickerSheet(
show = showColorPicker, show = showColorPicker,
initialColor = primaryColorValue.value, initialColor = if (pickNightSeedColor) {
nightPrimaryColorValue.value
} else {
primaryColorValue.value
},
onDismissRequest = { showColorPicker = false }, onDismissRequest = { showColorPicker = false },
onColorSelected = { color -> onColorSelected = { color ->
if (pickNightSeedColor) {
nightPrimaryColorValue.value = color
ThemeConfig.cNPrimary = color
} else {
primaryColorValue.value = color primaryColorValue.value = color
ThemeConfig.cPrimary = color ThemeConfig.cPrimary = color
ThemeStore.editTheme(context) ThemeStore.editTheme(context)
@@ -624,6 +636,7 @@ fun ThemeConfigScreen(
.build() .build()
) )
} }
}
) )
LauncherIconPickerSheet( LauncherIconPickerSheet(
@@ -727,6 +740,8 @@ fun ThemeColorSelector(
isDark: Boolean, isDark: Boolean,
isAmoled: Boolean, isAmoled: Boolean,
paletteStyle: String?, paletteStyle: String?,
customLightSeedColor: Int,
customNightSeedColor: Int,
onThemeSelected: (String) -> Unit onThemeSelected: (String) -> Unit
) { ) {
LazyRow( LazyRow(
@@ -742,6 +757,8 @@ fun ThemeColorSelector(
isDark = isDark, isDark = isDark,
isAmoled = isAmoled, isAmoled = isAmoled,
paletteStyle = paletteStyle, paletteStyle = paletteStyle,
customLightSeedColor = customLightSeedColor,
customNightSeedColor = customNightSeedColor,
onClick = { onThemeSelected(value) } onClick = { onThemeSelected(value) }
) )
} }
@@ -758,9 +775,19 @@ fun ThemeColorButton(
isDark: Boolean, isDark: Boolean,
isAmoled: Boolean, isAmoled: Boolean,
paletteStyle: String?, paletteStyle: String?,
customLightSeedColor: Int,
customNightSeedColor: Int,
onClick: () -> Unit onClick: () -> Unit
) { ) {
val colors = getThemeColorPalette(context, value, isDark, isAmoled, paletteStyle) val colors = getThemeColorPalette(
context = context,
value = value,
isDark = isDark,
isAmoled = isAmoled,
paletteStyle = paletteStyle,
customLightSeedColor = customLightSeedColor,
customNightSeedColor = customNightSeedColor
)
val borderWidth by animateDpAsState( val borderWidth by animateDpAsState(
targetValue = if (isSelected) 2.dp else 0.dp, targetValue = if (isSelected) 2.dp else 0.dp,
label = "borderWidth" label = "borderWidth"
@@ -849,9 +876,19 @@ fun ThemeCard(
value: String, value: String,
isDark: Boolean, isDark: Boolean,
isAmoled: Boolean, isAmoled: Boolean,
paletteStyle: String? paletteStyle: String?,
customLightSeedColor: Int,
customNightSeedColor: Int
) { ) {
val colors = getThemeColors(context, value, isDark, isAmoled, paletteStyle) val colors = getThemeColors(
context = context,
value = value,
isDark = isDark,
isAmoled = isAmoled,
paletteStyle = paletteStyle,
customLightSeedColor = customLightSeedColor,
customNightSeedColor = customNightSeedColor
)
Column( Column(
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
@@ -924,6 +961,27 @@ fun ThemeCard(
} }
} }
private fun formatColorOption(colorValue: Int): String? {
if (colorValue == 0) return null
return "#${Integer.toHexString(colorValue).uppercase()}"
}
@Composable
private fun ColorSwatch(colorValue: Int) {
if (colorValue == 0) return
Box(
modifier = Modifier
.size(28.dp)
.clip(CircleShape)
.background(Color(colorValue))
.border(
1.dp,
MaterialTheme.colorScheme.outlineVariant,
CircleShape
)
)
}
data class ThemeColorPalette( data class ThemeColorPalette(
val primary: Color, val primary: Color,
val secondary: Color, val secondary: Color,
@@ -949,16 +1007,20 @@ private fun getThemeColorPalette(
isDark: Boolean, isDark: Boolean,
isAmoled: Boolean, isAmoled: Boolean,
paletteStyle: String?, paletteStyle: String?,
materialVersion: String? = null materialVersion: String? = null,
customLightSeedColor: Int = 0,
customNightSeedColor: Int = 0
): ThemeColorPalette { ): ThemeColorPalette {
val appThemeMode = ThemeResolver.resolveThemeMode(value) val appThemeMode = ThemeResolver.resolveThemeMode(value)
val customSeedColor = if (isDark) customNightSeedColor else customLightSeedColor
val colorScheme = ThemeEngine.getColorScheme( val colorScheme = ThemeEngine.getColorScheme(
context = context, context = context,
mode = appThemeMode, mode = appThemeMode,
darkTheme = isDark, darkTheme = isDark,
isAmoled = isAmoled, isAmoled = isAmoled,
paletteStyle = paletteStyle, paletteStyle = paletteStyle,
materialVersion = materialVersion materialVersion = materialVersion,
customSeedColor = customSeedColor
) )
return ThemeColorPalette( return ThemeColorPalette(
@@ -976,16 +1038,20 @@ private fun getThemeColors(
isDark: Boolean, isDark: Boolean,
isAmoled: Boolean, isAmoled: Boolean,
paletteStyle: String?, paletteStyle: String?,
materialVersion: String? = null materialVersion: String? = null,
customLightSeedColor: Int = 0,
customNightSeedColor: Int = 0
): ThemeColors { ): ThemeColors {
val appThemeMode = ThemeResolver.resolveThemeMode(value) val appThemeMode = ThemeResolver.resolveThemeMode(value)
val customSeedColor = if (isDark) customNightSeedColor else customLightSeedColor
val colorScheme = ThemeEngine.getColorScheme( val colorScheme = ThemeEngine.getColorScheme(
context = context, context = context,
mode = appThemeMode, mode = appThemeMode,
darkTheme = isDark, darkTheme = isDark,
isAmoled = isAmoled, isAmoled = isAmoled,
paletteStyle = paletteStyle, paletteStyle = paletteStyle,
materialVersion = materialVersion materialVersion = materialVersion,
customSeedColor = customSeedColor
) )
return ThemeColors( return ThemeColors(
@@ -45,7 +45,8 @@ object ThemeEngine {
isAmoled: Boolean, isAmoled: Boolean,
paletteStyle: String?, paletteStyle: String?,
materialVersion: String? = null, materialVersion: String? = null,
forceOpaque: Boolean = false forceOpaque: Boolean = false,
customSeedColor: Int? = null
): ColorScheme { ): ColorScheme {
val resolvedMode = resolveMode(mode = mode, forceOpaque = forceOpaque) val resolvedMode = resolveMode(mode = mode, forceOpaque = forceOpaque)
val baseColorScheme = resolveBaseColorScheme( val baseColorScheme = resolveBaseColorScheme(
@@ -53,7 +54,8 @@ object ThemeEngine {
mode = resolvedMode, mode = resolvedMode,
darkTheme = darkTheme, darkTheme = darkTheme,
paletteStyle = paletteStyle, paletteStyle = paletteStyle,
materialVersion = materialVersion materialVersion = materialVersion,
customSeedColor = customSeedColor
) )
return baseColorScheme return baseColorScheme
@@ -77,14 +79,15 @@ object ThemeEngine {
mode: AppThemeMode, mode: AppThemeMode,
darkTheme: Boolean, darkTheme: Boolean,
paletteStyle: String?, paletteStyle: String?,
materialVersion: String? materialVersion: String?,
customSeedColor: Int?
): ColorScheme { ): ColorScheme {
if (mode == AppThemeMode.Dynamic) { if (mode == AppThemeMode.Dynamic) {
return resolveDynamicColorScheme(context = context, darkTheme = darkTheme) return resolveDynamicColorScheme(context = context, darkTheme = darkTheme)
} }
if (mode == AppThemeMode.Custom) { if (mode == AppThemeMode.Custom) {
return resolveCustomColorScheme( return resolveCustomColorScheme(
seedColor = context.primaryColor, seedColor = customSeedColor ?: context.primaryColor,
darkTheme = darkTheme, darkTheme = darkTheme,
paletteStyle = paletteStyle, paletteStyle = paletteStyle,
materialVersion = materialVersion materialVersion = materialVersion