Files
proxypin/lib/ui/component/context_menu_region.dart
2023-09-18 01:41:43 +08:00

97 lines
2.4 KiB
Dart

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
typedef ContextMenuBuilder = List<ContextMenuButtonItem> Function();
/// 根据用户手势显示和隐藏上下文菜单。
/// 默认情况下,在右键单击和长按时显示菜单。
class ContextMenuRegion extends StatefulWidget {
const ContextMenuRegion({
super.key,
required this.child,
required this.contextMenuBuilder,
});
/// Builds the context menu.
final ContextMenuBuilder contextMenuBuilder;
/// The child widget that will be listened to for gestures.
final Widget child;
@override
State<ContextMenuRegion> createState() => _ContextMenuRegionState();
}
class _ContextMenuRegionState extends State<ContextMenuRegion> {
Offset? _longPressOffset;
final ContextMenuController _contextMenuController = ContextMenuController();
static bool get _longPressEnabled {
switch (defaultTargetPlatform) {
case TargetPlatform.android:
case TargetPlatform.iOS:
return true;
case TargetPlatform.macOS:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
return false;
}
}
void _onSecondaryTapUp(TapUpDetails details) {
_show(details.globalPosition);
}
void _onTap() {
if (!_contextMenuController.isShown) {
return;
}
_hide();
}
void _onLongPressStart(LongPressStartDetails details) {
_longPressOffset = details.globalPosition;
}
void _onLongPress() {
assert(_longPressOffset != null);
_show(_longPressOffset!);
_longPressOffset = null;
}
void _show(Offset position) {
_contextMenuController.show(
context: context,
contextMenuBuilder: (context) {
return AdaptiveTextSelectionToolbar.buttonItems(
buttonItems: widget.contextMenuBuilder.call(),
anchors: TextSelectionToolbarAnchors(primaryAnchor: position));
},
);
}
void _hide() {
_contextMenuController.remove();
}
@override
void dispose() {
_hide();
super.dispose();
}
@override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onSecondaryTapUp: _onSecondaryTapUp,
onTap: _onTap,
onLongPress: _longPressEnabled ? _onLongPress : null,
onLongPressStart: _longPressEnabled ? _onLongPressStart : null,
child: widget.child,
);
}
}