Add slider for changing columns (#9421)

- It changes the columns based on the current orientation
This commit is contained in:
Andreas 2023-04-28 21:13:41 +02:00 committed by GitHub
parent ccd4143d9d
commit 7451c13edd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 56 additions and 154 deletions

View File

@ -1,126 +0,0 @@
package eu.kanade.presentation.library
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.saveable.rememberSaveable
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.text.style.TextAlign
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import eu.kanade.tachiyomi.R
import tachiyomi.presentation.core.components.WheelPickerDefaults
import tachiyomi.presentation.core.components.WheelTextPicker
@Composable
fun LibraryColumnsDialog(
initialPortrait: Int,
initialLandscape: Int,
onDismissRequest: () -> Unit,
onValueChanged: (portrait: Int, landscape: Int) -> Unit,
) {
var portraitValue by rememberSaveable { mutableStateOf(initialPortrait) }
var landscapeValue by rememberSaveable { mutableStateOf(initialLandscape) }
AlertDialog(
onDismissRequest = onDismissRequest,
title = { Text(text = stringResource(R.string.pref_library_columns)) },
text = {
Column {
Row {
Text(
modifier = Modifier.weight(1f),
text = stringResource(R.string.portrait),
textAlign = TextAlign.Center,
maxLines = 1,
style = MaterialTheme.typography.labelMedium,
)
Text(
modifier = Modifier.weight(1f),
text = stringResource(R.string.landscape),
textAlign = TextAlign.Center,
maxLines = 1,
style = MaterialTheme.typography.labelMedium,
)
}
LibraryColumnsPicker(
modifier = Modifier.fillMaxWidth(),
portraitValue = portraitValue,
onPortraitChange = { portraitValue = it },
landscapeValue = landscapeValue,
onLandscapeChange = { landscapeValue = it },
)
}
},
dismissButton = {
TextButton(onClick = onDismissRequest) {
Text(text = stringResource(R.string.action_cancel))
}
},
confirmButton = {
TextButton(
enabled = portraitValue != initialPortrait || landscapeValue != initialLandscape,
onClick = { onValueChanged(portraitValue, landscapeValue) },
) {
Text(text = stringResource(android.R.string.ok))
}
},
)
}
@Composable
private fun LibraryColumnsPicker(
modifier: Modifier = Modifier,
portraitValue: Int,
onPortraitChange: (Int) -> Unit,
landscapeValue: Int,
onLandscapeChange: (Int) -> Unit,
) {
BoxWithConstraints(
modifier = modifier,
contentAlignment = Alignment.Center,
) {
WheelPickerDefaults.Background(size = DpSize(maxWidth, 128.dp))
val size = DpSize(width = maxWidth / 2, height = 128.dp)
Row {
val columns = (0..10).map { getColumnValue(value = it) }
WheelTextPicker(
startIndex = portraitValue,
items = columns,
size = size,
onSelectionChanged = onPortraitChange,
backgroundContent = null,
)
WheelTextPicker(
startIndex = landscapeValue,
items = columns,
size = size,
onSelectionChanged = onLandscapeChange,
backgroundContent = null,
)
}
}
}
@Composable
@ReadOnlyComposable
private fun getColumnValue(value: Int): String {
return if (value == 0) {
stringResource(R.string.label_default)
} else {
value.toString()
}
}

View File

@ -1,25 +1,34 @@
package eu.kanade.presentation.library package eu.kanade.presentation.library
import android.content.res.Configuration
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.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons import androidx.compose.material3.MaterialTheme
import androidx.compose.material.icons.outlined.Apps import androidx.compose.material3.Slider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.components.TabbedDialog import eu.kanade.presentation.components.TabbedDialog
import eu.kanade.presentation.components.TabbedDialogPaddings import eu.kanade.presentation.components.TabbedDialogPaddings
import eu.kanade.presentation.components.TriStateItem import eu.kanade.presentation.components.TriStateItem
import eu.kanade.presentation.util.collectAsState import eu.kanade.presentation.util.collectAsState
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.library.LibrarySettingsScreenModel import eu.kanade.tachiyomi.ui.library.LibrarySettingsScreenModel
import kotlinx.coroutines.flow.map
import tachiyomi.domain.category.model.Category import tachiyomi.domain.category.model.Category
import tachiyomi.domain.library.model.LibraryDisplayMode import tachiyomi.domain.library.model.LibraryDisplayMode
import tachiyomi.domain.library.model.LibrarySort import tachiyomi.domain.library.model.LibrarySort
@ -29,8 +38,8 @@ import tachiyomi.domain.library.service.LibraryPreferences
import tachiyomi.domain.manga.model.TriStateFilter import tachiyomi.domain.manga.model.TriStateFilter
import tachiyomi.presentation.core.components.CheckboxItem import tachiyomi.presentation.core.components.CheckboxItem
import tachiyomi.presentation.core.components.HeadingItem import tachiyomi.presentation.core.components.HeadingItem
import tachiyomi.presentation.core.components.IconItem
import tachiyomi.presentation.core.components.RadioItem import tachiyomi.presentation.core.components.RadioItem
import tachiyomi.presentation.core.components.SettingsItemsPaddings
import tachiyomi.presentation.core.components.SortItem import tachiyomi.presentation.core.components.SortItem
@Composable @Composable
@ -176,23 +185,6 @@ private fun ColumnScope.DisplayPage(
category: Category, category: Category,
screenModel: LibrarySettingsScreenModel, screenModel: LibrarySettingsScreenModel,
) { ) {
val portraitColumns by screenModel.libraryPreferences.portraitColumns().collectAsState()
val landscapeColumns by screenModel.libraryPreferences.landscapeColumns().collectAsState()
var showColumnsDialog by rememberSaveable { mutableStateOf(false) }
if (showColumnsDialog) {
LibraryColumnsDialog(
initialPortrait = portraitColumns,
initialLandscape = landscapeColumns,
onDismissRequest = { showColumnsDialog = false },
onValueChanged = { portrait, landscape ->
screenModel.libraryPreferences.portraitColumns().set(portrait)
screenModel.libraryPreferences.landscapeColumns().set(landscape)
showColumnsDialog = false
},
)
}
HeadingItem(R.string.action_display_mode) HeadingItem(R.string.action_display_mode)
listOf( listOf(
R.string.action_display_grid to LibraryDisplayMode.CompactGrid, R.string.action_display_grid to LibraryDisplayMode.CompactGrid,
@ -208,11 +200,46 @@ private fun ColumnScope.DisplayPage(
} }
if (category.display != LibraryDisplayMode.List) { if (category.display != LibraryDisplayMode.List) {
IconItem( Row(
label = stringResource(R.string.pref_library_columns), modifier = Modifier
icon = Icons.Outlined.Apps, .fillMaxWidth()
onClick = { showColumnsDialog = true }, .padding(
horizontal = SettingsItemsPaddings.Horizontal,
vertical = SettingsItemsPaddings.Vertical,
),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(24.dp),
) {
val configuration = LocalConfiguration.current
val columnPreference = remember {
if (configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
screenModel.libraryPreferences.landscapeColumns()
} else {
screenModel.libraryPreferences.portraitColumns()
}
}
val columns by columnPreference.changes().collectAsState(initial = 0)
Column {
Text(
stringResource(id = R.string.pref_library_columns),
style = MaterialTheme.typography.bodyMedium,
) )
if (columns > 0) {
Text(stringResource(id = R.string.pref_library_columns_per_row, columns))
} else {
Text(stringResource(id = R.string.label_default))
}
}
Slider(
value = columns.toFloat(),
onValueChange = { columnPreference.set(it.toInt()) },
modifier = Modifier.weight(1f),
valueRange = 0f..10f,
steps = 10,
)
}
} }
HeadingItem(R.string.overlay_header) HeadingItem(R.string.overlay_header)

View File

@ -230,7 +230,8 @@
<!-- Library section --> <!-- Library section -->
<string name="pref_category_display">Display</string> <string name="pref_category_display">Display</string>
<string name="pref_library_columns">Items per row</string> <string name="pref_library_columns">Grid size</string>
<string name="pref_library_columns_per_row">%d per row</string>
<string name="portrait">Portrait</string> <string name="portrait">Portrait</string>
<string name="landscape">Landscape</string> <string name="landscape">Landscape</string>