From 3d0d87cb0cdc6d1a508506be4614a339e5847f7c Mon Sep 17 00:00:00 2001 From: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Date: Tue, 13 May 2025 23:56:18 +0800 Subject: [PATCH] Add application DPI setting function - Allow users to customize the display density of the current application - Fix some popup color errors --- .../java/com/sukisu/ultra/ui/MainActivity.kt | 23 ++ .../ultra/ui/component/SlotSelectionDialog.kt | 6 +- .../sukisu/ultra/ui/screen/MoreSettings.kt | 207 +++++++++++++++++- .../src/main/res/values-zh-rCN/strings.xml | 14 ++ manager/app/src/main/res/values/strings.xml | 14 ++ 5 files changed, 256 insertions(+), 8 deletions(-) diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/MainActivity.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/MainActivity.kt index 96c2425c..7e08653b 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/MainActivity.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/MainActivity.kt @@ -49,6 +49,9 @@ class MainActivity : ComponentActivity() { } override fun onCreate(savedInstanceState: Bundle?) { + // 应用DPI设置(仅对当前应用生效) + applyCustomDpi() + // Enable edge to edge enableEdgeToEdge() @@ -135,6 +138,26 @@ class MainActivity : ComponentActivity() { } } + // 应用自定义DPI设置(仅对当前应用生效) + private fun applyCustomDpi() { + val prefs = getSharedPreferences("settings", MODE_PRIVATE) + val customDpi = prefs.getInt("app_dpi", 0) + + if (customDpi > 0) { + try { + val resources = resources + val metrics = resources.displayMetrics + + // 仅更新应用内显示,不影响系统状态栏 + metrics.density = customDpi / 160f + metrics.scaledDensity = customDpi / 160f + metrics.densityDpi = customDpi + } catch (e: Exception) { + e.printStackTrace() + } + } + } + override fun onPause() { super.onPause() CardConfig.save(applicationContext) diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/component/SlotSelectionDialog.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/component/SlotSelectionDialog.kt index db6f9e04..b4f8087d 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/component/SlotSelectionDialog.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/component/SlotSelectionDialog.kt @@ -47,11 +47,7 @@ fun SlotSelectionDialog( } if (show) { - val cardColor = if (!ThemeConfig.useDynamicColor) { - ThemeConfig.currentTheme.ButtonContrast - } else { - MaterialTheme.colorScheme.surfaceContainerHigh - } + val cardColor = MaterialTheme.colorScheme.surfaceContainerHighest AlertDialog( onDismissRequest = onDismiss, diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/MoreSettings.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/MoreSettings.kt index 2afb2127..40f889a5 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/MoreSettings.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/MoreSettings.kt @@ -1,6 +1,7 @@ package com.sukisu.ultra.ui.screen import android.content.Context +import android.content.Intent import android.net.Uri import android.os.Build import android.widget.Toast @@ -29,6 +30,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.automirrored.filled.NavigateNext +import androidx.compose.material.icons.filled.AcUnit import androidx.compose.material.icons.filled.Brush import androidx.compose.material.icons.filled.ColorLens import androidx.compose.material.icons.filled.DarkMode @@ -81,9 +83,7 @@ import androidx.core.content.edit import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.RootGraph import com.ramcosta.composedestinations.navigation.DestinationsNavigator -import com.sukisu.ultra.Natives import com.sukisu.ultra.R -import com.sukisu.ultra.ksuApp import com.sukisu.ultra.ui.component.ImageEditorDialog import com.sukisu.ultra.ui.component.KsuIsValid import com.sukisu.ultra.ui.component.SwitchItem @@ -227,6 +227,36 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) { var isCustomizeExpanded by remember { mutableStateOf(false) } var isAppearanceExpanded by remember { mutableStateOf(true) } var isAdvancedExpanded by remember { mutableStateOf(false) } + var isDpiExpanded by remember { mutableStateOf(false) } + + // DPI 设置 + val systemDpi = remember { context.resources.displayMetrics.densityDpi } + var currentDpi by remember { + mutableIntStateOf(prefs.getInt("app_dpi", systemDpi)) + } + var tempDpi by remember { mutableIntStateOf(currentDpi) } + var isDpiCustom by remember { mutableStateOf(true) } + var showDpiConfirmDialog by remember { mutableStateOf(false) } + + // 预设 DPI 选项 + val dpiPresets = mapOf( + stringResource(R.string.dpi_size_small) to 240, + stringResource(R.string.dpi_size_medium) to 320, + stringResource(R.string.dpi_size_large) to 420, + stringResource(R.string.dpi_size_extra_large) to 560 + ) + + // 获取DPI大小 + @Composable + fun getDpiFriendlyName(dpi: Int): String { + return when (dpi) { + 240 -> stringResource(R.string.dpi_size_small) + 320 -> stringResource(R.string.dpi_size_medium) + 420 -> stringResource(R.string.dpi_size_large) + 560 -> stringResource(R.string.dpi_size_extra_large) + else -> stringResource(R.string.dpi_size_custom) + } + } // 初始化卡片配置 LaunchedEffect(Unit) { @@ -263,10 +293,37 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) { CardConfig.setDarkModeDefaults() } - // 保存设置 + currentDpi = prefs.getInt("app_dpi", systemDpi) + tempDpi = currentDpi + CardConfig.save(context) } + // 应用 DPI 设置 + val applyDpiSetting = { dpi: Int -> + if (dpi != currentDpi) { + // 保存到 SharedPreferences + prefs.edit { + putInt("app_dpi", dpi) + } + + // 只修改应用级别的DPI设置 + currentDpi = dpi + tempDpi = dpi + Toast.makeText( + context, + context.getString(R.string.dpi_applied_success, dpi), + Toast.LENGTH_SHORT + ).show() + + val restartIntent = context.packageManager.getLaunchIntentForPackage(context.packageName) + restartIntent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK) + context.startActivity(restartIntent) + + showDpiConfirmDialog = false + } + } + // 主题色选项 val themeColorOptions = listOf( stringResource(R.string.color_default) to ThemeColors.Default, @@ -575,6 +632,114 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) { } } + // DPI 设置部分 + SectionHeader( + title = stringResource(R.string.dpi_settings), + expanded = isDpiExpanded, + onToggle = { isDpiExpanded = !isDpiExpanded } + ) + + AnimatedVisibility( + visible = isDpiExpanded, + enter = fadeIn() + expandVertically(), + exit = fadeOut() + shrinkVertically() + ) { + Surface( + shape = RoundedCornerShape(16.dp), + tonalElevation = 1.dp, + modifier = Modifier.padding(bottom = 16.dp) + ) { + Column { + ListItem( + headlineContent = { Text(stringResource(R.string.app_dpi_title)) }, + supportingContent = { Text(stringResource(R.string.app_dpi_summary)) }, + leadingContent = { + Icon( + Icons.Default.AcUnit, + contentDescription = null, + tint = MaterialTheme.colorScheme.primary + ) + }, + trailingContent = { + Text( + text = getDpiFriendlyName(tempDpi), + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.primary + ) + }, + colors = ListItemDefaults.colors( + containerColor = Color.Transparent + ) + ) + + // DPI 滑动条 + Column(modifier = Modifier.padding(horizontal = 32.dp, vertical = 8.dp)) { + Slider( + value = tempDpi.toFloat(), + onValueChange = { + tempDpi = it.toInt() + isDpiCustom = !dpiPresets.containsValue(tempDpi) + }, + valueRange = 160f..600f, + steps = 11, + colors = SliderDefaults.colors( + thumbColor = MaterialTheme.colorScheme.primary, + activeTrackColor = MaterialTheme.colorScheme.primary, + inactiveTrackColor = MaterialTheme.colorScheme.surfaceVariant + ) + ) + + Row( + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp), + ) { + dpiPresets.forEach { (name, dpi) -> + TextButton( + onClick = { + tempDpi = dpi + isDpiCustom = false + }, + modifier = Modifier.weight(1f) + ) { + Text( + text = name, + color = if (tempDpi == dpi) + MaterialTheme.colorScheme.primary + else + MaterialTheme.colorScheme.onSurfaceVariant + ) + } + } + } + + TextButton( + onClick = { + if (tempDpi != currentDpi) { + showDpiConfirmDialog = true + } + }, + modifier = Modifier + .fillMaxWidth() + .padding(top = 8.dp) + ) { + Text(stringResource(R.string.dpi_apply_settings)) + } + + Text( + text = if (isDpiCustom) + "${stringResource(R.string.dpi_size_custom)}: $tempDpi" + else + "${getDpiFriendlyName(tempDpi)}: $tempDpi", + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.padding(top = 4.dp) + ) + } + } + } + } + // 自定义设置部分 SectionHeader( title = stringResource(R.string.custom_settings), @@ -863,6 +1028,42 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) { ) } + // DPI 设置确认对话框 + if (showDpiConfirmDialog) { + AlertDialog( + onDismissRequest = { showDpiConfirmDialog = false }, + title = { Text(stringResource(R.string.dpi_confirm_title)) }, + text = { + Column { + Text(stringResource(R.string.dpi_confirm_message, currentDpi, tempDpi)) + Text( + stringResource(R.string.dpi_confirm_summary), + style = MaterialTheme.typography.bodySmall, + color = MaterialTheme.colorScheme.onSurfaceVariant, + modifier = Modifier.padding(top = 8.dp) + ) + } + }, + confirmButton = { + TextButton( + onClick = { applyDpiSetting(tempDpi) } + ) { + Text(stringResource(R.string.confirm)) + } + }, + dismissButton = { + TextButton( + onClick = { + showDpiConfirmDialog = false + tempDpi = currentDpi + } + ) { + Text(stringResource(R.string.cancel)) + } + } + ) + } + // 主题色选择对话框 if (showThemeColorDialog) { AlertDialog( diff --git a/manager/app/src/main/res/values-zh-rCN/strings.xml b/manager/app/src/main/res/values-zh-rCN/strings.xml index 61a67260..8a8fcd87 100644 --- a/manager/app/src/main/res/values-zh-rCN/strings.xml +++ b/manager/app/src/main/res/values-zh-rCN/strings.xml @@ -328,4 +328,18 @@ 使用支持更多 API 的 WebUI X 而不是 WebUI 将 Eruda 注入 WebUI X 在 WebUI X 中注入调试控制台,使调试更容易,需要启用 WebView 调试 + + DPI 设置 + 应用DPI + 仅调整当前应用的屏幕显示密度 + + + + 超大 + 自定义 + 应用DPI设置 + 确认更改DPI + 你确定要将应用DPI从 %1$d 更改为 %2$d 吗? + 应用需要重启以应用新的DPI设置,不会影响系统状态栏或其他应用 + DPI 已设置为 %1$d,重启应用后生效 diff --git a/manager/app/src/main/res/values/strings.xml b/manager/app/src/main/res/values/strings.xml index 6434432e..653987c5 100644 --- a/manager/app/src/main/res/values/strings.xml +++ b/manager/app/src/main/res/values/strings.xml @@ -332,4 +332,18 @@ Use WebUI X instead of WebUI which supports more API\'s Inject Eruda into WebUI X Inject a debug console into WebUI X to make debugging easier. Requires web debugging to be on. + + DPI setting + Applied DPI + Adjust the screen display density for the current application only + Small + Medium + Big + oversize + customizable + Applying DPI settings + Confirm DPI change + Are you sure you want to change the application DPI from %1$d to %2$d? + Application needs to be restarted to apply the new DPI settings, does not affect the system status bar or other applications + DPI has been set to %1$d, effective after restarting the application