Loading packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt +68 −60 Original line number Diff line number Diff line Loading @@ -31,8 +31,10 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material3.ExperimentalMaterial3Api Loading Loading @@ -130,6 +132,11 @@ fun VolumeSlider( disabledActiveTickColor = MaterialTheme.colorScheme.surfaceContainerHigh, disabledInactiveTrackColor = MaterialTheme.colorScheme.surfaceContainerHigh, ) val sliderHeight = 52.dp if (state is SliderState.Empty) { // reserve the space for the slider to avoid excess resizing Spacer(modifier = Modifier.weight(1f).height(sliderHeight)) } else { Slider( value = state.value, valueRange = state.valueRange, Loading Loading @@ -178,7 +185,7 @@ fun VolumeSlider( interactionSource = interactionSource, enabled = state.isEnabled, colors = materialSliderColors, thumbSize = DpSize(4.dp, 52.dp), thumbSize = DpSize(4.dp, sliderHeight), ) }, haptics = Loading @@ -189,8 +196,9 @@ fun VolumeSlider( orientation = Orientation.Horizontal, ) } ?: Haptics.Disabled, modifier = Modifier.weight(1f).sysuiResTag(state.label), modifier = Modifier.weight(1f).height(sliderHeight).sysuiResTag(state.label), ) } button?.invoke(this) } state.disabledMessage?.let { disabledMessage -> Loading packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/compose/VolumeDialogSliderTrack.kt +24 −21 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ fun SliderTrack( ) { val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl val measurePolicy = remember(sliderState) { remember(sliderState, isRtl, isVertical, thumbTrackGapSize) { TrackMeasurePolicy( sliderState = sliderState, shouldMirrorIcons = !isVertical && isRtl || isVertical, Loading Loading @@ -102,28 +102,28 @@ fun SliderTrack( contents = Contents.Active.TrackStartIcon, isEnabled = isEnabled, colors = colors, state = measurePolicy, trackMeasurePolicy = measurePolicy, ) TrackIcon( icon = activeTrackEndIcon, contents = Contents.Active.TrackEndIcon, isEnabled = isEnabled, colors = colors, state = measurePolicy, trackMeasurePolicy = measurePolicy, ) TrackIcon( icon = inactiveTrackStartIcon, contents = Contents.Inactive.TrackStartIcon, isEnabled = isEnabled, colors = colors, state = measurePolicy, trackMeasurePolicy = measurePolicy, ) TrackIcon( icon = inactiveTrackEndIcon, contents = Contents.Inactive.TrackEndIcon, isEnabled = isEnabled, colors = colors, state = measurePolicy, trackMeasurePolicy = measurePolicy, ) }, modifier = modifier, Loading @@ -135,7 +135,7 @@ private fun TrackIcon( icon: (@Composable BoxScope.(sliderIconsState: SliderIconsState) -> Unit)?, isEnabled: Boolean, contents: Contents, state: SliderIconsState, trackMeasurePolicy: TrackMeasurePolicy, colors: SliderColors, modifier: Modifier = Modifier, ) { Loading Loading @@ -164,7 +164,11 @@ private fun TrackIcon( } } Box(modifier = modifier.layoutId(contents).fillMaxSize()) { CompositionLocalProvider(LocalContentColor provides iconColor) { icon(state) } if (trackMeasurePolicy.isVisible(contents) != null) { CompositionLocalProvider(LocalContentColor provides iconColor) { icon(trackMeasurePolicy) } } } } Loading @@ -176,25 +180,27 @@ private class TrackMeasurePolicy( private val isVertical: Boolean, ) : MeasurePolicy, SliderIconsState { private val isVisible: Map<Contents, MutableState<Boolean>> = private val isVisible: Map<Contents, MutableState<Boolean?>> = mutableMapOf( Contents.Active.TrackStartIcon to mutableStateOf(false), Contents.Active.TrackEndIcon to mutableStateOf(false), Contents.Inactive.TrackStartIcon to mutableStateOf(false), Contents.Inactive.TrackEndIcon to mutableStateOf(false), Contents.Active.TrackStartIcon to mutableStateOf(null), Contents.Active.TrackEndIcon to mutableStateOf(null), Contents.Inactive.TrackStartIcon to mutableStateOf(null), Contents.Inactive.TrackEndIcon to mutableStateOf(null), ) fun isVisible(contents: Contents): Boolean? = isVisible.getValue(contents.resolve()).value override val isActiveTrackStartIconVisible: Boolean get() = isVisible.getValue(Contents.Active.TrackStartIcon.resolve()).value get() = isVisible(Contents.Active.TrackStartIcon)!! override val isActiveTrackEndIconVisible: Boolean get() = isVisible.getValue(Contents.Active.TrackEndIcon.resolve()).value get() = isVisible(Contents.Active.TrackEndIcon)!! override val isInactiveTrackStartIconVisible: Boolean get() = isVisible.getValue(Contents.Inactive.TrackStartIcon.resolve()).value get() = isVisible(Contents.Inactive.TrackStartIcon)!! override val isInactiveTrackEndIconVisible: Boolean get() = isVisible.getValue(Contents.Inactive.TrackEndIcon.resolve()).value get() = isVisible(Contents.Inactive.TrackEndIcon)!! override fun MeasureScope.measure( measurables: List<Measurable>, Loading Loading @@ -252,8 +258,7 @@ private class TrackMeasurePolicy( // isVisible is only relevant for the icons if (iconLayoutId != Contents.Track) { val isVisibleState = isVisible.getValue(iconLayoutId) val newIsVisible = val isIconVisible = iconLayoutId.isVisible( placeableDimension = if (isVertical) iconPlaceable.height else iconPlaceable.width, Loading @@ -261,9 +266,7 @@ private class TrackMeasurePolicy( gapSize = gapSizePx, coercedValueAsFraction = coercedValueAsFraction, ) if (isVisibleState.value != newIsVisible) { isVisibleState.value = newIsVisible } isVisible.getValue(iconLayoutId).value = isIconVisible } } } Loading packages/SystemUI/src/com/android/systemui/volume/ui/compose/slider/SliderIcon.kt +26 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.volume.ui.compose.slider import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.snap import androidx.compose.animation.core.tween import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut Loading @@ -24,6 +25,10 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier Loading @@ -33,13 +38,32 @@ fun SliderIcon( isVisible: Boolean, modifier: Modifier = Modifier, ) { var previousIsVisible: Boolean? by remember { mutableStateOf(null) } Box(contentAlignment = Alignment.Center, modifier = modifier.fillMaxSize()) { AnimatedVisibility( visible = isVisible, enter = fadeIn(animationSpec = tween(delayMillis = 33, durationMillis = 100)), exit = fadeOut(animationSpec = tween(durationMillis = 50)), enter = fadeIn( animationSpec = if (previousIsVisible == null) { snap() } else { tween(delayMillis = 33, durationMillis = 100) } ), exit = fadeOut( animationSpec = if (previousIsVisible == null) { snap() } else { tween(durationMillis = 50) } ), ) { icon() } } previousIsVisible = isVisible } Loading
packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt +68 −60 Original line number Diff line number Diff line Loading @@ -31,8 +31,10 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material3.ExperimentalMaterial3Api Loading Loading @@ -130,6 +132,11 @@ fun VolumeSlider( disabledActiveTickColor = MaterialTheme.colorScheme.surfaceContainerHigh, disabledInactiveTrackColor = MaterialTheme.colorScheme.surfaceContainerHigh, ) val sliderHeight = 52.dp if (state is SliderState.Empty) { // reserve the space for the slider to avoid excess resizing Spacer(modifier = Modifier.weight(1f).height(sliderHeight)) } else { Slider( value = state.value, valueRange = state.valueRange, Loading Loading @@ -178,7 +185,7 @@ fun VolumeSlider( interactionSource = interactionSource, enabled = state.isEnabled, colors = materialSliderColors, thumbSize = DpSize(4.dp, 52.dp), thumbSize = DpSize(4.dp, sliderHeight), ) }, haptics = Loading @@ -189,8 +196,9 @@ fun VolumeSlider( orientation = Orientation.Horizontal, ) } ?: Haptics.Disabled, modifier = Modifier.weight(1f).sysuiResTag(state.label), modifier = Modifier.weight(1f).height(sliderHeight).sysuiResTag(state.label), ) } button?.invoke(this) } state.disabledMessage?.let { disabledMessage -> Loading
packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/compose/VolumeDialogSliderTrack.kt +24 −21 Original line number Diff line number Diff line Loading @@ -66,7 +66,7 @@ fun SliderTrack( ) { val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl val measurePolicy = remember(sliderState) { remember(sliderState, isRtl, isVertical, thumbTrackGapSize) { TrackMeasurePolicy( sliderState = sliderState, shouldMirrorIcons = !isVertical && isRtl || isVertical, Loading Loading @@ -102,28 +102,28 @@ fun SliderTrack( contents = Contents.Active.TrackStartIcon, isEnabled = isEnabled, colors = colors, state = measurePolicy, trackMeasurePolicy = measurePolicy, ) TrackIcon( icon = activeTrackEndIcon, contents = Contents.Active.TrackEndIcon, isEnabled = isEnabled, colors = colors, state = measurePolicy, trackMeasurePolicy = measurePolicy, ) TrackIcon( icon = inactiveTrackStartIcon, contents = Contents.Inactive.TrackStartIcon, isEnabled = isEnabled, colors = colors, state = measurePolicy, trackMeasurePolicy = measurePolicy, ) TrackIcon( icon = inactiveTrackEndIcon, contents = Contents.Inactive.TrackEndIcon, isEnabled = isEnabled, colors = colors, state = measurePolicy, trackMeasurePolicy = measurePolicy, ) }, modifier = modifier, Loading @@ -135,7 +135,7 @@ private fun TrackIcon( icon: (@Composable BoxScope.(sliderIconsState: SliderIconsState) -> Unit)?, isEnabled: Boolean, contents: Contents, state: SliderIconsState, trackMeasurePolicy: TrackMeasurePolicy, colors: SliderColors, modifier: Modifier = Modifier, ) { Loading Loading @@ -164,7 +164,11 @@ private fun TrackIcon( } } Box(modifier = modifier.layoutId(contents).fillMaxSize()) { CompositionLocalProvider(LocalContentColor provides iconColor) { icon(state) } if (trackMeasurePolicy.isVisible(contents) != null) { CompositionLocalProvider(LocalContentColor provides iconColor) { icon(trackMeasurePolicy) } } } } Loading @@ -176,25 +180,27 @@ private class TrackMeasurePolicy( private val isVertical: Boolean, ) : MeasurePolicy, SliderIconsState { private val isVisible: Map<Contents, MutableState<Boolean>> = private val isVisible: Map<Contents, MutableState<Boolean?>> = mutableMapOf( Contents.Active.TrackStartIcon to mutableStateOf(false), Contents.Active.TrackEndIcon to mutableStateOf(false), Contents.Inactive.TrackStartIcon to mutableStateOf(false), Contents.Inactive.TrackEndIcon to mutableStateOf(false), Contents.Active.TrackStartIcon to mutableStateOf(null), Contents.Active.TrackEndIcon to mutableStateOf(null), Contents.Inactive.TrackStartIcon to mutableStateOf(null), Contents.Inactive.TrackEndIcon to mutableStateOf(null), ) fun isVisible(contents: Contents): Boolean? = isVisible.getValue(contents.resolve()).value override val isActiveTrackStartIconVisible: Boolean get() = isVisible.getValue(Contents.Active.TrackStartIcon.resolve()).value get() = isVisible(Contents.Active.TrackStartIcon)!! override val isActiveTrackEndIconVisible: Boolean get() = isVisible.getValue(Contents.Active.TrackEndIcon.resolve()).value get() = isVisible(Contents.Active.TrackEndIcon)!! override val isInactiveTrackStartIconVisible: Boolean get() = isVisible.getValue(Contents.Inactive.TrackStartIcon.resolve()).value get() = isVisible(Contents.Inactive.TrackStartIcon)!! override val isInactiveTrackEndIconVisible: Boolean get() = isVisible.getValue(Contents.Inactive.TrackEndIcon.resolve()).value get() = isVisible(Contents.Inactive.TrackEndIcon)!! override fun MeasureScope.measure( measurables: List<Measurable>, Loading Loading @@ -252,8 +258,7 @@ private class TrackMeasurePolicy( // isVisible is only relevant for the icons if (iconLayoutId != Contents.Track) { val isVisibleState = isVisible.getValue(iconLayoutId) val newIsVisible = val isIconVisible = iconLayoutId.isVisible( placeableDimension = if (isVertical) iconPlaceable.height else iconPlaceable.width, Loading @@ -261,9 +266,7 @@ private class TrackMeasurePolicy( gapSize = gapSizePx, coercedValueAsFraction = coercedValueAsFraction, ) if (isVisibleState.value != newIsVisible) { isVisibleState.value = newIsVisible } isVisible.getValue(iconLayoutId).value = isIconVisible } } } Loading
packages/SystemUI/src/com/android/systemui/volume/ui/compose/slider/SliderIcon.kt +26 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.volume.ui.compose.slider import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.snap import androidx.compose.animation.core.tween import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut Loading @@ -24,6 +25,10 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier Loading @@ -33,13 +38,32 @@ fun SliderIcon( isVisible: Boolean, modifier: Modifier = Modifier, ) { var previousIsVisible: Boolean? by remember { mutableStateOf(null) } Box(contentAlignment = Alignment.Center, modifier = modifier.fillMaxSize()) { AnimatedVisibility( visible = isVisible, enter = fadeIn(animationSpec = tween(delayMillis = 33, durationMillis = 100)), exit = fadeOut(animationSpec = tween(durationMillis = 50)), enter = fadeIn( animationSpec = if (previousIsVisible == null) { snap() } else { tween(delayMillis = 33, durationMillis = 100) } ), exit = fadeOut( animationSpec = if (previousIsVisible == null) { snap() } else { tween(durationMillis = 50) } ), ) { icon() } } previousIsVisible = isVisible }