Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7c515991 authored by Kelly Zhang's avatar Kelly Zhang Committed by Android (Google) Code Review
Browse files

Merge "Extract slider in SettingsSlider to a simple ui widget and rename the...

Merge "Extract slider in SettingsSlider to a simple ui widget and rename the slider preference widget to SliderPreference."
parents f3d63567 370a4a6f
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -33,8 +33,8 @@ import com.android.settingslib.spa.framework.common.SettingsPage
import com.android.settingslib.spa.framework.common.SettingsPageProvider
import com.android.settingslib.spa.framework.compose.navigator
import com.android.settingslib.spa.framework.theme.SettingsTheme
import com.android.settingslib.spa.widget.SettingsSlider
import com.android.settingslib.spa.widget.SettingsSliderModel
import com.android.settingslib.spa.widget.preference.SliderPreference
import com.android.settingslib.spa.widget.preference.SliderPreferenceModel
import com.android.settingslib.spa.widget.preference.Preference
import com.android.settingslib.spa.widget.preference.PreferenceModel
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
@@ -51,7 +51,7 @@ object SliderPageProvider : SettingsPageProvider {
            SettingsEntryBuilder.create("Simple Slider", owner)
                .setIsAllowSearch(true)
                .setUiLayoutFn {
                    SettingsSlider(object : SettingsSliderModel {
                    SliderPreference(object : SliderPreferenceModel {
                        override val title = "Simple Slider"
                        override val initValue = 40
                    })
@@ -61,7 +61,7 @@ object SliderPageProvider : SettingsPageProvider {
            SettingsEntryBuilder.create("Slider with icon", owner)
                .setIsAllowSearch(true)
                .setUiLayoutFn {
                    SettingsSlider(object : SettingsSliderModel {
                    SliderPreference(object : SliderPreferenceModel {
                        override val title = "Slider with icon"
                        override val initValue = 30
                        override val onValueChangeFinished = {
@@ -78,7 +78,7 @@ object SliderPageProvider : SettingsPageProvider {
                    val initValue = 0
                    var icon by remember { mutableStateOf(Icons.Outlined.MusicOff) }
                    var sliderPosition by remember { mutableStateOf(initValue) }
                    SettingsSlider(object : SettingsSliderModel {
                    SliderPreference(object : SliderPreferenceModel {
                        override val title = "Slider with changeable icon"
                        override val initValue = initValue
                        override val onValueChange = { it: Int ->
@@ -96,7 +96,7 @@ object SliderPageProvider : SettingsPageProvider {
            SettingsEntryBuilder.create("Slider with steps", owner)
                .setIsAllowSearch(true)
                .setUiLayoutFn {
                    SettingsSlider(object : SettingsSliderModel {
                    SliderPreference(object : SliderPreferenceModel {
                        override val title = "Slider with steps"
                        override val initValue = 2
                        override val valueRange = 1..5
+45 −51
Original line number Diff line number Diff line
@@ -14,14 +14,13 @@
 * limitations under the License.
 */

package com.android.settingslib.spa.widget
package com.android.settingslib.spa.widget.preference

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.AccessAlarm
import androidx.compose.material.icons.outlined.MusicNote
import androidx.compose.material.icons.outlined.MusicOff
import androidx.compose.material3.Icon
import androidx.compose.material3.Slider
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -33,32 +32,31 @@ import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.tooling.preview.Preview
import com.android.settingslib.spa.framework.theme.SettingsTheme
import com.android.settingslib.spa.framework.util.EntryHighlight
import com.android.settingslib.spa.widget.preference.BaseLayout
import kotlin.math.roundToInt
import com.android.settingslib.spa.widget.ui.SettingsSlider

/**
 * The widget model for [SettingsSlider] widget.
 * The widget model for [SliderPreference] widget.
 */
interface SettingsSliderModel {
interface SliderPreferenceModel {
    /**
     * The title of this [SettingsSlider].
     * The title of this [SliderPreference].
     */
    val title: String

    /**
     * The initial position of the [SettingsSlider].
     * The initial position of the [SliderPreference].
     */
    val initValue: Int

    /**
     * The value range for this [SettingsSlider].
     * The value range for this [SliderPreference].
     */
    val valueRange: IntRange
        get() = 0..100

    /**
     * The lambda to be invoked during the value change by dragging or a click. This callback is
     * used to get the real time value of the [SettingsSlider].
     * used to get the real time value of the [SliderPreference].
     */
    val onValueChange: ((value: Int) -> Unit)?
        get() = null
@@ -71,7 +69,7 @@ interface SettingsSliderModel {
        get() = null

    /**
     * The icon image for [SettingsSlider]. If not specified, the slider hides the icon by default.
     * The icon image for [SliderPreference]. If not specified, the slider hides the icon by default.
     */
    val icon: ImageVector?
        get() = null
@@ -90,11 +88,12 @@ interface SettingsSliderModel {
/**
 * Settings slider widget.
 *
 * Data is provided through [SettingsSliderModel].
 * Data is provided through [SliderPreferenceModel].
 */
@Composable
fun SettingsSlider(model: SettingsSliderModel) {
    SettingsSlider(
fun SliderPreference(model: SliderPreferenceModel) {
    EntryHighlight {
        SliderPreference(
            title = model.title,
            initValue = model.initValue,
            valueRange = model.valueRange,
@@ -104,9 +103,10 @@ fun SettingsSlider(model: SettingsSliderModel) {
            showSteps = model.showSteps,
        )
    }
}

@Composable
internal fun SettingsSlider(
internal fun SliderPreference(
    title: String,
    initValue: Int,
    modifier: Modifier = Modifier,
@@ -116,21 +116,16 @@ internal fun SettingsSlider(
    icon: ImageVector? = null,
    showSteps: Boolean = false,
) {
    var sliderPosition by rememberSaveable { mutableStateOf(initValue.toFloat()) }
    EntryHighlight {
    BaseLayout(
        title = title,
        subTitle = {
                Slider(
                    value = sliderPosition,
                    onValueChange = {
                        sliderPosition = it
                        onValueChange?.invoke(sliderPosition.roundToInt())
                    },
                    modifier = modifier,
                    valueRange = valueRange.first.toFloat()..valueRange.last.toFloat(),
                    steps = if (showSteps) (valueRange.count() - 2) else 0,
                    onValueChangeFinished = onValueChangeFinished,
            SettingsSlider(
                initValue,
                modifier,
                valueRange,
                onValueChange,
                onValueChangeFinished,
                showSteps
            )
        },
        icon = if (icon != null) ({
@@ -138,15 +133,14 @@ internal fun SettingsSlider(
        }) else null,
    )
}
}

@Preview
@Composable
private fun SettingsSliderPreview() {
private fun SliderPreferencePreview() {
    SettingsTheme {
        val initValue = 30
        var sliderPosition by rememberSaveable { mutableStateOf(initValue) }
        SettingsSlider(
        SliderPreference(
            title = "Alarm Volume",
            initValue = 30,
            onValueChange = { sliderPosition = it },
@@ -160,10 +154,10 @@ private fun SettingsSliderPreview() {

@Preview
@Composable
private fun SettingsSliderIconChangePreview() {
private fun SliderPreferenceIconChangePreview() {
    SettingsTheme {
        var icon by remember { mutableStateOf(Icons.Outlined.MusicNote) }
        SettingsSlider(
        SliderPreference(
            title = "Media Volume",
            initValue = 40,
            onValueChange = { it: Int ->
@@ -176,9 +170,9 @@ private fun SettingsSliderIconChangePreview() {

@Preview
@Composable
private fun SettingsSliderStepsPreview() {
private fun SliderPreferenceStepsPreview() {
    SettingsTheme {
        SettingsSlider(
        SliderPreference(
            title = "Display Text",
            initValue = 2,
            valueRange = 1..5,
+49 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.settingslib.spa.widget.ui

import androidx.compose.material3.Slider
import androidx.compose.runtime.Composable
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.Modifier
import kotlin.math.roundToInt

@Composable
fun SettingsSlider(
    initValue: Int,
    modifier: Modifier = Modifier,
    valueRange: IntRange = 0..100,
    onValueChange: ((value: Int) -> Unit)? = null,
    onValueChangeFinished: (() -> Unit)? = null,
    showSteps: Boolean = false,
) {
    var sliderPosition by rememberSaveable { mutableStateOf(initValue.toFloat()) }
    Slider(
        value = sliderPosition,
        onValueChange = {
            sliderPosition = it
            onValueChange?.invoke(sliderPosition.roundToInt())
        },
        modifier = modifier,
        valueRange = valueRange.first.toFloat()..valueRange.last.toFloat(),
        steps = if (showSteps) (valueRange.count() - 2) else 0,
        onValueChangeFinished = onValueChangeFinished,
    )
}
+4 −4
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
 * limitations under the License.
 */

package com.android.settingslib.spa.widget
package com.android.settingslib.spa.widget.preference

import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
@@ -25,14 +25,14 @@ import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
class SettingsSliderTest {
class SliderPreferenceTest {
    @get:Rule
    val composeTestRule = createComposeRule()

    @Test
    fun title_displayed() {
        composeTestRule.setContent {
            SettingsSlider(object : SettingsSliderModel {
            SliderPreference(object : SliderPreferenceModel {
                override val title = "Slider"
                override val initValue = 40
            })
@@ -41,5 +41,5 @@ class SettingsSliderTest {
        composeTestRule.onNodeWithText("Slider").assertIsDisplayed()
    }

    // TODO: Add more unit tests for SettingsSlider widget.
    // TODO: Add more unit tests for SliderPreference widget.
}