diff --git a/frontend/app_flowy/packages/appflowy_popover/example/lib/example_button.dart b/frontend/app_flowy/packages/appflowy_popover/example/lib/example_button.dart index 956e1fdbaa..80b06422ed 100644 --- a/frontend/app_flowy/packages/appflowy_popover/example/lib/example_button.dart +++ b/frontend/app_flowy/packages/appflowy_popover/example/lib/example_button.dart @@ -7,16 +7,7 @@ class PopoverMenu extends StatefulWidget { } class _PopoverMenuState extends State { - final PopoverMutex exclusive = PopoverMutex(); - late PopoverController firstPopover; - late PopoverController secondPopover; - - @override - void initState() { - firstPopover = PopoverController(mutex: exclusive); - secondPopover = PopoverController(mutex: exclusive); - super.initState(); - } + final PopoverMutex popOverMutex = PopoverMutex(); @override Widget build(BuildContext context) { @@ -27,7 +18,9 @@ class _PopoverMenuState extends State { child: ListView(children: [ const Text("App"), Popover( - controller: firstPopover, + triggerActions: + PopoverTriggerActionFlags.hover | PopoverTriggerActionFlags.click, + mutex: popOverMutex, offset: const Offset(10, 0), targetAnchor: Alignment.topRight, followerAnchor: Alignment.topLeft, @@ -35,19 +28,14 @@ class _PopoverMenuState extends State { return PopoverMenu(); }, child: TextButton( - onPressed: () { - firstPopover.show(); - }, - onHover: (value) { - if (value) { - firstPopover.show(); - } - }, + onPressed: () {}, child: const Text("First"), ), ), Popover( - controller: secondPopover, + triggerActions: + PopoverTriggerActionFlags.hover | PopoverTriggerActionFlags.click, + mutex: popOverMutex, offset: const Offset(10, 0), targetAnchor: Alignment.topRight, followerAnchor: Alignment.topLeft, @@ -55,14 +43,7 @@ class _PopoverMenuState extends State { return PopoverMenu(); }, child: TextButton( - onPressed: () { - secondPopover.show(); - }, - onHover: (value) { - if (value) { - secondPopover.show(); - } - }, + onPressed: () {}, child: const Text("Second"), ), ), @@ -72,14 +53,12 @@ class _PopoverMenuState extends State { } class ExampleButton extends StatelessWidget { - final PopoverController _popover = PopoverController(); - final String label; final Alignment targetAnchor; final Alignment followerAnchor; final Offset? offset; - ExampleButton({ + const ExampleButton({ Key? key, required this.label, this.targetAnchor = Alignment.topLeft, @@ -90,16 +69,11 @@ class ExampleButton extends StatelessWidget { @override Widget build(BuildContext context) { return Popover( - controller: _popover, targetAnchor: targetAnchor, followerAnchor: followerAnchor, + triggerActions: PopoverTriggerActionFlags.click, offset: offset, - child: TextButton( - onPressed: (() { - _popover.show(); - }), - child: Text(label), - ), + child: TextButton(child: Text(label), onPressed: () {}), popupBuilder: (BuildContext context) { return PopoverMenu(); }, diff --git a/frontend/app_flowy/packages/appflowy_popover/lib/popover.dart b/frontend/app_flowy/packages/appflowy_popover/lib/popover.dart index 45b5a692e4..dfa0c3a850 100644 --- a/frontend/app_flowy/packages/appflowy_popover/lib/popover.dart +++ b/frontend/app_flowy/packages/appflowy_popover/lib/popover.dart @@ -3,32 +3,26 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class PopoverMutex { - PopoverController? controller; + PopoverState? state; } class PopoverController { PopoverState? state; - PopoverMutex? mutex; - - PopoverController({this.mutex}); close() { state?.close(); - if (mutex != null && mutex!.controller == this) { - mutex!.controller = null; - } } show() { - if (mutex != null) { - debugPrint("show popover"); - mutex!.controller?.close(); - mutex!.controller = this; - } state?.showOverlay(); } } +class PopoverTriggerActionFlags { + static int click = 0x01; + static int hover = 0x02; +} + class Popover extends StatefulWidget { final Widget child; final PopoverController? controller; @@ -37,6 +31,8 @@ class Popover extends StatefulWidget { final Alignment targetAnchor; final Alignment followerAnchor; final Widget Function(BuildContext context) popupBuilder; + final int triggerActions; + final PopoverMutex? mutex; final void Function()? onClose; const Popover({ @@ -48,6 +44,8 @@ class Popover extends StatefulWidget { this.maskDecoration, this.targetAnchor = Alignment.topLeft, this.followerAnchor = Alignment.topLeft, + this.triggerActions = 0, + this.mutex, this.onClose, }) : super(key: key); @@ -59,20 +57,12 @@ class PopoverState extends State { final LayerLink layerLink = LayerLink(); OverlayEntry? _overlayEntry; bool hasMask = true; - late TapGestureRecognizer _recognizer; static PopoverState? _popoverWithMask; @override void initState() { widget.controller?.state = this; - _recognizer = TapGestureRecognizer(); - _recognizer.onTapDown = (details) { - debugPrint("ggg tapdown"); - }; - _recognizer.onTap = (() { - debugPrint("ggg tap"); - }); super.initState(); } @@ -80,12 +70,19 @@ class PopoverState extends State { debugPrint("show overlay"); close(); + if (widget.mutex != null) { + if (widget.mutex!.state != null && widget.mutex!.state != this) { + widget.mutex!.state!.close(); + } + + widget.mutex!.state = this; + } + if (_popoverWithMask == null) { _popoverWithMask = this; } else { hasMask = false; } - debugPrint("has mask: $hasMask"); final newEntry = OverlayEntry(builder: (context) { final children = []; @@ -126,6 +123,10 @@ class PopoverState extends State { widget.onClose!(); } } + + if (widget.mutex?.state == this) { + widget.mutex!.state = null; + } } @override @@ -135,15 +136,30 @@ class PopoverState extends State { super.deactivate(); } - @override - void dispose() { - _recognizer.dispose(); - super.dispose(); + _handleTargetPointerDown(PointerDownEvent event) { + if (widget.triggerActions & PopoverTriggerActionFlags.click != 0) { + showOverlay(); + } + } + + _handleTargetPointerEnter(PointerEnterEvent event) { + if (widget.triggerActions & PopoverTriggerActionFlags.hover != 0) { + showOverlay(); + } } @override Widget build(BuildContext context) { - return CompositedTransformTarget(link: layerLink, child: widget.child); + return CompositedTransformTarget( + link: layerLink, + child: MouseRegion( + onEnter: _handleTargetPointerEnter, + child: Listener( + onPointerDown: _handleTargetPointerDown, + child: widget.child, + ), + ), + ); } }