diff --git a/Core.cs b/Core.cs index c8fcca811..b20558d72 100644 --- a/Core.cs +++ b/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; + } + + /// + /// Merely a debugging aid to see the raw mouse events + /// + static public Action 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) diff --git a/Driver.cs b/Driver.cs index 0244562d7..70981d32b 100644 --- a/Driver.cs +++ b/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)); diff --git a/Event.cs b/Event.cs index 50c55b724..b6844cf41 100644 --- a/Event.cs +++ b/Event.cs @@ -162,30 +162,4 @@ namespace Terminal { /// 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); - } - - } - } \ No newline at end of file diff --git a/Views/Checkbox.cs b/Views/Checkbox.cs index e95598bac..b66ceec5d 100644 --- a/Views/Checkbox.cs +++ b/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 } } diff --git a/Views/RadioGroup.cs b/Views/RadioGroup.cs index 60c32e50b..fe41c34fb 100644 --- a/Views/RadioGroup.cs +++ b/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; + } } } diff --git a/Views/TextField.cs b/Views/TextField.cs index a1cc71d6c..96a166bfe 100644 --- a/Views/TextField.cs +++ b/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; + public override bool MouseEvent (MouseEvent ev) + { + if (!ev.Flags.HasFlag (MouseFlags.Button1Clicked)) + return false; - .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 + 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; + } } diff --git a/demo.cs b/demo.cs index 7149cf385..749bb32d6 100644 --- a/demo.cs +++ b/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);