Bladeren bron

Non breaking implementation of cancellable root mouse events

tznind 2 jaren geleden
bovenliggende
commit
20856f0ce0
2 gewijzigde bestanden met toevoegingen van 60 en 1 verwijderingen
  1. 17 0
      Terminal.Gui/Core/Application.cs
  2. 43 1
      UnitTests/TextFieldTests.cs

+ 17 - 0
Terminal.Gui/Core/Application.cs

@@ -638,6 +638,18 @@ namespace Terminal.Gui {
 			UnGrabbedMouse?.Invoke (view);
 		}
 
+		/// <summary>
+		/// <para>
+		/// Cancellable overload of <see cref="RootMouseEvent"/>.
+		/// </para>
+		/// <para>
+		/// Called for new MouseEvent events before any processing is performed or
+		/// views evaluate.  Use for global mouse handling and/or debugging.
+		/// </para>
+		/// <para>Return true to suppress the MouseEvent event</para>
+		/// </summary>
+		public static Func<MouseEvent, bool> RootMouseEventCancellable;
+
 		/// <summary>
 		/// Merely a debugging aid to see the raw mouse events
 		/// </summary>
@@ -670,6 +682,11 @@ namespace Terminal.Gui {
 				me.View = view;
 			}
 			RootMouseEvent?.Invoke (me);
+
+			if (RootMouseEventCancellable?.Invoke (me) ?? false) {
+				return;
+			}
+
 			if (mouseGrabView != null) {
 				if (view == null) {
 					UngrabMouse ();

+ 43 - 1
UnitTests/TextFieldTests.cs

@@ -1203,10 +1203,52 @@ namespace Terminal.Gui.Views {
 			Application.Driver.SendKeys ('j', ConsoleKey.A, false, false, false);
 			Assert.Equal ("aj", tf.Text.ToString ());
 		}
+		[Fact]
+		[AutoInitShutdown]
+		public void Test_RootMouseKeyEvent_Cancel ()
+		{
+			Application.RootMouseEventCancellable += SuppressRightClick;
+
+			var tf = new TextField () { Width = 10 };
+			int clickCounter = 0;
+			tf.MouseClick += (m) => { clickCounter++; };
+
+			Application.Top.Add (tf);
+			Application.Begin (Application.Top);
+
+			var processMouseEventMethod = typeof (Application).GetMethod ("ProcessMouseEvent", BindingFlags.Static | BindingFlags.NonPublic)
+				?? throw new Exception ("Expected private method not found 'ProcessMouseEvent', this method was used for testing mouse behaviours");
+
+			var mouseEvent = new MouseEvent {
+				Flags = MouseFlags.Button1Clicked,
+				View = tf
+			};
+
+			processMouseEventMethod.Invoke (null, new object [] { mouseEvent });
+			Assert.Equal (1, clickCounter);
+
+			mouseEvent.Flags = MouseFlags.Button3Clicked;
+
+			// should be ignored because of SuppressRightClick callback
+			processMouseEventMethod.Invoke (null, new object [] { mouseEvent });
+			Assert.Equal (1, clickCounter);
+
+			Application.RootMouseEventCancellable -= SuppressRightClick;
+
+			// should no longer be ignored as the callback was removed
+			processMouseEventMethod.Invoke (null, new object [] { mouseEvent });
+			Assert.Equal (2, clickCounter);
+		}
+
 
 		private bool SuppressKey (KeyEvent arg)
 		{
-			if (arg.KeyValue == 'j')
+			return false;
+		}
+
+		private bool SuppressRightClick (MouseEvent arg)
+		{
+			if (arg.Flags.HasFlag (MouseFlags.Button3Clicked))
 				return true;
 
 			return false;