Skip to content

Commit

Permalink
YaruPopupMenuButton: add multi check item (#319)
Browse files Browse the repository at this point in the history
  • Loading branch information
Feichtmeier committed Oct 23, 2022
1 parent b1aebdb commit c227e22
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 52 deletions.
151 changes: 99 additions & 52 deletions example/lib/pages/popup_page.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:yaru_widgets/yaru_widgets.dart';

class PopupPage extends StatefulWidget {
Expand All @@ -11,62 +12,108 @@ class PopupPage extends StatefulWidget {
class _PopupPageState extends State<PopupPage> {
MyEnum myEnum = MyEnum.option1;
Set<MyEnum> enumSet = {MyEnum.option1, MyEnum.option3};

@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.all(kYaruPagePadding),
child: Row(
children: [
YaruPopupMenuButton<MyEnum>(
initialValue: myEnum,
onSelected: (v) {
setState(() {
myEnum = v;
});
},
child: Text(myEnum.name),
itemBuilder: (context) {
return [
for (final value in MyEnum.values)
PopupMenuItem(
value: value,
child: Text(
value.name,
),
)
];
},
return Column(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.all(kYaruPagePadding),
child: Wrap(
spacing: 10,
runSpacing: 10,
children: [
YaruPopupMenuButton<MyEnum>(
initialValue: myEnum,
onSelected: (v) {
setState(() {
myEnum = v;
});
},
child: Text(myEnum.name),
itemBuilder: (context) {
return [
for (final value in MyEnum.values)
PopupMenuItem(
value: value,
child: Text(
value.name,
),
)
];
},
),
YaruPopupMenuButton<MyEnum>(
onSelected: (value) {
if (enumSet.contains(value)) {
enumSet.remove(value);
} else {
enumSet.add(value);
}
},
child: const Text('Multi Select'),
itemBuilder: (context) {
return [
for (final value in MyEnum.values)
YaruCheckedPopupMenuItem<MyEnum>(
padding: EdgeInsets.zero,
value: value,
checked: enumSet.contains(value),
child: Text(value.name),
)
];
},
),
YaruPopupMenuButton<MyEnum>(
child: const Text('Multi Select Without close'),
itemBuilder: (context) {
return [
for (final value in MyEnum.values)
YaruMultiSelectPopupMenuItem<MyEnum>(
padding: EdgeInsets.zero,
value: value,
child: Text(value.name),
checked: enumSet.contains(value),
onChanged: (checked) {
// Handle model changes here
setState(() {
checked
? enumSet.add(value)
: enumSet.remove(value);
});
},
)
];
},
)
],
),
),
const SizedBox(
width: 10,
),
const SizedBox(
height: 500,
width: 500,
child: Markdown(
data: '''
YaruMultiSelectPopupMenuItem<MyEnum>(
padding: EdgeInsets.zero,
value: value,
child: Text(value.name),
checked: enumSet.contains(value),
onChanged: (checked) {
// Handle model changes here
setState(() {
checked
? enumSet.add(value)
: enumSet.remove(value);
});
},
)
''',
),
StatefulBuilder(
builder: (context, setState) {
return YaruPopupMenuButton<MyEnum>(
onSelected: (value) {
if (enumSet.contains(value)) {
enumSet.remove(value);
} else {
enumSet.add(value);
}
},
child: const Text('Multi Select'),
itemBuilder: (context) {
return [
for (final value in MyEnum.values)
YaruCheckedPopupMenuItem<MyEnum>(
padding: EdgeInsets.zero,
value: value,
checked: enumSet.contains(value),
child: Text(value.name),
)
];
},
);
},
)
],
),
),
],
);
}
}
Expand Down
1 change: 1 addition & 0 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ environment:
dependencies:
flutter:
sdk: flutter
flutter_markdown: ^0.6.12
handy_window: ^0.1.2
provider: ^6.0.2
yaru: ^0.4.1
Expand Down
56 changes: 56 additions & 0 deletions lib/src/controls/yaru_popup_menu_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,59 @@ class _YaruCheckMark extends StatelessWidget {
);
}
}

class YaruMultiSelectPopupMenuItem<T> extends PopupMenuItem<T> {
/// Creates a popup menu item with a checkmark that does not close on tap.
///
/// By default, the menu item is [enabled] but unchecked. To mark the item as
/// checked, set [checked] to true.
///
/// The `checked` and `enabled` arguments must not be null.
const YaruMultiSelectPopupMenuItem({
super.key,
super.value,
this.checked = false,
super.enabled,
super.padding,
super.height,
super.mouseCursor,
super.child,
this.onChanged,
});

final bool checked;
final ValueChanged<bool>? onChanged;

@override
PopupMenuItemState<T, YaruMultiSelectPopupMenuItem<T>> createState() =>
_YaruMultiSelectPopupMenuItemState<T>();
}

class _YaruMultiSelectPopupMenuItemState<T>
extends PopupMenuItemState<T, YaruMultiSelectPopupMenuItem<T>> {
var _checked = false;

@override
void handleTap() {
setState(() => _checked = !_checked);
widget.onChanged?.call(_checked);
}

@override
void initState() {
super.initState();
_checked = widget.checked;
}

@override
Widget buildChild() {
return IgnorePointer(
child: ListTile(
minLeadingWidth: 18,
enabled: widget.enabled,
leading: _YaruCheckMark(checked: _checked),
title: widget.child,
),
);
}
}

0 comments on commit c227e22

Please sign in to comment.