Unverified Commit 0cb9f704 authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Menu bar accelerators (#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.
parent db631f14
This diff is collapsed.
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/// Flutter code sample for [MenuAcceleratorLabel].
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(const MenuAcceleratorApp());
class MyMenuBar extends StatelessWidget {
const MyMenuBar({super.key});
@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Expanded(
child: MenuBar(
children: <Widget>[
SubmenuButton(
menuChildren: <Widget>[
MenuItemButton(
onPressed: () {
showAboutDialog(
context: context,
applicationName: 'MenuBar Sample',
applicationVersion: '1.0.0',
);
},
child: const MenuAcceleratorLabel('&About'),
),
MenuItemButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Saved!'),
),
);
},
child: const MenuAcceleratorLabel('&Save'),
),
MenuItemButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Quit!'),
),
);
},
child: const MenuAcceleratorLabel('&Quit'),
),
],
child: const MenuAcceleratorLabel('&File'),
),
SubmenuButton(
menuChildren: <Widget>[
MenuItemButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Magnify!'),
),
);
},
child: const MenuAcceleratorLabel('&Magnify'),
),
MenuItemButton(
onPressed: () {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Minify!'),
),
);
},
child: const MenuAcceleratorLabel('Mi&nify'),
),
],
child: const MenuAcceleratorLabel('&View'),
),
],
),
),
],
),
Expanded(
child: FlutterLogo(
size: MediaQuery.of(context).size.shortestSide * 0.5,
),
),
],
);
}
}
class MenuAcceleratorApp extends StatelessWidget {
const MenuAcceleratorApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Shortcuts(
shortcuts: <ShortcutActivator, Intent>{
const SingleActivator(LogicalKeyboardKey.keyT, control: true): VoidCallbackIntent(() {
debugDumpApp();
}),
},
child: const Scaffold(body: MyMenuBar()),
),
);
}
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
/// Flutter code sample for [MenuBar] /// Flutter code sample for [MenuBar].
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
......
...@@ -49,9 +49,9 @@ class _MyStatefulWidgetState extends State<MyStatefulWidget> { ...@@ -49,9 +49,9 @@ class _MyStatefulWidgetState extends State<MyStatefulWidget> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Shortcuts( return Shortcuts(
shortcuts: <ShortcutActivator, Intent>{ shortcuts: const <ShortcutActivator, Intent>{
LogicalKeySet(LogicalKeyboardKey.arrowUp): const IncrementIntent(), SingleActivator(LogicalKeyboardKey.arrowUp): IncrementIntent(),
LogicalKeySet(LogicalKeyboardKey.arrowDown): const DecrementIntent(), SingleActivator(LogicalKeyboardKey.arrowDown): DecrementIntent(),
}, },
child: Actions( child: Actions(
actions: <Type, Action<Intent>>{ actions: <Type, Action<Intent>>{
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_api_samples/material/menu_anchor/menu_accelerator_label.0.dart' as example;
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('Can open menu', (WidgetTester tester) async {
Finder findMenu(String label) {
return find
.ancestor(
of: find.text(label, findRichText: true),
matching: find.byType(FocusScope),
)
.first;
}
await tester.pumpWidget(const example.MenuAcceleratorApp());
await tester.sendKeyDownEvent(LogicalKeyboardKey.altLeft);
await tester.pump();
await tester.sendKeyEvent(LogicalKeyboardKey.keyF, character: 'f');
await tester.pumpAndSettle();
await tester.pump();
expect(find.text('About', findRichText: true), findsOneWidget);
expect(
tester.getRect(findMenu('About')),
equals(const Rect.fromLTRB(4.0, 48.0, 98.0, 208.0)),
);
expect(find.text('Save', findRichText: true), findsOneWidget);
expect(find.text('Quit', findRichText: true), findsOneWidget);
expect(find.text('Magnify', findRichText: true), findsNothing);
expect(find.text('Minify', findRichText: true), findsNothing);
// Open the About dialog.
await tester.sendKeyEvent(LogicalKeyboardKey.keyA, character: 'a');
await tester.sendKeyUpEvent(LogicalKeyboardKey.altLeft);
await tester.pumpAndSettle();
expect(find.text('Save', findRichText: true), findsNothing);
expect(find.text('Quit', findRichText: true), findsNothing);
expect(find.text('Magnify', findRichText: true), findsNothing);
expect(find.text('Minify', findRichText: true), findsNothing);
expect(find.text('CLOSE'), findsOneWidget);
await tester.tap(find.text('CLOSE'));
await tester.pumpAndSettle();
expect(find.text('CLOSE'), findsNothing);
});
}
...@@ -191,11 +191,11 @@ void main() { ...@@ -191,11 +191,11 @@ void main() {
' Localizations\n' ' Localizations\n'
' MediaQuery\n' ' MediaQuery\n'
' _MediaQueryFromWindow\n' ' _MediaQueryFromWindow\n'
' _ShortcutRegistrarMarker\n'
' Semantics\n' ' Semantics\n'
' _FocusMarker\n' ' _FocusMarker\n'
' Focus\n' ' Focus\n'
' Shortcuts\n' ' Shortcuts\n'
' _ShortcutRegistrarMarker\n'
' ShortcutRegistrar\n' ' ShortcutRegistrar\n'
' TapRegionSurface\n' ' TapRegionSurface\n'
' _FocusMarker\n' ' _FocusMarker\n'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment