diff --git a/app/src/main/java/com/orange/ods/app/ui/components/sliders/ComponentSliders.kt b/app/src/main/java/com/orange/ods/app/ui/components/sliders/ComponentSliders.kt index 9fc2f5d6f..e80aeb41a 100644 --- a/app/src/main/java/com/orange/ods/app/ui/components/sliders/ComponentSliders.kt +++ b/app/src/main/java/com/orange/ods/app/ui/components/sliders/ComponentSliders.kt @@ -30,11 +30,11 @@ import com.orange.ods.app.R import com.orange.ods.app.ui.components.utilities.ComponentCustomizationBottomSheetScaffold import com.orange.ods.app.ui.utilities.composable.CodeImplementationColumn import com.orange.ods.app.ui.utilities.composable.FunctionCallCode -import com.orange.ods.app.ui.utilities.composable.IconPainterValue import com.orange.ods.app.ui.utilities.composable.TechnicalText import com.orange.ods.app.ui.utilities.composable.Title import com.orange.ods.compose.OdsComposable import com.orange.ods.compose.component.control.OdsSlider +import com.orange.ods.compose.component.control.OdsSliderIcon import com.orange.ods.compose.component.control.OdsSliderLockups import com.orange.ods.compose.component.list.OdsListItem import com.orange.ods.compose.component.list.OdsSwitchTrailing @@ -68,10 +68,10 @@ fun ComponentSliders() { ) { val technicalText = if (shouldDisplayValue) OdsComposable.OdsSliderLockups.name else OdsComposable.OdsSlider.name val steps = if (isStepped) 9 else 0 - val leftIcon = if (hasSideIcons) painterResource(id = R.drawable.ic_volume_status_1) else null - val leftIconContentDescription = if (hasSideIcons) stringResource(id = R.string.component_slider_low_volume) else null - val rightIcon = if (hasSideIcons) painterResource(id = R.drawable.ic_volume_status_4) else null - val rightIconContentDescription = if (hasSideIcons) stringResource(id = R.string.component_slider_high_volume) else null + val leftIconContentDescription = stringResource(id = R.string.component_slider_low_volume) + val leftIcon = if (hasSideIcons) OdsSliderIcon(painterResource(id = R.drawable.ic_volume_status_1), leftIconContentDescription) else null + val rightIconContentDescription = stringResource(id = R.string.component_slider_high_volume) + val rightIcon = if (hasSideIcons) OdsSliderIcon(painterResource(id = R.drawable.ic_volume_status_4), rightIconContentDescription) else null var sliderPosition by remember { mutableStateOf(0f) } val valueRange = 0f..100f @@ -90,9 +90,7 @@ fun ComponentSliders() { valueRange = valueRange, onValueChange = { sliderPosition = it }, leftIcon = leftIcon, - leftIconContentDescription = leftIconContentDescription, - rightIcon = rightIcon, - rightIconContentDescription = rightIconContentDescription + rightIcon = rightIcon ) } else { componentName = OdsComposable.OdsSlider.name @@ -102,9 +100,7 @@ fun ComponentSliders() { valueRange = valueRange, onValueChange = { sliderPosition = it }, leftIcon = leftIcon, - leftIconContentDescription = leftIconContentDescription, - rightIcon = rightIcon, - rightIconContentDescription = rightIconContentDescription + rightIcon = rightIcon ) } @@ -118,10 +114,14 @@ fun ComponentSliders() { lambda("onValueChange") if (isStepped) stringRepresentation("steps", steps) if (hasSideIcons) { - simple("leftIcon", IconPainterValue) - leftIconContentDescription?.let { string("leftIconContentDescription", it) } - simple("rightIcon", IconPainterValue) - rightIconContentDescription?.let { string("rightIconContentDescription", it) } + classInstance("leftIcon") { + painter() + contentDescription(leftIconContentDescription) + } + classInstance("rightIcon") { + painter() + contentDescription(rightIconContentDescription) + } } }) } diff --git a/changelog.md b/changelog.md index 31dcc46ce..57cf0fe6e 100644 --- a/changelog.md +++ b/changelog.md @@ -5,6 +5,12 @@ All notable changes done in ODS library will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [Unreleased](https://github.com/Orange-OpenSource/ods-android/compare/0.15.1...develop) + +### Changed + +- \[Lib\] Update `OdsSlider` and `OdsSliderLockups` APIs ([#648](https://github.com/Orange-OpenSource/ods-android/issues/648)) + ## [0.15.1](https://github.com/Orange-OpenSource/ods-android/compare/0.15.0...0.15.1) - 2023-09-28 ### Changed diff --git a/lib/src/main/java/com/orange/ods/compose/component/control/OdsSlider.kt b/lib/src/main/java/com/orange/ods/compose/component/control/OdsSlider.kt index c338e1e98..265c6e567 100644 --- a/lib/src/main/java/com/orange/ods/compose/component/control/OdsSlider.kt +++ b/lib/src/main/java/com/orange/ods/compose/component/control/OdsSlider.kt @@ -18,7 +18,6 @@ import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Icon import androidx.compose.material.Slider import androidx.compose.material.SliderDefaults import androidx.compose.material.Text @@ -29,7 +28,10 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextAlign @@ -38,6 +40,7 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.orange.ods.R import com.orange.ods.compose.component.OdsComposable +import com.orange.ods.compose.component.content.OdsComponentIcon import com.orange.ods.compose.component.utilities.BasicPreviewParameterProvider import com.orange.ods.compose.component.utilities.Preview import com.orange.ods.compose.component.utilities.UiModePreviews @@ -72,10 +75,8 @@ private const val ActiveTickColorAlpha = 0.4f * @param onValueChangeFinished lambda to be invoked when value change has ended. This callback * shouldn't be used to update the slider value (use [onValueChange] for that), but rather to * know when the user has completed selecting a new value by ending a drag or a click. - * @param leftIcon Optional icon displayed on the left of the slider - * @param leftIconContentDescription Left icon content description - * @param rightIcon Optional icon displayed on the right of the slider - * @param rightIconContentDescription Right icon content description + * @param leftIcon Icon displayed on the left of the slider + * @param rightIcon Icon displayed on the right of the slider */ @Composable @OdsComposable @@ -87,23 +88,15 @@ fun OdsSlider( valueRange: ClosedFloatingPointRange = 0f..1f, steps: Int = 0, onValueChangeFinished: (() -> Unit)? = null, - leftIcon: Painter? = null, - leftIconContentDescription: String? = null, - rightIcon: Painter? = null, - rightIconContentDescription: String? = null + leftIcon: OdsSliderIcon? = null, + rightIcon: OdsSliderIcon? = null ) { Row( modifier = modifier, verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing_m)) ) { - leftIcon?.let { painter -> - Icon( - painter = painter, - contentDescription = leftIconContentDescription, - tint = OdsTheme.colors.onSurface - ) - } + leftIcon?.Content() // For the moment we cannot change the height of the slider track (need to check in jetpack compose future versions) Slider( value = value, @@ -116,13 +109,7 @@ fun OdsSlider( onValueChangeFinished = onValueChangeFinished, colors = SliderDefaults.colors(activeTickColor = OdsTheme.colors.surface.copy(alpha = ActiveTickColorAlpha)) ) - rightIcon?.let { painter -> - Icon( - painter = painter, - contentDescription = rightIconContentDescription, - tint = OdsTheme.colors.onSurface - ) - } + rightIcon?.Content() } } @@ -155,10 +142,8 @@ fun OdsSlider( * @param onValueChangeFinished lambda to be invoked when value change has ended. This callback * shouldn't be used to update the slider value (use [onValueChange] for that), but rather to * know when the user has completed selecting a new value by ending a drag or a click. - * @param leftIcon Optional icon displayed on the left of the slider - * @param leftIconContentDescription Left icon content description - * @param rightIcon Optional icon displayed on the right of the slider - * @param rightIconContentDescription Right icon content description + * @param leftIcon Icon displayed on the left of the slider + * @param rightIcon Icon displayed on the right of the slider */ @Composable @OdsComposable @@ -170,10 +155,8 @@ fun OdsSliderLockups( valueRange: ClosedFloatingPointRange = 0f..1f, steps: Int = 0, onValueChangeFinished: (() -> Unit)? = null, - leftIcon: Painter? = null, - leftIconContentDescription: String? = null, - rightIcon: Painter? = null, - rightIconContentDescription: String? = null + leftIcon: OdsSliderIcon? = null, + rightIcon: OdsSliderIcon? = null ) { val labelMinWidth = 32.dp val sideIconBottomPadding = 12.dp @@ -182,16 +165,11 @@ fun OdsSliderLockups( modifier = modifier, horizontalArrangement = Arrangement.spacedBy(dimensionResource(id = R.dimen.spacing_xs)) ) { - leftIcon?.let { painter -> - Icon( - modifier = Modifier - .align(alignment = Alignment.Bottom) - .padding(bottom = sideIconBottomPadding), - painter = painter, - contentDescription = leftIconContentDescription, - tint = OdsTheme.colors.onSurface - ) - } + leftIcon?.Content( + modifier = Modifier + .align(alignment = Alignment.Bottom) + .padding(bottom = sideIconBottomPadding) + ) BoxWithConstraints(modifier = modifier.weight(1f)) { val offset = getSliderOffset( value = value, @@ -224,19 +202,48 @@ fun OdsSliderLockups( onValueChangeFinished = onValueChangeFinished, ) } - rightIcon?.let { painter -> - Icon( - modifier = Modifier - .align(alignment = Alignment.Bottom) - .padding(bottom = sideIconBottomPadding), - painter = painter, - contentDescription = rightIconContentDescription, - tint = OdsTheme.colors.onSurface - ) - } + rightIcon?.Content( + modifier = Modifier + .align(alignment = Alignment.Bottom) + .padding(bottom = sideIconBottomPadding), + ) } } +/** + * An icon in an [OdsSlider] or an [OdsSliderLockups]. + */ +class OdsSliderIcon : OdsComponentIcon { + + /** + * Creates an instance of [OdsSliderIcon]. + * + * @param painter Painter of the icon. + * @param contentDescription The content description associated to this [OdsSliderIcon]. + */ + constructor(painter: Painter, contentDescription: String) : super(painter, contentDescription) + + /** + * Creates an instance of [OdsSliderIcon]. + * + * @param imageVector Image vector of the icon. + * @param contentDescription The content description associated to this [OdsSliderIcon]. + */ + constructor(imageVector: ImageVector, contentDescription: String) : super(imageVector, contentDescription) + + /** + * Creates an instance of [OdsSliderIcon]. + * + * @param bitmap Image bitmap of the icon. + * @param contentDescription The content description associated to this [OdsSliderIcon]. + */ + constructor(bitmap: ImageBitmap, contentDescription: String) : super(bitmap, contentDescription) + + override val tint: Color? + @Composable + get() = OdsTheme.colors.onSurface +} + @Composable private fun SliderLabel( modifier: Modifier = Modifier, @@ -286,8 +293,8 @@ private fun PreviewOdsSlider(@PreviewParameter(OdsSliderPreviewParameterProvider value = sliderValue.value, onValueChange = { sliderValue.value = it }, steps = 9, - leftIcon = if (withIcons) painterResource(id = R.drawable.ic_crosset_out_eye) else null, - rightIcon = if (withIcons) painterResource(id = R.drawable.ic_eye) else null, + leftIcon = if (withIcons) OdsSliderIcon(painterResource(id = R.drawable.ic_crosset_out_eye), "") else null, + rightIcon = if (withIcons) OdsSliderIcon(painterResource(id = R.drawable.ic_eye), "") else null, ) } @@ -299,8 +306,8 @@ private fun PreviewOdsSliderLockups(@PreviewParameter(OdsSliderPreviewParameterP value = value, valueRange = 0f..100f, onValueChange = { value = it }, - leftIcon = if (withIcons) painterResource(id = R.drawable.ic_crosset_out_eye) else null, - rightIcon = if (withIcons) painterResource(id = R.drawable.ic_eye) else null, + leftIcon = if (withIcons) OdsSliderIcon(painterResource(id = R.drawable.ic_crosset_out_eye), "") else null, + rightIcon = if (withIcons) OdsSliderIcon(painterResource(id = R.drawable.ic_eye), "") else null, ) }