manager: Refactor card elevation handling and improve theme support
This commit is contained in:
@@ -63,7 +63,12 @@ fun SearchAppBar(
|
||||
var onSearch by remember { mutableStateOf(false) }
|
||||
|
||||
// 获取卡片颜色和透明度
|
||||
val cardColor = MaterialTheme.colorScheme.surfaceContainerLow
|
||||
val colorScheme = MaterialTheme.colorScheme
|
||||
val cardColor = if (CardConfig.isCustomBackgroundEnabled) {
|
||||
colorScheme.surfaceContainerLow
|
||||
} else {
|
||||
colorScheme.background
|
||||
}
|
||||
val cardAlpha = CardConfig.cardAlpha
|
||||
|
||||
if (onSearch) {
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
package com.sukisu.ultra.ui.component
|
||||
|
||||
import androidx.compose.foundation.LocalIndication
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.selection.toggleable
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import com.dergoogler.mmrl.ui.component.LabelItem
|
||||
import com.dergoogler.mmrl.ui.component.text.TextRow
|
||||
|
||||
@Composable
|
||||
fun SwitchItem(
|
||||
icon: ImageVector? = null,
|
||||
title: String,
|
||||
summary: String? = null,
|
||||
checked: Boolean,
|
||||
enabled: Boolean = true,
|
||||
beta: Boolean = false,
|
||||
onCheckedChange: (Boolean) -> Unit,
|
||||
) {
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
val stateAlpha = remember(checked, enabled) { Modifier.alpha(if (enabled) 1f else 0.5f) }
|
||||
|
||||
ListItem(
|
||||
modifier = Modifier
|
||||
.toggleable(
|
||||
value = checked,
|
||||
interactionSource = interactionSource,
|
||||
role = Role.Switch,
|
||||
enabled = enabled,
|
||||
indication = LocalIndication.current,
|
||||
onValueChange = onCheckedChange
|
||||
),
|
||||
headlineContent = {
|
||||
TextRow(
|
||||
leadingContent = if (beta) {
|
||||
{
|
||||
LabelItem(
|
||||
modifier = Modifier.then(stateAlpha),
|
||||
text = "Beta"
|
||||
)
|
||||
}
|
||||
} else null
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.then(stateAlpha),
|
||||
text = title,
|
||||
)
|
||||
}
|
||||
},
|
||||
leadingContent = icon?.let {
|
||||
{
|
||||
Icon(
|
||||
modifier = Modifier.then(stateAlpha),
|
||||
imageVector = icon,
|
||||
contentDescription = title,
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
},
|
||||
trailingContent = {
|
||||
Switch(
|
||||
checked = checked,
|
||||
enabled = enabled,
|
||||
onCheckedChange = onCheckedChange,
|
||||
interactionSource = interactionSource
|
||||
)
|
||||
},
|
||||
supportingContent = {
|
||||
if (summary != null) {
|
||||
Text(
|
||||
modifier = Modifier.then(stateAlpha),
|
||||
text = summary
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -21,7 +21,7 @@ import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun SwitchItem(
|
||||
icon: ImageVector,
|
||||
icon: ImageVector? = null,
|
||||
title: String,
|
||||
summary: String? = null,
|
||||
checked: Boolean,
|
||||
@@ -55,6 +55,11 @@ fun SwitchItem(
|
||||
disabledUncheckedIconColor = MaterialTheme.colorScheme.surfaceVariant
|
||||
)
|
||||
|
||||
MaterialTheme(
|
||||
colorScheme = MaterialTheme.colorScheme.copy(
|
||||
surface = MaterialTheme.colorScheme.surfaceContainerHigh
|
||||
)
|
||||
) {
|
||||
ListItem(
|
||||
headlineContent = {
|
||||
Text(
|
||||
@@ -75,13 +80,15 @@ fun SwitchItem(
|
||||
)
|
||||
}
|
||||
},
|
||||
leadingContent = {
|
||||
leadingContent = icon?.let {
|
||||
{
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
imageVector = it,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(24.dp),
|
||||
tint = iconTint
|
||||
)
|
||||
}
|
||||
},
|
||||
trailingContent = {
|
||||
Switch(
|
||||
@@ -98,4 +105,5 @@ fun SwitchItem(
|
||||
}
|
||||
.padding(vertical = 4.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,6 @@ fun AppProfileConfig(
|
||||
onValueChange = { onProfileChange(profile.copy(name = it)) }
|
||||
)
|
||||
}
|
||||
|
||||
SwitchItem(
|
||||
title = stringResource(R.string.profile_umount_modules),
|
||||
summary = stringResource(R.string.profile_umount_modules_summary),
|
||||
|
||||
@@ -37,7 +37,6 @@ import androidx.compose.material3.FilterChip
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.IconButtonDefaults
|
||||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
@@ -84,6 +83,8 @@ import com.sukisu.ultra.ui.component.profile.AppProfileConfig
|
||||
import com.sukisu.ultra.ui.component.profile.RootProfileConfig
|
||||
import com.sukisu.ultra.ui.component.profile.TemplateConfig
|
||||
import com.sukisu.ultra.ui.theme.CardConfig
|
||||
import com.sukisu.ultra.ui.theme.getCardColors
|
||||
import com.sukisu.ultra.ui.theme.getCardElevation
|
||||
import com.sukisu.ultra.ui.util.LocalSnackbarHost
|
||||
import com.sukisu.ultra.ui.util.forceStopApp
|
||||
import com.sukisu.ultra.ui.util.getSepolicy
|
||||
@@ -122,7 +123,12 @@ fun AppProfileScreen(
|
||||
mutableStateOf(initialProfile)
|
||||
}
|
||||
|
||||
val cardColor = MaterialTheme.colorScheme.surfaceContainerLow
|
||||
val colorScheme = MaterialTheme.colorScheme
|
||||
val cardColor = if (CardConfig.isCustomBackgroundEnabled) {
|
||||
colorScheme.surfaceContainerLow
|
||||
} else {
|
||||
colorScheme.background
|
||||
}
|
||||
val cardAlpha = CardConfig.cardAlpha
|
||||
|
||||
Scaffold(
|
||||
@@ -203,13 +209,21 @@ private fun AppProfileInner(
|
||||
onProfileChange: (Natives.Profile) -> Unit,
|
||||
) {
|
||||
val isRootGranted = profile.allowSu
|
||||
val cardColors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh)
|
||||
|
||||
MaterialTheme(
|
||||
colorScheme = MaterialTheme.colorScheme.copy(
|
||||
surface = MaterialTheme.colorScheme.surfaceContainerHigh
|
||||
)
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
ElevatedCard(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
shape = MaterialTheme.shapes.medium
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
colors = cardColors,
|
||||
elevation = getCardElevation(),
|
||||
) {
|
||||
AppMenuBox(packageName) {
|
||||
ListItem(
|
||||
@@ -235,7 +249,9 @@ private fun AppProfileInner(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
shape = MaterialTheme.shapes.medium
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
colors = cardColors,
|
||||
elevation = getCardElevation(),
|
||||
) {
|
||||
SwitchItem(
|
||||
icon = Icons.Filled.Security,
|
||||
@@ -268,7 +284,8 @@ private fun AppProfileInner(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
shape = MaterialTheme.shapes.medium
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
colors = cardColors,
|
||||
) {
|
||||
ProfileBox(mode, true) {
|
||||
// template mode shouldn't change profile here!
|
||||
@@ -288,10 +305,15 @@ private fun AppProfileInner(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
shape = MaterialTheme.shapes.medium
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
colors = cardColors,
|
||||
elevation = getCardElevation(),
|
||||
) {
|
||||
Column(modifier = Modifier.padding(vertical = 8.dp)) {
|
||||
Crossfade(targetState = mode, label = "ProfileMode") { currentMode ->
|
||||
Crossfade(
|
||||
targetState = mode,
|
||||
label = "ProfileMode"
|
||||
) { currentMode ->
|
||||
when (currentMode) {
|
||||
Mode.Template -> {
|
||||
TemplateConfig(
|
||||
@@ -301,6 +323,7 @@ private fun AppProfileInner(
|
||||
onProfileChange = onProfileChange
|
||||
)
|
||||
}
|
||||
|
||||
Mode.Custom -> {
|
||||
RootProfileConfig(
|
||||
fixedName = true,
|
||||
@@ -308,6 +331,7 @@ private fun AppProfileInner(
|
||||
onProfileChange = onProfileChange
|
||||
)
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
@@ -321,7 +345,9 @@ private fun AppProfileInner(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
shape = MaterialTheme.shapes.medium
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
colors = cardColors,
|
||||
elevation = getCardElevation(),
|
||||
) {
|
||||
ProfileBox(mode, false) {
|
||||
onProfileChange(profile.copy(nonRootUseDefault = (it == Mode.Default)))
|
||||
@@ -337,7 +363,9 @@ private fun AppProfileInner(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
shape = MaterialTheme.shapes.medium
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
colors = cardColors,
|
||||
elevation = getCardElevation(),
|
||||
) {
|
||||
Column(modifier = Modifier.padding(vertical = 8.dp)) {
|
||||
AppProfileConfig(
|
||||
@@ -353,6 +381,7 @@ private fun AppProfileInner(
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum class Mode(@StringRes private val res: Int) {
|
||||
@@ -377,12 +406,10 @@ private fun TopBar(
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
Text(
|
||||
text = packageName,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
modifier = Modifier.alpha(0.8f)
|
||||
)
|
||||
}
|
||||
@@ -391,9 +418,6 @@ private fun TopBar(
|
||||
navigationIcon = {
|
||||
IconButton(
|
||||
onClick = onBack,
|
||||
colors = IconButtonDefaults.iconButtonColors(
|
||||
contentColor = MaterialTheme.colorScheme.onSurface
|
||||
)
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
|
||||
@@ -408,7 +432,6 @@ private fun TopBar(
|
||||
modifier = Modifier.shadow(
|
||||
elevation = if ((scrollBehavior?.state?.overlappedFraction ?: 0f) > 0.01f)
|
||||
4.dp else 0.dp,
|
||||
spotColor = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -431,7 +454,6 @@ private fun ProfileBox(
|
||||
Text(
|
||||
text = mode.text,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
},
|
||||
leadingContent = {
|
||||
@@ -444,7 +466,6 @@ private fun ProfileBox(
|
||||
|
||||
HorizontalDivider(
|
||||
thickness = Dp.Hairline,
|
||||
color = MaterialTheme.colorScheme.outlineVariant
|
||||
)
|
||||
|
||||
ListItem(
|
||||
@@ -574,6 +595,11 @@ private fun AppMenuOption(text: String, onClick: () -> Unit) {
|
||||
@Composable
|
||||
private fun AppProfilePreview() {
|
||||
var profile by remember { mutableStateOf(Natives.Profile("")) }
|
||||
MaterialTheme(
|
||||
colorScheme = MaterialTheme.colorScheme.copy(
|
||||
surface = MaterialTheme.colorScheme.surfaceContainerHigh
|
||||
)
|
||||
) {
|
||||
Surface {
|
||||
AppProfileInner(
|
||||
packageName = "icu.nullptr.test",
|
||||
@@ -590,4 +616,5 @@ private fun AppProfilePreview() {
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -439,7 +439,12 @@ private fun TopBar(
|
||||
onSave: () -> Unit = {},
|
||||
scrollBehavior: TopAppBarScrollBehavior? = null
|
||||
) {
|
||||
val cardColor = MaterialTheme.colorScheme.surfaceContainerLow
|
||||
val colorScheme = MaterialTheme.colorScheme
|
||||
val cardColor = if (CardConfig.isCustomBackgroundEnabled) {
|
||||
colorScheme.surfaceContainerLow
|
||||
} else {
|
||||
colorScheme.background
|
||||
}
|
||||
val cardAlpha = CardConfig.cardAlpha
|
||||
|
||||
val statusColor = when(status) {
|
||||
|
||||
@@ -90,9 +90,11 @@ import com.sukisu.ultra.Natives
|
||||
import com.sukisu.ultra.R
|
||||
import com.sukisu.ultra.ui.component.KsuIsValid
|
||||
import com.sukisu.ultra.ui.component.rememberConfirmDialog
|
||||
import com.sukisu.ultra.ui.theme.CardConfig
|
||||
import com.sukisu.ultra.ui.theme.CardConfig.cardAlpha
|
||||
import com.sukisu.ultra.ui.theme.CardConfig.cardElevation
|
||||
import com.sukisu.ultra.ui.theme.getCardColors
|
||||
import com.sukisu.ultra.ui.theme.getCardElevation
|
||||
import com.sukisu.ultra.ui.util.checkNewVersion
|
||||
import com.sukisu.ultra.ui.util.getKpmModuleCount
|
||||
import com.sukisu.ultra.ui.util.getKpmVersion
|
||||
@@ -281,7 +283,12 @@ private fun TopBar(
|
||||
onInstallClick: () -> Unit,
|
||||
scrollBehavior: TopAppBarScrollBehavior? = null
|
||||
) {
|
||||
val cardColor = MaterialTheme.colorScheme.surfaceContainerLow
|
||||
val colorScheme = MaterialTheme.colorScheme
|
||||
val cardColor = if (CardConfig.isCustomBackgroundEnabled) {
|
||||
colorScheme.surfaceContainerLow
|
||||
} else {
|
||||
colorScheme.background
|
||||
}
|
||||
|
||||
TopAppBar(
|
||||
title = {
|
||||
@@ -336,7 +343,7 @@ private fun StatusCard(
|
||||
ElevatedCard(
|
||||
colors = getCardColors( if (systemStatus.ksuVersion != null)MaterialTheme.colorScheme.secondaryContainer
|
||||
else MaterialTheme.colorScheme.errorContainer),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation),
|
||||
elevation = getCardElevation(),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
@@ -510,7 +517,7 @@ fun WarningCard(
|
||||
) {
|
||||
ElevatedCard(
|
||||
colors = getCardColors(color),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation),
|
||||
elevation = getCardElevation(),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
@@ -534,7 +541,7 @@ fun ContributionCard() {
|
||||
|
||||
ElevatedCard(
|
||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceContainer),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation),
|
||||
elevation = getCardElevation(),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
@@ -602,7 +609,7 @@ fun DonateCard() {
|
||||
|
||||
ElevatedCard(
|
||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceContainer),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation),
|
||||
elevation = getCardElevation(),
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
@@ -641,7 +648,7 @@ private fun InfoCard(
|
||||
) {
|
||||
ElevatedCard(
|
||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceContainer),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation),
|
||||
elevation = getCardElevation(),
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
|
||||
@@ -33,7 +33,6 @@ import androidx.compose.material.icons.filled.FileUpload
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
@@ -92,6 +91,8 @@ import com.sukisu.ultra.ui.util.isAbDevice
|
||||
import com.sukisu.ultra.ui.util.isInitBoot
|
||||
import com.sukisu.ultra.ui.util.rootAvailable
|
||||
import com.sukisu.ultra.getKernelVersion
|
||||
import com.sukisu.ultra.ui.theme.CardConfig
|
||||
import com.sukisu.ultra.ui.theme.getCardElevation
|
||||
|
||||
/**
|
||||
* @author ShirkNeko
|
||||
@@ -253,7 +254,7 @@ fun InstallScreen(navigator: DestinationsNavigator) {
|
||||
(lkmSelection as? LkmSelection.LkmUri)?.let {
|
||||
ElevatedCard(
|
||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceVariant),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation),
|
||||
elevation = getCardElevation(),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 12.dp)
|
||||
@@ -279,7 +280,7 @@ fun InstallScreen(navigator: DestinationsNavigator) {
|
||||
if (method.slot != null) {
|
||||
ElevatedCard(
|
||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceVariant),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation),
|
||||
elevation = getCardElevation(),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 12.dp)
|
||||
@@ -478,7 +479,7 @@ private fun SelectInstallMethod(
|
||||
if (isGKI) {
|
||||
ElevatedCard(
|
||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceVariant),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation),
|
||||
elevation = getCardElevation(),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 12.dp)
|
||||
@@ -488,6 +489,11 @@ private fun SelectInstallMethod(
|
||||
shape = MaterialTheme.shapes.large,
|
||||
spotColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.1f)
|
||||
)
|
||||
) {
|
||||
MaterialTheme(
|
||||
colorScheme = MaterialTheme.colorScheme.copy(
|
||||
surface = MaterialTheme.colorScheme.surfaceVariant
|
||||
)
|
||||
) {
|
||||
ListItem(
|
||||
leadingContent = {
|
||||
@@ -507,6 +513,7 @@ private fun SelectInstallMethod(
|
||||
LKMExpanded = !LKMExpanded
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = LKMExpanded,
|
||||
@@ -584,7 +591,7 @@ private fun SelectInstallMethod(
|
||||
if (rootAvailable) {
|
||||
ElevatedCard(
|
||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceVariant),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation),
|
||||
elevation = getCardElevation(),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 12.dp)
|
||||
@@ -594,6 +601,11 @@ private fun SelectInstallMethod(
|
||||
shape = MaterialTheme.shapes.large,
|
||||
spotColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.1f)
|
||||
)
|
||||
) {
|
||||
MaterialTheme(
|
||||
colorScheme = MaterialTheme.colorScheme.copy(
|
||||
surface = MaterialTheme.colorScheme.surfaceVariant
|
||||
)
|
||||
) {
|
||||
ListItem(
|
||||
leadingContent = {
|
||||
@@ -613,6 +625,7 @@ private fun SelectInstallMethod(
|
||||
GKIExpanded = !GKIExpanded
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = GKIExpanded,
|
||||
@@ -732,7 +745,12 @@ private fun TopBar(
|
||||
onLkmUpload: () -> Unit = {},
|
||||
scrollBehavior: TopAppBarScrollBehavior? = null
|
||||
) {
|
||||
val cardColor = MaterialTheme.colorScheme.surfaceContainerLow
|
||||
val colorScheme = MaterialTheme.colorScheme
|
||||
val cardColor = if (CardConfig.isCustomBackgroundEnabled) {
|
||||
colorScheme.surfaceContainerLow
|
||||
} else {
|
||||
colorScheme.background
|
||||
}
|
||||
val cardAlpha = cardAlpha
|
||||
|
||||
TopAppBar(
|
||||
|
||||
@@ -366,7 +366,12 @@ private fun TopBar(
|
||||
else -> MaterialTheme.colorScheme.primary
|
||||
}
|
||||
|
||||
val cardColor = MaterialTheme.colorScheme.surfaceContainerLow
|
||||
val colorScheme = MaterialTheme.colorScheme
|
||||
val cardColor = if (CardConfig.isCustomBackgroundEnabled) {
|
||||
colorScheme.surfaceContainerLow
|
||||
} else {
|
||||
colorScheme.background
|
||||
}
|
||||
val cardAlpha = CardConfig.cardAlpha
|
||||
|
||||
TopAppBar(
|
||||
|
||||
@@ -617,7 +617,7 @@ private fun KpmModuleItem(
|
||||
|
||||
Card(
|
||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation)
|
||||
elevation = getCardElevation()
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(20.dp)
|
||||
|
||||
@@ -72,6 +72,7 @@ import com.dergoogler.mmrl.platform.Platform
|
||||
import androidx.core.net.toUri
|
||||
import com.dergoogler.mmrl.platform.model.ModuleConfig
|
||||
import com.dergoogler.mmrl.platform.model.ModuleConfig.Companion.asModuleConfig
|
||||
import com.sukisu.ultra.ui.theme.getCardElevation
|
||||
|
||||
/**
|
||||
* @author ShirkNeko
|
||||
@@ -711,7 +712,7 @@ fun ModuleItem(
|
||||
) {
|
||||
ElevatedCard(
|
||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation),
|
||||
elevation = getCardElevation(),
|
||||
) {
|
||||
val textDecoration = if (!module.remove) null else TextDecoration.LineThrough
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
|
||||
@@ -11,31 +11,42 @@ import android.widget.Toast
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.animateFloatAsState
|
||||
import androidx.compose.animation.expandVertically
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.shrinkVertically
|
||||
import androidx.compose.animation.slideInVertically
|
||||
import androidx.compose.animation.slideOutVertically
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.safeDrawing
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
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.*
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
@@ -49,14 +60,16 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
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.ui.MainActivity
|
||||
@@ -68,6 +81,7 @@ import com.sukisu.ultra.ui.theme.CardConfig.cardElevation
|
||||
import com.sukisu.ultra.ui.theme.ThemeColors
|
||||
import com.sukisu.ultra.ui.theme.ThemeConfig
|
||||
import com.sukisu.ultra.ui.theme.getCardColors
|
||||
import com.sukisu.ultra.ui.theme.getCardElevation
|
||||
import com.sukisu.ultra.ui.theme.saveAndApplyCustomBackground
|
||||
import com.sukisu.ultra.ui.theme.saveCustomBackground
|
||||
import com.sukisu.ultra.ui.theme.saveDynamicColorState
|
||||
@@ -96,7 +110,7 @@ fun saveCardConfig(context: Context) {
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Destination<RootGraph>
|
||||
@Composable
|
||||
fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
||||
fun MoreSettingsScreen() {
|
||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
|
||||
val context = LocalContext.current
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
@@ -393,7 +407,7 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
||||
|
||||
// 如果启用了系统跟随且系统是深色模式,应用深色模式默认值
|
||||
if (themeMode == 0 && systemIsDark) {
|
||||
CardConfig.setDarkModeDefaults()
|
||||
CardConfig.setThemeDefaults(true)
|
||||
}
|
||||
|
||||
currentDpi = prefs.getInt("app_dpi", systemDpi)
|
||||
@@ -476,91 +490,43 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
val cardColor = MaterialTheme.colorScheme.surfaceContainerHigh
|
||||
val isDarkTheme = isSystemInDarkTheme()
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text(stringResource(R.string.more_settings)) },
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = cardColor.copy(alpha = cardAlpha),
|
||||
scrolledContainerColor = cardColor.copy(alpha = cardAlpha)),
|
||||
navigationIcon = {
|
||||
IconButton(onClick = { navigator.popBackStack() }) {
|
||||
Icon(Icons.AutoMirrored.Filled.ArrowBack,
|
||||
contentDescription = stringResource(R.string.back))
|
||||
}
|
||||
TopBar(scrollBehavior = scrollBehavior)
|
||||
},
|
||||
scrollBehavior = scrollBehavior,
|
||||
)
|
||||
}
|
||||
contentWindowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal)
|
||||
) { paddingValues ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues)
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
.padding(horizontal = 16.dp)
|
||||
.padding(top = 8.dp)
|
||||
) {
|
||||
// 外观设置部分
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 16.dp),
|
||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation)
|
||||
SettingsCard(
|
||||
title = stringResource(R.string.appearance_settings),
|
||||
icon = Icons.Default.Palette
|
||||
) {
|
||||
Column(modifier = Modifier.padding(vertical = 8.dp)) {
|
||||
Text(
|
||||
text = stringResource(R.string.appearance_settings),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
)
|
||||
// 语言设置
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(R.string.language_setting)) },
|
||||
supportingContent = {
|
||||
Text(supportedLanguages.find { it.first == currentLanguage }?.second
|
||||
?: stringResource(R.string.language_follow_system))
|
||||
},
|
||||
leadingContent = {
|
||||
Icon(
|
||||
Icons.Default.Language,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
},
|
||||
trailingContent = {
|
||||
Icon(
|
||||
Icons.AutoMirrored.Filled.NavigateNext,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
},
|
||||
modifier = Modifier.clickable { showLanguageDialog = true }
|
||||
SettingItem(
|
||||
icon = Icons.Default.Language,
|
||||
title = stringResource(R.string.language_setting),
|
||||
subtitle = supportedLanguages.find { it.first == currentLanguage }?.second
|
||||
?: stringResource(R.string.language_follow_system),
|
||||
onClick = { showLanguageDialog = true }
|
||||
)
|
||||
|
||||
// 主题模式
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(R.string.theme_mode)) },
|
||||
supportingContent = { Text(themeOptions[themeMode]) },
|
||||
leadingContent = {
|
||||
Icon(
|
||||
Icons.Default.DarkMode,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
},
|
||||
trailingContent = {
|
||||
Icon(
|
||||
Icons.AutoMirrored.Filled.NavigateNext,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
},
|
||||
modifier = Modifier.clickable { showThemeModeDialog = true }
|
||||
SettingItem(
|
||||
icon = Icons.Default.DarkMode,
|
||||
title = stringResource(R.string.theme_mode),
|
||||
subtitle = themeOptions[themeMode],
|
||||
onClick = { showThemeModeDialog = true }
|
||||
)
|
||||
|
||||
// 动态颜色开关
|
||||
@@ -582,11 +548,10 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
||||
enter = fadeIn() + expandVertically(),
|
||||
exit = fadeOut() + shrinkVertically()
|
||||
) {
|
||||
Column {
|
||||
ListItem(
|
||||
headlineContent = { Text(stringResource(R.string.theme_color)) },
|
||||
supportingContent = {
|
||||
val currentThemeName = when (ThemeConfig.currentTheme) {
|
||||
SettingItem(
|
||||
icon = Icons.Default.Palette,
|
||||
title = stringResource(R.string.theme_color),
|
||||
subtitle = when (ThemeConfig.currentTheme) {
|
||||
is ThemeColors.Green -> stringResource(R.string.color_green)
|
||||
is ThemeColors.Purple -> stringResource(R.string.color_purple)
|
||||
is ThemeColors.Orange -> stringResource(R.string.color_orange)
|
||||
@@ -594,51 +559,50 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
||||
is ThemeColors.Gray -> stringResource(R.string.color_gray)
|
||||
is ThemeColors.Yellow -> stringResource(R.string.color_yellow)
|
||||
else -> stringResource(R.string.color_default)
|
||||
}
|
||||
Text(currentThemeName)
|
||||
},
|
||||
leadingContent = {
|
||||
Icon(
|
||||
Icons.Default.Palette,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
},
|
||||
onClick = { showThemeColorDialog = true },
|
||||
trailingContent = {
|
||||
Icon(
|
||||
Icons.AutoMirrored.Filled.NavigateNext,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
},
|
||||
modifier = Modifier.clickable { showThemeColorDialog = true }
|
||||
Row {
|
||||
themeColorOptions.take(4).forEach { (_, theme) ->
|
||||
ColorCircle(
|
||||
color = if (isDarkTheme) theme.primaryDark else theme.primaryLight,
|
||||
isSelected = ThemeConfig.currentTheme::class == theme::class,
|
||||
modifier = Modifier.padding(horizontal = 2.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// DPI 设置
|
||||
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
|
||||
HorizontalDivider(
|
||||
modifier = Modifier.padding(vertical = 8.dp)
|
||||
)
|
||||
},
|
||||
|
||||
// DPI 设置
|
||||
SettingItem(
|
||||
icon = Icons.Default.FormatSize,
|
||||
title = stringResource(R.string.app_dpi_title),
|
||||
subtitle = stringResource(R.string.app_dpi_summary),
|
||||
onClick = {},
|
||||
trailingContent = {
|
||||
Text(
|
||||
text = getDpiFriendlyName(tempDpi),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
// DPI 滑动条
|
||||
Column(modifier = Modifier.padding(horizontal = 32.dp, vertical = 8.dp)) {
|
||||
Column(modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)) {
|
||||
val sliderValue by animateFloatAsState(
|
||||
targetValue = tempDpi.toFloat(),
|
||||
label = "DPI Slider Animation"
|
||||
)
|
||||
|
||||
Slider(
|
||||
value = tempDpi.toFloat(),
|
||||
value = sliderValue,
|
||||
onValueChange = {
|
||||
tempDpi = it.toInt()
|
||||
isDpiCustom = !dpiPresets.containsValue(tempDpi)
|
||||
@@ -658,46 +622,72 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
||||
.padding(top = 8.dp),
|
||||
) {
|
||||
dpiPresets.forEach { (name, dpi) ->
|
||||
TextButton(
|
||||
onClick = {
|
||||
val isSelected = tempDpi == dpi
|
||||
val buttonColor = if (isSelected)
|
||||
MaterialTheme.colorScheme.primaryContainer
|
||||
else
|
||||
MaterialTheme.colorScheme.surfaceVariant
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(horizontal = 2.dp)
|
||||
.clip(RoundedCornerShape(8.dp))
|
||||
.background(buttonColor)
|
||||
.clickable {
|
||||
tempDpi = dpi
|
||||
isDpiCustom = false
|
||||
},
|
||||
modifier = Modifier.weight(1f)
|
||||
}
|
||||
.padding(vertical = 8.dp, horizontal = 4.dp),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Text(
|
||||
text = name,
|
||||
color = if (tempDpi == dpi)
|
||||
MaterialTheme.colorScheme.primary
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = if (isSelected)
|
||||
MaterialTheme.colorScheme.onPrimaryContainer
|
||||
else
|
||||
MaterialTheme.colorScheme.onSurfaceVariant
|
||||
MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
modifier = Modifier.padding(top = 4.dp)
|
||||
modifier = Modifier.padding(top = 8.dp)
|
||||
)
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
if (tempDpi != currentDpi) {
|
||||
showDpiConfirmDialog = true
|
||||
}
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = 8.dp),
|
||||
enabled = tempDpi != currentDpi
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Check,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(16.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
Text(stringResource(R.string.dpi_apply_settings))
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalDivider(
|
||||
modifier = Modifier.padding(vertical = 8.dp),
|
||||
)
|
||||
|
||||
// 自定义背景开关
|
||||
SwitchItem(
|
||||
@@ -711,15 +701,12 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
||||
} else {
|
||||
context.saveCustomBackground(null)
|
||||
isCustomBackgroundEnabled = false
|
||||
cardElevation
|
||||
CardConfig.cardAlpha = 1f
|
||||
CardConfig.cardDim = 0f
|
||||
CardConfig.isCustomAlphaSet = false
|
||||
CardConfig.isCustomDimSet = false
|
||||
CardConfig.isCustomBackgroundEnabled = false
|
||||
saveCardConfig(context)
|
||||
cardAlpha = 1f
|
||||
cardDim = 0f
|
||||
|
||||
// 重置其他相关设置
|
||||
ThemeConfig.needsResetOnThemeChange = true
|
||||
@@ -744,11 +731,10 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
||||
// 透明度和亮度调节滑动条
|
||||
AnimatedVisibility(
|
||||
visible = ThemeConfig.customBackgroundUri != null,
|
||||
enter = fadeIn() + expandVertically(),
|
||||
exit = fadeOut() + shrinkVertically(),
|
||||
modifier = Modifier.padding(horizontal = 32.dp)
|
||||
enter = fadeIn() + slideInVertically(),
|
||||
exit = fadeOut() + slideOutVertically()
|
||||
) {
|
||||
Column(modifier = Modifier.padding(vertical = 8.dp)) {
|
||||
Column(modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)) {
|
||||
// 透明度滑动条
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
@@ -772,8 +758,13 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
||||
)
|
||||
}
|
||||
|
||||
val alphaSliderValue by animateFloatAsState(
|
||||
targetValue = cardAlpha,
|
||||
label = "Alpha Slider Animation"
|
||||
)
|
||||
|
||||
Slider(
|
||||
value = cardAlpha,
|
||||
value = alphaSliderValue,
|
||||
onValueChange = { newValue ->
|
||||
cardAlpha = newValue
|
||||
CardConfig.cardAlpha = newValue
|
||||
@@ -820,8 +811,13 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
||||
)
|
||||
}
|
||||
|
||||
val dimSliderValue by animateFloatAsState(
|
||||
targetValue = cardDim,
|
||||
label = "Dim Slider Animation"
|
||||
)
|
||||
|
||||
Slider(
|
||||
value = cardDim,
|
||||
value = dimSliderValue,
|
||||
onValueChange = { newValue ->
|
||||
cardDim = newValue
|
||||
CardConfig.cardDim = newValue
|
||||
@@ -847,22 +843,12 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 自定义设置部分
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 16.dp),
|
||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation)
|
||||
SettingsCard(
|
||||
title = stringResource(R.string.custom_settings),
|
||||
icon = Icons.Default.Settings
|
||||
) {
|
||||
Column(Modifier.padding(vertical = 8.dp)) {
|
||||
Text(
|
||||
text = stringResource(R.string.custom_settings),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
)
|
||||
// 添加简洁模式开关
|
||||
SwitchItem(
|
||||
icon = Icons.Filled.Brush,
|
||||
@@ -925,22 +911,12 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
||||
onHideLinkCardChange(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 高级设置部分
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 16.dp),
|
||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation)
|
||||
SettingsCard(
|
||||
title = stringResource(R.string.advanced_settings),
|
||||
icon = Icons.Default.AdminPanelSettings
|
||||
) {
|
||||
Column( Modifier.padding(vertical = 8.dp)) {
|
||||
Text(
|
||||
text = stringResource(R.string.advanced_settings),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
|
||||
)
|
||||
// SELinux 开关
|
||||
KsuIsValid {
|
||||
SwitchItem(
|
||||
@@ -1026,7 +1002,6 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 主题模式选择对话框
|
||||
if (showThemeModeDialog) {
|
||||
@@ -1053,36 +1028,21 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
||||
ThemeConfig.forceDarkMode = true
|
||||
CardConfig.isUserDarkModeEnabled = true
|
||||
CardConfig.isUserLightModeEnabled = false
|
||||
if (!CardConfig.isCustomAlphaSet) {
|
||||
CardConfig.cardAlpha = 1f
|
||||
}
|
||||
if (!CardConfig.isCustomDimSet) {
|
||||
CardConfig.cardDim = 0.5f
|
||||
}
|
||||
CardConfig.setThemeDefaults(true)
|
||||
CardConfig.save(context)
|
||||
}
|
||||
1 -> { // 浅色
|
||||
ThemeConfig.forceDarkMode = false
|
||||
CardConfig.isUserLightModeEnabled = true
|
||||
CardConfig.isUserDarkModeEnabled = false
|
||||
if (!CardConfig.isCustomAlphaSet) {
|
||||
CardConfig.cardAlpha = 1f
|
||||
}
|
||||
if (!CardConfig.isCustomDimSet) {
|
||||
CardConfig.cardDim = 0f
|
||||
}
|
||||
CardConfig.setThemeDefaults(false)
|
||||
CardConfig.save(context)
|
||||
}
|
||||
0 -> { // 跟随系统
|
||||
ThemeConfig.forceDarkMode = null
|
||||
CardConfig.isUserLightModeEnabled = false
|
||||
CardConfig.isUserDarkModeEnabled = false
|
||||
if (!CardConfig.isCustomAlphaSet) {
|
||||
CardConfig.cardAlpha = 1f
|
||||
}
|
||||
if (!CardConfig.isCustomDimSet) {
|
||||
CardConfig.cardDim = if (isDarkTheme) 0.5f else 0f
|
||||
}
|
||||
CardConfig.setThemeDefaults(isDarkTheme)
|
||||
CardConfig.save(context)
|
||||
}
|
||||
}
|
||||
@@ -1200,3 +1160,143 @@ fun MoreSettingsScreen(navigator: DestinationsNavigator) {
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SettingsCard(
|
||||
title: String,
|
||||
icon: ImageVector,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = 16.dp),
|
||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh),
|
||||
elevation = getCardElevation(),
|
||||
shape = MaterialTheme.shapes.medium
|
||||
) {
|
||||
Column(modifier = Modifier.padding(vertical = 8.dp)) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp)
|
||||
) {
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.size(24.dp)
|
||||
)
|
||||
Spacer(modifier = Modifier.width(12.dp))
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
)
|
||||
}
|
||||
content()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SettingItem(
|
||||
icon: ImageVector,
|
||||
title: String,
|
||||
subtitle: String? = null,
|
||||
onClick: () -> Unit,
|
||||
iconTint: Color = MaterialTheme.colorScheme.primary,
|
||||
trailingContent: @Composable (() -> Unit)? = {
|
||||
Icon(
|
||||
Icons.AutoMirrored.Filled.NavigateNext,
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = onClick)
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
contentDescription = null,
|
||||
tint = iconTint,
|
||||
modifier = Modifier
|
||||
.padding(end = 16.dp)
|
||||
.size(24.dp)
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier.weight(1f)
|
||||
) {
|
||||
Text(
|
||||
text = title,
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
)
|
||||
if (subtitle != null) {
|
||||
Text(
|
||||
text = subtitle,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
trailingContent?.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
fun ColorCircle(
|
||||
color: Color,
|
||||
isSelected: Boolean,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.size(20.dp)
|
||||
.clip(CircleShape)
|
||||
.background(color)
|
||||
.then(
|
||||
if (isSelected) {
|
||||
Modifier.border(
|
||||
width = 2.dp,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
shape = CircleShape
|
||||
)
|
||||
} else {
|
||||
Modifier
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun TopBar(
|
||||
scrollBehavior: TopAppBarScrollBehavior? = null
|
||||
) {
|
||||
val colorScheme = MaterialTheme.colorScheme
|
||||
val cardColor = if (CardConfig.isCustomBackgroundEnabled) {
|
||||
colorScheme.surfaceContainerLow
|
||||
} else {
|
||||
colorScheme.background
|
||||
}
|
||||
TopAppBar(
|
||||
title = {
|
||||
Text(
|
||||
text = stringResource(R.string.more_settings),
|
||||
style = MaterialTheme.typography.titleLarge
|
||||
)
|
||||
},
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = cardColor.copy(alpha = CardConfig.cardAlpha),
|
||||
scrolledContainerColor = cardColor.copy(alpha = CardConfig.cardAlpha)
|
||||
),
|
||||
windowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal),
|
||||
scrollBehavior = scrollBehavior
|
||||
)
|
||||
}
|
||||
@@ -63,7 +63,6 @@ import com.sukisu.ultra.ui.util.getBugreportFile
|
||||
import java.time.LocalDateTime
|
||||
import java.time.format.DateTimeFormatter
|
||||
import com.sukisu.ultra.ui.component.KsuIsValid
|
||||
import com.sukisu.ultra.ui.theme.CardConfig.cardElevation
|
||||
|
||||
/**
|
||||
* @author ShirkNeko
|
||||
@@ -127,7 +126,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation)
|
||||
elevation = getCardElevation()
|
||||
) {
|
||||
Column(modifier = Modifier.padding(vertical = 8.dp)) {
|
||||
Text(
|
||||
@@ -195,7 +194,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation)
|
||||
elevation = getCardElevation()
|
||||
) {
|
||||
Column(modifier = Modifier.padding(vertical = 8.dp)) {
|
||||
Text(
|
||||
@@ -340,7 +339,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation)
|
||||
elevation = getCardElevation()
|
||||
) {
|
||||
Column(modifier = Modifier.padding(vertical = 8.dp)) {
|
||||
Text(
|
||||
@@ -436,7 +435,7 @@ fun SettingScreen(navigator: DestinationsNavigator) {
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
colors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh),
|
||||
elevation = CardDefaults.cardElevation(defaultElevation = cardElevation)
|
||||
elevation = getCardElevation()
|
||||
) {
|
||||
Column(modifier = Modifier.padding(vertical = 8.dp)) {
|
||||
Text(
|
||||
@@ -740,14 +739,12 @@ fun rememberUninstallDialog(onSelected: (UninstallType) -> Unit): DialogHandle {
|
||||
private fun TopBar(
|
||||
scrollBehavior: TopAppBarScrollBehavior? = null
|
||||
) {
|
||||
val systemIsDark = isSystemInDarkTheme()
|
||||
val cardColor = MaterialTheme.colorScheme.surfaceContainerLow
|
||||
val cardAlpha = if (ThemeConfig.customBackgroundUri != null) {
|
||||
cardAlpha
|
||||
val colorScheme = MaterialTheme.colorScheme
|
||||
val cardColor = if (CardConfig.isCustomBackgroundEnabled) {
|
||||
colorScheme.surfaceContainerLow
|
||||
} else {
|
||||
if (systemIsDark) 0.8f else 1f
|
||||
colorScheme.background
|
||||
}
|
||||
|
||||
TopAppBar(
|
||||
title = {
|
||||
Text(
|
||||
|
||||
@@ -231,7 +231,12 @@ private fun TopBar(
|
||||
colors: TopAppBarColors,
|
||||
scrollBehavior: TopAppBarScrollBehavior? = null
|
||||
) {
|
||||
val cardColor = MaterialTheme.colorScheme.surfaceContainerLow
|
||||
val colorScheme = MaterialTheme.colorScheme
|
||||
val cardColor = if (CardConfig.isCustomBackgroundEnabled) {
|
||||
colorScheme.surfaceContainerLow
|
||||
} else {
|
||||
colorScheme.background
|
||||
}
|
||||
val cardAlpha = CardConfig.cardAlpha
|
||||
|
||||
TopAppBar(
|
||||
|
||||
@@ -10,19 +10,15 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.luminance
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
object CardConfig {
|
||||
val settingElevation: Dp = 4.dp
|
||||
val customBackgroundElevation: Dp = 0.dp
|
||||
|
||||
// 卡片透明度
|
||||
var cardAlpha by mutableFloatStateOf(1f)
|
||||
// 卡片亮度
|
||||
var cardDim by mutableFloatStateOf(0f)
|
||||
// 卡片阴影
|
||||
var cardElevation by mutableStateOf(settingElevation)
|
||||
var cardElevation by mutableStateOf(4.dp)
|
||||
var isShadowEnabled by mutableStateOf(true)
|
||||
var isCustomAlphaSet by mutableStateOf(false)
|
||||
var isCustomDimSet by mutableStateOf(false)
|
||||
@@ -69,37 +65,24 @@ object CardConfig {
|
||||
*/
|
||||
fun updateShadowEnabled(enabled: Boolean) {
|
||||
isShadowEnabled = enabled
|
||||
cardElevation = if (isCustomBackgroundEnabled && cardAlpha != 1f) {
|
||||
customBackgroundElevation
|
||||
cardElevation = if (isCustomBackgroundEnabled) {
|
||||
0.dp
|
||||
} else if (enabled) {
|
||||
settingElevation
|
||||
4.dp
|
||||
} else {
|
||||
customBackgroundElevation
|
||||
0.dp
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置深色模式默认值
|
||||
* 设置主题模式默认值
|
||||
*/
|
||||
fun setDarkModeDefaults() {
|
||||
fun setThemeDefaults(isDarkMode: Boolean) {
|
||||
if (!isCustomAlphaSet) {
|
||||
cardAlpha = 1f
|
||||
}
|
||||
if (!isCustomDimSet) {
|
||||
cardDim = 0.5f
|
||||
}
|
||||
updateShadowEnabled(isShadowEnabled)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置浅色模式默认值
|
||||
*/
|
||||
fun setLightModeDefaults() {
|
||||
if (!isCustomAlphaSet) {
|
||||
cardAlpha = 1f
|
||||
}
|
||||
if (!isCustomDimSet) {
|
||||
cardDim = 0f
|
||||
cardDim = if (isDarkMode) 0.5f else 0f
|
||||
}
|
||||
updateShadowEnabled(isShadowEnabled)
|
||||
}
|
||||
@@ -114,6 +97,19 @@ fun getCardColors(originalColor: Color) = CardDefaults.cardColors(
|
||||
contentColor = determineContentColor(originalColor)
|
||||
)
|
||||
|
||||
/**
|
||||
* 获取卡片阴影配置
|
||||
*/
|
||||
@Composable
|
||||
fun getCardElevation() = CardDefaults.cardElevation(
|
||||
defaultElevation = CardConfig.cardElevation,
|
||||
pressedElevation = if (CardConfig.isCustomBackgroundEnabled) 0.dp else 8.dp,
|
||||
focusedElevation = if (CardConfig.isCustomBackgroundEnabled) 0.dp else 6.dp,
|
||||
hoveredElevation = if (CardConfig.isCustomBackgroundEnabled) 0.dp else 4.dp,
|
||||
draggedElevation = if (CardConfig.isCustomBackgroundEnabled) 0.dp else 8.dp,
|
||||
disabledElevation = 0.dp
|
||||
)
|
||||
|
||||
/**
|
||||
* 根据背景颜色、主题模式和用户设置确定内容颜色
|
||||
*/
|
||||
|
||||
@@ -47,6 +47,7 @@ import com.sukisu.ultra.ui.util.saveTransformedBackground
|
||||
import androidx.activity.SystemBarStyle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.compose.material3.ColorScheme
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
|
||||
@@ -150,9 +151,9 @@ fun KernelSUTheme(
|
||||
// 根据暗色模式和自定义背景调整卡片配置
|
||||
val isDarkModeWithCustomBackground = darkTheme && ThemeConfig.customBackgroundUri != null
|
||||
if (darkTheme && !dynamicColor) {
|
||||
CardConfig.setDarkModeDefaults()
|
||||
CardConfig.setThemeDefaults(true)
|
||||
} else if (!darkTheme && !dynamicColor) {
|
||||
CardConfig.setLightModeDefaults()
|
||||
CardConfig.setThemeDefaults(false)
|
||||
}
|
||||
CardConfig.updateShadowEnabled(!isDarkModeWithCustomBackground)
|
||||
|
||||
@@ -216,7 +217,8 @@ fun KernelSUTheme(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.zIndex(-2f)
|
||||
.background(if (darkTheme) MaterialTheme.colorScheme.surfaceContainerLow else MaterialTheme.colorScheme.surfaceContainerLow)
|
||||
.background(if (darkTheme) if (CardConfig.isCustomBackgroundEnabled) { colorScheme.surfaceContainerLow } else { colorScheme.background }
|
||||
else if (CardConfig.isCustomBackgroundEnabled) { colorScheme.surfaceContainerLow } else { colorScheme.background })
|
||||
)
|
||||
|
||||
// 自定义背景层
|
||||
@@ -287,22 +289,30 @@ fun KernelSUTheme(
|
||||
*/
|
||||
@RequiresApi(Build.VERSION_CODES.S)
|
||||
@Composable
|
||||
private fun createDynamicDarkColorScheme(context: Context) =
|
||||
dynamicDarkColorScheme(context).copy(
|
||||
background = Color.Transparent,
|
||||
surface = Color.Transparent
|
||||
private fun createDynamicDarkColorScheme(context: Context): ColorScheme {
|
||||
val scheme = dynamicDarkColorScheme(context)
|
||||
return scheme.copy(
|
||||
background = if (CardConfig.isCustomBackgroundEnabled) Color.Transparent else scheme.background,
|
||||
surface = if (CardConfig.isCustomBackgroundEnabled) Color.Transparent else scheme.surface,
|
||||
onBackground = Color.White,
|
||||
onSurface = Color.White
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建动态浅色颜色方案
|
||||
*/
|
||||
@RequiresApi(Build.VERSION_CODES.S)
|
||||
@Composable
|
||||
private fun createDynamicLightColorScheme(context: Context) =
|
||||
dynamicLightColorScheme(context).copy(
|
||||
background = Color.Transparent,
|
||||
surface = Color.Transparent
|
||||
private fun createDynamicLightColorScheme(context: Context): ColorScheme {
|
||||
val scheme = dynamicLightColorScheme(context)
|
||||
return scheme.copy(
|
||||
background = if (CardConfig.isCustomBackgroundEnabled) Color.Transparent else scheme.background,
|
||||
surface = if (CardConfig.isCustomBackgroundEnabled) Color.Transparent else scheme.surface
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 创建深色颜色方案
|
||||
@@ -325,9 +335,9 @@ private fun createDarkColorScheme() = darkColorScheme(
|
||||
onError = ThemeConfig.currentTheme.onErrorDark,
|
||||
errorContainer = ThemeConfig.currentTheme.errorContainerDark,
|
||||
onErrorContainer = ThemeConfig.currentTheme.onErrorContainerDark,
|
||||
background = Color.Transparent,
|
||||
background = if (CardConfig.isCustomBackgroundEnabled) Color.Transparent else ThemeConfig.currentTheme.backgroundDark,
|
||||
onBackground = ThemeConfig.currentTheme.onBackgroundDark,
|
||||
surface = Color.Transparent,
|
||||
surface = if (CardConfig.isCustomBackgroundEnabled) Color.Transparent else ThemeConfig.currentTheme.surfaceDark,
|
||||
onSurface = ThemeConfig.currentTheme.onSurfaceDark,
|
||||
surfaceVariant = ThemeConfig.currentTheme.surfaceVariantDark,
|
||||
onSurfaceVariant = ThemeConfig.currentTheme.onSurfaceVariantDark,
|
||||
@@ -367,9 +377,9 @@ private fun createLightColorScheme() = lightColorScheme(
|
||||
onError = ThemeConfig.currentTheme.onErrorLight,
|
||||
errorContainer = ThemeConfig.currentTheme.errorContainerLight,
|
||||
onErrorContainer = ThemeConfig.currentTheme.onErrorContainerLight,
|
||||
background = Color.Transparent,
|
||||
background = if (CardConfig.isCustomBackgroundEnabled) Color.Transparent else ThemeConfig.currentTheme.backgroundLight,
|
||||
onBackground = ThemeConfig.currentTheme.onBackgroundLight,
|
||||
surface = Color.Transparent,
|
||||
surface = if (CardConfig.isCustomBackgroundEnabled) Color.Transparent else ThemeConfig.currentTheme.surfaceLight,
|
||||
onSurface = ThemeConfig.currentTheme.onSurfaceLight,
|
||||
surfaceVariant = ThemeConfig.currentTheme.surfaceVariantLight,
|
||||
onSurfaceVariant = ThemeConfig.currentTheme.onSurfaceVariantLight,
|
||||
@@ -388,6 +398,7 @@ private fun createLightColorScheme() = lightColorScheme(
|
||||
surfaceContainerHighest = ThemeConfig.currentTheme.surfaceContainerHighestLight,
|
||||
)
|
||||
|
||||
|
||||
/**
|
||||
* 复制图片到应用内部存储并提升持久性
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user