From 20556ce5a3cab04ce29c4b4181d7884598c8ff12 Mon Sep 17 00:00:00 2001 From: Miuzarte <982809597@qq.com> Date: Thu, 23 Apr 2026 19:10:02 +0800 Subject: [PATCH] feat: more options for monet --- CHANGELOG.md | 4 ++ app/build.gradle.kts | 4 +- .../LockscreenPasswordActivity.kt | 20 ++++----- .../scrcpyforandroid/pages/MainScreen.kt | 16 ++++--- .../scrcpyforandroid/pages/SettingsScreen.kt | 44 ++++++++++++++++-- .../scrcpyforandroid/pages/StreamScreen.kt | 19 ++++---- .../scrcpyforandroid/storage/AppSettings.kt | 21 +++++++++ .../scrcpyforandroid/ui/AppThemeConfig.kt | 45 +++++++++++++++++++ 8 files changed, 142 insertions(+), 31 deletions(-) create mode 100644 app/src/main/java/io/github/miuzarte/scrcpyforandroid/ui/AppThemeConfig.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index c2d1653..21ad538 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ~~什么我居然开始写更新日志了~~ +## 0.2.3 + +- 改进: 莫奈颜色更多配置项 + ## 0.2.2 - 改进: 设备页连接设备后选项卡显示当前配置名 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 0d74acb..53dfd24 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -54,8 +54,8 @@ android { applicationId = "io.github.miuzarte.scrcpyforandroid" minSdk = 26 targetSdk = 37 - versionCode = 18 - versionName = "0.2.2" + versionCode = 19 + versionName = "0.2.3" externalNativeBuild { cmake { diff --git a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/LockscreenPasswordActivity.kt b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/LockscreenPasswordActivity.kt index 8bf8297..be67d6a 100644 --- a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/LockscreenPasswordActivity.kt +++ b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/LockscreenPasswordActivity.kt @@ -55,6 +55,7 @@ import io.github.miuzarte.scrcpyforandroid.services.LocalSnackbarController import io.github.miuzarte.scrcpyforandroid.services.SnackbarController import io.github.miuzarte.scrcpyforandroid.storage.Settings import io.github.miuzarte.scrcpyforandroid.storage.Storage.appSettings +import io.github.miuzarte.scrcpyforandroid.ui.createThemeController import io.github.miuzarte.scrcpyforandroid.ui.rememberBlurBackdrop import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -89,11 +90,9 @@ import top.yukonga.miuix.kmp.overlay.OverlayDialog import top.yukonga.miuix.kmp.overlay.OverlayListPopup import top.yukonga.miuix.kmp.preference.ArrowPreference import top.yukonga.miuix.kmp.preference.SwitchPreference -import top.yukonga.miuix.kmp.theme.ColorSchemeMode import top.yukonga.miuix.kmp.theme.MiuixTheme import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme import top.yukonga.miuix.kmp.theme.MiuixTheme.textStyles -import top.yukonga.miuix.kmp.theme.ThemeController class LockscreenPasswordActivity : FragmentActivity() { override fun onCreate(savedInstanceState: Bundle?) { @@ -107,14 +106,15 @@ class LockscreenPasswordActivity : FragmentActivity() { val snackbarController = remember(scope, hostState) { SnackbarController(scope = scope, hostState = hostState) } - val themeMode = - when (asBundle.themeBaseIndex.coerceIn(0, ThemeModes.baseOptions.lastIndex)) { - 1 -> if (!asBundle.monet) ColorSchemeMode.Light else ColorSchemeMode.MonetLight - 2 -> if (!asBundle.monet) ColorSchemeMode.Dark else ColorSchemeMode.MonetDark - else -> if (!asBundle.monet) ColorSchemeMode.System else ColorSchemeMode.MonetSystem - } - val themeController = - remember(themeMode) { ThemeController(colorSchemeMode = themeMode) } + val themeController = remember( + asBundle.themeBaseIndex, + asBundle.monet, + asBundle.monetSeedIndex, + asBundle.monetPaletteStyle, + asBundle.monetColorSpec, + ) { + asBundle.createThemeController() + } MiuixTheme( controller = themeController, smoothRounding = asBundle.smoothCorner, diff --git a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/MainScreen.kt b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/MainScreen.kt index fedf1d5..c5f0f5c 100644 --- a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/MainScreen.kt +++ b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/MainScreen.kt @@ -75,6 +75,7 @@ import io.github.miuzarte.scrcpyforandroid.storage.AppSettings import io.github.miuzarte.scrcpyforandroid.storage.Settings import io.github.miuzarte.scrcpyforandroid.storage.Storage.appSettings import io.github.miuzarte.scrcpyforandroid.storage.Storage.quickDevices +import io.github.miuzarte.scrcpyforandroid.ui.createThemeController import io.github.miuzarte.scrcpyforandroid.ui.BlurredBar import io.github.miuzarte.scrcpyforandroid.ui.LocalEnableBlur import io.github.miuzarte.scrcpyforandroid.ui.LocalEnableFloatingBottomBar @@ -98,10 +99,8 @@ import top.yukonga.miuix.kmp.basic.Scaffold import top.yukonga.miuix.kmp.basic.SnackbarHost import top.yukonga.miuix.kmp.basic.SnackbarHostState import top.yukonga.miuix.kmp.basic.Text -import top.yukonga.miuix.kmp.theme.ColorSchemeMode import top.yukonga.miuix.kmp.theme.MiuixTheme import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme -import top.yukonga.miuix.kmp.theme.ThemeController import top.yukonga.miuix.kmp.blur.layerBackdrop as miuixLayerBackdrop import java.io.File @@ -670,12 +669,15 @@ fun MainScreen() { entryProvider = rootEntryProvider, ) - val themeMode = when (asBundle.themeBaseIndex.coerceIn(0, ThemeModes.baseOptions.lastIndex)) { - 1 -> if (!asBundle.monet) ColorSchemeMode.Light else ColorSchemeMode.MonetLight - 2 -> if (!asBundle.monet) ColorSchemeMode.Dark else ColorSchemeMode.MonetDark - else -> if (!asBundle.monet) ColorSchemeMode.System else ColorSchemeMode.MonetSystem + val themeController = remember( + asBundle.themeBaseIndex, + asBundle.monet, + asBundle.monetSeedIndex, + asBundle.monetPaletteStyle, + asBundle.monetColorSpec, + ) { + asBundle.createThemeController() } - val themeController = remember(themeMode) { ThemeController(colorSchemeMode = themeMode) } MiuixTheme( controller = themeController, diff --git a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/SettingsScreen.kt b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/SettingsScreen.kt index 8b54410..f10fdef 100644 --- a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/SettingsScreen.kt +++ b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/SettingsScreen.kt @@ -48,6 +48,7 @@ import io.github.miuzarte.scrcpyforandroid.storage.Settings import io.github.miuzarte.scrcpyforandroid.storage.Storage.appSettings import io.github.miuzarte.scrcpyforandroid.ui.BlurredBar import io.github.miuzarte.scrcpyforandroid.ui.LocalEnableBlur +import io.github.miuzarte.scrcpyforandroid.ui.MonetKeyColorOptions import io.github.miuzarte.scrcpyforandroid.ui.rememberBlurBackdrop import io.github.miuzarte.scrcpyforandroid.widgets.MultiGroupsDropdownGroup import io.github.miuzarte.scrcpyforandroid.widgets.MultiGroupsDropdownPreference @@ -70,11 +71,15 @@ import top.yukonga.miuix.kmp.preference.ArrowPreference import top.yukonga.miuix.kmp.preference.OverlayDropdownPreference import top.yukonga.miuix.kmp.preference.SwitchPreference import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme +import top.yukonga.miuix.kmp.theme.ThemeColorSpec +import top.yukonga.miuix.kmp.theme.ThemePaletteStyle import java.io.File import kotlin.math.roundToInt import android.provider.Settings as AndroidSettings private const val TERMINAL_FONT_RELATIVE_PATH = "terminal/font.ttf" +private val monetPaletteStyleOptions = ThemePaletteStyle.entries.map { it.name } +private val monetColorSpecOptions = ThemeColorSpec.entries.map { it.name } private fun terminalFontFile(context: android.content.Context): File { return File(context.filesDir, TERMINAL_FONT_RELATIVE_PATH) @@ -241,9 +246,42 @@ fun SettingsPage( asBundle = asBundle.copy(monet = it) }, ) - // AnimatedVisibility(asBundle.monet) { - // // TODO: 自选 Monet 强调色方案,从默认开始 - // } + AnimatedVisibility(asBundle.monet) { + OverlayDropdownPreference( + title = "Monet Key Color", + summary = "设置 Monet 强调色", + items = MonetKeyColorOptions, + selectedIndex = asBundle.monetSeedIndex + .coerceIn(0, MonetKeyColorOptions.lastIndex), + onSelectedIndexChange = { + asBundle = asBundle.copy(monetSeedIndex = it) + }, + ) + } + AnimatedVisibility(asBundle.monet && asBundle.monetSeedIndex > 0) { + Column { + OverlayDropdownPreference( + title = "Monet Palette Style", + summary = "设置 Monet 调色板风格", + items = monetPaletteStyleOptions, + selectedIndex = asBundle.monetPaletteStyle + .coerceIn(0, monetPaletteStyleOptions.lastIndex), + onSelectedIndexChange = { + asBundle = asBundle.copy(monetPaletteStyle = it) + }, + ) + OverlayDropdownPreference( + title = "Monet Color Spec", + summary = "设置 Monet 色彩规格", + items = monetColorSpecOptions, + selectedIndex = asBundle.monetColorSpec + .coerceIn(0, monetColorSpecOptions.lastIndex), + onSelectedIndexChange = { + asBundle = asBundle.copy(monetColorSpec = it) + }, + ) + } + } SwitchPreference( title = "模糊", summary = "启用顶栏和底栏的模糊效果", diff --git a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/StreamScreen.kt b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/StreamScreen.kt index 57cd95f..ce13b6e 100644 --- a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/StreamScreen.kt +++ b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/pages/StreamScreen.kt @@ -19,12 +19,11 @@ import io.github.miuzarte.scrcpyforandroid.services.AppRuntime import io.github.miuzarte.scrcpyforandroid.services.LocalSnackbarController import io.github.miuzarte.scrcpyforandroid.services.SnackbarController import io.github.miuzarte.scrcpyforandroid.storage.Storage +import io.github.miuzarte.scrcpyforandroid.ui.createThemeController import io.github.miuzarte.scrcpyforandroid.widgets.VideoOutputTarget import io.github.miuzarte.scrcpyforandroid.widgets.VideoOutputTargetState import top.yukonga.miuix.kmp.basic.SnackbarHostState -import top.yukonga.miuix.kmp.theme.ColorSchemeMode import top.yukonga.miuix.kmp.theme.MiuixTheme -import top.yukonga.miuix.kmp.theme.ThemeController @Composable fun StreamScreen(activity: StreamActivity) { @@ -88,13 +87,15 @@ fun StreamScreen(activity: StreamActivity) { } } - val themeMode = - when (asBundle.themeBaseIndex.coerceIn(0, ThemeModes.baseOptions.lastIndex)) { - 1 -> if (!asBundle.monet) ColorSchemeMode.Light else ColorSchemeMode.MonetLight - 2 -> if (!asBundle.monet) ColorSchemeMode.Dark else ColorSchemeMode.MonetDark - else -> if (!asBundle.monet) ColorSchemeMode.System else ColorSchemeMode.MonetSystem - } - val themeController = remember(themeMode) { ThemeController(colorSchemeMode = themeMode) } + val themeController = remember( + asBundle.themeBaseIndex, + asBundle.monet, + asBundle.monetSeedIndex, + asBundle.monetPaletteStyle, + asBundle.monetColorSpec, + ) { + asBundle.createThemeController() + } val snackbarHostState = remember { SnackbarHostState() } val snackbarScope = rememberCoroutineScope() diff --git a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/storage/AppSettings.kt b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/storage/AppSettings.kt index 028b0c7..b06c2a1 100644 --- a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/storage/AppSettings.kt +++ b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/storage/AppSettings.kt @@ -76,6 +76,18 @@ class AppSettings(context: Context) : Settings(context, "AppSettings") { booleanPreferencesKey("monet"), false, ) + val MONET_SEED_INDEX = Pair( + intPreferencesKey("monet_seed_index"), + 0, + ) + val MONET_PALETTE_STYLE = Pair( + intPreferencesKey("monet_palette_style"), + 0, + ) + val MONET_COLOR_SPEC = Pair( + intPreferencesKey("monet_color_spec"), + 0, + ) val BLUR = Pair( booleanPreferencesKey("blur"), true, @@ -249,6 +261,9 @@ class AppSettings(context: Context) : Settings(context, "AppSettings") { // Theme val themeBaseIndex: Int, val monet: Boolean, + val monetSeedIndex: Int, + val monetPaletteStyle: Int, + val monetColorSpec: Int, val blur: Boolean, val floatingBottomBar: Boolean, val floatingBottomBarBlur: Boolean, @@ -302,6 +317,9 @@ class AppSettings(context: Context) : Settings(context, "AppSettings") { // Theme bundleField(THEME_BASE_INDEX) { it.themeBaseIndex }, bundleField(MONET) { it.monet }, + bundleField(MONET_SEED_INDEX) { it.monetSeedIndex }, + bundleField(MONET_PALETTE_STYLE) { it.monetPaletteStyle }, + bundleField(MONET_COLOR_SPEC) { it.monetColorSpec }, bundleField(BLUR) { it.blur }, bundleField(FLOATING_BOTTOM_BAR) { it.floatingBottomBar }, bundleField(FLOATING_BOTTOM_BAR_BLUR) { it.floatingBottomBarBlur }, @@ -356,6 +374,9 @@ class AppSettings(context: Context) : Settings(context, "AppSettings") { // Theme themeBaseIndex = preferences.read(THEME_BASE_INDEX), monet = preferences.read(MONET), + monetSeedIndex = preferences.read(MONET_SEED_INDEX), + monetPaletteStyle = preferences.read(MONET_PALETTE_STYLE), + monetColorSpec = preferences.read(MONET_COLOR_SPEC), blur = preferences.read(BLUR), floatingBottomBar = preferences.read(FLOATING_BOTTOM_BAR), floatingBottomBarBlur = preferences.read(FLOATING_BOTTOM_BAR_BLUR), diff --git a/app/src/main/java/io/github/miuzarte/scrcpyforandroid/ui/AppThemeConfig.kt b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/ui/AppThemeConfig.kt new file mode 100644 index 0000000..3bbfd63 --- /dev/null +++ b/app/src/main/java/io/github/miuzarte/scrcpyforandroid/ui/AppThemeConfig.kt @@ -0,0 +1,45 @@ +package io.github.miuzarte.scrcpyforandroid.ui + +import androidx.compose.ui.graphics.Color +import io.github.miuzarte.scrcpyforandroid.storage.AppSettings +import top.yukonga.miuix.kmp.theme.ColorSchemeMode +import top.yukonga.miuix.kmp.theme.ThemeColorSpec +import top.yukonga.miuix.kmp.theme.ThemeController +import top.yukonga.miuix.kmp.theme.ThemePaletteStyle + +val MonetKeyColors: List> = listOf( + "Blue" to Color(0xFF3482FF), + "Green" to Color(0xFF36D167), + "Purple" to Color(0xFF7C4DFF), + "Yellow" to Color(0xFFFFB21D), + "Orange" to Color(0xFFFF5722), + "Pink" to Color(0xFFE91E63), + "Teal" to Color(0xFF00BCD4), +) + +val MonetKeyColorOptions: List = listOf("Default") + MonetKeyColors.map { it.first } + +fun monetKeyColorFor(index: Int): Color? = + if (index <= 0) null else MonetKeyColors.getOrNull(index - 1)?.second + +fun AppSettings.Bundle.createThemeController(): ThemeController { + val themeMode = when (themeBaseIndex.coerceIn(0, 2)) { + 1 -> if (!monet) ColorSchemeMode.Light else ColorSchemeMode.MonetLight + 2 -> if (!monet) ColorSchemeMode.Dark else ColorSchemeMode.MonetDark + else -> if (!monet) ColorSchemeMode.System else ColorSchemeMode.MonetSystem + } + if (!monet) return ThemeController(colorSchemeMode = themeMode) + + val keyColor = monetKeyColorFor(monetSeedIndex) + val paletteStyle = ThemePaletteStyle.entries.getOrNull(monetPaletteStyle) + ?: ThemePaletteStyle.Content + val colorSpec = ThemeColorSpec.entries.getOrNull(monetColorSpec) + ?: ThemeColorSpec.Spec2021 + + return ThemeController( + colorSchemeMode = themeMode, + keyColor = keyColor, + paletteStyle = paletteStyle, + colorSpec = colorSpec, + ) +}