Unverified Commit b9a0fb23 authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Adjust some of the interface names to be consistent (#101378)

This adjusts some of the names in the PlatformMenuBar to be more consistent with the rest of the API.

Matching engine PR is flutter/engine#32433
parent db518732
...@@ -398,7 +398,7 @@ class SystemChannels { ...@@ -398,7 +398,7 @@ class SystemChannels {
/// The following outgoing method is defined for this channel (invoked using /// The following outgoing method is defined for this channel (invoked using
/// [OptionalMethodChannel.invokeMethod]): /// [OptionalMethodChannel.invokeMethod]):
/// ///
/// * `Menu.setMenu`: sends the configuration of the platform menu, including /// * `Menu.setMenus`: sends the configuration of the platform menu, including
/// labels, enable/disable information, and unique integer identifiers for /// labels, enable/disable information, and unique integer identifiers for
/// each menu item. The configuration is sent as a `Map<String, Object?>` /// each menu item. The configuration is sent as a `Map<String, Object?>`
/// encoding the list of top level menu items in window "0", which each /// encoding the list of top level menu items in window "0", which each
......
...@@ -15,7 +15,7 @@ import 'framework.dart'; ...@@ -15,7 +15,7 @@ import 'framework.dart';
import 'shortcuts.dart'; import 'shortcuts.dart';
// "flutter/menu" Method channel methods. // "flutter/menu" Method channel methods.
const String _kMenuSetMethod = 'Menu.setMenu'; const String _kMenuSetMethod = 'Menu.setMenus';
const String _kMenuSelectedCallbackMethod = 'Menu.selectedCallback'; const String _kMenuSelectedCallbackMethod = 'Menu.selectedCallback';
const String _kMenuItemOpenedMethod = 'Menu.opened'; const String _kMenuItemOpenedMethod = 'Menu.opened';
const String _kMenuItemClosedMethod = 'Menu.closed'; const String _kMenuItemClosedMethod = 'Menu.closed';
...@@ -27,6 +27,9 @@ const String _kEnabledKey = 'enabled'; ...@@ -27,6 +27,9 @@ const String _kEnabledKey = 'enabled';
const String _kChildrenKey = 'children'; const String _kChildrenKey = 'children';
const String _kIsDividerKey = 'isDivider'; const String _kIsDividerKey = 'isDivider';
const String _kPlatformDefaultMenuKey = 'platformProvidedMenu'; const String _kPlatformDefaultMenuKey = 'platformProvidedMenu';
const String _kShortcutCharacter = 'shortcutCharacter';
const String _kShortcutTrigger = 'shortcutTrigger';
const String _kShortcutModifiers = 'shortcutModifiers';
/// A class used by [MenuSerializableShortcut] to describe the shortcut for /// A class used by [MenuSerializableShortcut] to describe the shortcut for
/// serialization to send to the platform for rendering a [PlatformMenuBar]. /// serialization to send to the platform for rendering a [PlatformMenuBar].
...@@ -43,7 +46,7 @@ class ShortcutSerialization { ...@@ -43,7 +46,7 @@ class ShortcutSerialization {
/// ///
/// This is used by a [CharacterActivator] to serialize itself. /// This is used by a [CharacterActivator] to serialize itself.
ShortcutSerialization.character(String character) ShortcutSerialization.character(String character)
: _internal = <String, Object?>{_shortcutCharacter: character}, : _internal = <String, Object?>{_kShortcutCharacter: character},
assert(character.length == 1); assert(character.length == 1);
/// Creates a [ShortcutSerialization] representing a specific /// Creates a [ShortcutSerialization] representing a specific
...@@ -71,8 +74,8 @@ class ShortcutSerialization { ...@@ -71,8 +74,8 @@ class ShortcutSerialization {
'Specifying a modifier key as a trigger is not allowed. ' 'Specifying a modifier key as a trigger is not allowed. '
'Use provided boolean parameters instead.'), 'Use provided boolean parameters instead.'),
_internal = <String, Object?>{ _internal = <String, Object?>{
_shortcutTrigger: trigger.keyId, _kShortcutTrigger: trigger.keyId,
_shortcutModifiers: (control ? _shortcutModifierControl : 0) | _kShortcutModifiers: (control ? _shortcutModifierControl : 0) |
(alt ? _shortcutModifierAlt : 0) | (alt ? _shortcutModifierAlt : 0) |
(shift ? _shortcutModifierShift : 0) | (shift ? _shortcutModifierShift : 0) |
(meta ? _shortcutModifierMeta : 0), (meta ? _shortcutModifierMeta : 0),
...@@ -96,30 +99,6 @@ class ShortcutSerialization { ...@@ -96,30 +99,6 @@ class ShortcutSerialization {
/// equivalents) being down. /// equivalents) being down.
static const int _shortcutModifierControl = 1 << 3; static const int _shortcutModifierControl = 1 << 3;
/// The key for a string map field returned from [serializeForMenu] containing
/// a string that represents the character that, when typed, will trigger the
/// shortcut.
///
/// All platforms are limited to a single trigger key that can be represented,
/// so this string should only contain a character that can be typed with a
/// single keystroke.
static const String _shortcutCharacter = 'shortcutEquivalent';
/// The key for the integer map field returned from [serializeForMenu]
/// containing the logical key ID for the trigger key on this shortcut.
///
/// All platforms are limited to a single trigger key that can be represented.
static const String _shortcutTrigger = 'shortcutTrigger';
/// The key for the integer map field returned from [serializeForMenu]
/// containing a bitfield combination of [shortcutModifierControl],
/// [shortcutModifierAlt], [shortcutModifierShift], and/or
/// [shortcutModifierMeta].
///
/// If the shortcut responds to one of those modifiers, it should be
/// represented in the bitfield tagged with this key.
static const String _shortcutModifiers = 'shortcutModifiers';
/// Converts the internal representation to the format needed for a [MenuItem] /// Converts the internal representation to the format needed for a [MenuItem]
/// to include it in its serialized form for sending to the platform. /// to include it in its serialized form for sending to the platform.
Map<String, Object?> toChannelRepresentation() => _internal; Map<String, Object?> toChannelRepresentation() => _internal;
...@@ -173,8 +152,6 @@ abstract class MenuItem with Diagnosticable { ...@@ -173,8 +152,6 @@ abstract class MenuItem with Diagnosticable {
/// "id" field of the menu item data. /// "id" field of the menu item data.
Iterable<Map<String, Object?>> toChannelRepresentation( Iterable<Map<String, Object?>> toChannelRepresentation(
PlatformMenuDelegate delegate, { PlatformMenuDelegate delegate, {
required int index,
required int count,
required MenuItemSerializableIdGenerator getId, required MenuItemSerializableIdGenerator getId,
}); });
...@@ -340,11 +317,8 @@ class DefaultPlatformMenuDelegate extends PlatformMenuDelegate { ...@@ -340,11 +317,8 @@ class DefaultPlatformMenuDelegate extends PlatformMenuDelegate {
_idMap.clear(); _idMap.clear();
final List<Map<String, Object?>> representation = <Map<String, Object?>>[]; final List<Map<String, Object?>> representation = <Map<String, Object?>>[];
if (topLevelMenus.isNotEmpty) { if (topLevelMenus.isNotEmpty) {
int index = 0;
for (final MenuItem childItem in topLevelMenus) { for (final MenuItem childItem in topLevelMenus) {
representation representation.addAll(childItem.toChannelRepresentation(this, getId: _getId));
.addAll(childItem.toChannelRepresentation(this, index: index, count: topLevelMenus.length, getId: _getId));
index += 1;
} }
} }
// Currently there's only ever one window, but the channel's format allows // Currently there's only ever one window, but the channel's format allows
...@@ -598,8 +572,6 @@ class PlatformMenu extends MenuItem with DiagnosticableTreeMixin { ...@@ -598,8 +572,6 @@ class PlatformMenu extends MenuItem with DiagnosticableTreeMixin {
@override @override
Iterable<Map<String, Object?>> toChannelRepresentation( Iterable<Map<String, Object?>> toChannelRepresentation(
PlatformMenuDelegate delegate, { PlatformMenuDelegate delegate, {
required int index,
required int count,
required MenuItemSerializableIdGenerator getId, required MenuItemSerializableIdGenerator getId,
}) { }) {
return <Map<String, Object?>>[serialize(this, delegate, getId)]; return <Map<String, Object?>>[serialize(this, delegate, getId)];
...@@ -616,15 +588,31 @@ class PlatformMenu extends MenuItem with DiagnosticableTreeMixin { ...@@ -616,15 +588,31 @@ class PlatformMenu extends MenuItem with DiagnosticableTreeMixin {
MenuItemSerializableIdGenerator getId, MenuItemSerializableIdGenerator getId,
) { ) {
final List<Map<String, Object?>> result = <Map<String, Object?>>[]; final List<Map<String, Object?>> result = <Map<String, Object?>>[];
int index = 0;
for (final MenuItem childItem in item.menus) { for (final MenuItem childItem in item.menus) {
result.addAll(childItem.toChannelRepresentation( result.addAll(childItem.toChannelRepresentation(
delegate, delegate,
index: index,
count: item.menus.length,
getId: getId, getId: getId,
)); ));
index += 1; }
// To avoid doing type checking for groups, just filter out when there are
// multiple sequential dividers, or when they are first or last, since
// groups may be interleaved with non-groups, and non-groups may also add
// dividers.
Map<String, Object?>? previousItem;
result.removeWhere((Map<String, Object?> item) {
if (previousItem == null && item[_kIsDividerKey] == true) {
// Strip any leading dividers.
return true;
}
if (previousItem != null && previousItem![_kIsDividerKey] == true && item[_kIsDividerKey] == true) {
// Strip any duplicate dividers.
return true;
}
previousItem = item;
return false;
});
if (result.isNotEmpty && result.last[_kIsDividerKey] == true) {
result.removeLast();
} }
return <String, Object?>{ return <String, Object?>{
_kIdKey: getId(item), _kIdKey: getId(item),
...@@ -666,32 +654,24 @@ class PlatformMenuItemGroup extends MenuItem { ...@@ -666,32 +654,24 @@ class PlatformMenuItemGroup extends MenuItem {
@override @override
Iterable<Map<String, Object?>> toChannelRepresentation( Iterable<Map<String, Object?>> toChannelRepresentation(
PlatformMenuDelegate delegate, { PlatformMenuDelegate delegate, {
required int index,
required int count,
required MenuItemSerializableIdGenerator getId, required MenuItemSerializableIdGenerator getId,
}) { }) {
assert(members.isNotEmpty, 'There must be at least one member in a PlatformMenuItemGroup'); assert(members.isNotEmpty, 'There must be at least one member in a PlatformMenuItemGroup');
final List<Map<String, Object?>> result = <Map<String, Object?>>[]; final List<Map<String, Object?>> result = <Map<String, Object?>>[];
if (index != 0) { result.add(<String, Object?>{
result.add(<String, Object?>{ _kIdKey: getId(this),
_kIdKey: getId(this), _kIsDividerKey: true,
_kIsDividerKey: true, });
});
}
for (final MenuItem item in members) { for (final MenuItem item in members) {
result.addAll(item.toChannelRepresentation( result.addAll(item.toChannelRepresentation(
delegate, delegate,
index: index,
count: count,
getId: getId, getId: getId,
)); ));
} }
if (index != count - 1) { result.add(<String, Object?>{
result.add(<String, Object?>{ _kIdKey: getId(this),
_kIdKey: getId(this), _kIsDividerKey: true,
_kIsDividerKey: true, });
});
}
return result; return result;
} }
...@@ -740,8 +720,6 @@ class PlatformMenuItem extends MenuItem { ...@@ -740,8 +720,6 @@ class PlatformMenuItem extends MenuItem {
@override @override
Iterable<Map<String, Object?>> toChannelRepresentation( Iterable<Map<String, Object?>> toChannelRepresentation(
PlatformMenuDelegate delegate, { PlatformMenuDelegate delegate, {
required int index,
required int count,
required MenuItemSerializableIdGenerator getId, required MenuItemSerializableIdGenerator getId,
}) { }) {
return <Map<String, Object?>>[PlatformMenuItem.serialize(this, delegate, getId)]; return <Map<String, Object?>>[PlatformMenuItem.serialize(this, delegate, getId)];
...@@ -852,8 +830,6 @@ class PlatformProvidedMenuItem extends PlatformMenuItem { ...@@ -852,8 +830,6 @@ class PlatformProvidedMenuItem extends PlatformMenuItem {
@override @override
Iterable<Map<String, Object?>> toChannelRepresentation( Iterable<Map<String, Object?>> toChannelRepresentation(
PlatformMenuDelegate delegate, { PlatformMenuDelegate delegate, {
required int index,
required int count,
required MenuItemSerializableIdGenerator getId, required MenuItemSerializableIdGenerator getId,
}) { }) {
assert(() { assert(() {
......
...@@ -69,105 +69,94 @@ void main() { ...@@ -69,105 +69,94 @@ void main() {
), ),
); );
expect(fakeMenuChannel.outgoingCalls.last.method, equals('Menu.setMenu')); expect(fakeMenuChannel.outgoingCalls.last.method, equals('Menu.setMenus'));
expect( expect(
fakeMenuChannel.outgoingCalls.last.arguments, fakeMenuChannel.outgoingCalls.last.arguments,
equals( equals(<String, Object?>{
<String, Object?>{ '0': <Map<String, Object?>>[
'0': <Map<String, Object?>>[ <String, Object?>{
<String, Object?>{ 'id': 2,
'id': 2, 'label': 'Menu 0',
'label': 'Menu 0', 'enabled': true,
'enabled': true, 'children': <Map<String, Object?>>[
'children': <Map<String, Object?>>[ <String, Object?>{
<String, Object?>{ 'id': 1,
'id': 1, 'label': 'Sub Menu 00',
'label': 'Sub Menu 00', 'enabled': true,
'enabled': true, },
} ],
] },
}, <String, Object?>{
<String, Object?>{ 'id': 18,
'id': 12, 'label': 'Menu 1',
'label': 'Menu 1', 'enabled': true,
'enabled': true, 'children': <Map<String, Object?>>[
'children': <Map<String, Object?>>[ <String, Object?>{
<String, Object?>{ 'id': 4,
'id': 3, 'label': 'Sub Menu 10',
'label': 'Sub Menu 10', 'enabled': true,
'enabled': true, },
}, <String, Object?>{'id': 5, 'isDivider': true},
<String, Object?>{ <String, Object?>{
'id': 4, 'id': 16,
'isDivider': true, 'label': 'Sub Menu 11',
}, 'enabled': true,
<String, Object?>{ 'children': <Map<String, Object?>>[
'id': 10, <String, Object?>{
'label': 'Sub Menu 11', 'id': 7,
'enabled': true, 'label': 'Sub Sub Menu 100',
'children': <Map<String, Object?>>[ 'enabled': true,
<String, Object?>{ 'shortcutTrigger': 97,
'id': 5, 'shortcutModifiers': 8,
'label': 'Sub Sub Menu 100', },
'enabled': true, <String, Object?>{'id': 8, 'isDivider': true},
'shortcutTrigger': 97, <String, Object?>{
'shortcutModifiers': 8 'id': 10,
}, 'label': 'Sub Sub Menu 101',
<String, Object?>{ 'enabled': true,
'id': 6, 'shortcutTrigger': 98,
'isDivider': true, 'shortcutModifiers': 2,
}, },
<String, Object?>{ <String, Object?>{'id': 11, 'isDivider': true},
'id': 7, <String, Object?>{
'label': 'Sub Sub Menu 101', 'id': 12,
'enabled': true, 'label': 'Sub Sub Menu 102',
'shortcutTrigger': 98, 'enabled': true,
'shortcutModifiers': 2 'shortcutTrigger': 99,
}, 'shortcutModifiers': 4,
<String, Object?>{ },
'id': 8, <String, Object?>{'id': 13, 'isDivider': true},
'label': 'Sub Sub Menu 102', <String, Object?>{
'enabled': true, 'id': 14,
'shortcutTrigger': 99, 'label': 'Sub Sub Menu 103',
'shortcutModifiers': 4 'enabled': true,
}, 'shortcutTrigger': 100,
<String, Object?>{ 'shortcutModifiers': 1,
'id': 9, }
'label': 'Sub Sub Menu 103', ]
'enabled': true, },
'shortcutTrigger': 100, <String, Object?>{
'shortcutModifiers': 1 'id': 17,
} 'label': 'Sub Menu 12',
] 'enabled': true,
}, }
<String, Object?>{ ]
'id': 11, },
'label': 'Sub Menu 12', <String, Object?>{
'enabled': true, 'id': 20,
} 'label': 'Menu 2',
] 'enabled': true,
}, 'children': <Map<String, Object?>>[
<String, Object?>{ <String, Object?>{
'id': 14, 'id': 19,
'label': 'Menu 2', 'label': 'Sub Menu 20',
'enabled': true, 'enabled': false,
'children': <Map<String, Object?>>[ },
<String, Object?>{ ],
'id': 13, },
'label': 'Sub Menu 20', <String, Object?>{'id': 21, 'label': 'Menu 3', 'enabled': false, 'children': <Map<String, Object?>>[]}
'enabled': false, ]
} }),
]
},
<String, Object?>{
'id': 15,
'label': 'Menu 3',
'enabled': false,
'children': <Map<String, Object?>>[],
},
],
},
),
); );
}); });
testWidgets('asserts when more than one has locked the delegate', (WidgetTester tester) async { testWidgets('asserts when more than one has locked the delegate', (WidgetTester tester) async {
...@@ -318,20 +307,28 @@ List<MenuItem> createTestMenus({ ...@@ -318,20 +307,28 @@ List<MenuItem> createTestMenus({
), ),
], ],
), ),
PlatformMenuItem( PlatformMenuItemGroup(
label: subSubMenu10[1], members: <MenuItem>[
onSelected: onActivate != null ? () => onActivate(subSubMenu10[1]) : null, PlatformMenuItem(
shortcut: shortcuts[subSubMenu10[1]], label: subSubMenu10[1],
onSelected: onActivate != null ? () => onActivate(subSubMenu10[1]) : null,
shortcut: shortcuts[subSubMenu10[1]],
),
],
), ),
PlatformMenuItem( PlatformMenuItem(
label: subSubMenu10[2], label: subSubMenu10[2],
onSelected: onActivate != null ? () => onActivate(subSubMenu10[2]) : null, onSelected: onActivate != null ? () => onActivate(subSubMenu10[2]) : null,
shortcut: shortcuts[subSubMenu10[2]], shortcut: shortcuts[subSubMenu10[2]],
), ),
PlatformMenuItem( PlatformMenuItemGroup(
label: subSubMenu10[3], members: <MenuItem>[
onSelected: onActivate != null ? () => onActivate(subSubMenu10[3]) : null, PlatformMenuItem(
shortcut: shortcuts[subSubMenu10[3]], label: subSubMenu10[3],
onSelected: onActivate != null ? () => onActivate(subSubMenu10[3]) : null,
shortcut: shortcuts[subSubMenu10[3]],
),
],
), ),
], ],
), ),
......
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