mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-27 00:07:58 +01:00
Some mouse support, and support in some views
This commit is contained in:
54
Core.cs
54
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)
|
||||
|
||||
@@ -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));
|
||||
|
||||
26
Event.cs
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
9
demo.cs
9
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);
|
||||
|
||||
Reference in New Issue
Block a user