Refactor(SettingDialog): Componentized settings page elements
This commit is contained in:
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user