@@ -15,7 +15,7 @@ import 'framework.dart';
1515import 'shortcuts.dart' ;
1616
1717// "flutter/menu" Method channel methods.
18- const String _kMenuSetMethod = 'Menu.setMenu ' ;
18+ const String _kMenuSetMethod = 'Menu.setMenus ' ;
1919const String _kMenuSelectedCallbackMethod = 'Menu.selectedCallback' ;
2020const String _kMenuItemOpenedMethod = 'Menu.opened' ;
2121const String _kMenuItemClosedMethod = 'Menu.closed' ;
@@ -27,6 +27,9 @@ const String _kEnabledKey = 'enabled';
2727const String _kChildrenKey = 'children' ;
2828const String _kIsDividerKey = 'isDivider' ;
2929const String _kPlatformDefaultMenuKey = 'platformProvidedMenu' ;
30+ const String _kShortcutCharacter = 'shortcutCharacter' ;
31+ const String _kShortcutTrigger = 'shortcutTrigger' ;
32+ const String _kShortcutModifiers = 'shortcutModifiers' ;
3033
3134/// A class used by [MenuSerializableShortcut] to describe the shortcut for
3235/// serialization to send to the platform for rendering a [PlatformMenuBar] .
@@ -43,7 +46,7 @@ class ShortcutSerialization {
4346 ///
4447 /// This is used by a [CharacterActivator] to serialize itself.
4548 ShortcutSerialization .character (String character)
46- : _internal = < String , Object ? > {_shortcutCharacter : character},
49+ : _internal = < String , Object ? > {_kShortcutCharacter : character},
4750 assert (character.length == 1 );
4851
4952 /// Creates a [ShortcutSerialization] representing a specific
@@ -71,8 +74,8 @@ class ShortcutSerialization {
7174 'Specifying a modifier key as a trigger is not allowed. '
7275 'Use provided boolean parameters instead.' ),
7376 _internal = < String , Object ? > {
74- _shortcutTrigger : trigger.keyId,
75- _shortcutModifiers : (control ? _shortcutModifierControl : 0 ) |
77+ _kShortcutTrigger : trigger.keyId,
78+ _kShortcutModifiers : (control ? _shortcutModifierControl : 0 ) |
7679 (alt ? _shortcutModifierAlt : 0 ) |
7780 (shift ? _shortcutModifierShift : 0 ) |
7881 (meta ? _shortcutModifierMeta : 0 ),
@@ -96,30 +99,6 @@ class ShortcutSerialization {
9699 /// equivalents) being down.
97100 static const int _shortcutModifierControl = 1 << 3 ;
98101
99- /// The key for a string map field returned from [serializeForMenu] containing
100- /// a string that represents the character that, when typed, will trigger the
101- /// shortcut.
102- ///
103- /// All platforms are limited to a single trigger key that can be represented,
104- /// so this string should only contain a character that can be typed with a
105- /// single keystroke.
106- static const String _shortcutCharacter = 'shortcutEquivalent' ;
107-
108- /// The key for the integer map field returned from [serializeForMenu]
109- /// containing the logical key ID for the trigger key on this shortcut.
110- ///
111- /// All platforms are limited to a single trigger key that can be represented.
112- static const String _shortcutTrigger = 'shortcutTrigger' ;
113-
114- /// The key for the integer map field returned from [serializeForMenu]
115- /// containing a bitfield combination of [shortcutModifierControl] ,
116- /// [shortcutModifierAlt] , [shortcutModifierShift] , and/or
117- /// [shortcutModifierMeta] .
118- ///
119- /// If the shortcut responds to one of those modifiers, it should be
120- /// represented in the bitfield tagged with this key.
121- static const String _shortcutModifiers = 'shortcutModifiers' ;
122-
123102 /// Converts the internal representation to the format needed for a [MenuItem]
124103 /// to include it in its serialized form for sending to the platform.
125104 Map <String , Object ?> toChannelRepresentation () => _internal;
@@ -173,8 +152,6 @@ abstract class MenuItem with Diagnosticable {
173152 /// "id" field of the menu item data.
174153 Iterable <Map <String , Object ?>> toChannelRepresentation (
175154 PlatformMenuDelegate delegate, {
176- required int index,
177- required int count,
178155 required MenuItemSerializableIdGenerator getId,
179156 });
180157
@@ -340,11 +317,8 @@ class DefaultPlatformMenuDelegate extends PlatformMenuDelegate {
340317 _idMap.clear ();
341318 final List <Map <String , Object ?>> representation = < Map <String , Object ?>> [];
342319 if (topLevelMenus.isNotEmpty) {
343- int index = 0 ;
344320 for (final MenuItem childItem in topLevelMenus) {
345- representation
346- .addAll (childItem.toChannelRepresentation (this , index: index, count: topLevelMenus.length, getId: _getId));
347- index += 1 ;
321+ representation.addAll (childItem.toChannelRepresentation (this , getId: _getId));
348322 }
349323 }
350324 // Currently there's only ever one window, but the channel's format allows
@@ -598,8 +572,6 @@ class PlatformMenu extends MenuItem with DiagnosticableTreeMixin {
598572 @override
599573 Iterable <Map <String , Object ?>> toChannelRepresentation (
600574 PlatformMenuDelegate delegate, {
601- required int index,
602- required int count,
603575 required MenuItemSerializableIdGenerator getId,
604576 }) {
605577 return < Map <String , Object ?>> [serialize (this , delegate, getId)];
@@ -616,15 +588,31 @@ class PlatformMenu extends MenuItem with DiagnosticableTreeMixin {
616588 MenuItemSerializableIdGenerator getId,
617589 ) {
618590 final List <Map <String , Object ?>> result = < Map <String , Object ?>> [];
619- int index = 0 ;
620591 for (final MenuItem childItem in item.menus) {
621592 result.addAll (childItem.toChannelRepresentation (
622593 delegate,
623- index: index,
624- count: item.menus.length,
625594 getId: getId,
626595 ));
627- index += 1 ;
596+ }
597+ // To avoid doing type checking for groups, just filter out when there are
598+ // multiple sequential dividers, or when they are first or last, since
599+ // groups may be interleaved with non-groups, and non-groups may also add
600+ // dividers.
601+ Map <String , Object ?>? previousItem;
602+ result.removeWhere ((Map <String , Object ?> item) {
603+ if (previousItem == null && item[_kIsDividerKey] == true ) {
604+ // Strip any leading dividers.
605+ return true ;
606+ }
607+ if (previousItem != null && previousItem! [_kIsDividerKey] == true && item[_kIsDividerKey] == true ) {
608+ // Strip any duplicate dividers.
609+ return true ;
610+ }
611+ previousItem = item;
612+ return false ;
613+ });
614+ if (result.isNotEmpty && result.last[_kIsDividerKey] == true ) {
615+ result.removeLast ();
628616 }
629617 return < String , Object ? > {
630618 _kIdKey: getId (item),
@@ -666,32 +654,24 @@ class PlatformMenuItemGroup extends MenuItem {
666654 @override
667655 Iterable <Map <String , Object ?>> toChannelRepresentation (
668656 PlatformMenuDelegate delegate, {
669- required int index,
670- required int count,
671657 required MenuItemSerializableIdGenerator getId,
672658 }) {
673659 assert (members.isNotEmpty, 'There must be at least one member in a PlatformMenuItemGroup' );
674660 final List <Map <String , Object ?>> result = < Map <String , Object ?>> [];
675- if (index != 0 ) {
676- result.add (< String , Object ? > {
677- _kIdKey: getId (this ),
678- _kIsDividerKey: true ,
679- });
680- }
661+ result.add (< String , Object ? > {
662+ _kIdKey: getId (this ),
663+ _kIsDividerKey: true ,
664+ });
681665 for (final MenuItem item in members) {
682666 result.addAll (item.toChannelRepresentation (
683667 delegate,
684- index: index,
685- count: count,
686668 getId: getId,
687669 ));
688670 }
689- if (index != count - 1 ) {
690- result.add (< String , Object ? > {
691- _kIdKey: getId (this ),
692- _kIsDividerKey: true ,
693- });
694- }
671+ result.add (< String , Object ? > {
672+ _kIdKey: getId (this ),
673+ _kIsDividerKey: true ,
674+ });
695675 return result;
696676 }
697677
@@ -740,8 +720,6 @@ class PlatformMenuItem extends MenuItem {
740720 @override
741721 Iterable <Map <String , Object ?>> toChannelRepresentation (
742722 PlatformMenuDelegate delegate, {
743- required int index,
744- required int count,
745723 required MenuItemSerializableIdGenerator getId,
746724 }) {
747725 return < Map <String , Object ?>> [PlatformMenuItem .serialize (this , delegate, getId)];
@@ -852,8 +830,6 @@ class PlatformProvidedMenuItem extends PlatformMenuItem {
852830 @override
853831 Iterable <Map <String , Object ?>> toChannelRepresentation (
854832 PlatformMenuDelegate delegate, {
855- required int index,
856- required int count,
857833 required MenuItemSerializableIdGenerator getId,
858834 }) {
859835 assert (() {
0 commit comments