1
1
#nullable enable
2
+ using Microsoft . CodeAnalysis ;
3
+
2
4
namespace Terminal . Gui ;
3
5
4
6
/// <summary>
@@ -28,6 +30,63 @@ public PopoverMenu (Menuv2? root)
28
30
29
31
Root = root ;
30
32
33
+ AddCommand ( Command . Right , MoveRight ) ;
34
+ bool ? MoveRight ( ICommandContext ? ctx )
35
+ {
36
+ MenuItemv2 ? focused = MostFocused as MenuItemv2 ;
37
+
38
+ if ( focused is { SubMenu . Visible : true } )
39
+ {
40
+ focused . SubMenu . SetFocus ( ) ;
41
+
42
+ return true ;
43
+ }
44
+
45
+ return AdvanceFocus ( NavigationDirection . Forward , TabBehavior . TabStop ) ;
46
+ }
47
+ KeyBindings . Add ( Key . CursorRight , Command . Right ) ;
48
+
49
+ AddCommand ( Command . Left , MoveLeft ) ;
50
+ bool ? MoveLeft ( ICommandContext ? ctx )
51
+ {
52
+ if ( MostFocused is MenuItemv2 { SuperView : Menuv2 focusedMenu } )
53
+ {
54
+ focusedMenu . SuperMenuItem ? . SetFocus ( ) ;
55
+
56
+ return true ;
57
+ }
58
+ return AdvanceFocus ( NavigationDirection . Backward , TabBehavior . TabStop ) ;
59
+ }
60
+ KeyBindings . Add ( Key . CursorLeft , Command . Left ) ;
61
+
62
+ //AddCommand (Command.Down, MoveDown);
63
+
64
+ //bool? MoveDown (ICommandContext? ctx)
65
+ //{
66
+ // if (Orientation == Orientation.Horizontal)
67
+ // {
68
+ // return false;
69
+ // }
70
+
71
+ // return AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
72
+ //}
73
+
74
+ //AddCommand (Command.Up, MoveUp);
75
+
76
+ //bool? MoveUp (ICommandContext? ctx)
77
+ //{
78
+ // if (Orientation == Orientation.Horizontal)
79
+ // {
80
+ // return false;
81
+ // }
82
+
83
+ // return AdvanceFocus (NavigationDirection.Backward, TabBehavior.TabStop);
84
+ //}
85
+
86
+
87
+ //KeyBindings.Add (Key.CursorDown, Command.Down);
88
+ //KeyBindings.Add (Key.CursorUp, Command.Up);
89
+
31
90
}
32
91
33
92
private Menuv2 ? _root ;
@@ -50,6 +109,7 @@ public Menuv2? Root
50
109
base . Remove ( _root ) ;
51
110
_root . Accepting -= RootOnAccepting ;
52
111
_root . MenuItemCommandInvoked -= RootOnMenuItemCommandInvoked ;
112
+ _root . SelectedMenuItemChanged -= RootOnSelectedMenuItemChanged ;
53
113
}
54
114
55
115
_root = value ;
@@ -59,6 +119,9 @@ public Menuv2? Root
59
119
base . Add ( _root ) ;
60
120
_root . Accepting += RootOnAccepting ;
61
121
_root . MenuItemCommandInvoked += RootOnMenuItemCommandInvoked ;
122
+ _root . SelectedMenuItemChanged += RootOnSelectedMenuItemChanged ;
123
+
124
+
62
125
}
63
126
64
127
return ;
@@ -72,6 +135,55 @@ void RootOnAccepting (object? sender, CommandEventArgs e)
72
135
{
73
136
Logging . Trace ( $ "RootOnAccepting: { e . Context } ") ;
74
137
}
138
+
139
+ void RootOnSelectedMenuItemChanged ( object ? sender , MenuItemv2 ? e )
140
+ {
141
+ Logging . Trace ( $ "RootOnSelectedMenuItemChanged: { e . Title } ") ;
142
+ ShowSubMenu ( e ) ;
143
+ }
144
+
75
145
}
76
146
}
147
+ public void ShowSubMenu ( MenuItemv2 ? menuItem )
148
+ {
149
+ // Hide any other submenus that might be visible
150
+ foreach ( MenuItemv2 mi in menuItem . SuperView . SubViews . Where ( v => v is MenuItemv2 { SubMenu . Visible : true } ) . Cast < MenuItemv2 > ( ) )
151
+ {
152
+ mi . ForceFocusColors = false ;
153
+ mi . SubMenu ! . Visible = false ;
154
+ Remove ( mi . SubMenu ) ;
155
+ }
156
+
157
+ if ( menuItem is { SubMenu : { Visible : false } } )
158
+ {
159
+ Add ( menuItem . SubMenu ) ;
160
+ Point pos = GetMostVisibleLocationForSubMenu ( menuItem ) ;
161
+ menuItem . SubMenu . X = pos . X ;
162
+ menuItem . SubMenu . Y = pos . Y ;
163
+
164
+ menuItem . SubMenu . Visible = true ;
165
+ menuItem . ForceFocusColors = true ;
166
+ }
167
+ }
168
+
169
+ /// <summary>
170
+ /// Given a <see cref="MenuItemv2"/>, returns the most visible location for the submenu.
171
+ /// The location is relative to the Frame.
172
+ /// </summary>
173
+ /// <param name="menuItem"></param>
174
+ /// <returns></returns>
175
+ internal Point GetMostVisibleLocationForSubMenu ( MenuItemv2 menuItem )
176
+ {
177
+ Point pos = Point . Empty ;
178
+
179
+ // Calculate the initial position to the right of the menu item
180
+ pos . X = menuItem . SuperView ! . Frame . X + menuItem . Frame . Width ;
181
+ pos . Y = menuItem . SuperView . Frame . Y + menuItem . Frame . Y ;
182
+
183
+ GetLocationEnsuringFullVisibility ( menuItem . SubMenu , pos . X , pos . Y , out int nx , out int ny ) ;
184
+
185
+
186
+ return new ( nx , ny ) ;
187
+ }
188
+
77
189
}
0 commit comments