Merge changes I05b50ace,Ic370f271
* changes: Add gallery page of item list operation Add arguments in displayName of page.
This commit is contained in:
@@ -24,6 +24,9 @@ import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.gallery.button.ActionButtonPageProvider
|
||||
import com.android.settingslib.spa.gallery.dialog.AlterDialogPageProvider
|
||||
import com.android.settingslib.spa.gallery.home.HomePageProvider
|
||||
import com.android.settingslib.spa.gallery.itemList.ItemListPageProvider
|
||||
import com.android.settingslib.spa.gallery.itemList.ItemOperatePageProvider
|
||||
import com.android.settingslib.spa.gallery.itemList.OperateListPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.ArgumentPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.ChartPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.FooterPageProvider
|
||||
@@ -50,6 +53,8 @@ enum class SettingsPageProviderEnum(val displayName: String) {
|
||||
HOME("home"),
|
||||
PREFERENCE("preference"),
|
||||
ARGUMENT("argument"),
|
||||
ITEM_LIST("itemList"),
|
||||
ITEM_OP_PAGE("itemOp"),
|
||||
|
||||
// Add your SPPs
|
||||
}
|
||||
@@ -76,6 +81,9 @@ class GallerySpaEnvironment(context: Context) : SpaEnvironment(context) {
|
||||
LoadingBarPageProvider,
|
||||
ChartPageProvider,
|
||||
AlterDialogPageProvider,
|
||||
ItemListPageProvider,
|
||||
ItemOperatePageProvider,
|
||||
OperateListPageProvider,
|
||||
),
|
||||
rootPages = listOf(
|
||||
HomePageProvider.createSettingsPage(),
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.settingslib.spa.gallery.home
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
@@ -28,6 +29,7 @@ import com.android.settingslib.spa.gallery.R
|
||||
import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
|
||||
import com.android.settingslib.spa.gallery.button.ActionButtonPageProvider
|
||||
import com.android.settingslib.spa.gallery.dialog.AlterDialogPageProvider
|
||||
import com.android.settingslib.spa.gallery.itemList.OperateListPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.ArgumentPageModel
|
||||
import com.android.settingslib.spa.gallery.page.ArgumentPageProvider
|
||||
import com.android.settingslib.spa.gallery.page.ChartPageProvider
|
||||
@@ -50,6 +52,7 @@ object HomePageProvider : SettingsPageProvider {
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
return listOf(
|
||||
PreferenceMainPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
OperateListPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
ArgumentPageProvider.buildInjectEntry("foo")!!.setLink(fromPage = owner).build(),
|
||||
SliderPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
SpinnerPageProvider.buildInjectEntry().setLink(fromPage = owner).build(),
|
||||
@@ -71,8 +74,10 @@ object HomePageProvider : SettingsPageProvider {
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
HomeScaffold(title = getTitle(arguments)) {
|
||||
for (entry in buildEntry(arguments)) {
|
||||
val title = remember { getTitle(arguments) }
|
||||
val entries = remember { buildEntry(arguments) }
|
||||
HomeScaffold(title) {
|
||||
for (entry in entries) {
|
||||
if (entry.owner.isCreateBy(SettingsPageProviderEnum.ARGUMENT.name)) {
|
||||
entry.UiLayout(ArgumentPageModel.buildArgument(intParam = 0))
|
||||
} else {
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.itemList
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.navArgument
|
||||
import com.android.settingslib.spa.framework.common.EntrySearchData
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.util.getStringArg
|
||||
import com.android.settingslib.spa.framework.util.navLink
|
||||
import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.scaffold.RegularScaffold
|
||||
|
||||
private const val OPERATOR_PARAM_NAME = "opParam"
|
||||
|
||||
object ItemListPageProvider : SettingsPageProvider {
|
||||
override val name = SettingsPageProviderEnum.ITEM_LIST.name
|
||||
override val displayName = SettingsPageProviderEnum.ITEM_LIST.displayName
|
||||
override val parameter = listOf(
|
||||
navArgument(OPERATOR_PARAM_NAME) { type = NavType.StringType },
|
||||
)
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
val operation = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments) ?: "NULL"
|
||||
return "Operation: $operation"
|
||||
}
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
if (!ItemOperatePageProvider.isValidArgs(arguments)) return emptyList()
|
||||
val operation = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments)!!
|
||||
val owner = createSettingsPage(arguments)
|
||||
return listOf(
|
||||
ItemOperatePageProvider.buildInjectEntry(operation)!!.setLink(fromPage = owner).build(),
|
||||
)
|
||||
}
|
||||
|
||||
fun buildInjectEntry(opParam: String): SettingsEntryBuilder? {
|
||||
val arguments = bundleOf(OPERATOR_PARAM_NAME to opParam)
|
||||
if (!ItemOperatePageProvider.isValidArgs(arguments)) return null
|
||||
|
||||
return SettingsEntryBuilder.createInject(
|
||||
owner = createSettingsPage(arguments),
|
||||
displayName = "ItemList_$opParam",
|
||||
).setUiLayoutFn {
|
||||
Preference(
|
||||
object : PreferenceModel {
|
||||
override val title = opParam
|
||||
override val onClick = navigator(
|
||||
SettingsPageProviderEnum.ITEM_LIST.name + parameter.navLink(it)
|
||||
)
|
||||
}
|
||||
)
|
||||
}.setSearchDataFn {
|
||||
EntrySearchData(title = "Operation: $opParam")
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
val title = remember { getTitle(arguments) }
|
||||
val entries = remember { buildEntry(arguments) }
|
||||
val itemList = remember {
|
||||
// Add logic to get item List during runtime.
|
||||
listOf("itemFoo", "itemBar", "itemToy")
|
||||
}
|
||||
RegularScaffold(title) {
|
||||
for (item in itemList) {
|
||||
val rtArgs = ItemOperatePageProvider.genRuntimeArguments(item)
|
||||
for (entry in entries) {
|
||||
entry.UiLayout(rtArgs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.itemList
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.core.os.bundleOf
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.navArgument
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.framework.util.getStringArg
|
||||
import com.android.settingslib.spa.framework.util.navLink
|
||||
import com.android.settingslib.spa.gallery.SettingsPageProviderEnum
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
import com.android.settingslib.spa.widget.preference.SwitchPreference
|
||||
import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel
|
||||
|
||||
private const val OPERATOR_PARAM_NAME = "opParam"
|
||||
private const val ITEM_NAME_PARAM_NAME = "rt_nameParam"
|
||||
private val ALLOWED_OPERATOR_LIST = listOf("opDnD", "opPiP", "opInstall", "opConnect")
|
||||
|
||||
object ItemOperatePageProvider : SettingsPageProvider {
|
||||
override val name = SettingsPageProviderEnum.ITEM_OP_PAGE.name
|
||||
override val displayName = SettingsPageProviderEnum.ITEM_OP_PAGE.displayName
|
||||
override val parameter = listOf(
|
||||
navArgument(OPERATOR_PARAM_NAME) { type = NavType.StringType },
|
||||
navArgument(ITEM_NAME_PARAM_NAME) { type = NavType.StringType },
|
||||
)
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
// Operation name is not a runtime parameter, which should always available
|
||||
val operation = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments) ?: "opInValid"
|
||||
// Item name is a runtime parameter, which could be missing
|
||||
val itemName = parameter.getStringArg(ITEM_NAME_PARAM_NAME, arguments) ?: "[unset]"
|
||||
return "$operation on $itemName"
|
||||
}
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
if (!isValidArgs(arguments)) return emptyList()
|
||||
|
||||
val owner = createSettingsPage(arguments)
|
||||
val entryList = mutableListOf<SettingsEntry>()
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create("ItemName", owner)
|
||||
.setUiLayoutFn {
|
||||
// Item name is a runtime parameter, which needs to be read inside UiLayoutFn
|
||||
val itemName = parameter.getStringArg(ITEM_NAME_PARAM_NAME, it) ?: "NULL"
|
||||
Preference(
|
||||
object : PreferenceModel {
|
||||
override val title = "Item $itemName"
|
||||
}
|
||||
)
|
||||
}.build()
|
||||
)
|
||||
|
||||
// Operation name is not a runtime parameter, which can be read outside.
|
||||
val opName = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments)!!
|
||||
entryList.add(
|
||||
SettingsEntryBuilder.create("ItemOp", owner)
|
||||
.setUiLayoutFn {
|
||||
val checked = rememberSaveable { mutableStateOf(false) }
|
||||
SwitchPreference(remember {
|
||||
object : SwitchPreferenceModel {
|
||||
override val title = "Item operation: $opName"
|
||||
override val checked = checked
|
||||
override val onCheckedChange =
|
||||
{ newChecked: Boolean -> checked.value = newChecked }
|
||||
}
|
||||
})
|
||||
}.build(),
|
||||
)
|
||||
return entryList
|
||||
}
|
||||
|
||||
fun buildInjectEntry(opParam: String): SettingsEntryBuilder? {
|
||||
val arguments = bundleOf(OPERATOR_PARAM_NAME to opParam)
|
||||
if (!isValidArgs(arguments)) return null
|
||||
|
||||
return SettingsEntryBuilder.createInject(
|
||||
owner = createSettingsPage(arguments),
|
||||
displayName = "ItemOp_$opParam",
|
||||
).setUiLayoutFn {
|
||||
// Item name is a runtime parameter, which needs to be read inside UiLayoutFn
|
||||
val itemName = parameter.getStringArg(ITEM_NAME_PARAM_NAME, it) ?: "NULL"
|
||||
Preference(
|
||||
object : PreferenceModel {
|
||||
override val title = "item: $itemName"
|
||||
override val onClick = navigator(
|
||||
SettingsPageProviderEnum.ITEM_OP_PAGE.name + parameter.navLink(it)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun isValidArgs(arguments: Bundle?): Boolean {
|
||||
val opParam = parameter.getStringArg(OPERATOR_PARAM_NAME, arguments)
|
||||
return (opParam != null && ALLOWED_OPERATOR_LIST.contains(opParam))
|
||||
}
|
||||
|
||||
fun genRuntimeArguments(itemName: String): Bundle {
|
||||
return bundleOf(ITEM_NAME_PARAM_NAME to itemName)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.itemList
|
||||
|
||||
import android.os.Bundle
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
import com.android.settingslib.spa.framework.common.SettingsPageProvider
|
||||
import com.android.settingslib.spa.framework.common.createSettingsPage
|
||||
import com.android.settingslib.spa.framework.compose.navigator
|
||||
import com.android.settingslib.spa.widget.preference.Preference
|
||||
import com.android.settingslib.spa.widget.preference.PreferenceModel
|
||||
|
||||
private const val TITLE = "Operate List Main"
|
||||
|
||||
object OperateListPageProvider : SettingsPageProvider {
|
||||
override val name = "OpList"
|
||||
private val owner = createSettingsPage()
|
||||
|
||||
override fun buildEntry(arguments: Bundle?): List<SettingsEntry> {
|
||||
return listOf(
|
||||
ItemListPageProvider.buildInjectEntry("opPiP")!!.setLink(fromPage = owner).build(),
|
||||
ItemListPageProvider.buildInjectEntry("opInstall")!!.setLink(fromPage = owner).build(),
|
||||
ItemListPageProvider.buildInjectEntry("opDnD")!!.setLink(fromPage = owner).build(),
|
||||
ItemListPageProvider.buildInjectEntry("opConnect")!!.setLink(fromPage = owner).build(),
|
||||
)
|
||||
}
|
||||
|
||||
override fun getTitle(arguments: Bundle?): String {
|
||||
return TITLE
|
||||
}
|
||||
|
||||
fun buildInjectEntry(): SettingsEntryBuilder {
|
||||
return SettingsEntryBuilder.createInject(owner = owner)
|
||||
.setUiLayoutFn {
|
||||
Preference(object : PreferenceModel {
|
||||
override val title = TITLE
|
||||
override val onClick = navigator(name)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package com.android.settingslib.spa.gallery.page
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntry
|
||||
import com.android.settingslib.spa.framework.common.SettingsEntryBuilder
|
||||
@@ -101,10 +102,13 @@ object ArgumentPageProvider : SettingsPageProvider {
|
||||
|
||||
@Composable
|
||||
override fun Page(arguments: Bundle?) {
|
||||
RegularScaffold(title = getTitle(arguments)) {
|
||||
for (entry in buildEntry(arguments)) {
|
||||
val title = remember { getTitle(arguments) }
|
||||
val entries = remember { buildEntry(arguments) }
|
||||
val rtArgNext = remember { ArgumentPageModel.buildNextArgument(arguments) }
|
||||
RegularScaffold(title) {
|
||||
for (entry in entries) {
|
||||
if (entry.toPage != null) {
|
||||
entry.UiLayout(ArgumentPageModel.buildNextArgument(arguments))
|
||||
entry.UiLayout(rtArgNext)
|
||||
} else {
|
||||
entry.UiLayout()
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ class ArgumentPageModel : PageModel() {
|
||||
override val title = PAGE_TITLE
|
||||
override val summary = stateOf(summaryArray.joinToString(", "))
|
||||
override val onClick = navigator(
|
||||
SettingsPageProviderEnum.ARGUMENT.displayName + parameter.navLink(arguments)
|
||||
SettingsPageProviderEnum.ARGUMENT.name + parameter.navLink(arguments)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import androidx.navigation.NamedNavArgument
|
||||
import com.android.settingslib.spa.framework.util.isRuntimeParam
|
||||
import com.android.settingslib.spa.framework.util.navLink
|
||||
import com.android.settingslib.spa.framework.util.normalize
|
||||
import com.android.settingslib.spa.framework.util.normalizeArgList
|
||||
|
||||
private const val NULL_PAGE_NAME = "NULL"
|
||||
|
||||
@@ -114,9 +115,10 @@ data class SettingsPage(
|
||||
fun SettingsPageProvider.createSettingsPage(arguments: Bundle? = null): SettingsPage {
|
||||
return SettingsPage.create(
|
||||
name = name,
|
||||
displayName = displayName,
|
||||
displayName = displayName + parameter.normalizeArgList(arguments, eraseRuntimeValues = true)
|
||||
.joinToString("") { arg -> "/$arg" },
|
||||
parameter = parameter,
|
||||
arguments = arguments
|
||||
arguments = arguments,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -29,8 +29,16 @@ fun List<NamedNavArgument>.navRoute(): String {
|
||||
}
|
||||
|
||||
fun List<NamedNavArgument>.navLink(arguments: Bundle? = null): String {
|
||||
return normalizeArgList(arguments).joinToString("") { arg -> "/$arg" }
|
||||
}
|
||||
|
||||
fun List<NamedNavArgument>.normalizeArgList(
|
||||
arguments: Bundle? = null,
|
||||
eraseRuntimeValues: Boolean = false
|
||||
): List<String> {
|
||||
val argsArray = mutableListOf<String>()
|
||||
for (navArg in this) {
|
||||
if (eraseRuntimeValues && navArg.isRuntimeParam()) continue
|
||||
if (arguments == null || !arguments.containsKey(navArg.name)) {
|
||||
argsArray.add(UNSET_PARAM_VALUE)
|
||||
continue
|
||||
@@ -44,7 +52,7 @@ fun List<NamedNavArgument>.navLink(arguments: Bundle? = null): String {
|
||||
}
|
||||
}
|
||||
}
|
||||
return argsArray.joinToString("") { arg -> "/$arg" }
|
||||
return argsArray
|
||||
}
|
||||
|
||||
fun List<NamedNavArgument>.normalize(
|
||||
@@ -55,7 +63,7 @@ fun List<NamedNavArgument>.normalize(
|
||||
val normArgs = Bundle()
|
||||
for (navArg in this) {
|
||||
// Erase value of runtime parameters.
|
||||
if (navArg.isRuntimeParam() && eraseRuntimeValues) {
|
||||
if (eraseRuntimeValues && navArg.isRuntimeParam()) {
|
||||
normArgs.putString(navArg.name, null)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ class SettingsPageTest {
|
||||
)
|
||||
)
|
||||
assertThat(page.sppName).isEqualTo("SppWithParam")
|
||||
assertThat(page.displayName).isEqualTo("SppWithParam")
|
||||
assertThat(page.displayName).isEqualTo("SppWithParam/myStr/10")
|
||||
assertThat(page.buildRoute()).isEqualTo("SppWithParam/myStr/10")
|
||||
assertThat(page.isCreateBy("SppWithParam")).isTrue()
|
||||
assertThat(page.hasRuntimeParam()).isFalse()
|
||||
@@ -100,7 +100,7 @@ class SettingsPageTest {
|
||||
)
|
||||
)
|
||||
assertThat(page.sppName).isEqualTo("SppWithRtParam")
|
||||
assertThat(page.displayName).isEqualTo("SppWithRtParam")
|
||||
assertThat(page.displayName).isEqualTo("SppWithRtParam/myStr/10")
|
||||
assertThat(page.buildRoute()).isEqualTo("SppWithRtParam/myStr/10/rtStr")
|
||||
assertThat(page.isCreateBy("SppWithRtParam")).isTrue()
|
||||
assertThat(page.hasRuntimeParam()).isTrue()
|
||||
|
||||
Reference in New Issue
Block a user