mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: add flags to popover
This commit is contained in:
parent
33e45a86c4
commit
27557c52a3
@ -7,16 +7,7 @@ class PopoverMenu extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _PopoverMenuState extends State<PopoverMenu> {
|
class _PopoverMenuState extends State<PopoverMenu> {
|
||||||
final PopoverMutex exclusive = PopoverMutex();
|
final PopoverMutex popOverMutex = PopoverMutex();
|
||||||
late PopoverController firstPopover;
|
|
||||||
late PopoverController secondPopover;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
firstPopover = PopoverController(mutex: exclusive);
|
|
||||||
secondPopover = PopoverController(mutex: exclusive);
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -27,7 +18,9 @@ class _PopoverMenuState extends State<PopoverMenu> {
|
|||||||
child: ListView(children: [
|
child: ListView(children: [
|
||||||
const Text("App"),
|
const Text("App"),
|
||||||
Popover(
|
Popover(
|
||||||
controller: firstPopover,
|
triggerActions:
|
||||||
|
PopoverTriggerActionFlags.hover | PopoverTriggerActionFlags.click,
|
||||||
|
mutex: popOverMutex,
|
||||||
offset: const Offset(10, 0),
|
offset: const Offset(10, 0),
|
||||||
targetAnchor: Alignment.topRight,
|
targetAnchor: Alignment.topRight,
|
||||||
followerAnchor: Alignment.topLeft,
|
followerAnchor: Alignment.topLeft,
|
||||||
@ -35,19 +28,14 @@ class _PopoverMenuState extends State<PopoverMenu> {
|
|||||||
return PopoverMenu();
|
return PopoverMenu();
|
||||||
},
|
},
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
onPressed: () {
|
onPressed: () {},
|
||||||
firstPopover.show();
|
|
||||||
},
|
|
||||||
onHover: (value) {
|
|
||||||
if (value) {
|
|
||||||
firstPopover.show();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: const Text("First"),
|
child: const Text("First"),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Popover(
|
Popover(
|
||||||
controller: secondPopover,
|
triggerActions:
|
||||||
|
PopoverTriggerActionFlags.hover | PopoverTriggerActionFlags.click,
|
||||||
|
mutex: popOverMutex,
|
||||||
offset: const Offset(10, 0),
|
offset: const Offset(10, 0),
|
||||||
targetAnchor: Alignment.topRight,
|
targetAnchor: Alignment.topRight,
|
||||||
followerAnchor: Alignment.topLeft,
|
followerAnchor: Alignment.topLeft,
|
||||||
@ -55,14 +43,7 @@ class _PopoverMenuState extends State<PopoverMenu> {
|
|||||||
return PopoverMenu();
|
return PopoverMenu();
|
||||||
},
|
},
|
||||||
child: TextButton(
|
child: TextButton(
|
||||||
onPressed: () {
|
onPressed: () {},
|
||||||
secondPopover.show();
|
|
||||||
},
|
|
||||||
onHover: (value) {
|
|
||||||
if (value) {
|
|
||||||
secondPopover.show();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: const Text("Second"),
|
child: const Text("Second"),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -72,14 +53,12 @@ class _PopoverMenuState extends State<PopoverMenu> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ExampleButton extends StatelessWidget {
|
class ExampleButton extends StatelessWidget {
|
||||||
final PopoverController _popover = PopoverController();
|
|
||||||
|
|
||||||
final String label;
|
final String label;
|
||||||
final Alignment targetAnchor;
|
final Alignment targetAnchor;
|
||||||
final Alignment followerAnchor;
|
final Alignment followerAnchor;
|
||||||
final Offset? offset;
|
final Offset? offset;
|
||||||
|
|
||||||
ExampleButton({
|
const ExampleButton({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.label,
|
required this.label,
|
||||||
this.targetAnchor = Alignment.topLeft,
|
this.targetAnchor = Alignment.topLeft,
|
||||||
@ -90,16 +69,11 @@ class ExampleButton extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Popover(
|
return Popover(
|
||||||
controller: _popover,
|
|
||||||
targetAnchor: targetAnchor,
|
targetAnchor: targetAnchor,
|
||||||
followerAnchor: followerAnchor,
|
followerAnchor: followerAnchor,
|
||||||
|
triggerActions: PopoverTriggerActionFlags.click,
|
||||||
offset: offset,
|
offset: offset,
|
||||||
child: TextButton(
|
child: TextButton(child: Text(label), onPressed: () {}),
|
||||||
onPressed: (() {
|
|
||||||
_popover.show();
|
|
||||||
}),
|
|
||||||
child: Text(label),
|
|
||||||
),
|
|
||||||
popupBuilder: (BuildContext context) {
|
popupBuilder: (BuildContext context) {
|
||||||
return PopoverMenu();
|
return PopoverMenu();
|
||||||
},
|
},
|
||||||
|
@ -3,32 +3,26 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
class PopoverMutex {
|
class PopoverMutex {
|
||||||
PopoverController? controller;
|
PopoverState? state;
|
||||||
}
|
}
|
||||||
|
|
||||||
class PopoverController {
|
class PopoverController {
|
||||||
PopoverState? state;
|
PopoverState? state;
|
||||||
PopoverMutex? mutex;
|
|
||||||
|
|
||||||
PopoverController({this.mutex});
|
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
state?.close();
|
state?.close();
|
||||||
if (mutex != null && mutex!.controller == this) {
|
|
||||||
mutex!.controller = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
show() {
|
show() {
|
||||||
if (mutex != null) {
|
|
||||||
debugPrint("show popover");
|
|
||||||
mutex!.controller?.close();
|
|
||||||
mutex!.controller = this;
|
|
||||||
}
|
|
||||||
state?.showOverlay();
|
state?.showOverlay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PopoverTriggerActionFlags {
|
||||||
|
static int click = 0x01;
|
||||||
|
static int hover = 0x02;
|
||||||
|
}
|
||||||
|
|
||||||
class Popover extends StatefulWidget {
|
class Popover extends StatefulWidget {
|
||||||
final Widget child;
|
final Widget child;
|
||||||
final PopoverController? controller;
|
final PopoverController? controller;
|
||||||
@ -37,6 +31,8 @@ class Popover extends StatefulWidget {
|
|||||||
final Alignment targetAnchor;
|
final Alignment targetAnchor;
|
||||||
final Alignment followerAnchor;
|
final Alignment followerAnchor;
|
||||||
final Widget Function(BuildContext context) popupBuilder;
|
final Widget Function(BuildContext context) popupBuilder;
|
||||||
|
final int triggerActions;
|
||||||
|
final PopoverMutex? mutex;
|
||||||
final void Function()? onClose;
|
final void Function()? onClose;
|
||||||
|
|
||||||
const Popover({
|
const Popover({
|
||||||
@ -48,6 +44,8 @@ class Popover extends StatefulWidget {
|
|||||||
this.maskDecoration,
|
this.maskDecoration,
|
||||||
this.targetAnchor = Alignment.topLeft,
|
this.targetAnchor = Alignment.topLeft,
|
||||||
this.followerAnchor = Alignment.topLeft,
|
this.followerAnchor = Alignment.topLeft,
|
||||||
|
this.triggerActions = 0,
|
||||||
|
this.mutex,
|
||||||
this.onClose,
|
this.onClose,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@ -59,20 +57,12 @@ class PopoverState extends State<Popover> {
|
|||||||
final LayerLink layerLink = LayerLink();
|
final LayerLink layerLink = LayerLink();
|
||||||
OverlayEntry? _overlayEntry;
|
OverlayEntry? _overlayEntry;
|
||||||
bool hasMask = true;
|
bool hasMask = true;
|
||||||
late TapGestureRecognizer _recognizer;
|
|
||||||
|
|
||||||
static PopoverState? _popoverWithMask;
|
static PopoverState? _popoverWithMask;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
widget.controller?.state = this;
|
widget.controller?.state = this;
|
||||||
_recognizer = TapGestureRecognizer();
|
|
||||||
_recognizer.onTapDown = (details) {
|
|
||||||
debugPrint("ggg tapdown");
|
|
||||||
};
|
|
||||||
_recognizer.onTap = (() {
|
|
||||||
debugPrint("ggg tap");
|
|
||||||
});
|
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,12 +70,19 @@ class PopoverState extends State<Popover> {
|
|||||||
debugPrint("show overlay");
|
debugPrint("show overlay");
|
||||||
close();
|
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) {
|
if (_popoverWithMask == null) {
|
||||||
_popoverWithMask = this;
|
_popoverWithMask = this;
|
||||||
} else {
|
} else {
|
||||||
hasMask = false;
|
hasMask = false;
|
||||||
}
|
}
|
||||||
debugPrint("has mask: $hasMask");
|
|
||||||
|
|
||||||
final newEntry = OverlayEntry(builder: (context) {
|
final newEntry = OverlayEntry(builder: (context) {
|
||||||
final children = <Widget>[];
|
final children = <Widget>[];
|
||||||
@ -126,6 +123,10 @@ class PopoverState extends State<Popover> {
|
|||||||
widget.onClose!();
|
widget.onClose!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (widget.mutex?.state == this) {
|
||||||
|
widget.mutex!.state = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -135,15 +136,30 @@ class PopoverState extends State<Popover> {
|
|||||||
super.deactivate();
|
super.deactivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
_handleTargetPointerDown(PointerDownEvent event) {
|
||||||
void dispose() {
|
if (widget.triggerActions & PopoverTriggerActionFlags.click != 0) {
|
||||||
_recognizer.dispose();
|
showOverlay();
|
||||||
super.dispose();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_handleTargetPointerEnter(PointerEnterEvent event) {
|
||||||
|
if (widget.triggerActions & PopoverTriggerActionFlags.hover != 0) {
|
||||||
|
showOverlay();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
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,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user