import 'package:comunic/ui/widgets/icon_button_badge.dart'; import 'package:flutter/material.dart'; /// Custom dropdown built for Appbar /// /// @author Pierre Hubert const _overlay_w = 300.0; const _overlay_h = 400.0; class AppBarCustomDropDownWidget extends StatefulWidget { final Widget icon; final int notificationsBadge; final Widget Function(BuildContext) onBuildOverlay; const AppBarCustomDropDownWidget({ Key? key, required this.icon, required this.notificationsBadge, required this.onBuildOverlay, }) : super(key: key); @override AppBarCustomDropDownWidgetState createState() => AppBarCustomDropDownWidgetState(); } class AppBarCustomDropDownWidgetState extends State { bool _visible = false; @override Widget build(BuildContext context) { return IconButtonWithBadge( icon: widget.icon, onPressed: toggleOverlay, number: widget.notificationsBadge, active: _visible, ); } void toggleOverlay() async { setState(() => _visible = !_visible); if (_visible) { RenderBox renderBox = context.findRenderObject() as RenderBox; final size = renderBox.size; final offset = renderBox.localToGlobal(Offset(size.width, size.height)); Navigator.of(context).push(_AppBarCustomPopupRoute( onBuild: widget.onBuildOverlay, showContext: context, offset: offset, onDispose: () => setState(() => _visible = false), )); } else Navigator.of(context).pop(); } } class _AppBarCustomPopupRoute extends PopupRoute { final BuildContext showContext; final Widget Function(BuildContext) onBuild; final Offset offset; final void Function() onDispose; _AppBarCustomPopupRoute({ required this.showContext, required this.onBuild, required this.offset, required this.onDispose, }); @override void dispose() { super.dispose(); onDispose(); } @override Color? get barrierColor => null; @override bool get barrierDismissible => true; @override String get barrierLabel => MaterialLocalizations.of(showContext).modalBarrierDismissLabel; @override Widget buildPage(BuildContext context, Animation animation, Animation secondaryAnimation) { return MediaQuery.removePadding( context: context, removeTop: true, removeBottom: true, removeLeft: true, removeRight: true, child: Builder( builder: (BuildContext context) { return _PopupContentBody( onBuild: onBuild, offset: offset, ); }, ), ); } @override Duration get transitionDuration => Duration(milliseconds: 0); } class _PopupContentBody extends StatelessWidget { final Widget Function(BuildContext)? onBuild; final Offset? offset; const _PopupContentBody({Key? key, this.onBuild, this.offset}) : super(key: key); @override Widget build(BuildContext context) { return Stack( children: [ GestureDetector( onTapDown: (d) => Navigator.of(context).pop(), onPanDown: (d) => Navigator.of(context).pop(), child: Container(color: Color(0x55000000)), ), Positioned( left: offset!.dx - _overlay_w + 4, top: offset!.dy - 4, width: _overlay_w, height: _overlay_h, child: Scaffold( body: Card(child: onBuild!(context)), backgroundColor: Colors.transparent, ), ) ], ); } }