mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2025-12-28 00:38:00 +01:00
Added mouse features in the Unix version. Supports xterm-1006.
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using Mono.Terminal;
|
||||
using NStack;
|
||||
using Unix.Terminal;
|
||||
@@ -182,12 +183,185 @@ namespace Terminal.Gui {
|
||||
}
|
||||
}
|
||||
|
||||
static MouseEvent ToDriverMouse (Curses.MouseEvent cev)
|
||||
Curses.Event? LastMouseButtonPressed = null;
|
||||
bool IsButtonPressed = false;
|
||||
bool cancelButtonClicked = false;
|
||||
Point point;
|
||||
|
||||
MouseEvent ToDriverMouse (Curses.MouseEvent cev)
|
||||
{
|
||||
MouseFlags mouseFlag = MouseFlags.AllEvents;
|
||||
|
||||
if (LastMouseButtonPressed != null && cev.ButtonState != Curses.Event.ReportMousePosition) {
|
||||
LastMouseButtonPressed = null;
|
||||
IsButtonPressed = false;
|
||||
}
|
||||
|
||||
|
||||
if ((cev.ButtonState == Curses.Event.Button1Clicked || cev.ButtonState == Curses.Event.Button2Clicked ||
|
||||
cev.ButtonState == Curses.Event.Button3Clicked) &&
|
||||
LastMouseButtonPressed == null) {
|
||||
|
||||
IsButtonPressed = false;
|
||||
mouseFlag = ProcessButtonClickedEvent (cev, mouseFlag);
|
||||
|
||||
} else if (((cev.ButtonState == Curses.Event.Button1Pressed || cev.ButtonState == Curses.Event.Button2Pressed ||
|
||||
cev.ButtonState == Curses.Event.Button3Pressed) && LastMouseButtonPressed == null) ||
|
||||
IsButtonPressed && cev.ButtonState == Curses.Event.ReportMousePosition) {
|
||||
|
||||
mouseFlag = (MouseFlags)cev.ButtonState;
|
||||
if (cev.ButtonState != Curses.Event.ReportMousePosition)
|
||||
LastMouseButtonPressed = cev.ButtonState;
|
||||
IsButtonPressed = true;
|
||||
|
||||
if (cev.ButtonState == Curses.Event.ReportMousePosition) {
|
||||
mouseFlag = (MouseFlags)LastMouseButtonPressed | MouseFlags.ReportMousePosition;
|
||||
point = new Point ();
|
||||
cancelButtonClicked = true;
|
||||
} else {
|
||||
point = new Point () {
|
||||
X = cev.X,
|
||||
Y = cev.Y
|
||||
};
|
||||
}
|
||||
|
||||
if ((mouseFlag & MouseFlags.ReportMousePosition) == 0) {
|
||||
Task.Run (async () => {
|
||||
while (IsButtonPressed && LastMouseButtonPressed != null) {
|
||||
await Task.Delay (200);
|
||||
var me = new MouseEvent () {
|
||||
X = cev.X,
|
||||
Y = cev.Y,
|
||||
Flags = mouseFlag
|
||||
};
|
||||
|
||||
var view = Application.wantContinuousButtonPressedView;
|
||||
if (view == null)
|
||||
break;
|
||||
if (IsButtonPressed && LastMouseButtonPressed != null && (mouseFlag & MouseFlags.ReportMousePosition) == 0) {
|
||||
mouseHandler (me);
|
||||
mainLoop.Driver.Wakeup ();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
} else if ((cev.ButtonState == Curses.Event.Button1Released || cev.ButtonState == Curses.Event.Button2Released ||
|
||||
cev.ButtonState == Curses.Event.Button3Released)) {
|
||||
|
||||
mouseFlag = ProcessButtonReleasedEvent (cev, mouseFlag);
|
||||
IsButtonPressed = false;
|
||||
|
||||
} else if (cev.ButtonState == Curses.Event.Button4Pressed) {
|
||||
|
||||
mouseFlag = MouseFlags.WheeledUp;
|
||||
|
||||
} else if (cev.ButtonState == Curses.Event.ReportMousePosition && cev.X == point.X && cev.Y == point.Y) {
|
||||
|
||||
mouseFlag = MouseFlags.WheeledDown;
|
||||
|
||||
}
|
||||
else if (cev.ButtonState == Curses.Event.ReportMousePosition) {
|
||||
|
||||
mouseFlag = MouseFlags.ReportMousePosition;
|
||||
} else {
|
||||
mouseFlag = (MouseFlags)cev.ButtonState;
|
||||
}
|
||||
|
||||
point = new Point () {
|
||||
X = cev.X,
|
||||
Y = cev.Y
|
||||
};
|
||||
|
||||
|
||||
|
||||
if (cev.ID != 0)
|
||||
mouseFlag = MouseFlags.WheeledDown;
|
||||
|
||||
return new MouseEvent () {
|
||||
X = cev.X,
|
||||
Y = cev.Y,
|
||||
//Flags = (MouseFlags)cev.ButtonState
|
||||
Flags = mouseFlag
|
||||
};
|
||||
}
|
||||
|
||||
private MouseFlags ProcessButtonClickedEvent (Curses.MouseEvent cev, MouseFlags mf)
|
||||
{
|
||||
LastMouseButtonPressed = cev.ButtonState;
|
||||
mf = GetButtonState (cev, true);
|
||||
mouseHandler (ProcessButtonState (cev, mf));
|
||||
if (LastMouseButtonPressed != null && LastMouseButtonPressed == cev.ButtonState) {
|
||||
mf = GetButtonState (cev, false);
|
||||
mouseHandler (ProcessButtonState (cev, mf));
|
||||
if (LastMouseButtonPressed != null && LastMouseButtonPressed == cev.ButtonState) {
|
||||
mf = (MouseFlags)cev.ButtonState;
|
||||
}
|
||||
}
|
||||
LastMouseButtonPressed = null;
|
||||
return mf;
|
||||
}
|
||||
|
||||
private MouseFlags ProcessButtonReleasedEvent (Curses.MouseEvent cev, MouseFlags mf)
|
||||
{
|
||||
mf = (MouseFlags)cev.ButtonState;
|
||||
mouseHandler (ProcessButtonState (cev, mf));
|
||||
if (!cancelButtonClicked && LastMouseButtonPressed == null)
|
||||
mf = GetButtonState (cev);
|
||||
else
|
||||
cancelButtonClicked = false;
|
||||
return mf;
|
||||
}
|
||||
|
||||
MouseFlags GetButtonState (Curses.MouseEvent cev, bool pressed = false)
|
||||
{
|
||||
MouseFlags mf = default;
|
||||
switch (cev.ButtonState) {
|
||||
case Curses.Event.Button1Clicked:
|
||||
if (pressed)
|
||||
mf = MouseFlags.Button1Pressed;
|
||||
else
|
||||
mf = MouseFlags.Button1Released;
|
||||
break;
|
||||
|
||||
case Curses.Event.Button2Clicked:
|
||||
if (pressed)
|
||||
mf = MouseFlags.Button2Pressed;
|
||||
else
|
||||
mf = MouseFlags.Button2Released;
|
||||
break;
|
||||
|
||||
case Curses.Event.Button3Clicked:
|
||||
if (pressed)
|
||||
mf = MouseFlags.Button3Pressed;
|
||||
else
|
||||
mf = MouseFlags.Button3Released;
|
||||
break;
|
||||
|
||||
case Curses.Event.Button1Released:
|
||||
mf = MouseFlags.Button1Clicked;
|
||||
break;
|
||||
|
||||
case Curses.Event.Button2Released:
|
||||
mf = MouseFlags.Button2Clicked;
|
||||
break;
|
||||
|
||||
case Curses.Event.Button3Released:
|
||||
mf = MouseFlags.Button3Clicked;
|
||||
break;
|
||||
|
||||
|
||||
}
|
||||
return mf;
|
||||
}
|
||||
|
||||
MouseEvent ProcessButtonState (Curses.MouseEvent cev, MouseFlags mf)
|
||||
{
|
||||
return new MouseEvent () {
|
||||
X = cev.X,
|
||||
Y = cev.Y,
|
||||
Flags = (MouseFlags)cev.ButtonState
|
||||
Flags = mf
|
||||
};
|
||||
}
|
||||
|
||||
@@ -245,12 +419,17 @@ namespace Terminal.Gui {
|
||||
keyHandler (new KeyEvent ((Key)wch));
|
||||
}
|
||||
|
||||
Action<MouseEvent> mouseHandler;
|
||||
MainLoop mainLoop;
|
||||
|
||||
public override void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> keyHandler, Action<KeyEvent> keyDownHandler, Action<KeyEvent> keyUpHandler, Action<MouseEvent> mouseHandler)
|
||||
{
|
||||
// Note: Curses doesn't support keydown/up events and thus any passed keyDown/UpHandlers will never be called
|
||||
Curses.timeout (-1);
|
||||
Curses.timeout (0);
|
||||
this.mouseHandler = mouseHandler;
|
||||
this.mainLoop = mainLoop;
|
||||
|
||||
(mainLoop.Driver as Mono.Terminal.UnixMainLoop).AddWatch (0, Mono.Terminal.UnixMainLoop.Condition.PollIn, x => {
|
||||
(mainLoop.Driver as Mono.Terminal.UnixMainLoop).AddWatch (0, Mono.Terminal.UnixMainLoop.Condition.PollIn, x => {
|
||||
ProcessInput (keyHandler, mouseHandler);
|
||||
return true;
|
||||
});
|
||||
@@ -418,21 +597,21 @@ namespace Terminal.Gui {
|
||||
Console.Out.Flush ();
|
||||
}
|
||||
|
||||
int lastMouseInterval;
|
||||
bool mouseGrabbed;
|
||||
//int lastMouseInterval;
|
||||
//bool mouseGrabbed;
|
||||
|
||||
public override void UncookMouse ()
|
||||
{
|
||||
if (mouseGrabbed)
|
||||
return;
|
||||
lastMouseInterval = Curses.mouseinterval (0);
|
||||
mouseGrabbed = true;
|
||||
//if (mouseGrabbed)
|
||||
// return;
|
||||
//lastMouseInterval = Curses.mouseinterval (0);
|
||||
//mouseGrabbed = true;
|
||||
}
|
||||
|
||||
public override void CookMouse ()
|
||||
{
|
||||
mouseGrabbed = false;
|
||||
Curses.mouseinterval (lastMouseInterval);
|
||||
//mouseGrabbed = false;
|
||||
//Curses.mouseinterval (lastMouseInterval);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
* This file is autogenerated by the attrib.c program, do not edit
|
||||
*/
|
||||
|
||||
#define XTERM1006
|
||||
|
||||
using System;
|
||||
|
||||
namespace Unix.Terminal {
|
||||
@@ -76,6 +78,15 @@ namespace Unix.Terminal {
|
||||
ReportMousePosition = unchecked((int)0x8000000),
|
||||
AllEvents = unchecked((int)0x7ffffff),
|
||||
}
|
||||
#if XTERM1006
|
||||
public const int LeftRightUpNPagePPage= unchecked((int)0x8);
|
||||
public const int DownEnd = unchecked((int)0x6);
|
||||
public const int Home = unchecked((int)0x7);
|
||||
#else
|
||||
public const int LeftRightUpNPagePPage= unchecked((int)0x0);
|
||||
public const int DownEnd = unchecked((int)0x0);
|
||||
public const int Home = unchecked((int)0x0);
|
||||
#endif
|
||||
public const int ERR = unchecked((int)0xffffffff);
|
||||
public const int KeyBackspace = unchecked((int)0x107);
|
||||
public const int KeyUp = unchecked((int)0x103);
|
||||
@@ -109,30 +120,30 @@ namespace Unix.Terminal {
|
||||
public const int ShiftKeyPPage = unchecked((int)0x18e);
|
||||
public const int ShiftKeyHome = unchecked((int)0x187);
|
||||
public const int ShiftKeyEnd = unchecked((int)0x182);
|
||||
public const int AltKeyUp = unchecked((int)0x234);
|
||||
public const int AltKeyDown = unchecked((int)0x20b);
|
||||
public const int AltKeyLeft = unchecked((int)0x21f);
|
||||
public const int AltKeyRight = unchecked((int)0x22e);
|
||||
public const int AltKeyNPage = unchecked((int)0x224);
|
||||
public const int AltKeyPPage = unchecked((int)0x229);
|
||||
public const int AltKeyHome = unchecked((int)0x215);
|
||||
public const int AltKeyEnd = unchecked((int)0x210);
|
||||
public const int CtrlKeyUp = unchecked((int)0x236);
|
||||
public const int CtrlKeyDown = unchecked((int)0x20d);
|
||||
public const int CtrlKeyLeft = unchecked((int)0x221);
|
||||
public const int CtrlKeyRight = unchecked((int)0x230);
|
||||
public const int CtrlKeyNPage = unchecked((int)0x226);
|
||||
public const int CtrlKeyPPage = unchecked((int)0x22b);
|
||||
public const int CtrlKeyHome = unchecked((int)0x217);
|
||||
public const int CtrlKeyEnd = unchecked((int)0x212);
|
||||
public const int ShiftCtrlKeyUp = unchecked((int)0x237);
|
||||
public const int ShiftCtrlKeyDown = unchecked((int)0x20e);
|
||||
public const int ShiftCtrlKeyLeft = unchecked((int)0x222);
|
||||
public const int ShiftCtrlKeyRight = unchecked((int)0x231);
|
||||
public const int ShiftCtrlKeyNPage = unchecked((int)0x227);
|
||||
public const int ShiftCtrlKeyPPage = unchecked((int)0x22c);
|
||||
public const int ShiftCtrlKeyHome = unchecked((int)0x218);
|
||||
public const int ShiftCtrlKeyEnd = unchecked((int)0x213);
|
||||
public const int AltKeyUp = unchecked((int)0x234 + LeftRightUpNPagePPage);
|
||||
public const int AltKeyDown = unchecked((int)0x20b + DownEnd);
|
||||
public const int AltKeyLeft = unchecked((int)0x21f + LeftRightUpNPagePPage);
|
||||
public const int AltKeyRight = unchecked((int)0x22e + LeftRightUpNPagePPage);
|
||||
public const int AltKeyNPage = unchecked((int)0x224 + LeftRightUpNPagePPage);
|
||||
public const int AltKeyPPage = unchecked((int)0x229 + LeftRightUpNPagePPage);
|
||||
public const int AltKeyHome = unchecked((int)0x215 + Home);
|
||||
public const int AltKeyEnd = unchecked((int)0x210 + DownEnd);
|
||||
public const int CtrlKeyUp = unchecked((int)0x236 + LeftRightUpNPagePPage);
|
||||
public const int CtrlKeyDown = unchecked((int)0x20d + DownEnd);
|
||||
public const int CtrlKeyLeft = unchecked((int)0x221 + LeftRightUpNPagePPage);
|
||||
public const int CtrlKeyRight = unchecked((int)0x230 + LeftRightUpNPagePPage);
|
||||
public const int CtrlKeyNPage = unchecked((int)0x226 + LeftRightUpNPagePPage);
|
||||
public const int CtrlKeyPPage = unchecked((int)0x22b + LeftRightUpNPagePPage);
|
||||
public const int CtrlKeyHome = unchecked((int)0x217 + Home);
|
||||
public const int CtrlKeyEnd = unchecked((int)0x212 + DownEnd);
|
||||
public const int ShiftCtrlKeyUp = unchecked((int)0x237 + LeftRightUpNPagePPage);
|
||||
public const int ShiftCtrlKeyDown = unchecked((int)0x20e + DownEnd);
|
||||
public const int ShiftCtrlKeyLeft = unchecked((int)0x222 + LeftRightUpNPagePPage);
|
||||
public const int ShiftCtrlKeyRight = unchecked((int)0x231 + LeftRightUpNPagePPage);
|
||||
public const int ShiftCtrlKeyNPage = unchecked((int)0x227 + LeftRightUpNPagePPage);
|
||||
public const int ShiftCtrlKeyPPage = unchecked((int)0x22c + LeftRightUpNPagePPage);
|
||||
public const int ShiftCtrlKeyHome = unchecked((int)0x218 + Home);
|
||||
public const int ShiftCtrlKeyEnd = unchecked((int)0x213 + DownEnd);
|
||||
|
||||
public const int LC_ALL = 6;
|
||||
static public int ColorPair(int n){
|
||||
|
||||
Reference in New Issue
Block a user