66namespace OpenDreamClient . Interface ;
77
88public sealed class InterfaceMenu : InterfaceElement {
9- public readonly Dictionary < string , MenuElement > MenuElements = new ( ) ;
9+ public readonly Dictionary < string , MenuElement > MenuElementsById = new ( ) ;
10+ public readonly Dictionary < string , MenuElement > MenuElementsByName = new ( ) ;
1011 public readonly MenuBar MenuBar ;
1112
1213 private readonly bool _pauseMenuCreation ;
@@ -26,7 +27,7 @@ public InterfaceMenu(MenuDescriptor descriptor) : base(descriptor) {
2627 }
2728
2829 public void SetGroupChecked ( string group , string id ) {
29- foreach ( MenuElement menuElement in MenuElements . Values ) {
30+ foreach ( MenuElement menuElement in MenuElementsById . Values ) {
3031 if ( menuElement . ElementDescriptor is not MenuElementDescriptor menuElementDescriptor )
3132 continue ;
3233
@@ -44,22 +45,24 @@ public override void AddChild(ElementDescriptor descriptor) {
4445 if ( string . IsNullOrEmpty ( elementDescriptor . Category . Value ) ) {
4546 element = new ( elementDescriptor , this ) ;
4647 } else {
47- if ( ! MenuElements . TryGetValue ( elementDescriptor . Category . Value , out var parentMenu ) ) {
48+ if ( ! MenuElementsById . TryGetValue ( elementDescriptor . Category . Value , out var parentMenu ) &&
49+ ! MenuElementsByName . TryGetValue ( elementDescriptor . Category . Value , out parentMenu ) ) {
4850 //if category is set but the parent element doesn't exist, create it
49- var parentMenuDescriptor = new MenuElementDescriptor ( ) {
51+ var parentMenuDescriptor = new MenuElementDescriptor {
5052 Id = elementDescriptor . Category
5153 } ;
5254
5355 parentMenu = new ( parentMenuDescriptor , this ) ;
54- MenuElements . Add ( parentMenu . Id . AsRaw ( ) , parentMenu ) ;
56+ MenuElementsById . Add ( parentMenu . Id . AsRaw ( ) , parentMenu ) ;
5557 }
5658
5759 //now add this as a child
5860 element = new MenuElement ( elementDescriptor , this ) ;
5961 parentMenu . Children . Add ( element ) ;
6062 }
6163
62- MenuElements . Add ( element . Id . AsRaw ( ) , element ) ;
64+ MenuElementsById . Add ( element . Id . AsRaw ( ) , element ) ;
65+ MenuElementsByName [ element . ElementDescriptor . Name . AsRaw ( ) ] = element ;
6366 CreateMenu ( ) ; // Update the menu to include the new child
6467 }
6568
@@ -69,16 +72,16 @@ private void CreateMenu() {
6972
7073 MenuBar . Menus . Clear ( ) ;
7174
72- foreach ( MenuElement menuElement in MenuElements . Values ) {
75+ foreach ( MenuElement menuElement in MenuElementsById . Values ) {
7376 if ( ! string . IsNullOrEmpty ( menuElement . Category . Value ) ) // We only want the root-level menus here
7477 continue ;
7578
7679 MenuBar . Menu menu = new ( ) {
7780 Title = menuElement . ElementDescriptor . Name . AsRaw ( )
7881 } ;
7982
80- if ( menu . Title ? . StartsWith ( "&" ) ?? false )
81- menu . Title = menu . Title [ 1 .. ] ; //TODO: First character in name becomes a selection shortcut
83+ // TODO: Character after '&' becomes a selection shortcut
84+ menu . Title = menu . Title . Replace ( "&" , string . Empty ) ;
8285
8386 MenuBar . Menus . Add ( menu ) ;
8487 //visit each node in the tree, populating the menu from that
@@ -87,22 +90,16 @@ private void CreateMenu() {
8790 }
8891 }
8992
90- public sealed class MenuElement : InterfaceElement {
93+ public sealed class MenuElement ( MenuElementDescriptor data , InterfaceMenu menu ) : InterfaceElement ( data ) {
9194 public readonly List < MenuElement > Children = new ( ) ;
9295
9396 private MenuElementDescriptor MenuElementDescriptor => ( MenuElementDescriptor ) ElementDescriptor ;
9497 public DMFPropertyString Category => MenuElementDescriptor . Category ;
9598 public DMFPropertyString Command => MenuElementDescriptor . Command ;
96- private readonly InterfaceMenu _menu ;
97-
98- public MenuElement ( MenuElementDescriptor data , InterfaceMenu menu ) : base ( data ) {
99- _menu = menu ;
100- }
10199
102100 public MenuBar . MenuEntry CreateMenuEntry ( ) {
103101 string text = ElementDescriptor . Name . AsRaw ( ) ;
104- if ( text . StartsWith ( "&" ) )
105- text = text [ 1 ..] ; //TODO: First character in name becomes a selection shortcut
102+ text = text . Replace ( "&" , string . Empty ) ; // TODO: Character after '&' becomes a selection shortcut
106103
107104 if ( Children . Count > 0 ) {
108105 MenuBar . SubMenu subMenu = new ( ) {
@@ -115,25 +112,24 @@ public MenuBar.MenuEntry CreateMenuEntry() {
115112 return subMenu ;
116113 }
117114
118- if ( String . IsNullOrEmpty ( text ) )
115+ if ( string . IsNullOrEmpty ( text ) )
119116 return new MenuBar . MenuSeparator ( ) ;
120117
121118 if ( MenuElementDescriptor . CanCheck . Value )
122119 if ( MenuElementDescriptor . IsChecked . Value )
123- text = text + " ☑" ;
120+ text += " ☑" ;
124121
125122 MenuBar . MenuButton menuButton = new ( ) {
126123 Text = text
127124 } ;
128125
129-
130126 menuButton . OnPressed += ( ) => {
131127 if ( MenuElementDescriptor . CanCheck . Value )
132128 if ( ! string . IsNullOrEmpty ( MenuElementDescriptor . Group . Value ) )
133- _menu . SetGroupChecked ( MenuElementDescriptor . Group . Value , MenuElementDescriptor . Id . AsRaw ( ) ) ;
129+ menu . SetGroupChecked ( MenuElementDescriptor . Group . Value , MenuElementDescriptor . Id . AsRaw ( ) ) ;
134130 else
135131 MenuElementDescriptor . IsChecked = new DMFPropertyBool ( ! MenuElementDescriptor . IsChecked . Value ) ;
136- _menu . CreateMenu ( ) ;
132+ menu . CreateMenu ( ) ;
137133 if ( ! string . IsNullOrEmpty ( MenuElementDescriptor . Command . Value ) )
138134 _interfaceManager . RunCommand ( Command . AsRaw ( ) ) ;
139135 } ;
@@ -146,7 +142,7 @@ public override void AddChild(ElementDescriptor descriptor) {
146142 descriptor = ( ( MenuElementDescriptor ) descriptor ) . WithCategory ( IoCManager . Resolve < ISerializationManager > ( ) , MenuElementDescriptor . Name ) ;
147143
148144 // Pass this on to the parent menu
149- _menu . AddChild ( descriptor ) ;
145+ menu . AddChild ( descriptor ) ;
150146 }
151147 }
152148}
0 commit comments