Browse Source

Improves the MenuOpening event.

BDisp 4 years ago
parent
commit
b2a8a7cb6d
1 changed files with 49 additions and 11 deletions
  1. 49 11
      Terminal.Gui/Views/Menu.cs

+ 49 - 11
Terminal.Gui/Views/Menu.cs

@@ -166,7 +166,7 @@ namespace Terminal.Gui {
 		/// <summary>
 		/// Gets if this <see cref="MenuItem"/> is from a sub-menu.
 		/// </summary>
-		internal bool IsFromSubMenu { get {return Parent != null; } }
+		internal bool IsFromSubMenu { get { return Parent != null; } }
 
 		/// <summary>
 		/// Merely a debugging aid to see the interaction with main
@@ -274,7 +274,7 @@ namespace Terminal.Gui {
 		/// <summary>
 		/// Initializes a new <see cref="MenuBarItem"/>.
 		/// </summary>
-		public MenuBarItem () : this (children: new MenuItem [] { }) {  }
+		public MenuBarItem () : this (children: new MenuItem [] { }) { }
 
 		//static int GetMaxTitleLength (MenuItem [] children)
 		//{
@@ -447,7 +447,7 @@ namespace Terminal.Gui {
 				for (int p = 0; p < Frame.Width - 2; p++)
 					if (item == null)
 						Driver.AddRune (Driver.HLine);
-					else if (p == Frame.Width - 3 && barItems.SubMenu(barItems.Children [i]) != null)
+					else if (p == Frame.Width - 3 && barItems.SubMenu (barItems.Children [i]) != null)
 						Driver.AddRune (Driver.RightArrow);
 					else
 						Driver.AddRune (' ');
@@ -916,7 +916,7 @@ namespace Terminal.Gui {
 				var menu = Menus [i];
 				Move (pos, 0);
 				Attribute hotColor, normalColor;
-				if (i == selected) {
+				if (i == selected && IsMenuOpen) {
 					hotColor = i == selected ? ColorScheme.HotFocus : ColorScheme.HotNormal;
 					normalColor = i == selected ? ColorScheme.Focus : ColorScheme.Normal;
 				} else if (openedByAltKey) {
@@ -966,7 +966,7 @@ namespace Terminal.Gui {
 		/// <summary>
 		/// Raised as a menu is opening.
 		/// </summary>
-		public event Action MenuOpening;
+		public event Action<MenuOpeningEventArgs> MenuOpening;
 
 		/// <summary>
 		/// Raised when a menu is closing.
@@ -986,11 +986,15 @@ namespace Terminal.Gui {
 		public bool IsMenuOpen { get; protected set; }
 
 		/// <summary>
-		/// Virtual method that will invoke the <see cref="MenuOpening"/>
+		/// Virtual method that will invoke the <see cref="MenuOpening"/> event if it's defined.
 		/// </summary>
-		public virtual void OnMenuOpening ()
+		/// <param name="currentMenu">The current menu to be replaced.</param>
+		/// /// <returns>Returns the <see cref="MenuOpeningEventArgs"/></returns>
+		public virtual MenuOpeningEventArgs OnMenuOpening (MenuBarItem currentMenu)
 		{
-			MenuOpening?.Invoke ();
+			var ev = new MenuOpeningEventArgs (currentMenu);
+			MenuOpening?.Invoke (ev);
+			return ev;
 		}
 
 		/// <summary>
@@ -1011,11 +1015,17 @@ namespace Terminal.Gui {
 		internal void OpenMenu (int index, int sIndex = -1, MenuBarItem subMenu = null)
 		{
 			isMenuOpening = true;
-			OnMenuOpening ();
+			var newMenu = OnMenuOpening (Menus [index]);
+			if (newMenu.Cancel) {
+				return;
+			}
+			if (newMenu.NewMenuBarItem != null && Menus [index].Title == newMenu.NewMenuBarItem.Title) {
+				Menus [index] = newMenu.NewMenuBarItem;
+			}
 			int pos = 0;
 			switch (subMenu) {
 			case null:
-				lastFocused = lastFocused ?? SuperView.MostFocused;
+				lastFocused = lastFocused ?? SuperView?.MostFocused;
 				if (openSubMenu != null)
 					CloseMenu (false, true);
 				if (openMenu != null) {
@@ -1460,7 +1470,7 @@ namespace Terminal.Gui {
 			case Key.CursorDown:
 			case Key.Enter:
 				if (selected > -1) {
-					ProcessMenu (selected, Menus [selected]); 
+					ProcessMenu (selected, Menus [selected]);
 				}
 				break;
 
@@ -1638,4 +1648,32 @@ namespace Terminal.Gui {
 			return base.OnEnter (view);
 		}
 	}
+
+	/// <summary>
+	/// An <see cref="EventArgs"/> which allows passing a cancelable menu opening event or replacing with a new <see cref="MenuBarItem"/>.
+	/// </summary>
+	public class MenuOpeningEventArgs : EventArgs {
+		/// <summary>
+		/// The current <see cref="MenuBarItem"/> parent.
+		/// </summary>
+		public MenuBarItem CurrentMenu { get; }
+
+		/// <summary>
+		/// The new <see cref="MenuBarItem"/> to be replaced.
+		/// </summary>
+		public MenuBarItem NewMenuBarItem { get; set; }
+		/// <summary>
+		/// Flag that allows you to cancel the opening of the menu.
+		/// </summary>
+		public bool Cancel { get; set; }
+
+		/// <summary>
+		/// Initializes a new instance of <see cref="MenuOpeningEventArgs"/>
+		/// </summary>
+		/// <param name="currentMenu">The current <see cref="MenuBarItem"/> parent.</param>
+		public MenuOpeningEventArgs (MenuBarItem currentMenu)
+		{
+			CurrentMenu = currentMenu;
+		}
+	}
 }