Browse Source

Some mouse support, and support in some views

Miguel de Icaza 7 years ago
parent
commit
82b7a47702
7 changed files with 105 additions and 58 deletions
  1. 53 1
      Core.cs
  2. 1 1
      Driver.cs
  3. 0 26
      Event.cs
  4. 10 12
      Views/Checkbox.cs
  5. 14 0
      Views/RadioGroup.cs
  6. 18 18
      Views/TextField.cs
  7. 9 0
      demo.cs

+ 53 - 1
Core.cs

@@ -106,7 +106,10 @@ namespace Terminal {
 		}
 
 		// Mouse events
-		public virtual void MouseEvent (Event.Mouse me) { }
+		public virtual bool MouseEvent (MouseEvent me) 
+		{
+			return false;
+		}
 	}
 
 	public class View : Responder, IEnumerable {
@@ -946,8 +949,57 @@ namespace Terminal {
 				return;
 		}
 
+		static View FindDeepestView (View start, int x, int y, out int resx, out int resy)
+		{
+			var startFrame = start.Frame;
+
+			if (!startFrame.Contains (x, y)) {
+				resx = 0;
+				resy = 0;
+				return null;
+			}
+
+			if (start.Subviews != null){
+				int count = start.Subviews.Count;
+				if (count > 0) {
+					var rx = x - startFrame.X;
+					var ry = y - startFrame.Y;
+					for (int i = count - 1; i >= 0; i--) {
+						View v = start.Subviews [i];
+						if (v.Frame.Contains (rx, ry)) {
+							var deep = FindDeepestView (v, rx, ry, out resx, out resy);
+							if (deep == null)
+								return v;
+							return deep;
+						}
+					}
+				}
+			}
+			resx = x-startFrame.X;
+			resy = y-startFrame.Y;
+			return start;
+		}
+
+		/// <summary>
+		/// Merely a debugging aid to see the raw mouse events
+		/// </summary>
+		static public Action<MouseEvent> RootMouseEvent;
+
 		static void ProcessMouseEvent (MouseEvent me)
 		{
+			RootMouseEvent?.Invoke (me);
+			int rx, ry;
+			var view = FindDeepestView (Current, me.X, me.Y, out rx, out ry);
+			if (view != null) {
+				var nme = new MouseEvent () {
+					X = rx,
+					Y = ry,
+					Flags = me.Flags
+				};
+					          
+				// Should we bubbled up the event, if it is not handled?
+				view.MouseEvent (nme);
+			}
 		}
 
 		static public RunState Begin (Toplevel toplevel)

+ 1 - 1
Driver.cs

@@ -246,7 +246,7 @@ namespace Terminal {
 						return;
 					}
 				}
-				if (code == Curses.KeyMouse) {
+				if (wch == Curses.KeyMouse) {
 					Curses.MouseEvent ev;
 					Curses.getmouse (out ev);
 					mouseHandler (ToDriverMouse (ev));

+ 0 - 26
Event.cs

@@ -162,30 +162,4 @@ namespace Terminal {
 		/// </summary>
 		public MouseFlags Flags;
 	}
-
-	public class Event {
-		public class Key : Event {
-			public int Code { get; private set; }
-			public bool Alt { get; private set; }
-			public Key (int code)
-			{
-				Code = code;
-			}
-		}
-
-		public class Mouse : Event {
-		}
-
-		public static Event CreateMouseEvent ()
-		{
-			return new Mouse ();
-		}
-
-		public static Event CreateKeyEvent (int code)
-		{
-			return new Key (code);
-		}
-
-	}
-
 }

+ 10 - 12
Views/Checkbox.cs

@@ -113,20 +113,18 @@ namespace Terminal {
 			return base.ProcessKey (kb);
 		}
 
-#if false
-		public override void ProcessMouse (Curses.MouseEvent ev)
+		public override bool MouseEvent (MouseEvent me)
 		{
-			if ((ev.ButtonState & Curses.Event.Button1Clicked) != 0){
-				Container.SetFocus (this);
-				Container.Redraw ();
+			if (!me.Flags.HasFlag (MouseFlags.Button1Clicked))
+				return false;
 
-				Checked = !Checked;
-				
-				if (Toggled != null)
-					Toggled (this, EventArgs.Empty);
-				Redraw ();
-			}
+			SuperView.SetFocus (this);
+			Checked = !Checked;
+			SetNeedsDisplay ();
+
+			if (Toggled != null)
+				Toggled (this, EventArgs.Empty);
+			return true;
 		}
-#endif
 	}
 }

+ 14 - 0
Views/RadioGroup.cs

@@ -137,5 +137,19 @@ namespace Terminal {
 			}
 			return base.ProcessKey (kb);
 		}
+
+		public override bool MouseEvent (MouseEvent me)
+		{
+			if (!me.Flags.HasFlag (MouseFlags.Button1Clicked))
+				return false;
+
+			SuperView.SetFocus (this);
+
+			if (me.Y < radioLabels.Length) {
+				cursor = selected = me.Y;
+				SetNeedsDisplay ();
+			}
+			return true;
+		}
 	}
 }

+ 18 - 18
Views/TextField.cs

@@ -303,24 +303,24 @@ namespace Terminal {
 			return -1;
 		}
 
-#if false
-        public override void ProcessMouse (Curses.MouseEvent ev)
-        {
-            if ((ev.ButtonState & Curses.Event.Button1Clicked) == 0)
-                return;
-
-            .SetFocus (this);
-
-            // We could also set the cursor position.
-            point = first + (ev.X - x);
-            if (point > text.Length)
-                point = text.Length;
-            if (point < first)
-                point = 0;
-
-            SetNeedsDisplay ();
-        }
-#endif
+        	public override bool MouseEvent (MouseEvent ev)
+		{
+			if (!ev.Flags.HasFlag (MouseFlags.Button1Clicked))
+				return false;
+
+			if (!HasFocus) 
+				SuperView.SetFocus (this);
+			
+			// We could also set the cursor position.
+			point = first + ev.X;
+			if (point > text.Length)
+				point = text.Length;
+			if (point < first)
+				point = 0;
+	
+			SetNeedsDisplay ();
+			return true;
+		}
 	}
 
 

+ 9 - 0
demo.cs

@@ -31,6 +31,7 @@ class Demo {
 		Application.Run (d);
 	}
 
+	static Label ml;
 	static void Main ()
 	{
 		Application.Init ();
@@ -53,6 +54,14 @@ class Demo {
 		});
 
 		ShowEntries (win);
+		int count = 0;
+		ml = new Label (new Rect (3, 16, 50, 1), "Mouse: ");
+		Application.RootMouseEvent += delegate (MouseEvent me) {
+			
+			ml.Text = $"Mouse: ({me.X},{me.Y}) - {me.Flags} {count++}";
+		};
+
+		win.Add (ml);
 
 		// ShowTextAlignments (win);
 		top.Add (win);