From ce97976bdd1801bb906689ddbb8ef0dec2c7046b Mon Sep 17 00:00:00 2001 From: FooIbar <118464521+FooIbar@users.noreply.github.com> Date: Mon, 6 May 2024 23:01:40 +0800 Subject: [PATCH] Refactor bottom bar icon dropdown menus in reader Avoid hard-coded width and offset. --- .../tachiyomi/ui/reader/BottomReaderBar.kt | 137 +++++++++--------- .../ui/reader/setting/OrientationType.kt | 9 +- .../ui/reader/setting/PreferenceType.kt | 15 ++ .../ui/reader/setting/ReadingModeType.kt | 8 +- 4 files changed, 97 insertions(+), 72 deletions(-) create mode 100644 app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/setting/PreferenceType.kt diff --git a/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/BottomReaderBar.kt b/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/BottomReaderBar.kt index a44b4bd08..e8f0a78df 100644 --- a/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/BottomReaderBar.kt +++ b/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/BottomReaderBar.kt @@ -3,20 +3,19 @@ package eu.kanade.tachiyomi.ui.reader import androidx.compose.foundation.background import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Check import androidx.compose.material.icons.outlined.Settings -import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ExposedDropdownMenuBox import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.MenuAnchorType import androidx.compose.material3.Text import androidx.compose.material3.surfaceColorAtElevation import androidx.compose.runtime.Composable @@ -27,7 +26,6 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.dp import com.hippo.ehviewer.R import com.hippo.ehviewer.Settings @@ -37,81 +35,38 @@ import com.hippo.ehviewer.icons.EhIcons import com.hippo.ehviewer.icons.filled.Crop import com.hippo.ehviewer.icons.filled.CropOff import eu.kanade.tachiyomi.ui.reader.setting.OrientationType +import eu.kanade.tachiyomi.ui.reader.setting.PreferenceType import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType @Composable fun BottomReaderBar(onClickSettings: () -> Unit) { // Match with toolbar background color set in ReaderActivity - val backgroundColor = MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp).copy(alpha = if (isSystemInDarkTheme()) 0.9f else 0.95f) - - val readingMode by Settings.readingMode.collectAsState { ReadingModeType.fromPreference(it) } - var readingModeExpanded by remember { mutableStateOf(false) } - Box { - DropdownMenu( - readingModeExpanded, - onDismissRequest = { readingModeExpanded = false }, - ) { - ReadingModeType.entries.forEach { - DropdownMenuItem( - text = { Text(stringResource(it.stringRes)) }, - onClick = { - Settings.readingMode.value = it.flagValue - readingModeExpanded = false - }, - modifier = Modifier.width(192.dp), - leadingIcon = { - if (readingMode == it) { - Icon(imageVector = Icons.Default.Check, contentDescription = null) - } - }, - ) - } - } - } - - val orientationMode by Settings.orientationMode.collectAsState { OrientationType.fromPreference(it) } - var orientationModeExpanded by remember { mutableStateOf(false) } - Box { - DropdownMenu( - orientationModeExpanded, - onDismissRequest = { orientationModeExpanded = false }, - offset = DpOffset(320.dp, 0.dp), - ) { - OrientationType.entries.forEach { - DropdownMenuItem( - text = { Text(stringResource(it.stringRes)) }, - onClick = { - Settings.orientationMode.value = it.flagValue - orientationModeExpanded = false - }, - modifier = Modifier.width(192.dp), - leadingIcon = { - if (orientationMode == it) { - Icon(imageVector = Icons.Default.Check, contentDescription = null) - } - }, - ) - } - } - } + val backgroundColor = MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp) + .copy(alpha = if (isSystemInDarkTheme()) 0.9f else 0.95f) Row( modifier = Modifier.fillMaxWidth().background(backgroundColor).padding(8.dp).navigationBarsPadding(), horizontalArrangement = Arrangement.SpaceEvenly, verticalAlignment = Alignment.CenterVertically, ) { - IconButton(onClick = { readingModeExpanded = true }) { - Icon( - imageVector = readingMode.icon, - contentDescription = stringResource(R.string.viewer), - ) - } - IconButton(onClick = { orientationModeExpanded = true }) { - Icon( - imageVector = orientationMode.icon, - contentDescription = stringResource(R.string.pref_rotation_type), - ) - } + val readingMode by Settings.readingMode.collectAsState { ReadingModeType.fromPreference(it) } + DropdownIconButton( + label = stringResource(R.string.viewer), + menuItems = ReadingModeType.entries, + selectedItem = readingMode, + onSelectedItemChange = { + Settings.readingMode.value = it.flagValue + }, + ) + val orientationMode by Settings.orientationMode.collectAsState { OrientationType.fromPreference(it) } + DropdownIconButton( + label = stringResource(R.string.pref_rotation_type), + menuItems = OrientationType.entries, + selectedItem = orientationMode, + onSelectedItemChange = { + Settings.orientationMode.value = it.flagValue + }, + ) var cropBorder by Settings.cropBorder.asMutableState() IconButton(onClick = { cropBorder = !cropBorder }) { Icon( @@ -127,3 +82,49 @@ fun BottomReaderBar(onClickSettings: () -> Unit) { } } } + +@Composable +private fun DropdownIconButton( + label: String, + menuItems: List, + selectedItem: PreferenceType, + onSelectedItemChange: (PreferenceType) -> Unit, + modifier: Modifier = Modifier, +) { + var expanded by remember { mutableStateOf(false) } + ExposedDropdownMenuBox( + expanded = expanded, + onExpandedChange = { expanded = it }, + modifier = modifier, + ) { + IconButton( + onClick = {}, + modifier = Modifier.menuAnchor(MenuAnchorType.PrimaryNotEditable), + ) { + Icon( + imageVector = selectedItem.icon, + contentDescription = label, + ) + } + ExposedDropdownMenu( + expanded = expanded, + onDismissRequest = { expanded = false }, + matchTextFieldWidth = false, + ) { + menuItems.forEach { + DropdownMenuItem( + text = { Text(stringResource(it.stringRes)) }, + onClick = { + expanded = false + onSelectedItemChange(it) + }, + leadingIcon = { + if (selectedItem == it) { + Icon(imageVector = Icons.Default.Check, contentDescription = null) + } + }, + ) + } + } + } +} diff --git a/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/setting/OrientationType.kt b/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/setting/OrientationType.kt index 076e718e8..e50892a35 100644 --- a/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/setting/OrientationType.kt +++ b/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/setting/OrientationType.kt @@ -1,7 +1,6 @@ package eu.kanade.tachiyomi.ui.reader.setting import android.content.pm.ActivityInfo -import androidx.annotation.StringRes import androidx.compose.ui.graphics.vector.ImageVector import com.hippo.ehviewer.R import com.hippo.ehviewer.icons.EhIcons @@ -11,7 +10,13 @@ import com.hippo.ehviewer.icons.reader.Portrait import com.hippo.ehviewer.icons.reader.PortraitLocked import com.hippo.ehviewer.icons.reader.ScreenRotation -enum class OrientationType(val prefValue: Int, val flag: Int, @StringRes val stringRes: Int, val icon: ImageVector, val flagValue: Int) { +enum class OrientationType( + override val prefValue: Int, + val flag: Int, + override val stringRes: Int, + override val icon: ImageVector, + override val flagValue: Int, +) : PreferenceType { DEFAULT(0, ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED, R.string.label_default, EhIcons.Reader.ScreenRotation, 0x00000000), FREE(1, ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED, R.string.rotation_free, EhIcons.Reader.ScreenRotation, 0x00000008), PORTRAIT(2, ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT, R.string.rotation_portrait, EhIcons.Reader.Portrait, 0x00000010), diff --git a/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/setting/PreferenceType.kt b/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/setting/PreferenceType.kt new file mode 100644 index 000000000..93c25fb07 --- /dev/null +++ b/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/setting/PreferenceType.kt @@ -0,0 +1,15 @@ +package eu.kanade.tachiyomi.ui.reader.setting + +import androidx.annotation.StringRes +import androidx.compose.ui.graphics.vector.ImageVector + +interface PreferenceType { + val prefValue: Int + + @get:StringRes + val stringRes: Int + + val icon: ImageVector + + val flagValue: Int +} diff --git a/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/setting/ReadingModeType.kt b/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/setting/ReadingModeType.kt index 28ee20fc7..ae656977b 100644 --- a/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/setting/ReadingModeType.kt +++ b/app/src/main/kotlin/eu/kanade/tachiyomi/ui/reader/setting/ReadingModeType.kt @@ -1,6 +1,5 @@ package eu.kanade.tachiyomi.ui.reader.setting -import androidx.annotation.StringRes import androidx.compose.runtime.Stable import androidx.compose.ui.graphics.vector.ImageVector import com.hippo.ehviewer.R @@ -19,7 +18,12 @@ import eu.kanade.tachiyomi.ui.reader.viewer.pager.VerticalPagerViewer import eu.kanade.tachiyomi.ui.reader.viewer.webtoon.WebtoonViewer @Stable -enum class ReadingModeType(val prefValue: Int, @StringRes val stringRes: Int, val icon: ImageVector, val flagValue: Int) { +enum class ReadingModeType( + override val prefValue: Int, + override val stringRes: Int, + override val icon: ImageVector, + override val flagValue: Int, +) : PreferenceType { DEFAULT(0, R.string.label_default, EhIcons.Reader.Default, 0x00000000), LEFT_TO_RIGHT(1, R.string.left_to_right_viewer, EhIcons.Reader.LeftToRight, 0x00000001), RIGHT_TO_LEFT(2, R.string.right_to_left_viewer, EhIcons.Reader.RightToLeft, 0x00000002),