diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt index 08fb134a2a9ce..0bfdd22b4934b 100644 --- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/SpaEnvironment.kt @@ -25,6 +25,7 @@ import com.android.settingslib.spa.gallery.page.FooterPageProvider import com.android.settingslib.spa.gallery.page.IllustrationPageProvider import com.android.settingslib.spa.gallery.page.SettingsPagerPageProvider import com.android.settingslib.spa.gallery.page.SliderPageProvider +import com.android.settingslib.spa.gallery.preference.MainSwitchPreferencePageProvider import com.android.settingslib.spa.gallery.preference.PreferenceMainPageProvider import com.android.settingslib.spa.gallery.preference.PreferencePageProvider import com.android.settingslib.spa.gallery.preference.SwitchPreferencePageProvider @@ -40,6 +41,7 @@ object SpaEnvironment { PreferenceMainPageProvider, PreferencePageProvider, SwitchPreferencePageProvider, + MainSwitchPreferencePageProvider, TwoTargetSwitchPreferencePageProvider, ArgumentPageProvider, SliderPageProvider, diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/MainSwitchPreferencePage.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/MainSwitchPreferencePage.kt new file mode 100644 index 0000000000000..53d764896f5c1 --- /dev/null +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/MainSwitchPreferencePage.kt @@ -0,0 +1,93 @@ +/* + * 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.gallery.preference + +import android.os.Bundle +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.ui.tooling.preview.Preview +import com.android.settingslib.spa.framework.common.SettingsPageProvider +import com.android.settingslib.spa.framework.compose.navigator +import com.android.settingslib.spa.framework.compose.stateOf +import com.android.settingslib.spa.framework.theme.SettingsTheme +import com.android.settingslib.spa.widget.preference.MainSwitchPreference +import com.android.settingslib.spa.widget.preference.Preference +import com.android.settingslib.spa.widget.preference.PreferenceModel +import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel +import com.android.settingslib.spa.widget.scaffold.RegularScaffold + +private const val TITLE = "Sample MainSwitchPreference" + +object MainSwitchPreferencePageProvider : SettingsPageProvider { + override val name = "MainSwitchPreference" + + @Composable + override fun Page(arguments: Bundle?) { + MainSwitchPreferencePage() + } + + @Composable + fun EntryItem() { + Preference(object : PreferenceModel { + override val title = TITLE + override val onClick = navigator(name) + }) + } +} + +@Composable +private fun MainSwitchPreferencePage() { + RegularScaffold(title = TITLE) { + SampleMainSwitchPreference() + SampleNotChangeableMainSwitchPreference() + } +} + +@Composable +private fun SampleMainSwitchPreference() { + val checked = rememberSaveable { mutableStateOf(false) } + MainSwitchPreference(remember { + object : SwitchPreferenceModel { + override val title = "MainSwitchPreference" + override val checked = checked + override val onCheckedChange = { newChecked: Boolean -> checked.value = newChecked } + } + }) +} + +@Composable +private fun SampleNotChangeableMainSwitchPreference() { + val checked = rememberSaveable { mutableStateOf(true) } + MainSwitchPreference(remember { + object : SwitchPreferenceModel { + override val title = "Not changeable" + override val changeable = stateOf(false) + override val checked = checked + override val onCheckedChange = { newChecked: Boolean -> checked.value = newChecked } + } + }) +} + +@Preview(showBackground = true) +@Composable +private fun MainSwitchPreferencePagePreview() { + SettingsTheme { + MainSwitchPreferencePage() + } +} diff --git a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferenceMain.kt b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferenceMain.kt index e71c30cc1f3d0..0a8dae321ac60 100644 --- a/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferenceMain.kt +++ b/packages/SettingsLib/Spa/gallery/src/com/android/settingslib/spa/gallery/preference/PreferenceMain.kt @@ -48,6 +48,7 @@ private fun PreferenceMain() { RegularScaffold(title = TITLE) { PreferencePageProvider.EntryItem() SwitchPreferencePageProvider.EntryItem() + MainSwitchPreferencePageProvider.EntryItem() TwoTargetSwitchPreferencePageProvider.EntryItem() } } diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsShape.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsShape.kt index 20020d0e7275f..c66e20a335efc 100644 --- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsShape.kt +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/theme/SettingsShape.kt @@ -21,4 +21,6 @@ import androidx.compose.ui.unit.dp object SettingsShape { val CornerMedium = RoundedCornerShape(12.dp) + + val CornerLarge = RoundedCornerShape(24.dp) } diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/MainSwitchPreference.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/MainSwitchPreference.kt new file mode 100644 index 0000000000000..f2fe7ad7635af --- /dev/null +++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/preference/MainSwitchPreference.kt @@ -0,0 +1,71 @@ +/* + * 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.preference + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.android.settingslib.spa.framework.compose.toState +import com.android.settingslib.spa.framework.theme.SettingsDimension +import com.android.settingslib.spa.framework.theme.SettingsShape +import com.android.settingslib.spa.framework.theme.SettingsTheme + +@Composable +fun MainSwitchPreference(model: SwitchPreferenceModel) { + Surface( + modifier = Modifier.padding(SettingsDimension.itemPaddingEnd), + color = when (model.checked.value) { + true -> MaterialTheme.colorScheme.primaryContainer + else -> MaterialTheme.colorScheme.secondaryContainer + }, + shape = SettingsShape.CornerLarge, + ) { + InternalSwitchPreference( + title = model.title, + checked = model.checked, + changeable = model.changeable, + onCheckedChange = model.onCheckedChange, + paddingStart = 20.dp, + paddingEnd = 20.dp, + paddingVertical = 18.dp, + ) + } +} + +@Preview +@Composable +fun MainSwitchPreferencePreview() { + SettingsTheme { + Column { + MainSwitchPreference(object : SwitchPreferenceModel { + override val title = "Use Dark theme" + override val checked = true.toState() + override val onCheckedChange: (Boolean) -> Unit = {} + }) + MainSwitchPreference(object : SwitchPreferenceModel { + override val title = "Use Dark theme" + override val checked = false.toState() + override val onCheckedChange: (Boolean) -> Unit = {} + }) + } + } +} diff --git a/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/preference/MainSwitchPreferenceTest.kt b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/preference/MainSwitchPreferenceTest.kt new file mode 100644 index 0000000000000..6588cf53957f5 --- /dev/null +++ b/packages/SettingsLib/Spa/tests/src/com/android/settingslib/spa/widget/preference/MainSwitchPreferenceTest.kt @@ -0,0 +1,93 @@ +/* + * 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.preference + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.assertIsOff +import androidx.compose.ui.test.assertIsOn +import androidx.compose.ui.test.isToggleable +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performClick +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settingslib.spa.framework.compose.stateOf +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +private const val TITLE = "Title" + +@RunWith(AndroidJUnit4::class) +class MainSwitchPreferenceTest { + @get:Rule + val composeTestRule = createComposeRule() + + @Test + fun title_displayed() { + composeTestRule.setContent { + TestMainSwitchPreference(changeable = true) + } + + composeTestRule.onNodeWithText(TITLE).assertIsDisplayed() + } + + @Test + fun toggleable_initialStateIsCorrect() { + composeTestRule.setContent { + TestMainSwitchPreference(changeable = true) + } + + composeTestRule.onNode(isToggleable()).assertIsOff() + } + + @Test + fun click_changeable_withEffect() { + composeTestRule.setContent { + TestMainSwitchPreference(changeable = true) + } + + composeTestRule.onNodeWithText(TITLE).performClick() + composeTestRule.onNode(isToggleable()).assertIsOn() + } + + @Test + fun click_notChangeable_noEffect() { + composeTestRule.setContent { + TestMainSwitchPreference(changeable = false) + } + + composeTestRule.onNodeWithText(TITLE).performClick() + composeTestRule.onNode(isToggleable()).assertIsOff() + } +} + +@Composable +private fun TestMainSwitchPreference(changeable: Boolean) { + val checked = rememberSaveable { mutableStateOf(false) } + MainSwitchPreference(remember { + object : SwitchPreferenceModel { + override val title = TITLE + override val checked = checked + override val changeable = stateOf(changeable) + override val onCheckedChange = { newChecked: Boolean -> checked.value = newChecked } + } + }) +}