فهرست منبع

Improved View Key event handling

+ Added Handled property of type bool to the KeyEventEventArgs class.
+ Added ability to stop further propagation for already handled events on Views for Keyboard related event subscribers (like KeyDown, KeyUp and KeyPress). The driver will check the Handled property of the KeyEventEventArgs passed to the subscribers and will stop any further invocations when its found true.
+ Updated Example project to expose the ability to programatically Open/Close a MenuBar from custom keystrokes.

This commit fixes an issue where the library would crash if the Subviews collection of the currently active View gets updated from inside any of the Keyboard event handlers, such as when the view is updated as a result of a custom Hotkey/Coldkey press.
Fabian R 5 سال پیش
والد
کامیت
46b4c9025b
2فایلهای تغییر یافته به همراه40 افزوده شده و 6 حذف شده
  1. 14 1
      Example/demo.cs
  2. 26 5
      Terminal.Gui/Core.cs

+ 14 - 1
Example/demo.cs

@@ -190,7 +190,7 @@ static class Demo {
 			new DateField (3, 22, DateTime.Now),
 			new DateField (3, 22, DateTime.Now),
 			new DateField (23, 22, DateTime.Now, true),
 			new DateField (23, 22, DateTime.Now, true),
 			progress,
 			progress,
-			new Label (3, 24, "Press F9 (on Unix, ESC+9 is an alias) to activate the menubar"),
+			new Label (3, 24, "Press F9 (on Unix, ESC+9 is an alias) or Ctrl+T to activate the menubar"),
 			menuKeysStyle,
 			menuKeysStyle,
 			menuAutoMouseNav
 			menuAutoMouseNav
 
 
@@ -636,10 +636,23 @@ static class Demo {
 		};
 		};
 #endif
 #endif
 
 
+		win.KeyPress += Win_KeyPress;
+
 
 
 		top.Add (win);
 		top.Add (win);
 		//top.Add (menu);
 		//top.Add (menu);
 		top.Add (menu, statusBar);
 		top.Add (menu, statusBar);
 		Application.Run ();
 		Application.Run ();
 	}
 	}
+
+	private static void Win_KeyPress (object sender, View.KeyEventEventArgs e)
+	{
+		if (e.KeyEvent.Key == Key.ControlT) {
+			if (menu.IsMenuOpen)
+				menu.CloseMenu ();
+			else
+				menu.OpenMenu ();
+			e.Handled = true;
+		}
+	}
 }
 }

+ 26 - 5
Terminal.Gui/Core.cs

@@ -1087,6 +1087,11 @@ namespace Terminal.Gui {
 			/// The <see cref="KeyEvent"/> for the event.
 			/// The <see cref="KeyEvent"/> for the event.
 			/// </summary>
 			/// </summary>
 			public KeyEvent KeyEvent { get; set; }
 			public KeyEvent KeyEvent { get; set; }
+			/// <summary>
+			/// Indicates if the current Key event has already been processed and the driver should stop notifying any other event subscriber.
+			/// Its important to set this value to true specially when updating any View's layout from inside the subscriber method.
+			/// </summary>
+			public bool Handled { get; set; } = false;
 		}
 		}
 
 
 		/// <summary>
 		/// <summary>
@@ -1097,7 +1102,11 @@ namespace Terminal.Gui {
 		/// <inheritdoc cref="ProcessKey"/>
 		/// <inheritdoc cref="ProcessKey"/>
 		public override bool ProcessKey (KeyEvent keyEvent)
 		public override bool ProcessKey (KeyEvent keyEvent)
 		{
 		{
-			KeyPress?.Invoke (this, new KeyEventEventArgs(keyEvent));
+
+			KeyEventEventArgs args = new KeyEventEventArgs (keyEvent);
+			KeyPress?.Invoke (this, args);
+			if (args.Handled)
+				return true;
 			if (Focused?.ProcessKey (keyEvent) == true)
 			if (Focused?.ProcessKey (keyEvent) == true)
 				return true;
 				return true;
 
 
@@ -1107,7 +1116,10 @@ namespace Terminal.Gui {
 		/// <inheritdoc cref="ProcessHotKey"/>
 		/// <inheritdoc cref="ProcessHotKey"/>
 		public override bool ProcessHotKey (KeyEvent keyEvent)
 		public override bool ProcessHotKey (KeyEvent keyEvent)
 		{
 		{
-			KeyPress?.Invoke (this, new KeyEventEventArgs (keyEvent));
+			KeyEventEventArgs args = new KeyEventEventArgs (keyEvent);
+			KeyPress?.Invoke (this, args);
+			if (args.Handled)
+				return true;
 			if (subviews == null || subviews.Count == 0)
 			if (subviews == null || subviews.Count == 0)
 				return false;
 				return false;
 			foreach (var view in subviews)
 			foreach (var view in subviews)
@@ -1119,7 +1131,10 @@ namespace Terminal.Gui {
 		/// <inheritdoc cref="ProcessColdKey"/>
 		/// <inheritdoc cref="ProcessColdKey"/>
 		public override bool ProcessColdKey (KeyEvent keyEvent)
 		public override bool ProcessColdKey (KeyEvent keyEvent)
 		{
 		{
-			KeyPress?.Invoke (this, new KeyEventEventArgs(keyEvent));
+			KeyEventEventArgs args = new KeyEventEventArgs (keyEvent);
+			KeyPress?.Invoke (this, args);
+			if (args.Handled)
+				return true;
 			if (subviews == null || subviews.Count == 0)
 			if (subviews == null || subviews.Count == 0)
 				return false;
 				return false;
 			foreach (var view in subviews)
 			foreach (var view in subviews)
@@ -1136,7 +1151,10 @@ namespace Terminal.Gui {
 		/// <param name="keyEvent">Contains the details about the key that produced the event.</param>
 		/// <param name="keyEvent">Contains the details about the key that produced the event.</param>
 		public override bool OnKeyDown (KeyEvent keyEvent)
 		public override bool OnKeyDown (KeyEvent keyEvent)
 		{
 		{
-			KeyDown?.Invoke (this, new KeyEventEventArgs (keyEvent));
+			KeyEventEventArgs args = new KeyEventEventArgs (keyEvent);
+			KeyDown?.Invoke (this, args);
+			if (args.Handled)
+				return true;
 			if (subviews == null || subviews.Count == 0)
 			if (subviews == null || subviews.Count == 0)
 				return false;
 				return false;
 			foreach (var view in subviews)
 			foreach (var view in subviews)
@@ -1154,7 +1172,10 @@ namespace Terminal.Gui {
 		/// <param name="keyEvent">Contains the details about the key that produced the event.</param>
 		/// <param name="keyEvent">Contains the details about the key that produced the event.</param>
 		public override bool OnKeyUp (KeyEvent keyEvent)
 		public override bool OnKeyUp (KeyEvent keyEvent)
 		{
 		{
-			KeyUp?.Invoke (this, new KeyEventEventArgs (keyEvent));
+			KeyEventEventArgs args = new KeyEventEventArgs (keyEvent);
+			KeyUp?.Invoke (this, args);
+			if (args.Handled)
+				return true;
 			if (subviews == null || subviews.Count == 0)
 			if (subviews == null || subviews.Count == 0)
 				return false;
 				return false;
 			foreach (var view in subviews)
 			foreach (var view in subviews)