123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- import 'package:expandable/expandable.dart';
- import 'package:flutter/material.dart';
- import 'package:photos/ente_theme_data.dart';
- class MenuItemWidget extends StatefulWidget {
- final Widget captionedTextWidget;
- final bool isExpandable;
- /// leading icon can be passed without specifing size of icon,
- /// this component sets size to 20x20 irrespective of passed icon's size
- final IconData? leadingIcon;
- final Color? leadingIconColor;
- /// trailing icon can be passed without size as default size set by
- /// flutter is what this component expects
- final IconData? trailingIcon;
- final Widget? trailingSwitch;
- final bool trailingIconIsMuted;
- final VoidCallback? onTap;
- final VoidCallback? onDoubleTap;
- final Color? menuItemColor;
- final bool alignCaptionedTextToLeft;
- final double borderRadius;
- final Color? pressedColor;
- final ExpandableController? expandableController;
- final bool isBottomBorderRadiusRemoved;
- final bool isTopBorderRadiusRemoved;
- /// disable gesture detector if not used
- final bool isGestureDetectorDisabled;
- const MenuItemWidget({
- required this.captionedTextWidget,
- this.isExpandable = false,
- this.leadingIcon,
- this.leadingIconColor,
- this.trailingIcon,
- this.trailingSwitch,
- this.trailingIconIsMuted = false,
- this.onTap,
- this.onDoubleTap,
- this.menuItemColor,
- this.alignCaptionedTextToLeft = false,
- this.borderRadius = 4.0,
- this.pressedColor,
- this.expandableController,
- this.isBottomBorderRadiusRemoved = false,
- this.isTopBorderRadiusRemoved = false,
- this.isGestureDetectorDisabled = false,
- Key? key,
- }) : super(key: key);
- @override
- State<MenuItemWidget> createState() => _MenuItemWidgetState();
- }
- class _MenuItemWidgetState extends State<MenuItemWidget> {
- Color? menuItemColor;
- @override
- void initState() {
- menuItemColor = widget.menuItemColor;
- if (widget.expandableController != null) {
- widget.expandableController!.addListener(() {
- setState(() {});
- });
- }
- super.initState();
- }
- @override
- void didChangeDependencies() {
- menuItemColor = widget.menuItemColor;
- super.didChangeDependencies();
- }
- @override
- void dispose() {
- if (widget.expandableController != null) {
- widget.expandableController!.dispose();
- }
- super.dispose();
- }
- @override
- Widget build(BuildContext context) {
- return widget.isExpandable || widget.isGestureDetectorDisabled
- ? menuItemWidget(context)
- : GestureDetector(
- onTap: widget.onTap,
- onDoubleTap: widget.onDoubleTap,
- onTapDown: _onTapDown,
- onTapUp: _onTapUp,
- onTapCancel: _onCancel,
- child: menuItemWidget(context),
- );
- }
- Widget menuItemWidget(BuildContext context) {
- final enteColorScheme = Theme.of(context).colorScheme.enteTheme.colorScheme;
- final borderRadius = Radius.circular(widget.borderRadius);
- final isExpanded = widget.expandableController?.value;
- final bottomBorderRadius =
- (isExpanded != null && isExpanded) || widget.isBottomBorderRadiusRemoved
- ? const Radius.circular(0)
- : borderRadius;
- final topBorderRadius = widget.isTopBorderRadiusRemoved
- ? const Radius.circular(0)
- : borderRadius;
- return AnimatedContainer(
- duration: const Duration(milliseconds: 20),
- width: double.infinity,
- padding: const EdgeInsets.only(left: 16, right: 12),
- decoration: BoxDecoration(
- borderRadius: BorderRadius.only(
- topLeft: topBorderRadius,
- topRight: topBorderRadius,
- bottomLeft: bottomBorderRadius,
- bottomRight: bottomBorderRadius,
- ),
- color: menuItemColor,
- ),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- widget.alignCaptionedTextToLeft && widget.leadingIcon == null
- ? const SizedBox.shrink()
- : Padding(
- padding: const EdgeInsets.only(right: 10),
- child: SizedBox(
- height: 20,
- width: 20,
- child: widget.leadingIcon == null
- ? const SizedBox.shrink()
- : FittedBox(
- fit: BoxFit.contain,
- child: Icon(
- widget.leadingIcon,
- color: widget.leadingIconColor ??
- enteColorScheme.strokeBase,
- ),
- ),
- ),
- ),
- widget.captionedTextWidget,
- widget.expandableController != null
- ? AnimatedOpacity(
- duration: const Duration(milliseconds: 100),
- curve: Curves.easeInOut,
- opacity: isExpanded! ? 0 : 1,
- child: AnimatedSwitcher(
- transitionBuilder: (child, animation) {
- return ScaleTransition(scale: animation, child: child);
- },
- duration: const Duration(milliseconds: 200),
- switchInCurve: Curves.easeOut,
- child: isExpanded
- ? const SizedBox.shrink()
- : Icon(widget.trailingIcon),
- ),
- )
- : widget.trailingIcon != null
- ? Icon(
- widget.trailingIcon,
- color: widget.trailingIconIsMuted
- ? enteColorScheme.strokeMuted
- : null,
- )
- : widget.trailingSwitch ?? const SizedBox.shrink(),
- ],
- ),
- );
- }
- void _onTapDown(details) {
- setState(() {
- menuItemColor = widget.pressedColor ?? widget.menuItemColor;
- });
- }
- void _onTapUp(details) {
- Future.delayed(
- const Duration(milliseconds: 100),
- () => setState(() {
- menuItemColor = widget.menuItemColor;
- }),
- );
- }
- void _onCancel() {
- setState(() {
- menuItemColor = widget.menuItemColor;
- });
- }
- }
|