@@ -11,7 +11,9 @@ import androidx.compose.foundation.layout.Row
11
11
import androidx.compose.foundation.layout.defaultMinSize
12
12
import androidx.compose.foundation.layout.fillMaxSize
13
13
import androidx.compose.foundation.layout.fillMaxWidth
14
+ import androidx.compose.foundation.layout.height
14
15
import androidx.compose.foundation.layout.padding
16
+ import androidx.compose.foundation.layout.wrapContentHeight
15
17
import androidx.compose.foundation.rememberScrollState
16
18
import androidx.compose.foundation.selection.selectable
17
19
import androidx.compose.foundation.selection.selectableGroup
@@ -72,6 +74,7 @@ import androidx.compose.ui.semantics.contentDescription
72
74
import androidx.compose.ui.semantics.customActions
73
75
import androidx.compose.ui.semantics.invisibleToUser
74
76
import androidx.compose.ui.semantics.semantics
77
+ import androidx.compose.ui.text.style.TextAlign
75
78
import androidx.compose.ui.tooling.preview.Preview
76
79
import androidx.compose.ui.unit.dp
77
80
import androidx.compose.ui.window.Dialog
@@ -263,21 +266,26 @@ fun FilterDialog(
263
266
properties = DialogProperties (usePlatformDefaultWidth = isLarge),
264
267
onDismissRequest = onDismiss
265
268
) {
266
- Surface (modifier = Modifier .testTag(TEST_TAG_DIALOG )
269
+ Surface (modifier = Modifier
270
+ .testTag(TEST_TAG_DIALOG )
267
271
.conditional(
268
272
isLarge,
269
273
ifTrue = { defaultMinSize(minHeight = 400 .dp) },
270
274
ifFalse = { fillMaxSize() }
271
- ) ) {
272
- Column {
275
+ )) {
276
+ Column (modifier = Modifier
277
+ .conditional(isLarge && criteriaSet.value.isEmpty()) {
278
+ height(400 .dp)
279
+ }
280
+ ) {
273
281
Box (
274
282
modifier = Modifier .fillMaxWidth(),
275
283
) {
276
284
ActionButton (
277
- stringResource(android.R .string.cancel),
278
- Icons .Filled .Clear ,
279
- Modifier .align(Alignment .CenterStart ),
280
- onDismiss
285
+ hintText = stringResource(android.R .string.cancel),
286
+ icon = Icons .Filled .Clear ,
287
+ modifier = Modifier .align(Alignment .CenterStart ),
288
+ onclick = onDismiss
281
289
)
282
290
Text (
283
291
text = stringResource(R .string.menu_search),
@@ -286,15 +294,16 @@ fun FilterDialog(
286
294
)
287
295
Row (modifier = Modifier .align(Alignment .CenterEnd )) {
288
296
ActionButton (
289
- stringResource(R .string.clear_all_filters),
290
- Icons .Filled .ClearAll
291
-
297
+ hintText = stringResource(R .string.clear_all_filters),
298
+ icon = Icons .Filled .ClearAll ,
299
+ enabled = criteriaSet.value.isNotEmpty()
292
300
) {
293
301
criteriaSet.value = emptySet()
294
302
}
295
303
ActionButton (
296
- stringResource(R .string.apply),
297
- Icons .Filled .Done
304
+ hintText = stringResource(R .string.apply),
305
+ icon = Icons .Filled .Done ,
306
+ enabled = isDirty
298
307
) {
299
308
onConfirmRequest(
300
309
when (criteriaSet.value.size) {
@@ -356,127 +365,142 @@ fun FilterDialog(
356
365
}
357
366
}
358
367
}
359
- Row (
360
- Modifier
361
- .minimumInteractiveComponentSize()
362
- .padding(horizontal = 16 .dp)
363
- .selectableGroup(),
364
- horizontalArrangement = Arrangement .spacedBy(4 .dp),
365
- verticalAlignment = Alignment .CenterVertically
366
- ) {
367
368
368
- val options = listOf (R .string.matchAll, R .string.matchAny)
369
- options.forEachIndexed { index, labelRes ->
370
- Row (
371
- Modifier
372
- .weight(1f )
373
- .selectable(
374
- selected = index == selectedComplex,
375
- onClick = { setSelectedComplex(index) },
376
- role = Role .RadioButton
377
- ), verticalAlignment = Alignment .CenterVertically
378
- ) {
379
- RadioButton (
380
- onClick = null ,
381
- selected = index == selectedComplex
382
- )
383
- Text (
384
- text = stringResource(labelRes),
385
- modifier = Modifier .padding(start = 8 .dp)
386
- )
369
+ if (criteriaSet.value.isEmpty()) {
370
+ Text (
371
+ text= stringResource(R .string.filter_dialog_empty),
372
+ modifier = Modifier
373
+ .padding(horizontal = 24 .dp)
374
+ .fillMaxWidth()
375
+ .weight(1f )
376
+ .wrapContentHeight(),
377
+ textAlign = TextAlign .Center
378
+ )
379
+ } else {
380
+ Row (
381
+ Modifier
382
+ .minimumInteractiveComponentSize()
383
+ .padding(horizontal = 16 .dp)
384
+ .selectableGroup(),
385
+ horizontalArrangement = Arrangement .spacedBy(4 .dp),
386
+ verticalAlignment = Alignment .CenterVertically
387
+ ) {
388
+
389
+ val options = listOf (R .string.matchAll, R .string.matchAny)
390
+ options.forEachIndexed { index, labelRes ->
391
+ Row (
392
+ Modifier
393
+ .weight(1f )
394
+ .selectable(
395
+ selected = index == selectedComplex,
396
+ onClick = { setSelectedComplex(index) },
397
+ role = Role .RadioButton
398
+ ), verticalAlignment = Alignment .CenterVertically
399
+ ) {
400
+ RadioButton (
401
+ onClick = null ,
402
+ selected = index == selectedComplex
403
+ )
404
+ Text (
405
+ text = stringResource(labelRes),
406
+ modifier = Modifier .padding(start = 8 .dp)
407
+ )
408
+ }
387
409
}
388
410
}
389
- }
390
-
391
- Column (Modifier
392
- .verticalScroll(rememberScrollState())
393
- .semantics {
394
- collectionInfo = CollectionInfo (criteriaSet.value.size, 1 )
395
- }
396
- ) {
397
411
398
- criteriaSet.value.forEachIndexed { index, criterion ->
399
- val negate = { criteriaSet.value = criteriaSet.value.negate(index) }
400
- val delete = { criteriaSet.value - = criterion }
401
- val edit = {
402
- currentEdit.value = criterion
403
- handleEdit(criterion)
412
+ Column (Modifier
413
+ .verticalScroll(rememberScrollState())
414
+ .semantics {
415
+ collectionInfo = CollectionInfo (criteriaSet.value.size, 1 )
404
416
}
405
- val title = stringResource(criterion.displayTitle)
406
- val symbol = criterion.displaySymbol.first
407
- val prettyPrint = ((criterion as ? NotCriterion )?.criterion
408
- ? : criterion).prettyPrint(LocalContext .current)
409
- val contentDescription = criterion.contentDescription(LocalContext .current)
410
- val labelDelete = stringResource(R .string.menu_delete)
411
- val labelEdit = stringResource(R .string.menu_edit)
412
- Row (
413
- modifier = Modifier
414
- .padding(horizontal = 16 .dp)
415
- .clearAndSetSemantics {
416
- this .contentDescription = contentDescription
417
- collectionItemInfo = CollectionItemInfo (index, 1 , 1 , 1 )
418
- customActions = listOf (
419
- CustomAccessibilityAction (
420
- label = " Negate" ,
421
- action = {
422
- negate()
423
- true
424
- }
425
- ),
426
- CustomAccessibilityAction (
427
- label = labelDelete,
428
- action = {
429
- delete()
430
- true
431
- }
432
- ),
433
- CustomAccessibilityAction (
434
- label = labelEdit,
435
- action = {
436
- edit
437
- true
438
- }
439
- )
440
- )
441
- },
442
- verticalAlignment = Alignment .CenterVertically
443
- ) {
444
- Icon (
445
- imageVector = criterion.displayIcon,
446
- contentDescription = title
447
- )
448
- IconButton (
449
- modifier = Modifier .semantics {
450
- invisibleToUser()
451
- },
452
- onClick = negate
453
- ) {
454
- CharIcon (symbol)
417
+ ) {
418
+
419
+ criteriaSet.value.forEachIndexed { index, criterion ->
420
+ val negate = { criteriaSet.value = criteriaSet.value.negate(index) }
421
+ val delete = { criteriaSet.value - = criterion }
422
+ val edit = {
423
+ currentEdit.value = criterion
424
+ handleEdit(criterion)
455
425
}
456
- Text (
457
- modifier = Modifier .weight(1f ),
458
- text = prettyPrint
459
- )
460
- IconButton (
461
- onClick = delete
426
+ val title = stringResource(criterion.displayTitle)
427
+ val symbol = criterion.displaySymbol.first
428
+ val prettyPrint = ((criterion as ? NotCriterion )?.criterion
429
+ ? : criterion).prettyPrint(LocalContext .current)
430
+ val contentDescription =
431
+ criterion.contentDescription(LocalContext .current)
432
+ val labelDelete = stringResource(R .string.menu_delete)
433
+ val labelEdit = stringResource(R .string.menu_edit)
434
+ Row (
435
+ modifier = Modifier
436
+ .padding(horizontal = 16 .dp)
437
+ .clearAndSetSemantics {
438
+ this .contentDescription = contentDescription
439
+ collectionItemInfo = CollectionItemInfo (index, 1 , 1 , 1 )
440
+ customActions = listOf (
441
+ CustomAccessibilityAction (
442
+ label = " Negate" ,
443
+ action = {
444
+ negate()
445
+ true
446
+ }
447
+ ),
448
+ CustomAccessibilityAction (
449
+ label = labelDelete,
450
+ action = {
451
+ delete()
452
+ true
453
+ }
454
+ ),
455
+ CustomAccessibilityAction (
456
+ label = labelEdit,
457
+ action = {
458
+ edit
459
+ true
460
+ }
461
+ )
462
+ )
463
+ },
464
+ verticalAlignment = Alignment .CenterVertically
462
465
) {
463
466
Icon (
464
- Icons . Filled . Delete ,
465
- contentDescription = labelDelete
467
+ imageVector = criterion.displayIcon ,
468
+ contentDescription = title
466
469
)
467
- }
468
- IconButton (
469
- onClick = edit
470
- ) {
471
- Icon (
472
- Icons .Filled .Edit ,
473
- contentDescription = labelEdit
470
+ IconButton (
471
+ modifier = Modifier .semantics {
472
+ invisibleToUser()
473
+ },
474
+ onClick = negate
475
+ ) {
476
+ CharIcon (symbol)
477
+ }
478
+ Text (
479
+ modifier = Modifier .weight(1f ),
480
+ text = prettyPrint
474
481
)
482
+ IconButton (
483
+ onClick = delete
484
+ ) {
485
+ Icon (
486
+ Icons .Filled .Delete ,
487
+ contentDescription = labelDelete
488
+ )
489
+ }
490
+ IconButton (
491
+ onClick = edit
492
+ ) {
493
+ Icon (
494
+ Icons .Filled .Edit ,
495
+ contentDescription = labelEdit
496
+ )
497
+ }
475
498
}
476
499
}
477
500
}
478
501
}
479
502
}
503
+
480
504
showCommentFilterPrompt?.let {
481
505
var search by rememberSaveable { mutableStateOf(it.searchString) }
482
506
@@ -498,7 +522,8 @@ fun FilterDialog(
498
522
val focusRequester = remember { FocusRequester () }
499
523
val keyboardController = LocalSoftwareKeyboardController .current
500
524
OutlinedTextField (
501
- modifier = Modifier .focusRequester(focusRequester)
525
+ modifier = Modifier
526
+ .focusRequester(focusRequester)
502
527
.onFocusChanged {
503
528
if (it.isFocused) {
504
529
keyboardController?.show()
@@ -545,6 +570,7 @@ fun ActionButton(
545
570
hintText : String ,
546
571
icon : ImageVector ,
547
572
modifier : Modifier = Modifier ,
573
+ enabled : Boolean = true,
548
574
onclick : () -> Unit ,
549
575
) {
550
576
TooltipBox (
@@ -553,7 +579,7 @@ fun ActionButton(
553
579
state = rememberTooltipState(),
554
580
modifier = modifier
555
581
) {
556
- IconButton (onClick = onclick) {
582
+ IconButton (onClick = onclick, enabled = enabled ) {
557
583
Icon (
558
584
imageVector = icon,
559
585
contentDescription = hintText
@@ -568,7 +594,16 @@ fun Set<Criterion>.negate(atIndex: Int) = mapIndexed { index, criterion ->
568
594
} else criterion
569
595
}.toSet()
570
596
571
- @Preview(device = " id:pixel" )
597
+ @Preview
598
+ @Composable
599
+ fun FilterDialogEmpty () {
600
+ FilterDialog (
601
+ account = null ,
602
+ sumInfo = SumInfo .EMPTY
603
+ )
604
+ }
605
+
606
+ @Preview
572
607
@Composable
573
608
fun FilterDialogPreview () {
574
609
FilterDialog (
0 commit comments