import 'dart:collection'; import 'package:appflowy_popover/appflowy_popover.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; typedef EntryMap = LinkedHashMap; class RootOverlayEntry { final EntryMap _entries = EntryMap(); RootOverlayEntry(); void addEntry( BuildContext context, PopoverState newState, OverlayEntry entry, bool asBarrier, ) { _entries[newState] = OverlayEntryContext(entry, newState, asBarrier); Overlay.of(context)?.insert(entry); } bool contains(PopoverState oldState) { return _entries.containsKey(oldState); } void removeEntry(PopoverState oldState) { if (_entries.isEmpty) return; final removedEntry = _entries.remove(oldState); removedEntry?.overlayEntry.remove(); } bool get isEmpty => _entries.isEmpty; bool get isNotEmpty => _entries.isNotEmpty; bool hasEntry() { return _entries.isNotEmpty; } PopoverState? popEntry() { if (_entries.isEmpty) return null; final lastEntry = _entries.values.last; _entries.remove(lastEntry.popoverState); lastEntry.overlayEntry.remove(); lastEntry.popoverState.widget.onClose?.call(); if (lastEntry.asBarrier) { return lastEntry.popoverState; } else { return popEntry(); } } } class OverlayEntryContext { final bool asBarrier; final PopoverState popoverState; final OverlayEntry overlayEntry; OverlayEntryContext( this.overlayEntry, this.popoverState, this.asBarrier, ); } class PopoverMask extends StatefulWidget { final void Function() onTap; final void Function()? onExit; final Decoration? decoration; const PopoverMask( {Key? key, required this.onTap, this.onExit, this.decoration}) : super(key: key); @override State createState() => _PopoverMaskState(); } class _PopoverMaskState extends State { @override void initState() { HardwareKeyboard.instance.addHandler(_handleGlobalKeyEvent); super.initState(); } bool _handleGlobalKeyEvent(KeyEvent event) { if (event.logicalKey == LogicalKeyboardKey.escape) { if (widget.onExit != null) { widget.onExit!(); } return true; } else { return false; } } @override void deactivate() { HardwareKeyboard.instance.removeHandler(_handleGlobalKeyEvent); super.deactivate(); } @override Widget build(BuildContext context) { return GestureDetector( onTap: widget.onTap, child: Container( decoration: widget.decoration, ), ); } }