Skip to content

Commit 0cb9f70

Browse files
authored
Menu bar accelerators (flutter#114852)
* Add MenuMenuAcceleratorLabel to support accelerators. * Review Changes * Review Changed * Fix default label builder to use characters * Remove golden test that shouldn't have been there.
1 parent db631f1 commit 0cb9f70

File tree

9 files changed

+1592
-669
lines changed

9 files changed

+1592
-669
lines changed

dev/manual_tests/lib/menu_anchor.dart

+416-393
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
/// Flutter code sample for [MenuAcceleratorLabel].
6+
7+
import 'package:flutter/material.dart';
8+
import 'package:flutter/services.dart';
9+
10+
void main() => runApp(const MenuAcceleratorApp());
11+
12+
class MyMenuBar extends StatelessWidget {
13+
const MyMenuBar({super.key});
14+
15+
@override
16+
Widget build(BuildContext context) {
17+
return Column(
18+
children: <Widget>[
19+
Row(
20+
mainAxisSize: MainAxisSize.min,
21+
children: <Widget>[
22+
Expanded(
23+
child: MenuBar(
24+
children: <Widget>[
25+
SubmenuButton(
26+
menuChildren: <Widget>[
27+
MenuItemButton(
28+
onPressed: () {
29+
showAboutDialog(
30+
context: context,
31+
applicationName: 'MenuBar Sample',
32+
applicationVersion: '1.0.0',
33+
);
34+
},
35+
child: const MenuAcceleratorLabel('&About'),
36+
),
37+
MenuItemButton(
38+
onPressed: () {
39+
ScaffoldMessenger.of(context).showSnackBar(
40+
const SnackBar(
41+
content: Text('Saved!'),
42+
),
43+
);
44+
},
45+
child: const MenuAcceleratorLabel('&Save'),
46+
),
47+
MenuItemButton(
48+
onPressed: () {
49+
ScaffoldMessenger.of(context).showSnackBar(
50+
const SnackBar(
51+
content: Text('Quit!'),
52+
),
53+
);
54+
},
55+
child: const MenuAcceleratorLabel('&Quit'),
56+
),
57+
],
58+
child: const MenuAcceleratorLabel('&File'),
59+
),
60+
SubmenuButton(
61+
menuChildren: <Widget>[
62+
MenuItemButton(
63+
onPressed: () {
64+
ScaffoldMessenger.of(context).showSnackBar(
65+
const SnackBar(
66+
content: Text('Magnify!'),
67+
),
68+
);
69+
},
70+
child: const MenuAcceleratorLabel('&Magnify'),
71+
),
72+
MenuItemButton(
73+
onPressed: () {
74+
ScaffoldMessenger.of(context).showSnackBar(
75+
const SnackBar(
76+
content: Text('Minify!'),
77+
),
78+
);
79+
},
80+
child: const MenuAcceleratorLabel('Mi&nify'),
81+
),
82+
],
83+
child: const MenuAcceleratorLabel('&View'),
84+
),
85+
],
86+
),
87+
),
88+
],
89+
),
90+
Expanded(
91+
child: FlutterLogo(
92+
size: MediaQuery.of(context).size.shortestSide * 0.5,
93+
),
94+
),
95+
],
96+
);
97+
}
98+
}
99+
100+
class MenuAcceleratorApp extends StatelessWidget {
101+
const MenuAcceleratorApp({super.key});
102+
103+
@override
104+
Widget build(BuildContext context) {
105+
return MaterialApp(
106+
home: Shortcuts(
107+
shortcuts: <ShortcutActivator, Intent>{
108+
const SingleActivator(LogicalKeyboardKey.keyT, control: true): VoidCallbackIntent(() {
109+
debugDumpApp();
110+
}),
111+
},
112+
child: const Scaffold(body: MyMenuBar()),
113+
),
114+
);
115+
}
116+
}

examples/api/lib/material/menu_anchor/menu_bar.0.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
/// Flutter code sample for [MenuBar]
5+
/// Flutter code sample for [MenuBar].
66
77
import 'package:flutter/material.dart';
88
import 'package:flutter/services.dart';

examples/api/lib/widgets/shortcuts/shortcuts.0.dart

+3-3
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ class _MyStatefulWidgetState extends State<MyStatefulWidget> {
4949
@override
5050
Widget build(BuildContext context) {
5151
return Shortcuts(
52-
shortcuts: <ShortcutActivator, Intent>{
53-
LogicalKeySet(LogicalKeyboardKey.arrowUp): const IncrementIntent(),
54-
LogicalKeySet(LogicalKeyboardKey.arrowDown): const DecrementIntent(),
52+
shortcuts: const <ShortcutActivator, Intent>{
53+
SingleActivator(LogicalKeyboardKey.arrowUp): IncrementIntent(),
54+
SingleActivator(LogicalKeyboardKey.arrowDown): DecrementIntent(),
5555
},
5656
child: Actions(
5757
actions: <Type, Action<Intent>>{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright 2014 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
import 'package:flutter/material.dart';
6+
import 'package:flutter/services.dart';
7+
import 'package:flutter_api_samples/material/menu_anchor/menu_accelerator_label.0.dart' as example;
8+
import 'package:flutter_test/flutter_test.dart';
9+
10+
void main() {
11+
testWidgets('Can open menu', (WidgetTester tester) async {
12+
Finder findMenu(String label) {
13+
return find
14+
.ancestor(
15+
of: find.text(label, findRichText: true),
16+
matching: find.byType(FocusScope),
17+
)
18+
.first;
19+
}
20+
21+
await tester.pumpWidget(const example.MenuAcceleratorApp());
22+
23+
await tester.sendKeyDownEvent(LogicalKeyboardKey.altLeft);
24+
await tester.pump();
25+
await tester.sendKeyEvent(LogicalKeyboardKey.keyF, character: 'f');
26+
await tester.pumpAndSettle();
27+
await tester.pump();
28+
29+
expect(find.text('About', findRichText: true), findsOneWidget);
30+
expect(
31+
tester.getRect(findMenu('About')),
32+
equals(const Rect.fromLTRB(4.0, 48.0, 98.0, 208.0)),
33+
);
34+
expect(find.text('Save', findRichText: true), findsOneWidget);
35+
expect(find.text('Quit', findRichText: true), findsOneWidget);
36+
expect(find.text('Magnify', findRichText: true), findsNothing);
37+
expect(find.text('Minify', findRichText: true), findsNothing);
38+
39+
// Open the About dialog.
40+
await tester.sendKeyEvent(LogicalKeyboardKey.keyA, character: 'a');
41+
await tester.sendKeyUpEvent(LogicalKeyboardKey.altLeft);
42+
await tester.pumpAndSettle();
43+
44+
expect(find.text('Save', findRichText: true), findsNothing);
45+
expect(find.text('Quit', findRichText: true), findsNothing);
46+
expect(find.text('Magnify', findRichText: true), findsNothing);
47+
expect(find.text('Minify', findRichText: true), findsNothing);
48+
expect(find.text('CLOSE'), findsOneWidget);
49+
50+
await tester.tap(find.text('CLOSE'));
51+
await tester.pumpAndSettle();
52+
expect(find.text('CLOSE'), findsNothing);
53+
});
54+
}

0 commit comments

Comments
 (0)