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 {
/// The following outgoing method is defined for this channel (invoked using
/// [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
/// 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
......
......@@ -15,7 +15,7 @@ import 'framework.dart';
import 'shortcuts.dart';
// "flutter/menu" Method channel methods.
const String _kMenuSetMethod = 'Menu.setMenu';
const String _kMenuSetMethod = 'Menu.setMenus';
const String _kMenuSelectedCallbackMethod = 'Menu.selectedCallback';
const String _kMenuItemOpenedMethod = 'Menu.opened';
const String _kMenuItemClosedMethod = 'Menu.closed';
......@@ -27,6 +27,9 @@ const String _kEnabledKey = 'enabled';
const String _kChildrenKey = 'children';
const String _kIsDividerKey = 'isDivider';
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
/// serialization to send to the platform for rendering a [PlatformMenuBar].
......@@ -43,7 +46,7 @@ class ShortcutSerialization {
///
/// This is used by a [CharacterActivator] to serialize itself.
ShortcutSerialization.character(String character)
: _internal = <String, Object?>{_shortcutCharacter: character},
: _internal = <String, Object?>{_kShortcutCharacter: character},
assert(character.length == 1);
/// Creates a [ShortcutSerialization] representing a specific
......@@ -71,8 +74,8 @@ class ShortcutSerialization {
'Specifying a modifier key as a trigger is not allowed. '
'Use provided boolean parameters instead.'),
_internal = <String, Object?>{
_shortcutTrigger: trigger.keyId,
_shortcutModifiers: (control ? _shortcutModifierControl : 0) |
_kShortcutTrigger: trigger.keyId,
_kShortcutModifiers: (control ? _shortcutModifierControl : 0) |
(alt ? _shortcutModifierAlt : 0) |
(shift ? _shortcutModifierShift : 0) |
(meta ? _shortcutModifierMeta : 0),
......@@ -96,30 +99,6 @@ class ShortcutSerialization {
/// equivalents) being down.
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]
/// to include it in its serialized form for sending to the platform.
Map<String, Object?> toChannelRepresentation() => _internal;
......@@ -173,8 +152,6 @@ abstract class MenuItem with Diagnosticable {
/// "id" field of the menu item data.
Iterable<Map<String, Object?>> toChannelRepresentation(
PlatformMenuDelegate delegate, {
required int index,
required int count,
required MenuItemSerializableIdGenerator getId,
});
......@@ -340,11 +317,8 @@ class DefaultPlatformMenuDelegate extends PlatformMenuDelegate {
_idMap.clear();
final List<Map<String, Object?>> representation = <Map<String, Object?>>[];
if (topLevelMenus.isNotEmpty) {
int index = 0;
for (final MenuItem childItem in topLevelMenus) {
representation
.addAll(childItem.toChannelRepresentation(this, index: index, count: topLevelMenus.length, getId: _getId));
index += 1;
representation.addAll(childItem.toChannelRepresentation(this, getId: _getId));
}
}
// Currently there's only ever one window, but the channel's format allows
......@@ -598,8 +572,6 @@ class PlatformMenu extends MenuItem with DiagnosticableTreeMixin {
@override
Iterable<Map<String, Object?>> toChannelRepresentation(
PlatformMenuDelegate delegate, {
required int index,
required int count,
required MenuItemSerializableIdGenerator getId,
}) {
return <Map<String, Object?>>[serialize(this, delegate, getId)];
......@@ -616,15 +588,31 @@ class PlatformMenu extends MenuItem with DiagnosticableTreeMixin {
MenuItemSerializableIdGenerator getId,
) {
final List<Map<String, Object?>> result = <Map<String, Object?>>[];
int index = 0;
for (final MenuItem childItem in item.menus) {
result.addAll(childItem.toChannelRepresentation(
delegate,
index: index,
count: item.menus.length,
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?>{
_kIdKey: getId(item),
......@@ -666,32 +654,24 @@ class PlatformMenuItemGroup extends MenuItem {
@override
Iterable<Map<String, Object?>> toChannelRepresentation(
PlatformMenuDelegate delegate, {
required int index,
required int count,
required MenuItemSerializableIdGenerator getId,
}) {
assert(members.isNotEmpty, 'There must be at least one member in a PlatformMenuItemGroup');
final List<Map<String, Object?>> result = <Map<String, Object?>>[];
if (index != 0) {
result.add(<String, Object?>{
_kIdKey: getId(this),
_kIsDividerKey: true,
});
}
result.add(<String, Object?>{
_kIdKey: getId(this),
_kIsDividerKey: true,
});
for (final MenuItem item in members) {
result.addAll(item.toChannelRepresentation(
delegate,
index: index,
count: count,
getId: getId,
));
}
if (index != count - 1) {
result.add(<String, Object?>{
_kIdKey: getId(this),
_kIsDividerKey: true,
});
}
result.add(<String, Object?>{
_kIdKey: getId(this),
_kIsDividerKey: true,
});
return result;
}
......@@ -740,8 +720,6 @@ class PlatformMenuItem extends MenuItem {
@override
Iterable<Map<String, Object?>> toChannelRepresentation(
PlatformMenuDelegate delegate, {
required int index,
required int count,
required MenuItemSerializableIdGenerator getId,
}) {
return <Map<String, Object?>>[PlatformMenuItem.serialize(this, delegate, getId)];
......@@ -852,8 +830,6 @@ class PlatformProvidedMenuItem extends PlatformMenuItem {
@override
Iterable<Map<String, Object?>> toChannelRepresentation(
PlatformMenuDelegate delegate, {
required int index,
required int count,
required MenuItemSerializableIdGenerator getId,
}) {
assert(() {
......
......@@ -69,105 +69,94 @@ void main() {
),
);
expect(fakeMenuChannel.outgoingCalls.last.method, equals('Menu.setMenu'));
expect(fakeMenuChannel.outgoingCalls.last.method, equals('Menu.setMenus'));
expect(
fakeMenuChannel.outgoingCalls.last.arguments,
equals(
<String, Object?>{
'0': <Map<String, Object?>>[
<String, Object?>{
'id': 2,
'label': 'Menu 0',
'enabled': true,
'children': <Map<String, Object?>>[
<String, Object?>{
'id': 1,
'label': 'Sub Menu 00',
'enabled': true,
}
]
},
<String, Object?>{
'id': 12,
'label': 'Menu 1',
'enabled': true,
'children': <Map<String, Object?>>[
<String, Object?>{
'id': 3,
'label': 'Sub Menu 10',
'enabled': true,
},
<String, Object?>{
'id': 4,
'isDivider': true,
},
<String, Object?>{
'id': 10,
'label': 'Sub Menu 11',
'enabled': true,
'children': <Map<String, Object?>>[
<String, Object?>{
'id': 5,
'label': 'Sub Sub Menu 100',
'enabled': true,
'shortcutTrigger': 97,
'shortcutModifiers': 8
},
<String, Object?>{
'id': 6,
'isDivider': true,
},
<String, Object?>{
'id': 7,
'label': 'Sub Sub Menu 101',
'enabled': true,
'shortcutTrigger': 98,
'shortcutModifiers': 2
},
<String, Object?>{
'id': 8,
'label': 'Sub Sub Menu 102',
'enabled': true,
'shortcutTrigger': 99,
'shortcutModifiers': 4
},
<String, Object?>{
'id': 9,
'label': 'Sub Sub Menu 103',
'enabled': true,
'shortcutTrigger': 100,
'shortcutModifiers': 1
}
]
},
<String, Object?>{
'id': 11,
'label': 'Sub Menu 12',
'enabled': true,
}
]
},
<String, Object?>{
'id': 14,
'label': 'Menu 2',
'enabled': true,
'children': <Map<String, Object?>>[
<String, Object?>{
'id': 13,
'label': 'Sub Menu 20',
'enabled': false,
}
]
},
<String, Object?>{
'id': 15,
'label': 'Menu 3',
'enabled': false,
'children': <Map<String, Object?>>[],
},
],
},
),
equals(<String, Object?>{
'0': <Map<String, Object?>>[
<String, Object?>{
'id': 2,
'label': 'Menu 0',
'enabled': true,
'children': <Map<String, Object?>>[
<String, Object?>{
'id': 1,
'label': 'Sub Menu 00',
'enabled': true,
},
],
},
<String, Object?>{
'id': 18,
'label': 'Menu 1',
'enabled': true,
'children': <Map<String, Object?>>[
<String, Object?>{
'id': 4,
'label': 'Sub Menu 10',
'enabled': true,
},
<String, Object?>{'id': 5, 'isDivider': true},
<String, Object?>{
'id': 16,
'label': 'Sub Menu 11',
'enabled': true,
'children': <Map<String, Object?>>[
<String, Object?>{
'id': 7,
'label': 'Sub Sub Menu 100',
'enabled': true,
'shortcutTrigger': 97,
'shortcutModifiers': 8,
},
<String, Object?>{'id': 8, 'isDivider': true},
<String, Object?>{
'id': 10,
'label': 'Sub Sub Menu 101',
'enabled': true,
'shortcutTrigger': 98,
'shortcutModifiers': 2,
},
<String, Object?>{'id': 11, 'isDivider': true},
<String, Object?>{
'id': 12,
'label': 'Sub Sub Menu 102',
'enabled': true,
'shortcutTrigger': 99,
'shortcutModifiers': 4,
},
<String, Object?>{'id': 13, 'isDivider': true},
<String, Object?>{
'id': 14,
'label': 'Sub Sub Menu 103',
'enabled': true,
'shortcutTrigger': 100,
'shortcutModifiers': 1,
}
]
},
<String, Object?>{
'id': 17,
'label': 'Sub Menu 12',
'enabled': true,
}
]
},
<String, Object?>{
'id': 20,
'label': 'Menu 2',
'enabled': true,
'children': <Map<String, Object?>>[
<String, Object?>{
'id': 19,
'label': 'Sub Menu 20',
'enabled': false,
},
],
},
<String, Object?>{'id': 21, 'label': 'Menu 3', 'enabled': false, 'children': <Map<String, Object?>>[]}
]
}),
);
});
testWidgets('asserts when more than one has locked the delegate', (WidgetTester tester) async {
......@@ -318,20 +307,28 @@ List<MenuItem> createTestMenus({
),
],
),
PlatformMenuItem(
label: subSubMenu10[1],
onSelected: onActivate != null ? () => onActivate(subSubMenu10[1]) : null,
shortcut: shortcuts[subSubMenu10[1]],
PlatformMenuItemGroup(
members: <MenuItem>[
PlatformMenuItem(
label: subSubMenu10[1],
onSelected: onActivate != null ? () => onActivate(subSubMenu10[1]) : null,
shortcut: shortcuts[subSubMenu10[1]],
),
],
),
PlatformMenuItem(
label: subSubMenu10[2],
onSelected: onActivate != null ? () => onActivate(subSubMenu10[2]) : null,
shortcut: shortcuts[subSubMenu10[2]],
),
PlatformMenuItem(
label: subSubMenu10[3],
onSelected: onActivate != null ? () => onActivate(subSubMenu10[3]) : null,
shortcut: shortcuts[subSubMenu10[3]],
PlatformMenuItemGroup(
members: <MenuItem>[
PlatformMenuItem(
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