expandable_menu_item_widget.dart 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import 'package:expandable/expandable.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:photos/ente_theme_data.dart';
  4. import 'package:photos/ui/components/captioned_text_widget.dart';
  5. import 'package:photos/ui/components/menu_item_widget/menu_item_widget.dart';
  6. import 'package:photos/ui/settings/common_settings.dart';
  7. import 'package:photos/ui/settings/inherited_settings_state.dart';
  8. class ExpandableMenuItemWidget extends StatefulWidget {
  9. final String title;
  10. final Widget selectionOptionsWidget;
  11. final IconData leadingIcon;
  12. const ExpandableMenuItemWidget({
  13. required this.title,
  14. required this.selectionOptionsWidget,
  15. required this.leadingIcon,
  16. Key? key,
  17. }) : super(key: key);
  18. @override
  19. State<ExpandableMenuItemWidget> createState() =>
  20. _ExpandableMenuItemWidgetState();
  21. }
  22. class _ExpandableMenuItemWidgetState extends State<ExpandableMenuItemWidget> {
  23. final expandableController = ExpandableController(initialExpanded: false);
  24. @override
  25. void initState() {
  26. expandableController.addListener(_expandableControllerListener);
  27. super.initState();
  28. }
  29. @override
  30. void dispose() {
  31. expandableController.removeListener(_expandableControllerListener);
  32. super.dispose();
  33. }
  34. @override
  35. Widget build(BuildContext context) {
  36. final isAnySectionExpanded =
  37. InheritedSettingsState.maybeOf(context)?.isAnySectionExpanded ?? false;
  38. final isCurrentSectionExpanded = expandableController.expanded;
  39. final isSuppressed = isAnySectionExpanded && !isCurrentSectionExpanded;
  40. final enteColorScheme = Theme.of(context).colorScheme.enteTheme.colorScheme;
  41. final backgroundColor =
  42. MediaQuery.of(context).platformBrightness == Brightness.light
  43. ? enteColorScheme.backgroundElevated2
  44. : enteColorScheme.backgroundElevated;
  45. return Padding(
  46. padding: EdgeInsets.only(bottom: expandableController.value ? 8 : 0),
  47. child: AnimatedContainer(
  48. curve: Curves.ease,
  49. duration: const Duration(milliseconds: 200),
  50. decoration: BoxDecoration(
  51. color: expandableController.value ? backgroundColor : null,
  52. borderRadius: BorderRadius.circular(4),
  53. ),
  54. child: ExpandableNotifier(
  55. controller: expandableController,
  56. child: ScrollOnExpand(
  57. child: ExpandablePanel(
  58. header: MenuItemWidget(
  59. captionedTextWidget: CaptionedTextWidget(
  60. title: widget.title,
  61. makeTextBold: true,
  62. textColor: isSuppressed
  63. ? enteColorScheme.textMuted
  64. : enteColorScheme.textBase,
  65. ),
  66. isExpandable: true,
  67. leadingIcon: widget.leadingIcon,
  68. leadingIconColor: isSuppressed
  69. ? enteColorScheme.strokeMuted
  70. : enteColorScheme.strokeBase,
  71. trailingIcon: Icons.expand_more,
  72. trailingIconColor: isSuppressed
  73. ? enteColorScheme.strokeMuted
  74. : enteColorScheme.strokeBase,
  75. menuItemColor: enteColorScheme.fillFaint,
  76. expandableController: expandableController,
  77. ),
  78. collapsed: const SizedBox.shrink(),
  79. expanded: Padding(
  80. padding: const EdgeInsets.only(bottom: 4),
  81. child: widget.selectionOptionsWidget,
  82. ),
  83. theme: getExpandableTheme(),
  84. controller: expandableController,
  85. ),
  86. ),
  87. ),
  88. ),
  89. );
  90. }
  91. void _expandableControllerListener() {
  92. setState(() {
  93. if (expandableController.expanded) {
  94. InheritedSettingsState.of(context).increment();
  95. } else {
  96. InheritedSettingsState.of(context).decrement();
  97. }
  98. });
  99. }
  100. }