mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 23:51:21 +02:00
Display size page polish: tick-slider control, typography lock, richer preview
Settings panel layout flipped: preview now occupies the left two-thirds of the page (nav rail at the natural app-left position), settings panel sits on the right at 300dp wide. Mirrors the real home-screen layout so the preview reads as a true reflection of what the user will see. Replaces the popup ChoicePreference selector with an inline tick-slider per control. Each slider is a chunky 24dp rounded track using surfaceVariant for the inactive background and primary for the thumb; the thumb is a rounded pill that snaps to one of four slot centers and fills 88% of the track height. D-pad LEFT/RIGHT cycles slots within the focused control; UP/DOWN moves between controls. Selection commits on focus change so the preview updates without an extra Enter press. Wraps the settings panel in a nested MaterialTheme using the unscaled AppTypography (both tv.material3 and compose.material3 flavors) so the panel's own labels stay at base size regardless of the Text size level the user picks. Without this nesting the panel chrome reflowed under the user's fingers as they cycled levels. Preview now uses SlimItemFields when fetching, so the Overview text populates on the hero. Episodes row is rendered first (matching the real home-screen ordering) so the hero defaults to an episode item, which exercises the full hero surface (title + episode name + overview + quick details). TimeDisplay is drawn over the preview area when the user's showClock preference is enabled. Text-size jumps are tuned wider: ExtraSmall 84% (was 88), Small 92% (was 94), Large 116% (was 108). Default stays at 100%. The hand-mapped sp lookup is regenerated for these percentages. scaledSp falls back to integer-rounded formula math instead of throwing on unmapped base sp values, so the helper is safe to call from any fontSize site without first extending the table.
This commit is contained in:
parent
ca8ed52cf0
commit
8ff97daf44
2 changed files with 174 additions and 82 deletions
|
|
@ -19,17 +19,17 @@ fun DisplaySizeLevel.scaledSp(baseSp: Int): TextUnit {
|
||||||
when (this) {
|
when (this) {
|
||||||
DisplaySizeLevel.EXTRA_SMALL -> {
|
DisplaySizeLevel.EXTRA_SMALL -> {
|
||||||
when (baseSp) {
|
when (baseSp) {
|
||||||
10 -> 9
|
10 -> 8
|
||||||
12 -> 11
|
12 -> 10
|
||||||
13 -> 11
|
13 -> 11
|
||||||
14 -> 12
|
14 -> 12
|
||||||
16 -> 14
|
16 -> 13
|
||||||
18 -> 16
|
18 -> 15
|
||||||
20 -> 18
|
20 -> 17
|
||||||
24 -> 21
|
24 -> 20
|
||||||
28 -> 25
|
28 -> 24
|
||||||
56 -> 49
|
56 -> 47
|
||||||
64 -> 56
|
64 -> 54
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -42,28 +42,28 @@ fun DisplaySizeLevel.scaledSp(baseSp: Int): TextUnit {
|
||||||
14 -> 13
|
14 -> 13
|
||||||
16 -> 15
|
16 -> 15
|
||||||
18 -> 17
|
18 -> 17
|
||||||
20 -> 19
|
20 -> 18
|
||||||
24 -> 23
|
24 -> 22
|
||||||
28 -> 26
|
28 -> 26
|
||||||
56 -> 53
|
56 -> 52
|
||||||
64 -> 60
|
64 -> 59
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplaySizeLevel.LARGE -> {
|
DisplaySizeLevel.LARGE -> {
|
||||||
when (baseSp) {
|
when (baseSp) {
|
||||||
10 -> 11
|
10 -> 12
|
||||||
12 -> 13
|
12 -> 14
|
||||||
13 -> 14
|
13 -> 15
|
||||||
14 -> 15
|
14 -> 16
|
||||||
16 -> 17
|
16 -> 19
|
||||||
18 -> 19
|
18 -> 21
|
||||||
20 -> 22
|
20 -> 23
|
||||||
24 -> 26
|
24 -> 28
|
||||||
28 -> 30
|
28 -> 32
|
||||||
56 -> 60
|
56 -> 65
|
||||||
64 -> 69
|
64 -> 74
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -77,9 +77,9 @@ fun DisplaySizeLevel.scaledSp(baseSp: Int): TextUnit {
|
||||||
|
|
||||||
fun DisplaySizeLevel.textPercent(): Int =
|
fun DisplaySizeLevel.textPercent(): Int =
|
||||||
when (this) {
|
when (this) {
|
||||||
DisplaySizeLevel.EXTRA_SMALL -> 88
|
DisplaySizeLevel.EXTRA_SMALL -> 84
|
||||||
DisplaySizeLevel.SMALL -> 94
|
DisplaySizeLevel.SMALL -> 92
|
||||||
DisplaySizeLevel.LARGE -> 108
|
DisplaySizeLevel.LARGE -> 116
|
||||||
DisplaySizeLevel.DEFAULT, DisplaySizeLevel.UNRECOGNIZED -> 100
|
DisplaySizeLevel.DEFAULT, DisplaySizeLevel.UNRECOGNIZED -> 100
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
package com.github.damontecres.wholphin.ui.preferences.displaysize
|
package com.github.damontecres.wholphin.ui.preferences.displaysize
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Canvas
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.focusable
|
||||||
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
|
import androidx.compose.foundation.interaction.collectIsFocusedAsState
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
|
@ -14,6 +18,7 @@ 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.width
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Add
|
import androidx.compose.material.icons.filled.Add
|
||||||
import androidx.compose.material.icons.filled.Favorite
|
import androidx.compose.material.icons.filled.Favorite
|
||||||
|
|
@ -35,6 +40,10 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.focus.focusRestorer
|
import androidx.compose.ui.focus.focusRestorer
|
||||||
|
import androidx.compose.ui.geometry.CornerRadius
|
||||||
|
import androidx.compose.ui.geometry.Offset
|
||||||
|
import androidx.compose.ui.geometry.Size
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.res.stringArrayResource
|
import androidx.compose.ui.res.stringArrayResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
|
@ -44,6 +53,7 @@ import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import androidx.tv.material3.Icon
|
import androidx.tv.material3.Icon
|
||||||
import androidx.tv.material3.MaterialTheme
|
import androidx.tv.material3.MaterialTheme
|
||||||
|
import androidx.tv.material3.contentColorFor
|
||||||
import com.github.damontecres.wholphin.R
|
import com.github.damontecres.wholphin.R
|
||||||
import com.github.damontecres.wholphin.data.model.BaseItem
|
import com.github.damontecres.wholphin.data.model.BaseItem
|
||||||
import com.github.damontecres.wholphin.preferences.AppChoicePreference
|
import com.github.damontecres.wholphin.preferences.AppChoicePreference
|
||||||
|
|
@ -52,13 +62,18 @@ import com.github.damontecres.wholphin.preferences.AppPreferences
|
||||||
import com.github.damontecres.wholphin.preferences.DisplaySizeLevel
|
import com.github.damontecres.wholphin.preferences.DisplaySizeLevel
|
||||||
import com.github.damontecres.wholphin.preferences.updateInterfacePreferences
|
import com.github.damontecres.wholphin.preferences.updateInterfacePreferences
|
||||||
import com.github.damontecres.wholphin.services.BackdropService
|
import com.github.damontecres.wholphin.services.BackdropService
|
||||||
|
import com.github.damontecres.wholphin.ui.SlimItemFields
|
||||||
|
import com.github.damontecres.wholphin.ui.components.TimeDisplay
|
||||||
import com.github.damontecres.wholphin.ui.data.RowColumn
|
import com.github.damontecres.wholphin.ui.data.RowColumn
|
||||||
|
import com.github.damontecres.wholphin.ui.handleDPadKeyEvents
|
||||||
import com.github.damontecres.wholphin.ui.launchIO
|
import com.github.damontecres.wholphin.ui.launchIO
|
||||||
import com.github.damontecres.wholphin.ui.main.HomePageContent
|
import com.github.damontecres.wholphin.ui.main.HomePageContent
|
||||||
import com.github.damontecres.wholphin.ui.main.settings.TitleText
|
import com.github.damontecres.wholphin.ui.main.settings.TitleText
|
||||||
import com.github.damontecres.wholphin.ui.main.settings.settingsWidth
|
import com.github.damontecres.wholphin.ui.preferences.PreferenceSummary
|
||||||
import com.github.damontecres.wholphin.ui.preferences.ChoicePreference
|
import com.github.damontecres.wholphin.ui.preferences.PreferenceTitle
|
||||||
import com.github.damontecres.wholphin.ui.preferences.PreferencesViewModel
|
import com.github.damontecres.wholphin.ui.preferences.PreferencesViewModel
|
||||||
|
import com.github.damontecres.wholphin.ui.theme.AppTypography
|
||||||
|
import com.github.damontecres.wholphin.ui.theme.toMaterialTypography
|
||||||
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
import com.github.damontecres.wholphin.ui.tryRequestFocus
|
||||||
import com.github.damontecres.wholphin.ui.util.ResStringProvider
|
import com.github.damontecres.wholphin.ui.util.ResStringProvider
|
||||||
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
import com.github.damontecres.wholphin.util.HomeRowLoadingState
|
||||||
|
|
@ -79,6 +94,7 @@ private const val PREVIEW_EPISODE_COUNT = 4
|
||||||
private val PREVIEW_NAV_RAIL_WIDTH_DP = 64.dp
|
private val PREVIEW_NAV_RAIL_WIDTH_DP = 64.dp
|
||||||
private val PREVIEW_NAV_ITEM_HEIGHT_DP = 56.dp
|
private val PREVIEW_NAV_ITEM_HEIGHT_DP = 56.dp
|
||||||
private val PREVIEW_NAV_ICON_SIZE_DP = 24.dp
|
private val PREVIEW_NAV_ICON_SIZE_DP = 24.dp
|
||||||
|
private val DisplaySizeSettingsWidth = 300.dp
|
||||||
|
|
||||||
private val PreviewNavRailIcons: List<ImageVector> =
|
private val PreviewNavRailIcons: List<ImageVector> =
|
||||||
listOf(
|
listOf(
|
||||||
|
|
@ -127,6 +143,7 @@ class DisplaySizeViewModel
|
||||||
sortBy = listOf(ItemSortBy.DATE_CREATED),
|
sortBy = listOf(ItemSortBy.DATE_CREATED),
|
||||||
sortOrder = listOf(SortOrder.DESCENDING),
|
sortOrder = listOf(SortOrder.DESCENDING),
|
||||||
limit = limit,
|
limit = limit,
|
||||||
|
fields = SlimItemFields,
|
||||||
)
|
)
|
||||||
val result = api.itemsApi.getItems(request).content
|
val result = api.itemsApi.getItems(request).content
|
||||||
val items = (result.items ?: emptyList()).map { BaseItem.from(it, api, false) }
|
val items = (result.items ?: emptyList()).map { BaseItem.from(it, api, false) }
|
||||||
|
|
@ -158,42 +175,6 @@ fun DisplaySizePage(
|
||||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
modifier = modifier.fillMaxSize(),
|
modifier = modifier.fillMaxSize(),
|
||||||
) {
|
) {
|
||||||
Box(
|
|
||||||
modifier =
|
|
||||||
Modifier
|
|
||||||
.width(settingsWidth)
|
|
||||||
.fillMaxHeight()
|
|
||||||
.background(color = MaterialTheme.colorScheme.surface)
|
|
||||||
.padding(8.dp),
|
|
||||||
) {
|
|
||||||
DisplaySizeSettingsColumn(
|
|
||||||
textLevel = iface.textSizeLevel,
|
|
||||||
cardLevel = iface.cardSizeLevel,
|
|
||||||
spacingLevel = iface.spacingLevel,
|
|
||||||
onChangeTextLevel = { value ->
|
|
||||||
scope.launch {
|
|
||||||
viewModel.preferenceDataStore.updateData {
|
|
||||||
it.updateInterfacePreferences { textSizeLevel = value }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onChangeCardLevel = { value ->
|
|
||||||
scope.launch {
|
|
||||||
viewModel.preferenceDataStore.updateData {
|
|
||||||
it.updateInterfacePreferences { cardSizeLevel = value }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onChangeSpacingLevel = { value ->
|
|
||||||
scope.launch {
|
|
||||||
viewModel.preferenceDataStore.updateData {
|
|
||||||
it.updateInterfacePreferences { spacingLevel = value }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier =
|
modifier =
|
||||||
Modifier
|
Modifier
|
||||||
|
|
@ -206,6 +187,51 @@ fun DisplaySizePage(
|
||||||
showLogos = iface.showLogos,
|
showLogos = iface.showLogos,
|
||||||
onUpdateBackdrop = previewViewModel::updateBackdrop,
|
onUpdateBackdrop = previewViewModel::updateBackdrop,
|
||||||
)
|
)
|
||||||
|
if (iface.showClock) {
|
||||||
|
TimeDisplay()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.width(DisplaySizeSettingsWidth)
|
||||||
|
.fillMaxHeight()
|
||||||
|
.background(color = MaterialTheme.colorScheme.surface)
|
||||||
|
.padding(8.dp),
|
||||||
|
) {
|
||||||
|
// Lock the settings-panel chrome to base typography so its labels
|
||||||
|
// don't reflow under the user as they cycle Text size levels.
|
||||||
|
androidx.compose.material3.MaterialTheme(typography = AppTypography.toMaterialTypography()) {
|
||||||
|
MaterialTheme(typography = AppTypography) {
|
||||||
|
DisplaySizeSettingsColumn(
|
||||||
|
textLevel = iface.textSizeLevel,
|
||||||
|
cardLevel = iface.cardSizeLevel,
|
||||||
|
spacingLevel = iface.spacingLevel,
|
||||||
|
onChangeTextLevel = { value ->
|
||||||
|
scope.launch {
|
||||||
|
viewModel.preferenceDataStore.updateData {
|
||||||
|
it.updateInterfacePreferences { textSizeLevel = value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onChangeCardLevel = { value ->
|
||||||
|
scope.launch {
|
||||||
|
viewModel.preferenceDataStore.updateData {
|
||||||
|
it.updateInterfacePreferences { cardSizeLevel = value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onChangeSpacingLevel = { value ->
|
||||||
|
scope.launch {
|
||||||
|
viewModel.preferenceDataStore.updateData {
|
||||||
|
it.updateInterfacePreferences { spacingLevel = value }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -225,15 +251,15 @@ private fun DisplaySizeSettingsColumn(
|
||||||
Column(modifier = Modifier.fillMaxSize()) {
|
Column(modifier = Modifier.fillMaxSize()) {
|
||||||
TitleText(stringResource(R.string.display_size))
|
TitleText(stringResource(R.string.display_size))
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||||
contentPadding = PaddingValues(horizontal = 8.dp),
|
contentPadding = PaddingValues(horizontal = 8.dp, vertical = 8.dp),
|
||||||
modifier =
|
modifier =
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxHeight()
|
.fillMaxHeight()
|
||||||
.focusRestorer(firstFocus),
|
.focusRestorer(firstFocus),
|
||||||
) {
|
) {
|
||||||
item {
|
item {
|
||||||
LevelChoicePreference(
|
LevelTickSlider(
|
||||||
preference = AppPreference.TextSize,
|
preference = AppPreference.TextSize,
|
||||||
currentValue = textLevel,
|
currentValue = textLevel,
|
||||||
onChange = onChangeTextLevel,
|
onChange = onChangeTextLevel,
|
||||||
|
|
@ -241,14 +267,14 @@ private fun DisplaySizeSettingsColumn(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
LevelChoicePreference(
|
LevelTickSlider(
|
||||||
preference = AppPreference.CardSize,
|
preference = AppPreference.CardSize,
|
||||||
currentValue = cardLevel,
|
currentValue = cardLevel,
|
||||||
onChange = onChangeCardLevel,
|
onChange = onChangeCardLevel,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
item {
|
item {
|
||||||
LevelChoicePreference(
|
LevelTickSlider(
|
||||||
preference = AppPreference.Spacing,
|
preference = AppPreference.Spacing,
|
||||||
currentValue = spacingLevel,
|
currentValue = spacingLevel,
|
||||||
onChange = onChangeSpacingLevel,
|
onChange = onChangeSpacingLevel,
|
||||||
|
|
@ -259,22 +285,88 @@ private fun DisplaySizeSettingsColumn(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun LevelChoicePreference(
|
private fun LevelTickSlider(
|
||||||
preference: AppChoicePreference<AppPreferences, DisplaySizeLevel>,
|
preference: AppChoicePreference<AppPreferences, DisplaySizeLevel>,
|
||||||
currentValue: DisplaySizeLevel,
|
currentValue: DisplaySizeLevel,
|
||||||
onChange: (DisplaySizeLevel) -> Unit,
|
onChange: (DisplaySizeLevel) -> Unit,
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
val levelNames = stringArrayResource(preference.displayValues).toList()
|
val labels = stringArrayResource(preference.displayValues).toList()
|
||||||
val selectedIndex = preference.valueToIndex(currentValue)
|
val tickCount = labels.size
|
||||||
ChoicePreference(
|
val currentIndex = preference.valueToIndex(currentValue).coerceIn(0, tickCount - 1)
|
||||||
title = stringResource(preference.title),
|
val interactionSource = remember { MutableInteractionSource() }
|
||||||
summary = levelNames.getOrNull(selectedIndex),
|
val focused by interactionSource.collectIsFocusedAsState()
|
||||||
possibleValues = levelNames,
|
val background =
|
||||||
selectedIndex = selectedIndex,
|
if (focused) MaterialTheme.colorScheme.inverseSurface else Color.Unspecified
|
||||||
onValueChange = { onChange(preference.indexToValue(it)) },
|
val contentColor = contentColorFor(background)
|
||||||
modifier = modifier,
|
val activeColor = MaterialTheme.colorScheme.primary
|
||||||
)
|
val inactiveColor = MaterialTheme.colorScheme.surfaceVariant
|
||||||
|
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||||
|
modifier =
|
||||||
|
modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.background(background, shape = RoundedCornerShape(8.dp))
|
||||||
|
.padding(horizontal = 12.dp, vertical = 10.dp)
|
||||||
|
.handleDPadKeyEvents(
|
||||||
|
onLeft = {
|
||||||
|
if (currentIndex > 0) {
|
||||||
|
onChange(preference.indexToValue(currentIndex - 1))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRight = {
|
||||||
|
if (currentIndex < tickCount - 1) {
|
||||||
|
onChange(preference.indexToValue(currentIndex + 1))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
).focusable(interactionSource = interactionSource),
|
||||||
|
) {
|
||||||
|
PreferenceTitle(stringResource(preference.title), color = contentColor)
|
||||||
|
ScrollbarTrack(
|
||||||
|
currentIndex = currentIndex,
|
||||||
|
tickCount = tickCount,
|
||||||
|
activeColor = activeColor,
|
||||||
|
inactiveColor = inactiveColor,
|
||||||
|
modifier =
|
||||||
|
Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(24.dp),
|
||||||
|
)
|
||||||
|
PreferenceSummary(labels.getOrNull(currentIndex), color = contentColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun ScrollbarTrack(
|
||||||
|
currentIndex: Int,
|
||||||
|
tickCount: Int,
|
||||||
|
activeColor: Color,
|
||||||
|
inactiveColor: Color,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
) {
|
||||||
|
Canvas(modifier = modifier) {
|
||||||
|
val trackRadius = size.height / 2f
|
||||||
|
drawRoundRect(
|
||||||
|
color = inactiveColor,
|
||||||
|
cornerRadius = CornerRadius(trackRadius, trackRadius),
|
||||||
|
)
|
||||||
|
if (tickCount <= 0) return@Canvas
|
||||||
|
val padding = size.height * 0.06f
|
||||||
|
val thumbHeight = size.height - padding * 2f
|
||||||
|
val thumbRadius = thumbHeight / 2f
|
||||||
|
val slotWidth = (size.width - padding * 2f) / tickCount
|
||||||
|
val thumbWidthIdeal = slotWidth * 0.9f
|
||||||
|
val thumbWidth = thumbWidthIdeal.coerceAtLeast(thumbHeight)
|
||||||
|
val slotCenter = padding + slotWidth * (currentIndex + 0.5f)
|
||||||
|
val thumbLeft = (slotCenter - thumbWidth / 2f).coerceIn(padding, size.width - padding - thumbWidth)
|
||||||
|
drawRoundRect(
|
||||||
|
color = activeColor,
|
||||||
|
topLeft = Offset(thumbLeft, padding),
|
||||||
|
size = Size(thumbWidth, thumbHeight),
|
||||||
|
cornerRadius = CornerRadius(thumbRadius, thumbRadius),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -289,8 +381,8 @@ private fun DisplaySizePreview(
|
||||||
val previewRows =
|
val previewRows =
|
||||||
remember(posters, episodes) {
|
remember(posters, episodes) {
|
||||||
listOf(
|
listOf(
|
||||||
HomeRowLoadingState.Success(title = recentlyAddedTitle, items = posters),
|
|
||||||
HomeRowLoadingState.Success(title = nextUpTitle, items = episodes),
|
HomeRowLoadingState.Success(title = nextUpTitle, items = episodes),
|
||||||
|
HomeRowLoadingState.Success(title = recentlyAddedTitle, items = posters),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
var position by remember { mutableStateOf(RowColumn(0, 0)) }
|
var position by remember { mutableStateOf(RowColumn(0, 0)) }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue