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
This commit is contained in:
parent
db51873250
commit
b9a0fb23b2
@ -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';
|
|||||||
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';
|
|||||||
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 {
|
|||||||
///
|
///
|
||||||
/// 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 {
|
|||||||
'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 {
|
|||||||
/// 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 {
|
|||||||
/// "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 {
|
|||||||
_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 {
|
|||||||
@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 {
|
|||||||
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 {
|
|||||||
@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 {
|
|||||||
@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 {
|
|||||||
@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,11 +69,10 @@ 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,
|
||||||
@ -84,90 +83,80 @@ void main() {
|
|||||||
'id': 1,
|
'id': 1,
|
||||||
'label': 'Sub Menu 00',
|
'label': 'Sub Menu 00',
|
||||||
'enabled': true,
|
'enabled': true,
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
<String, Object?>{
|
<String, Object?>{
|
||||||
'id': 12,
|
'id': 18,
|
||||||
'label': 'Menu 1',
|
'label': 'Menu 1',
|
||||||
'enabled': true,
|
'enabled': true,
|
||||||
'children': <Map<String, Object?>>[
|
'children': <Map<String, Object?>>[
|
||||||
<String, Object?>{
|
<String, Object?>{
|
||||||
'id': 3,
|
'id': 4,
|
||||||
'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,
|
|
||||||
},
|
|
||||||
<String, Object?>{
|
|
||||||
'id': 10,
|
|
||||||
'label': 'Sub Menu 11',
|
'label': 'Sub Menu 11',
|
||||||
'enabled': true,
|
'enabled': true,
|
||||||
'children': <Map<String, Object?>>[
|
'children': <Map<String, Object?>>[
|
||||||
<String, Object?>{
|
<String, Object?>{
|
||||||
'id': 5,
|
'id': 7,
|
||||||
'label': 'Sub Sub Menu 100',
|
'label': 'Sub Sub Menu 100',
|
||||||
'enabled': true,
|
'enabled': true,
|
||||||
'shortcutTrigger': 97,
|
'shortcutTrigger': 97,
|
||||||
'shortcutModifiers': 8
|
'shortcutModifiers': 8,
|
||||||
},
|
},
|
||||||
|
<String, Object?>{'id': 8, 'isDivider': true},
|
||||||
<String, Object?>{
|
<String, Object?>{
|
||||||
'id': 6,
|
'id': 10,
|
||||||
'isDivider': true,
|
|
||||||
},
|
|
||||||
<String, Object?>{
|
|
||||||
'id': 7,
|
|
||||||
'label': 'Sub Sub Menu 101',
|
'label': 'Sub Sub Menu 101',
|
||||||
'enabled': true,
|
'enabled': true,
|
||||||
'shortcutTrigger': 98,
|
'shortcutTrigger': 98,
|
||||||
'shortcutModifiers': 2
|
'shortcutModifiers': 2,
|
||||||
},
|
},
|
||||||
|
<String, Object?>{'id': 11, 'isDivider': true},
|
||||||
<String, Object?>{
|
<String, Object?>{
|
||||||
'id': 8,
|
'id': 12,
|
||||||
'label': 'Sub Sub Menu 102',
|
'label': 'Sub Sub Menu 102',
|
||||||
'enabled': true,
|
'enabled': true,
|
||||||
'shortcutTrigger': 99,
|
'shortcutTrigger': 99,
|
||||||
'shortcutModifiers': 4
|
'shortcutModifiers': 4,
|
||||||
},
|
},
|
||||||
|
<String, Object?>{'id': 13, 'isDivider': true},
|
||||||
<String, Object?>{
|
<String, Object?>{
|
||||||
'id': 9,
|
'id': 14,
|
||||||
'label': 'Sub Sub Menu 103',
|
'label': 'Sub Sub Menu 103',
|
||||||
'enabled': true,
|
'enabled': true,
|
||||||
'shortcutTrigger': 100,
|
'shortcutTrigger': 100,
|
||||||
'shortcutModifiers': 1
|
'shortcutModifiers': 1,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
<String, Object?>{
|
<String, Object?>{
|
||||||
'id': 11,
|
'id': 17,
|
||||||
'label': 'Sub Menu 12',
|
'label': 'Sub Menu 12',
|
||||||
'enabled': true,
|
'enabled': true,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
<String, Object?>{
|
<String, Object?>{
|
||||||
'id': 14,
|
'id': 20,
|
||||||
'label': 'Menu 2',
|
'label': 'Menu 2',
|
||||||
'enabled': true,
|
'enabled': true,
|
||||||
'children': <Map<String, Object?>>[
|
'children': <Map<String, Object?>>[
|
||||||
<String, Object?>{
|
<String, Object?>{
|
||||||
'id': 13,
|
'id': 19,
|
||||||
'label': 'Sub Menu 20',
|
'label': 'Sub Menu 20',
|
||||||
'enabled': false,
|
'enabled': false,
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
<String, Object?>{
|
|
||||||
'id': 15,
|
|
||||||
'label': 'Menu 3',
|
|
||||||
'enabled': false,
|
|
||||||
'children': <Map<String, Object?>>[],
|
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
),
|
<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 {
|
testWidgets('asserts when more than one has locked the delegate', (WidgetTester tester) async {
|
||||||
@ -318,16 +307,22 @@ List<MenuItem> createTestMenus({
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
PlatformMenuItemGroup(
|
||||||
|
members: <MenuItem>[
|
||||||
PlatformMenuItem(
|
PlatformMenuItem(
|
||||||
label: subSubMenu10[1],
|
label: subSubMenu10[1],
|
||||||
onSelected: onActivate != null ? () => onActivate(subSubMenu10[1]) : null,
|
onSelected: onActivate != null ? () => onActivate(subSubMenu10[1]) : null,
|
||||||
shortcut: shortcuts[subSubMenu10[1]],
|
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]],
|
||||||
),
|
),
|
||||||
|
PlatformMenuItemGroup(
|
||||||
|
members: <MenuItem>[
|
||||||
PlatformMenuItem(
|
PlatformMenuItem(
|
||||||
label: subSubMenu10[3],
|
label: subSubMenu10[3],
|
||||||
onSelected: onActivate != null ? () => onActivate(subSubMenu10[3]) : null,
|
onSelected: onActivate != null ? () => onActivate(subSubMenu10[3]) : null,
|
||||||
@ -335,6 +330,8 @@ List<MenuItem> createTestMenus({
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
PlatformMenuItem(
|
PlatformMenuItem(
|
||||||
label: subMenu1[2],
|
label: subMenu1[2],
|
||||||
onSelected: onActivate != null ? () => onActivate(subMenu1[2]) : null,
|
onSelected: onActivate != null ? () => onActivate(subMenu1[2]) : null,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user