1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.android.settingslib.spa.widget.preference
18
19 import androidx.compose.foundation.clickable
20 import androidx.compose.runtime.Composable
21 import androidx.compose.runtime.State
22 import androidx.compose.runtime.remember
23 import androidx.compose.ui.Modifier
24 import androidx.compose.ui.graphics.vector.ImageVector
25 import com.android.settingslib.spa.framework.common.EntryMacro
26 import com.android.settingslib.spa.framework.common.EntrySearchData
27 import com.android.settingslib.spa.framework.compose.navigator
28 import com.android.settingslib.spa.framework.compose.stateOf
29 import com.android.settingslib.spa.framework.util.EntryHighlight
30 import com.android.settingslib.spa.framework.util.wrapOnClickWithLog
31 import com.android.settingslib.spa.widget.ui.createSettingsIcon
32
33 data class SimplePreferenceMacro(
34 val title: String,
35 val summary: String? = null,
36 val icon: ImageVector? = null,
37 val disabled: Boolean = false,
38 val clickRoute: String? = null,
39 val searchKeywords: List<String> = emptyList(),
40 ) : EntryMacro {
41 @Composable
UiLayoutnull42 override fun UiLayout() {
43 Preference(model = object : PreferenceModel {
44 override val title: String = this@SimplePreferenceMacro.title
45 override val summary = stateOf(this@SimplePreferenceMacro.summary ?: "")
46 override val icon = createSettingsIcon(this@SimplePreferenceMacro.icon)
47 override val enabled = stateOf(!this@SimplePreferenceMacro.disabled)
48 override val onClick = navigator(clickRoute)
49 })
50 }
51
getSearchDatanull52 override fun getSearchData(): EntrySearchData {
53 return EntrySearchData(
54 title = this@SimplePreferenceMacro.title,
55 keyword = searchKeywords
56 )
57 }
58 }
59
60 /**
61 * The widget model for [Preference] widget.
62 */
63 interface PreferenceModel {
64 /**
65 * The title of this [Preference].
66 */
67 val title: String
68
69 /**
70 * The summary of this [Preference].
71 */
72 val summary: State<String>
73 get() = stateOf("")
74
75 /**
76 * The icon of this [Preference].
77 *
78 * Default is `null` which means no icon.
79 */
80 val icon: (@Composable () -> Unit)?
81 get() = null
82
83 /**
84 * Indicates whether this [Preference] is enabled.
85 *
86 * Disabled [Preference] will be displayed in disabled style.
87 */
88 val enabled: State<Boolean>
89 get() = stateOf(true)
90
91 /**
92 * The on click handler of this [Preference].
93 *
94 * This also indicates whether this [Preference] is clickable.
95 */
96 val onClick: (() -> Unit)?
97 get() = null
98 }
99
100 /**
101 * Preference widget.
102 *
103 * Data is provided through [PreferenceModel].
104 */
105 @Composable
Preferencenull106 fun Preference(
107 model: PreferenceModel,
108 singleLineSummary: Boolean = false,
109 ) {
110 val onClickWithLog = wrapOnClickWithLog(model.onClick)
111 val modifier = remember(model.enabled.value) {
112 if (onClickWithLog != null) {
113 Modifier.clickable(
114 enabled = model.enabled.value,
115 onClick = onClickWithLog
116 )
117 } else Modifier
118 }
119 EntryHighlight {
120 BasePreference(
121 title = model.title,
122 summary = model.summary,
123 singleLineSummary = singleLineSummary,
124 modifier = modifier,
125 icon = model.icon,
126 enabled = model.enabled,
127 )
128 }
129 }
130