17
17
18
18
package com.geeksville.mesh.ui.node.components
19
19
20
- import androidx.compose.animation.AnimatedVisibility
21
20
import androidx.compose.foundation.background
22
21
import androidx.compose.foundation.clickable
23
22
import androidx.compose.foundation.layout.Box
24
23
import androidx.compose.foundation.layout.Column
25
24
import androidx.compose.foundation.layout.Row
26
25
import androidx.compose.foundation.layout.defaultMinSize
27
26
import androidx.compose.foundation.layout.fillMaxWidth
27
+ import androidx.compose.foundation.layout.height
28
28
import androidx.compose.foundation.layout.heightIn
29
29
import androidx.compose.foundation.layout.padding
30
+ import androidx.compose.foundation.layout.wrapContentHeight
30
31
import androidx.compose.foundation.text.KeyboardActions
31
32
import androidx.compose.foundation.text.KeyboardOptions
32
33
import androidx.compose.material.icons.Icons
33
34
import androidx.compose.material.icons.automirrored.filled.Sort
34
35
import androidx.compose.material.icons.filled.Clear
35
36
import androidx.compose.material.icons.filled.Done
36
37
import androidx.compose.material.icons.filled.Search
38
+ import androidx.compose.material3.Checkbox
37
39
import androidx.compose.material3.DropdownMenu
38
40
import androidx.compose.material3.DropdownMenuItem
39
41
import androidx.compose.material3.HorizontalDivider
40
42
import androidx.compose.material3.Icon
41
43
import androidx.compose.material3.IconButton
42
44
import androidx.compose.material3.MaterialTheme
45
+ import androidx.compose.material3.MenuDefaults
43
46
import androidx.compose.material3.OutlinedTextField
47
+ import androidx.compose.material3.RadioButton
44
48
import androidx.compose.material3.Text
45
49
import androidx.compose.runtime.Composable
46
50
import androidx.compose.runtime.getValue
@@ -54,6 +58,7 @@ import androidx.compose.ui.platform.LocalFocusManager
54
58
import androidx.compose.ui.res.stringResource
55
59
import androidx.compose.ui.text.font.FontWeight
56
60
import androidx.compose.ui.text.input.ImeAction
61
+ import androidx.compose.ui.text.style.TextAlign
57
62
import androidx.compose.ui.tooling.preview.PreviewLightDark
58
63
import androidx.compose.ui.unit.dp
59
64
import com.geeksville.mesh.ui.common.preview.LargeFontPreview
@@ -184,104 +189,94 @@ private fun NodeSortButton(
184
189
onDismissRequest = { expanded = false },
185
190
modifier = Modifier .background(MaterialTheme .colorScheme.background.copy(alpha = 1f )),
186
191
) {
192
+ DropdownMenuTitle (text = stringResource(R .string.node_sort_title))
193
+
187
194
NodeSortOption .entries.forEach { sort ->
188
- DropdownMenuItem (
189
- onClick = {
190
- onSortSelect(sort)
191
- expanded = false
192
- },
193
- text = {
194
- Text (
195
- text = stringResource(id = sort.stringRes),
196
- fontWeight = if (sort == currentSortOption) FontWeight .ExtraBold else null ,
197
- )
198
- },
195
+ DropdownMenuRadio (
196
+ text = stringResource(id = sort.stringRes),
197
+ selected = sort == currentSortOption,
198
+ onClick = { onSortSelect(sort) },
199
199
)
200
200
}
201
- HorizontalDivider ()
202
- DropdownMenuItem (
203
- onClick = {
204
- toggles.onToggleIncludeUnknown()
205
- expanded = false
206
- },
207
- text = {
208
- Row {
209
- AnimatedVisibility (visible = toggles.includeUnknown) {
210
- Icon (
211
- imageVector = Icons .Default .Done ,
212
- contentDescription = null ,
213
- modifier = Modifier .padding(end = 4 .dp),
214
- )
215
- }
216
- Text (text = stringResource(id = R .string.node_filter_include_unknown))
217
- }
218
- },
201
+
202
+ HorizontalDivider (modifier = Modifier .padding(MenuDefaults .DropdownMenuItemContentPadding ))
203
+
204
+ DropdownMenuTitle (text = stringResource(R .string.node_filter_title))
205
+
206
+ DropdownMenuCheck (
207
+ text = stringResource(R .string.node_filter_include_unknown),
208
+ checked = toggles.includeUnknown,
209
+ onClick = toggles.onToggleIncludeUnknown,
219
210
)
220
- DropdownMenuItem (
221
- onClick = {
222
- toggles.onToggleOnlyOnline()
223
- expanded = false
224
- },
225
- text = {
226
- Row {
227
- AnimatedVisibility (visible = toggles.onlyOnline) {
228
- Icon (
229
- imageVector = Icons .Default .Done ,
230
- contentDescription = null ,
231
- modifier = Modifier .padding(end = 4 .dp),
232
- )
233
- }
234
- Text (text = stringResource(id = R .string.node_filter_only_online))
235
- }
236
- },
211
+
212
+ DropdownMenuCheck (
213
+ text = stringResource(R .string.node_filter_only_online),
214
+ checked = toggles.onlyOnline,
215
+ onClick = toggles.onToggleOnlyOnline,
237
216
)
238
- DropdownMenuItem (
239
- onClick = {
240
- toggles.onToggleOnlyDirect()
241
- expanded = false
242
- },
243
- text = {
244
- Row {
245
- AnimatedVisibility (visible = toggles.onlyDirect) {
246
- Icon (
247
- imageVector = Icons .Default .Done ,
248
- contentDescription = null ,
249
- modifier = Modifier .padding(end = 4 .dp),
250
- )
251
- }
252
- Text (text = stringResource(id = R .string.node_filter_only_direct))
253
- }
254
- },
217
+
218
+ DropdownMenuCheck (
219
+ text = stringResource(R .string.node_filter_only_direct),
220
+ checked = toggles.onlyDirect,
221
+ onClick = toggles.onToggleOnlyDirect,
255
222
)
256
- HorizontalDivider ()
257
- DropdownMenuItem (
258
- onClick = {
259
- toggles.onToggleShowIgnored()
260
- expanded = false
261
- },
262
- text = {
263
- Row {
264
- AnimatedVisibility (visible = toggles.showIgnored) {
265
- Icon (
266
- imageVector = Icons .Default .Done ,
267
- contentDescription = null ,
268
- modifier = Modifier .padding(end = 4 .dp),
269
- )
270
- }
271
- Text (text = stringResource(id = R .string.node_filter_show_ignored))
272
- if (toggles.ignoredNodeCount > 0 ) {
273
- Text (
274
- text = " (${toggles.ignoredNodeCount} )" ,
275
- color = MaterialTheme .colorScheme.primary,
276
- modifier = Modifier .padding(start = 4 .dp),
277
- )
278
- }
223
+
224
+ DropdownMenuCheck (
225
+ text = stringResource(R .string.node_filter_show_ignored),
226
+ checked = toggles.showIgnored,
227
+ onClick = toggles.onToggleShowIgnored,
228
+ trailing =
229
+ if (toggles.ignoredNodeCount > 0 ) {
230
+ {
231
+ Text (
232
+ text = " (${toggles.ignoredNodeCount} )" ,
233
+ color = MaterialTheme .colorScheme.primary,
234
+ modifier = Modifier .padding(start = 4 .dp),
235
+ )
279
236
}
237
+ } else {
238
+ null
280
239
},
281
240
)
282
241
}
283
242
}
284
243
244
+ @Composable
245
+ private fun DropdownMenuTitle (text : String ) {
246
+ Text (
247
+ text = text,
248
+ modifier =
249
+ Modifier .height(48 .dp)
250
+ .padding(MenuDefaults .DropdownMenuItemContentPadding )
251
+ .wrapContentHeight(align = Alignment .CenterVertically ),
252
+ fontWeight = FontWeight .ExtraBold ,
253
+ )
254
+ }
255
+
256
+ @Composable
257
+ private fun DropdownMenuRadio (text : String , selected : Boolean , onClick : () -> Unit ) {
258
+ DropdownMenuItem (
259
+ onClick = onClick,
260
+ leadingIcon = { RadioButton (selected = selected, onClick = null ) },
261
+ text = { Text (text = text) },
262
+ )
263
+ }
264
+
265
+ @Composable
266
+ private fun DropdownMenuCheck (
267
+ text : String ,
268
+ checked : Boolean ,
269
+ onClick : () -> Unit ,
270
+ trailing : @Composable (() -> Unit )? = null,
271
+ ) {
272
+ DropdownMenuItem (
273
+ onClick = onClick,
274
+ leadingIcon = { Checkbox (checked = checked, onCheckedChange = null ) },
275
+ trailingIcon = trailing,
276
+ text = { Text (text = text) },
277
+ )
278
+ }
279
+
285
280
@PreviewLightDark
286
281
@LargeFontPreview
287
282
@Composable
0 commit comments