Răsfoiți Sursa

Fixes #783. Menu is now activated by Alt key if the focused view doesn't need it.

BDisp 5 ani în urmă
părinte
comite
c159d47b3b
3 a modificat fișierele cu 111 adăugiri și 35 ștergeri
  1. 36 0
      Terminal.Gui/Core/Toplevel.cs
  2. 10 12
      Terminal.Gui/Core/View.cs
  3. 65 23
      Terminal.Gui/Views/Menu.cs

+ 36 - 0
Terminal.Gui/Core/Toplevel.cs

@@ -121,6 +121,42 @@ namespace Terminal.Gui {
 		/// </summary>
 		/// </summary>
 		public StatusBar StatusBar { get; set; }
 		public StatusBar StatusBar { get; set; }
 
 
+		///<inheritdoc/>
+		public override bool OnKeyDown (KeyEvent keyEvent)
+		{
+			if (base.OnKeyDown (keyEvent)) {
+				return true;
+			}
+
+			switch (keyEvent.Key) {
+			case Key.AltMask:
+				if (MenuBar != null && MenuBar.OnKeyDown (keyEvent)) {
+					return true;
+				}
+				break;
+			}
+
+			return false;
+		}
+
+		///<inheritdoc/>
+		public override bool OnKeyUp (KeyEvent keyEvent)
+		{
+			if (base.OnKeyUp (keyEvent)) {
+				return true;
+			}
+
+			switch (keyEvent.Key) {
+			case Key.AltMask:
+				if (MenuBar != null && MenuBar.OnKeyUp (keyEvent)) {
+					return true;
+				}
+				break;
+			}
+
+			return false;
+		}
+
 		///<inheritdoc/>
 		///<inheritdoc/>
 		public override bool ProcessKey (KeyEvent keyEvent)
 		public override bool ProcessKey (KeyEvent keyEvent)
 		{
 		{

+ 10 - 12
Terminal.Gui/Core/View.cs

@@ -1360,13 +1360,12 @@ namespace Terminal.Gui {
 		{
 		{
 			KeyEventEventArgs args = new KeyEventEventArgs (keyEvent);
 			KeyEventEventArgs args = new KeyEventEventArgs (keyEvent);
 			KeyDown?.Invoke (args);
 			KeyDown?.Invoke (args);
-			if (args.Handled)
+			if (args.Handled) {
 				return true;
 				return true;
-			if (subviews == null || subviews.Count == 0)
-				return false;
-			foreach (var view in subviews)
-				if (view.HasFocus && view.OnKeyDown (keyEvent))
-					return true;
+			}
+			if (Focused?.OnKeyDown (keyEvent) == true) {
+				return true;
+			}
 
 
 			return false;
 			return false;
 		}
 		}
@@ -1381,13 +1380,12 @@ namespace Terminal.Gui {
 		{
 		{
 			KeyEventEventArgs args = new KeyEventEventArgs (keyEvent);
 			KeyEventEventArgs args = new KeyEventEventArgs (keyEvent);
 			KeyUp?.Invoke (args);
 			KeyUp?.Invoke (args);
-			if (args.Handled)
+			if (args.Handled) {
 				return true;
 				return true;
-			if (subviews == null || subviews.Count == 0)
-				return false;
-			foreach (var view in subviews)
-				if (view.HasFocus && view.OnKeyUp (keyEvent))
-					return true;
+			}
+			if (Focused?.OnKeyUp (keyEvent) == true) {
+				return true;
+			}
 
 
 			return false;
 			return false;
 		}
 		}

+ 65 - 23
Terminal.Gui/Views/Menu.cs

@@ -400,6 +400,11 @@ namespace Terminal.Gui {
 			});
 			});
 		}
 		}
 
 
+		public override bool OnLeave (View view)
+		{
+			return host.OnLeave (view);
+		}
+
 		public override bool OnKeyDown (KeyEvent keyEvent)
 		public override bool OnKeyDown (KeyEvent keyEvent)
 		{
 		{
 			if (keyEvent.IsAlt) {
 			if (keyEvent.IsAlt) {
@@ -426,9 +431,12 @@ namespace Terminal.Gui {
 		{
 		{
 			bool disabled;
 			bool disabled;
 			switch (kb.Key) {
 			switch (kb.Key) {
+			case Key.Tab:
+				host.CleanUp ();
+				return true;
 			case Key.CursorUp:
 			case Key.CursorUp:
 				if (barItems.IsTopLevel || current == -1)
 				if (barItems.IsTopLevel || current == -1)
-					break;
+					return true;
 				do {
 				do {
 					disabled = false;
 					disabled = false;
 					current--;
 					current--;
@@ -436,6 +444,9 @@ namespace Terminal.Gui {
 						if (current == -1 && barItems.Children [current + 1].IsFromSubMenu && host.selectedSub > -1) {
 						if (current == -1 && barItems.Children [current + 1].IsFromSubMenu && host.selectedSub > -1) {
 							current++;
 							current++;
 							host.PreviousMenu (true);
 							host.PreviousMenu (true);
+							if (host.openMenu.current > 0) {
+								host.openMenu.current--;
+							}
 							break;
 							break;
 						}
 						}
 					}
 					}
@@ -443,12 +454,17 @@ namespace Terminal.Gui {
 						current = barItems.Children.Length - 1;
 						current = barItems.Children.Length - 1;
 					var item = barItems.Children [current];
 					var item = barItems.Children [current];
 					if (item == null || !item.IsEnabled ()) disabled = true;
 					if (item == null || !item.IsEnabled ()) disabled = true;
+					if (host.UseKeysUpDownAsKeysLeftRight && barItems.Children [current]?.SubMenu != null &&
+						!disabled && host.IsMenuOpen) {
+						CheckSubMenu ();
+						break;
+					}
 				} while (barItems.Children [current] == null || disabled);
 				} while (barItems.Children [current] == null || disabled);
 				SetNeedsDisplay ();
 				SetNeedsDisplay ();
-				break;
+				return true;
 			case Key.CursorDown:
 			case Key.CursorDown:
 				if (barItems.IsTopLevel) {
 				if (barItems.IsTopLevel) {
-					break;
+					return true;
 				}
 				}
 
 
 				do {
 				do {
@@ -467,17 +483,17 @@ namespace Terminal.Gui {
 						host.OpenMenu (host.selected);
 						host.OpenMenu (host.selected);
 				} while (barItems.Children [current] == null || disabled);
 				} while (barItems.Children [current] == null || disabled);
 				SetNeedsDisplay ();
 				SetNeedsDisplay ();
-				break;
+				return true;
 			case Key.CursorLeft:
 			case Key.CursorLeft:
 				host.PreviousMenu (true);
 				host.PreviousMenu (true);
-				break;
+				return true;
 			case Key.CursorRight:
 			case Key.CursorRight:
 				host.NextMenu (barItems.IsTopLevel || barItems.Children [current].IsFromSubMenu ? true : false);
 				host.NextMenu (barItems.IsTopLevel || barItems.Children [current].IsFromSubMenu ? true : false);
-				break;
+				return true;
 			case Key.Esc:
 			case Key.Esc:
 				Application.UngrabMouse ();
 				Application.UngrabMouse ();
 				host.CloseAllMenus ();
 				host.CloseAllMenus ();
-				break;
+				return true;
 			case Key.Enter:
 			case Key.Enter:
 				if (barItems.IsTopLevel) {
 				if (barItems.IsTopLevel) {
 					Run (barItems.Action);
 					Run (barItems.Action);
@@ -485,7 +501,7 @@ namespace Terminal.Gui {
 					CheckSubMenu ();
 					CheckSubMenu ();
 					Run (barItems.Children [current].Action);
 					Run (barItems.Children [current].Action);
 				}
 				}
-				break;
+				return true;
 			default:
 			default:
 				// TODO: rune-ify
 				// TODO: rune-ify
 				if (barItems.Children != null && Char.IsLetterOrDigit ((char)kb.KeyValue)) {
 				if (barItems.Children != null && Char.IsLetterOrDigit ((char)kb.KeyValue)) {
@@ -501,7 +517,7 @@ namespace Terminal.Gui {
 				}
 				}
 				break;
 				break;
 			}
 			}
-			return true;
+			return false;
 		}
 		}
 
 
 		public override bool MouseEvent (MouseEvent me)
 		public override bool MouseEvent (MouseEvent me)
@@ -629,6 +645,18 @@ namespace Terminal.Gui {
 
 
 		bool openedByAltKey;
 		bool openedByAltKey;
 
 
+		bool isCleaning;
+
+		///<inheritdoc/>
+		public override bool OnLeave (View view)
+		{
+			if ((!(view is MenuBar) && !(view is Menu) || !(view is MenuBar) && !(view is Menu) && openMenu != null) && !isCleaning && !reopen) {
+				CleanUp ();
+				return true;
+			}
+			return false;
+		}
+
 		///<inheritdoc/>
 		///<inheritdoc/>
 		public override bool OnKeyDown (KeyEvent keyEvent)
 		public override bool OnKeyDown (KeyEvent keyEvent)
 		{
 		{
@@ -664,16 +692,7 @@ namespace Terminal.Gui {
 					// we don't want to close the menu because it'll flash.
 					// we don't want to close the menu because it'll flash.
 					// How to deal with that?
 					// How to deal with that?
 
 
-					if (openMenu != null)
-						CloseAllMenus ();
-					openedByAltKey = false;
-					IsMenuOpen = false;
-					selected = -1;
-					CanFocus = false;
-					if (lastFocused != null)
-						SuperView?.SetFocus (lastFocused);
-					SetNeedsDisplay ();
-					Application.UngrabMouse ();
+					CleanUp ();
 				}
 				}
 
 
 				return true;
 				return true;
@@ -681,6 +700,24 @@ namespace Terminal.Gui {
 			return false;
 			return false;
 		}
 		}
 
 
+		internal void CleanUp ()
+		{
+			isCleaning = true;
+			if (openMenu != null) {
+				CloseAllMenus ();
+			}
+			openedByAltKey = false;
+			IsMenuOpen = false;
+			selected = -1;
+			CanFocus = false;
+			if (lastFocused != null) {
+				lastFocused.SuperView?.SetFocus (lastFocused);
+			}
+			SetNeedsDisplay ();
+			Application.UngrabMouse ();
+			isCleaning = false;
+		}
+
 		///<inheritdoc/>
 		///<inheritdoc/>
 		public override void Redraw (Rect bounds)
 		public override void Redraw (Rect bounds)
 		{
 		{
@@ -865,9 +902,12 @@ namespace Terminal.Gui {
 			CloseMenu (false, false);
 			CloseMenu (false, false);
 		}
 		}
 
 
+		bool reopen;
+
 		internal void CloseMenu (bool reopen = false, bool isSubMenu = false)
 		internal void CloseMenu (bool reopen = false, bool isSubMenu = false)
 		{
 		{
 			isMenuClosing = true;
 			isMenuClosing = true;
+			this.reopen = reopen;
 			OnMenuClosing ();
 			OnMenuClosing ();
 			switch (isSubMenu) {
 			switch (isSubMenu) {
 			case false:
 			case false:
@@ -875,18 +915,19 @@ namespace Terminal.Gui {
 					SuperView.Remove (openMenu);
 					SuperView.Remove (openMenu);
 				}
 				}
 				SetNeedsDisplay ();
 				SetNeedsDisplay ();
-				if (previousFocused != null && openMenu != null && previousFocused.ToString () != openCurrentMenu.ToString ())
+				if (previousFocused != null && previousFocused is Menu && openMenu != null && previousFocused.ToString () != openCurrentMenu.ToString ())
 					previousFocused?.SuperView?.SetFocus (previousFocused);
 					previousFocused?.SuperView?.SetFocus (previousFocused);
 				openMenu?.Dispose ();
 				openMenu?.Dispose ();
 				openMenu = null;
 				openMenu = null;
-				if (lastFocused is Menu) {
+				if (lastFocused is Menu || lastFocused is MenuBar) {
 					lastFocused = null;
 					lastFocused = null;
 				}
 				}
 				LastFocused = lastFocused;
 				LastFocused = lastFocused;
 				lastFocused = null;
 				lastFocused = null;
 				if (LastFocused != null) {
 				if (LastFocused != null) {
-					if (!reopen)
+					if (!reopen) {
 						selected = -1;
 						selected = -1;
+					}
 					LastFocused.SuperView?.SetFocus (LastFocused);
 					LastFocused.SuperView?.SetFocus (LastFocused);
 				} else {
 				} else {
 					SuperView.SetFocus (this);
 					SuperView.SetFocus (this);
@@ -904,6 +945,7 @@ namespace Terminal.Gui {
 				IsMenuOpen = true;
 				IsMenuOpen = true;
 				break;
 				break;
 			}
 			}
+			this.reopen = false;
 			isMenuClosing = false;
 			isMenuClosing = false;
 		}
 		}
 
 
@@ -1191,7 +1233,7 @@ namespace Terminal.Gui {
 						} else if (selected != i && selected > -1 && (me.Flags == MouseFlags.ReportMousePosition ||
 						} else if (selected != i && selected > -1 && (me.Flags == MouseFlags.ReportMousePosition ||
 							me.Flags == MouseFlags.Button1Pressed && me.Flags == MouseFlags.ReportMousePosition)) {
 							me.Flags == MouseFlags.Button1Pressed && me.Flags == MouseFlags.ReportMousePosition)) {
 							if (IsMenuOpen) {
 							if (IsMenuOpen) {
-								CloseMenu ();
+								CloseMenu (true, false);
 								Activate (i);
 								Activate (i);
 							}
 							}
 						} else {
 						} else {