manager: Refactor card elevation handling and improve theme support

This commit is contained in:
ShirkNeko
2025-06-01 20:17:22 +08:00
parent ee4c3bb03b
commit 5457a4772b
16 changed files with 1005 additions and 908 deletions

View File

@@ -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) {

View File

@@ -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
)
}
}
)
}

View File

@@ -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,47 +55,55 @@ fun SwitchItem(
disabledUncheckedIconColor = MaterialTheme.colorScheme.surfaceVariant
)
ListItem(
headlineContent = {
Text(
text = title,
style = MaterialTheme.typography.titleMedium,
maxLines = Int.MAX_VALUE,
overflow = TextOverflow.Ellipsis
)
},
supportingContent = summary?.let {
{
MaterialTheme(
colorScheme = MaterialTheme.colorScheme.copy(
surface = MaterialTheme.colorScheme.surfaceContainerHigh
)
) {
ListItem(
headlineContent = {
Text(
text = it,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
text = title,
style = MaterialTheme.typography.titleMedium,
maxLines = Int.MAX_VALUE,
overflow = TextOverflow.Ellipsis
)
}
},
leadingContent = {
Icon(
imageVector = icon,
contentDescription = null,
modifier = Modifier.size(24.dp),
tint = iconTint
)
},
trailingContent = {
Switch(
checked = checked,
onCheckedChange = null,
enabled = enabled,
colors = switchColors
)
},
modifier = Modifier
.fillMaxWidth()
.clickable(enabled = enabled) {
onCheckedChange(!checked)
}
.padding(vertical = 4.dp)
)
},
supportingContent = summary?.let {
{
Text(
text = it,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
maxLines = Int.MAX_VALUE,
overflow = TextOverflow.Ellipsis
)
}
},
leadingContent = icon?.let {
{
Icon(
imageVector = it,
contentDescription = null,
modifier = Modifier.size(24.dp),
tint = iconTint
)
}
},
trailingContent = {
Switch(
checked = checked,
onCheckedChange = null,
enabled = enabled,
colors = switchColors
)
},
modifier = Modifier
.fillMaxWidth()
.clickable(enabled = enabled) {
onCheckedChange(!checked)
}
.padding(vertical = 4.dp)
)
}
}

View File

@@ -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),

View File

@@ -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,149 +209,172 @@ private fun AppProfileInner(
onProfileChange: (Natives.Profile) -> Unit,
) {
val isRootGranted = profile.allowSu
val cardColors = getCardColors(MaterialTheme.colorScheme.surfaceContainerHigh)
Column(modifier = modifier) {
ElevatedCard(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp),
shape = MaterialTheme.shapes.medium
) {
AppMenuBox(packageName) {
ListItem(
headlineContent = {
Text(
text = appLabel,
style = MaterialTheme.typography.titleMedium
)
},
supportingContent = {
Text(
text = packageName,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
},
leadingContent = appIcon,
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,
colors = cardColors,
elevation = getCardElevation(),
) {
AppMenuBox(packageName) {
ListItem(
headlineContent = {
Text(
text = appLabel,
style = MaterialTheme.typography.titleMedium
)
},
supportingContent = {
Text(
text = packageName,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
},
leadingContent = appIcon,
)
}
}
ElevatedCard(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp),
shape = MaterialTheme.shapes.medium,
colors = cardColors,
elevation = getCardElevation(),
) {
SwitchItem(
icon = Icons.Filled.Security,
title = stringResource(id = R.string.superuser),
checked = isRootGranted,
onCheckedChange = { onProfileChange(profile.copy(allowSu = it)) },
)
}
}
ElevatedCard(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp),
shape = MaterialTheme.shapes.medium
) {
SwitchItem(
icon = Icons.Filled.Security,
title = stringResource(id = R.string.superuser),
checked = isRootGranted,
onCheckedChange = { onProfileChange(profile.copy(allowSu = it)) },
)
}
Crossfade(
targetState = isRootGranted,
label = "RootAccess"
) { current ->
Column(
modifier = Modifier.padding(bottom = 6.dp + 48.dp + 6.dp /* SnackBar height */)
) {
if (current) {
val initialMode = if (profile.rootUseDefault) {
Mode.Default
} else if (profile.rootTemplate != null) {
Mode.Template
} else {
Mode.Custom
}
var mode by rememberSaveable {
mutableStateOf(initialMode)
}
ElevatedCard(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp),
shape = MaterialTheme.shapes.medium
) {
ProfileBox(mode, true) {
// template mode shouldn't change profile here!
if (it == Mode.Default || it == Mode.Custom) {
onProfileChange(profile.copy(rootUseDefault = it == Mode.Default))
}
mode = it
Crossfade(
targetState = isRootGranted,
label = "RootAccess"
) { current ->
Column(
modifier = Modifier.padding(bottom = 6.dp + 48.dp + 6.dp /* SnackBar height */)
) {
if (current) {
val initialMode = if (profile.rootUseDefault) {
Mode.Default
} else if (profile.rootTemplate != null) {
Mode.Template
} else {
Mode.Custom
}
var mode by rememberSaveable {
mutableStateOf(initialMode)
}
}
AnimatedVisibility(
visible = mode != Mode.Default,
enter = fadeIn() + expandVertically(),
exit = fadeOut() + shrinkVertically()
) {
ElevatedCard(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp),
shape = MaterialTheme.shapes.medium
shape = MaterialTheme.shapes.medium,
colors = cardColors,
) {
Column(modifier = Modifier.padding(vertical = 8.dp)) {
Crossfade(targetState = mode, label = "ProfileMode") { currentMode ->
when (currentMode) {
Mode.Template -> {
TemplateConfig(
profile = profile,
onViewTemplate = onViewTemplate,
onManageTemplate = onManageTemplate,
onProfileChange = onProfileChange
)
ProfileBox(mode, true) {
// template mode shouldn't change profile here!
if (it == Mode.Default || it == Mode.Custom) {
onProfileChange(profile.copy(rootUseDefault = it == Mode.Default))
}
mode = it
}
}
AnimatedVisibility(
visible = mode != Mode.Default,
enter = fadeIn() + expandVertically(),
exit = fadeOut() + shrinkVertically()
) {
ElevatedCard(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp),
shape = MaterialTheme.shapes.medium,
colors = cardColors,
elevation = getCardElevation(),
) {
Column(modifier = Modifier.padding(vertical = 8.dp)) {
Crossfade(
targetState = mode,
label = "ProfileMode"
) { currentMode ->
when (currentMode) {
Mode.Template -> {
TemplateConfig(
profile = profile,
onViewTemplate = onViewTemplate,
onManageTemplate = onManageTemplate,
onProfileChange = onProfileChange
)
}
Mode.Custom -> {
RootProfileConfig(
fixedName = true,
profile = profile,
onProfileChange = onProfileChange
)
}
else -> {}
}
Mode.Custom -> {
RootProfileConfig(
fixedName = true,
profile = profile,
onProfileChange = onProfileChange
)
}
else -> {}
}
}
}
}
}
} else {
val mode = if (profile.nonRootUseDefault) Mode.Default else Mode.Custom
} else {
val mode = if (profile.nonRootUseDefault) Mode.Default else Mode.Custom
ElevatedCard(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp),
shape = MaterialTheme.shapes.medium
) {
ProfileBox(mode, false) {
onProfileChange(profile.copy(nonRootUseDefault = (it == Mode.Default)))
}
}
AnimatedVisibility(
visible = mode == Mode.Custom,
enter = fadeIn() + expandVertically(),
exit = fadeOut() + shrinkVertically()
) {
ElevatedCard(
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(
fixedName = true,
profile = profile,
enabled = mode == Mode.Custom,
onProfileChange = onProfileChange
)
ProfileBox(mode, false) {
onProfileChange(profile.copy(nonRootUseDefault = (it == Mode.Default)))
}
}
AnimatedVisibility(
visible = mode == Mode.Custom,
enter = fadeIn() + expandVertically(),
exit = fadeOut() + shrinkVertically()
) {
ElevatedCard(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 8.dp),
shape = MaterialTheme.shapes.medium,
colors = cardColors,
elevation = getCardElevation(),
) {
Column(modifier = Modifier.padding(vertical = 8.dp)) {
AppProfileConfig(
fixedName = true,
profile = profile,
enabled = mode == Mode.Custom,
onProfileChange = onProfileChange
)
}
}
}
}
@@ -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,20 +595,26 @@ private fun AppMenuOption(text: String, onClick: () -> Unit) {
@Composable
private fun AppProfilePreview() {
var profile by remember { mutableStateOf(Natives.Profile("")) }
Surface {
AppProfileInner(
packageName = "icu.nullptr.test",
appLabel = "Test",
appIcon = {
Icon(
imageVector = Icons.Filled.Android,
contentDescription = null,
)
},
profile = profile,
onProfileChange = {
profile = it
},
MaterialTheme(
colorScheme = MaterialTheme.colorScheme.copy(
surface = MaterialTheme.colorScheme.surfaceContainerHigh
)
) {
Surface {
AppProfileInner(
packageName = "icu.nullptr.test",
appLabel = "Test",
appIcon = {
Icon(
imageVector = Icons.Filled.Android,
contentDescription = null,
)
},
profile = profile,
onProfileChange = {
profile = it
},
)
}
}
}

View File

@@ -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) {

View File

@@ -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

View File

@@ -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)
@@ -489,24 +490,30 @@ private fun SelectInstallMethod(
spotColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.1f)
)
) {
ListItem(
leadingContent = {
Icon(
Icons.Filled.AutoFixHigh,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary
)
},
headlineContent = {
Text(
stringResource(R.string.Lkm_install_methods),
style = MaterialTheme.typography.titleMedium
)
},
modifier = Modifier.clickable {
LKMExpanded = !LKMExpanded
}
)
MaterialTheme(
colorScheme = MaterialTheme.colorScheme.copy(
surface = MaterialTheme.colorScheme.surfaceVariant
)
) {
ListItem(
leadingContent = {
Icon(
Icons.Filled.AutoFixHigh,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary
)
},
headlineContent = {
Text(
stringResource(R.string.Lkm_install_methods),
style = MaterialTheme.typography.titleMedium
)
},
modifier = Modifier.clickable {
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)
@@ -595,24 +602,30 @@ private fun SelectInstallMethod(
spotColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.1f)
)
) {
ListItem(
leadingContent = {
Icon(
Icons.Filled.FileUpload,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary
)
},
headlineContent = {
Text(
stringResource(R.string.GKI_install_methods),
style = MaterialTheme.typography.titleMedium
)
},
modifier = Modifier.clickable {
GKIExpanded = !GKIExpanded
}
)
MaterialTheme(
colorScheme = MaterialTheme.colorScheme.copy(
surface = MaterialTheme.colorScheme.surfaceVariant
)
) {
ListItem(
leadingContent = {
Icon(
Icons.Filled.FileUpload,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary
)
},
headlineContent = {
Text(
stringResource(R.string.GKI_install_methods),
style = MaterialTheme.typography.titleMedium
)
},
modifier = Modifier.clickable {
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(

View File

@@ -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(

View File

@@ -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)

View File

@@ -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() }

View File

@@ -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(

View File

@@ -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(

View File

@@ -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
)
/**
* 根据背景颜色、主题模式和用户设置确定内容颜色
*/

View File

@@ -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,
)
/**
* 复制图片到应用内部存储并提升持久性
*/