mirror of
https://github.com/flutter/samples.git
synced 2026-04-23 23:42:57 +00:00
Move context menus out of experimental (#2134)
Now that the context menu code is on stable, move the sample out of experimental. Fixes https://github.com/flutter/samples/issues/2110 ## Pre-launch Checklist - [x] I read the [Flutter Style Guide] _recently_, and have followed its advice. - [x] I signed the [CLA]. - [x] I read the [Contributors Guide]. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] All existing and new tests are passing. --------- Co-authored-by: Brett Morgan <brett.morgan@gmail.com>
This commit is contained in:
committed by
GitHub
parent
9b17f50671
commit
6c8d54a82b
97
context_menus/lib/context_menu_region.dart
Normal file
97
context_menus/lib/context_menu_region.dart
Normal file
@@ -0,0 +1,97 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
typedef ContextMenuBuilder = Widget Function(
|
||||
BuildContext context, Offset offset);
|
||||
|
||||
/// Shows and hides the context menu based on user gestures.
|
||||
///
|
||||
/// By default, shows the menu on right clicks and long presses.
|
||||
class ContextMenuRegion extends StatefulWidget {
|
||||
/// Creates an instance of [ContextMenuRegion].
|
||||
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 widget.contextMenuBuilder(context, 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,
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user