1 /*
2  * Copyright (C) 2023 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.ui.Modifier
22 import androidx.compose.ui.graphics.vector.ImageVector
23 import com.android.settingslib.spa.framework.common.EntryMacro
24 import com.android.settingslib.spa.framework.common.EntrySearchData
25 import com.android.settingslib.spa.framework.compose.navigator
26 import com.android.settingslib.spa.framework.util.EntryHighlight
27 import com.android.settingslib.spa.framework.util.wrapOnClickWithLog
28 import com.android.settingslib.spa.widget.ui.createSettingsIcon
29 
30 data class SimplePreferenceMacro(
31     val title: String,
32     val summary: String? = null,
33     val icon: ImageVector? = null,
34     val disabled: Boolean = false,
35     val clickRoute: String? = null,
36     val searchKeywords: List<String> = emptyList(),
37 ) : EntryMacro {
38     @Composable
UiLayoutnull39     override fun UiLayout() {
40         Preference(model = object : PreferenceModel {
41             override val title: String = this@SimplePreferenceMacro.title
42             override val summary = { this@SimplePreferenceMacro.summary ?: "" }
43             override val icon = createSettingsIcon(this@SimplePreferenceMacro.icon)
44             override val enabled = { !disabled }
45             override val onClick = navigator(clickRoute)
46         })
47     }
48 
getSearchDatanull49     override fun getSearchData(): EntrySearchData {
50         return EntrySearchData(
51             title = this@SimplePreferenceMacro.title,
52             keyword = searchKeywords
53         )
54     }
55 }
56 
57 /**
58  * The widget model for [Preference] widget.
59  */
60 interface PreferenceModel {
61     /**
62      * The title of this [Preference].
63      */
64     val title: String
65 
66     /**
67      * The content description of [title].
68      */
69     val titleContentDescription: String?
70         get() = null
71 
72     /**
73      * The summary of this [Preference].
74      */
75     val summary: () -> String
<lambda>null76         get() = { "" }
77 
78     /**
79      * The content description of [summary].
80      */
81     val summaryContentDescription: () -> String?
<lambda>null82         get() = { null }
83 
84     /**
85      * The icon of this [Preference].
86      *
87      * Default is `null` which means no icon.
88      */
89     val icon: (@Composable () -> Unit)?
90         get() = null
91 
92     /**
93      * Indicates whether this [Preference] is enabled.
94      *
95      * Disabled [Preference] will be displayed in disabled style.
96      */
97     val enabled: () -> Boolean
<lambda>null98         get() = { true }
99 
100     /**
101      * The on click handler of this [Preference].
102      *
103      * This also indicates whether this [Preference] is clickable.
104      */
105     val onClick: (() -> Unit)?
106         get() = null
107 }
108 
109 /**
110  * Preference widget.
111  *
112  * Data is provided through [PreferenceModel].
113  */
114 @Composable
Preferencenull115 fun Preference(
116     model: PreferenceModel,
117     singleLineSummary: Boolean = false,
118 ) {
119     val onClickWithLog = wrapOnClickWithLog(model.onClick)
120     val enabled = model.enabled()
121     val modifier = if (onClickWithLog != null) {
122         Modifier.clickable(enabled = enabled, onClick = onClickWithLog)
123     } else Modifier
124     EntryHighlight {
125         BasePreference(
126             title = model.title,
127             titleContentDescription = model.titleContentDescription,
128             summary = model.summary,
129             summaryContentDescription = model.summaryContentDescription,
130             singleLineSummary = singleLineSummary,
131             modifier = modifier,
132             icon = model.icon,
133             enabled = model.enabled,
134         )
135     }
136 }
137