Refactor(SettingDialog): Componentized settings page elements

This commit is contained in:
2024-08-12 14:33:28 +08:00
parent 3d69514a39
commit cb6fe19033
2 changed files with 138 additions and 103 deletions

View File

@@ -0,0 +1,108 @@
package top.fatweb.oxygen.toolbox.ui.component
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.selection.selectableGroup
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import top.fatweb.oxygen.toolbox.icon.OxygenIcons
@Composable
fun DialogTitle(
modifier: Modifier = Modifier,
text: String
) {
Text(
modifier = modifier.padding(16.dp),
text = text,
style = MaterialTheme.typography.titleLarge
)
}
@Composable
fun DialogSectionTitle(
modifier: Modifier = Modifier,
text: String
) {
Text(
modifier = modifier.padding(top = 16.dp, bottom = 8.dp),
text = text,
style = MaterialTheme.typography.titleMedium
)
}
@Composable
fun DialogSectionGroup(
modifier: Modifier = Modifier,
content: @Composable () -> Unit
) {
Column(
modifier = modifier.selectableGroup()
) {
content()
}
}
@Composable
fun DialogChooserRow(
modifier: Modifier = Modifier,
text: String,
selected: Boolean,
onClick: () -> Unit
) {
Row(
modifier = modifier
.fillMaxSize()
.selectable(
selected = selected,
role = Role.RadioButton,
onClick = onClick
)
.padding(12.dp),
verticalAlignment = Alignment.CenterVertically
) {
RadioButton(
selected = selected,
onClick = null
)
Spacer(modifier = Modifier.width(8.dp))
Text(text)
}
}
@Composable
fun DialogClickerRow(
modifier: Modifier = Modifier,
icon: ImageVector? = null,
text: String,
onClick: () -> Unit
) {
Row(
modifier = modifier
.fillMaxWidth()
.clickable(
onClick = onClick
)
.padding(12.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(imageVector = icon ?: OxygenIcons.Reorder, contentDescription = null)
Spacer(modifier = Modifier.width(8.dp))
Text(text)
}
}

View File

@@ -6,28 +6,20 @@ import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.selection.selectableGroup
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.AlertDialog import androidx.compose.material3.AlertDialog
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.RadioButton
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextButton import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@@ -35,10 +27,8 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -50,6 +40,10 @@ import top.fatweb.oxygen.toolbox.model.userdata.LanguageConfig
import top.fatweb.oxygen.toolbox.model.userdata.LaunchPageConfig import top.fatweb.oxygen.toolbox.model.userdata.LaunchPageConfig
import top.fatweb.oxygen.toolbox.model.userdata.ThemeBrandConfig import top.fatweb.oxygen.toolbox.model.userdata.ThemeBrandConfig
import top.fatweb.oxygen.toolbox.model.userdata.UserData import top.fatweb.oxygen.toolbox.model.userdata.UserData
import top.fatweb.oxygen.toolbox.ui.component.DialogChooserRow
import top.fatweb.oxygen.toolbox.ui.component.DialogClickerRow
import top.fatweb.oxygen.toolbox.ui.component.DialogSectionGroup
import top.fatweb.oxygen.toolbox.ui.component.DialogSectionTitle
import top.fatweb.oxygen.toolbox.ui.theme.OxygenPreviews import top.fatweb.oxygen.toolbox.ui.theme.OxygenPreviews
import top.fatweb.oxygen.toolbox.ui.theme.OxygenTheme import top.fatweb.oxygen.toolbox.ui.theme.OxygenTheme
import top.fatweb.oxygen.toolbox.ui.theme.supportsDynamicTheming import top.fatweb.oxygen.toolbox.ui.theme.supportsDynamicTheming
@@ -177,98 +171,86 @@ private fun ColumnScope.SettingsPanel(
onNavigateToLibraries: () -> Unit, onNavigateToLibraries: () -> Unit,
onNavigateToAbout: () -> Unit onNavigateToAbout: () -> Unit
) { ) {
SettingsDialogSectionTitle(text = stringResource(R.string.feature_settings_language)) DialogSectionTitle(text = stringResource(R.string.feature_settings_language))
Column( DialogSectionGroup {
modifier = Modifier.selectableGroup() DialogChooserRow(
) {
SettingsDialogChooserRow(
text = stringResource(R.string.feature_settings_language_system_default), text = stringResource(R.string.feature_settings_language_system_default),
selected = settings.languageConfig == LanguageConfig.FOLLOW_SYSTEM, selected = settings.languageConfig == LanguageConfig.FOLLOW_SYSTEM,
onClick = { onChangeLanguageConfig(LanguageConfig.FOLLOW_SYSTEM) } onClick = { onChangeLanguageConfig(LanguageConfig.FOLLOW_SYSTEM) }
) )
SettingsDialogChooserRow( DialogChooserRow(
text = stringResource(R.string.feature_settings_language_chinese), text = stringResource(R.string.feature_settings_language_chinese),
selected = settings.languageConfig == LanguageConfig.CHINESE, selected = settings.languageConfig == LanguageConfig.CHINESE,
onClick = { onChangeLanguageConfig(LanguageConfig.CHINESE) } onClick = { onChangeLanguageConfig(LanguageConfig.CHINESE) }
) )
SettingsDialogChooserRow( DialogChooserRow(
text = stringResource(R.string.feature_settings_language_english), text = stringResource(R.string.feature_settings_language_english),
selected = settings.languageConfig == LanguageConfig.ENGLISH, selected = settings.languageConfig == LanguageConfig.ENGLISH,
onClick = { onChangeLanguageConfig(LanguageConfig.ENGLISH) } onClick = { onChangeLanguageConfig(LanguageConfig.ENGLISH) }
) )
} }
SettingsDialogSectionTitle(text = stringResource(R.string.feature_settings_launch_page)) DialogSectionTitle(text = stringResource(R.string.feature_settings_launch_page))
Column( DialogSectionGroup {
modifier = Modifier.selectableGroup() DialogChooserRow(
) {
SettingsDialogChooserRow(
text = stringResource(R.string.feature_settings_launch_page_tools), text = stringResource(R.string.feature_settings_launch_page_tools),
selected = settings.launchPageConfig == LaunchPageConfig.TOOLS, selected = settings.launchPageConfig == LaunchPageConfig.TOOLS,
onClick = { onChangeLaunchPageConfig(LaunchPageConfig.TOOLS) } onClick = { onChangeLaunchPageConfig(LaunchPageConfig.TOOLS) }
) )
SettingsDialogChooserRow( DialogChooserRow(
text = stringResource(R.string.feature_settings_launch_page_star), text = stringResource(R.string.feature_settings_launch_page_star),
selected = settings.launchPageConfig == LaunchPageConfig.STAR, selected = settings.launchPageConfig == LaunchPageConfig.STAR,
onClick = { onChangeLaunchPageConfig(LaunchPageConfig.STAR) } onClick = { onChangeLaunchPageConfig(LaunchPageConfig.STAR) }
) )
} }
SettingsDialogSectionTitle(text = stringResource(R.string.feature_settings_theme_brand)) DialogSectionTitle(text = stringResource(R.string.feature_settings_theme_brand))
Column( DialogSectionGroup {
modifier = Modifier.selectableGroup() DialogChooserRow(
) {
SettingsDialogChooserRow(
text = stringResource(R.string.feature_settings_theme_brand_default), text = stringResource(R.string.feature_settings_theme_brand_default),
selected = settings.themeBrandConfig == ThemeBrandConfig.DEFAULT, selected = settings.themeBrandConfig == ThemeBrandConfig.DEFAULT,
onClick = { onchangeThemeBrandConfig(ThemeBrandConfig.DEFAULT) } onClick = { onchangeThemeBrandConfig(ThemeBrandConfig.DEFAULT) }
) )
SettingsDialogChooserRow( DialogChooserRow(
text = stringResource(R.string.feature_settings_theme_brand_android), text = stringResource(R.string.feature_settings_theme_brand_android),
selected = settings.themeBrandConfig == ThemeBrandConfig.ANDROID, selected = settings.themeBrandConfig == ThemeBrandConfig.ANDROID,
onClick = { onchangeThemeBrandConfig(ThemeBrandConfig.ANDROID) } onClick = { onchangeThemeBrandConfig(ThemeBrandConfig.ANDROID) }
) )
} }
AnimatedVisibility(visible = settings.themeBrandConfig == ThemeBrandConfig.DEFAULT && supportDynamicColor) { AnimatedVisibility(visible = settings.themeBrandConfig == ThemeBrandConfig.DEFAULT && supportDynamicColor) {
Column( DialogSectionGroup {
modifier = Modifier.selectableGroup() DialogSectionTitle(text = stringResource(R.string.feature_settings_dynamic_color))
) { DialogChooserRow(
SettingsDialogSectionTitle(text = stringResource(R.string.feature_settings_dynamic_color))
SettingsDialogChooserRow(
text = stringResource(R.string.feature_settings_dynamic_color_enable), text = stringResource(R.string.feature_settings_dynamic_color_enable),
selected = settings.useDynamicColor, selected = settings.useDynamicColor,
onClick = { onchangeUseDynamicColor(true) } onClick = { onchangeUseDynamicColor(true) }
) )
SettingsDialogChooserRow( DialogChooserRow(
text = stringResource(R.string.feature_settings_dynamic_color_disable), text = stringResource(R.string.feature_settings_dynamic_color_disable),
selected = !settings.useDynamicColor, selected = !settings.useDynamicColor,
onClick = { onchangeUseDynamicColor(false) } onClick = { onchangeUseDynamicColor(false) }
) )
} }
} }
SettingsDialogSectionTitle(text = stringResource(R.string.feature_settings_dark_mode)) DialogSectionTitle(text = stringResource(R.string.feature_settings_dark_mode))
Column( DialogSectionGroup {
modifier = Modifier.selectableGroup() DialogChooserRow(
) {
SettingsDialogChooserRow(
text = stringResource(R.string.feature_settings_dark_mode_system_default), text = stringResource(R.string.feature_settings_dark_mode_system_default),
selected = settings.darkThemeConfig == DarkThemeConfig.FOLLOW_SYSTEM, selected = settings.darkThemeConfig == DarkThemeConfig.FOLLOW_SYSTEM,
onClick = { onChangeDarkThemeConfig(DarkThemeConfig.FOLLOW_SYSTEM) } onClick = { onChangeDarkThemeConfig(DarkThemeConfig.FOLLOW_SYSTEM) }
) )
SettingsDialogChooserRow( DialogChooserRow(
text = stringResource(R.string.feature_settings_dark_mode_light), text = stringResource(R.string.feature_settings_dark_mode_light),
selected = settings.darkThemeConfig == DarkThemeConfig.LIGHT, selected = settings.darkThemeConfig == DarkThemeConfig.LIGHT,
onClick = { onChangeDarkThemeConfig(DarkThemeConfig.LIGHT) } onClick = { onChangeDarkThemeConfig(DarkThemeConfig.LIGHT) }
) )
SettingsDialogChooserRow( DialogChooserRow(
text = stringResource(R.string.feature_settings_dark_mode_dark), text = stringResource(R.string.feature_settings_dark_mode_dark),
selected = settings.darkThemeConfig == DarkThemeConfig.DARK, selected = settings.darkThemeConfig == DarkThemeConfig.DARK,
onClick = { onChangeDarkThemeConfig(DarkThemeConfig.DARK) } onClick = { onChangeDarkThemeConfig(DarkThemeConfig.DARK) }
) )
} }
SettingsDialogSectionTitle(text = stringResource(R.string.feature_settings_more)) DialogSectionTitle(text = stringResource(R.string.feature_settings_more))
Column( DialogSectionGroup {
modifier = Modifier.selectableGroup() DialogClickerRow(
) {
SettingsDialogClickerRow(
icon = OxygenIcons.Code, icon = OxygenIcons.Code,
text = stringResource(R.string.feature_settings_open_source_license), text = stringResource(R.string.feature_settings_open_source_license),
onClick = { onClick = {
@@ -276,7 +258,7 @@ private fun ColumnScope.SettingsPanel(
onDismiss() onDismiss()
} }
) )
SettingsDialogClickerRow( DialogClickerRow(
icon = OxygenIcons.Info, icon = OxygenIcons.Info,
text = stringResource(R.string.feature_settings_more_about), text = stringResource(R.string.feature_settings_more_about),
onClick = { onClick = {
@@ -287,61 +269,6 @@ private fun ColumnScope.SettingsPanel(
} }
} }
@Composable
private fun SettingsDialogSectionTitle(text: String) {
Text(
modifier = Modifier.padding(top = 16.dp, bottom = 8.dp),
text = text,
style = MaterialTheme.typography.titleMedium
)
}
@Composable
private fun SettingsDialogChooserRow(
text: String,
selected: Boolean,
onClick: () -> Unit
) {
Row(
modifier = Modifier
.fillMaxSize()
.selectable(
selected = selected,
role = Role.RadioButton,
onClick = onClick
)
.padding(12.dp),
verticalAlignment = Alignment.CenterVertically
) {
RadioButton(
selected = selected,
onClick = null
)
Spacer(modifier = Modifier.width(8.dp))
Text(text)
}
}
@Composable
private fun SettingsDialogClickerRow(
icon: ImageVector? = null,
text: String,
onClick: () -> Unit
) {
Row(
modifier = Modifier
.fillMaxSize()
.clickable(
onClick = onClick
)
.padding(12.dp),
verticalAlignment = Alignment.CenterVertically
) {
Icon(imageVector = icon ?: OxygenIcons.Reorder, contentDescription = null)
Spacer(modifier = Modifier.width(8.dp))
Text(text)
}
}
@OxygenPreviews @OxygenPreviews
@Composable @Composable