Skip to content

Commit

Permalink
Create ContextSubMenuEntry
Browse files Browse the repository at this point in the history
  • Loading branch information
chesnoksatan committed Jun 19, 2022
1 parent e4ea41b commit f72601c
Show file tree
Hide file tree
Showing 2 changed files with 142 additions and 70 deletions.
210 changes: 141 additions & 69 deletions lib/widgets/context_menu.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,37 +18,100 @@ class ContextMenu extends StatelessWidget {
Widget build(BuildContext context) {
return GestureDetector(
onLongPressStart: openOnLong
? (details) => _openContextMenu(context, details.globalPosition)
? (details) =>
_openContextMenu(context, details.globalPosition, entries)
: null,
onSecondaryTapUp: openOnSecondary
? (details) => _openContextMenu(context, details.globalPosition)
? (details) =>
_openContextMenu(context, details.globalPosition, entries)
: null,
behavior: HitTestBehavior.translucent,
child: child,
);
}
}

class ContextSubMenuEntry extends PopupMenuEntry<String> {
final String id;
final Widget text;
final List<PopupMenuEntry> entries;
final Widget? icon;

const ContextSubMenuEntry({
required this.id,
required this.text,
required this.entries,
this.icon,
Key? key,
}) : super(key: key);

@override
_ContextSubMenuEntryState createState() => _ContextSubMenuEntryState();

@override
double get height => 40;

@override
bool represents(String? value) => id == value;
}

// TODO: if not enough space, show from left
class _ContextSubMenuEntryState extends State<ContextSubMenuEntry> {
final _subMenuKey = GlobalKey();
@override
Widget build(BuildContext context) {
return InkWell(
key: _subMenuKey,
onTap: () {
final RenderBox renderBox =
_subMenuKey.currentContext?.findRenderObject() as RenderBox;
final Size size = renderBox.size;
final Offset offset =
renderBox.localToGlobal(Offset(size.width + 1, -8));

void _openContextMenu(BuildContext context, Offset position) {
showMenu(
context: context,
position: RelativeRect.fromLTRB(
position.dx,
position.dy,
position.dx,
position.dy,
_openContextMenu(context, offset, widget.entries);
},
child: Container(
height: widget.height,
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
children: [
if (widget.icon != null) ...[
IconTheme.merge(
data: IconThemeData(
size: 20,
color:
Theme.of(context).colorScheme.onSurface.withOpacity(0.7),
),
child: widget.icon!,
),
const SizedBox(width: 16),
],
Expanded(
child: DefaultTextStyle(
style: TextStyle(
fontSize: 16,
color:
Theme.of(context).colorScheme.onSurface.withOpacity(0.7),
),
overflow: TextOverflow.ellipsis,
child: widget.text,
),
),
IconTheme.merge(
data: IconThemeData(
size: 20,
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7),
),
child: const Icon(Icons.chevron_right),
)
],
),
),
items: entries,
color: Theme.of(context).colorScheme.surface,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)),
);
}
}

/// Just for rename
class ContextMenuDivider extends PopupMenuDivider {
const ContextMenuDivider({Key? key}) : super(key: key);
}

class ContextMenuEntry extends PopupMenuEntry<String> {
final String id;
final Widget? icon;
Expand Down Expand Up @@ -78,63 +141,72 @@ class ContextMenuEntry extends PopupMenuEntry<String> {
class _ContextMenuEntryState extends State<ContextMenuEntry> {
@override
Widget build(BuildContext context) {
return SizedBox(
height: widget.height,
width: 370,
child: InkWell(
onTap: () {
Navigator.pop(context);
widget.onTap();
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
children: [
if (widget.icon != null) ...[
IconTheme.merge(
data: IconThemeData(
size: 20,
color: Theme.of(context)
.colorScheme
.onSurface
.withOpacity(0.7),
),
child: widget.icon!,
return InkWell(
onTap: () {
Navigator.pop(context);
widget.onTap();
},
child: Container(
height: widget.height,
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Row(
children: [
if (widget.icon != null) ...[
IconTheme.merge(
data: IconThemeData(
size: 20,
color:
Theme.of(context).colorScheme.onSurface.withOpacity(0.7),
),
const SizedBox(width: 16),
],
Expanded(
child: DefaultTextStyle(
style: TextStyle(
fontSize: 16,
color: Theme.of(context)
.colorScheme
.onSurface
.withOpacity(0.7),
),
overflow: TextOverflow.ellipsis,
child: widget.text,
child: widget.icon!,
),
const SizedBox(width: 16),
],
Expanded(
child: DefaultTextStyle(
style: TextStyle(
fontSize: 16,
color:
Theme.of(context).colorScheme.onSurface.withOpacity(0.7),
),
overflow: TextOverflow.ellipsis,
child: widget.text,
),
if (widget.shortcut != null)
Padding(
padding: const EdgeInsets.only(right: 8),
child: DefaultTextStyle(
style: TextStyle(
fontSize: 16,
color: Theme.of(context)
.colorScheme
.onSurface
.withOpacity(0.5),
),
overflow: TextOverflow.ellipsis,
child: widget.shortcut!,
),
),
if (widget.shortcut != null)
DefaultTextStyle(
style: TextStyle(
fontSize: 16,
color:
Theme.of(context).colorScheme.onSurface.withOpacity(0.5),
),
],
),
overflow: TextOverflow.ellipsis,
child: widget.shortcut!,
),
],
),
),
);
}
}

/// Just for rename
class ContextMenuDivider extends PopupMenuDivider {
const ContextMenuDivider({Key? key}) : super(key: key);
}

void _openContextMenu(BuildContext context, Offset position,
List<PopupMenuEntry<dynamic>> entries) {
showMenu(
context: context,
position: RelativeRect.fromLTRB(
position.dx,
position.dy,
position.dx,
position.dy,
),
items: entries,
color: Theme.of(context).colorScheme.surface,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)),
);
}
2 changes: 1 addition & 1 deletion lib/widgets/side_pane.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class _SidePaneState extends State<SidePane> {
),
ContextMenuEntry(
id: 'open_in_new_window',
text: const Text("Copy in new window"),
text: const Text("Open in new window"),
onTap: () {},
),
],
Expand Down

0 comments on commit f72601c

Please sign in to comment.