Added more mouse events flags, drag features, toplevel color and more...

This commit is contained in:
BDisp
2020-03-29 21:50:54 +01:00
parent 2ca56a1180
commit 9c92b7123c
4 changed files with 267 additions and 152 deletions

View File

@@ -228,7 +228,15 @@ namespace Terminal.Gui {
View container = null;
View focused = null;
Direction focusDirection;
/// <summary>
/// Event fired when the view get focus.
/// </summary>
public event EventHandler OnEnter;
/// <summary>
/// Event fired when the view lost focus.
/// </summary>
public event EventHandler OnLeave;
internal Direction FocusDirection {
@@ -441,7 +449,7 @@ namespace Terminal.Gui {
layoutNeeded = true;
if (SuperView == null)
return;
SuperView.layoutNeeded = true;
SuperView.SetNeedsLayout ();
}
/// <summary>
@@ -657,58 +665,13 @@ namespace Terminal.Gui {
{
var h = r.Height;
var w = r.Width;
for (int line = 0; line < h; line++) {
Move (0, line);
for (int line = r.Y; line < r.Y + h; line++) {
Driver.Move (r.X, line);
for (int col = 0; col < w; col++)
Driver.AddRune (' ');
}
}
/// <summary>
/// Clears the specified rectangular region with the container color
/// </summary>
public void ClearContainer (Rect r)
{
if (this.container != null) {
var current = ColorScheme;
switch (this.container.ColorScheme.Caller) {
case "Base":
Driver.SetAttribute (Colors.Base.Normal);
break;
case "Dialog":
Driver.SetAttribute (Colors.Dialog.Normal);
break;
case "Error":
Driver.SetAttribute (Colors.Error.Normal);
break;
case "Menu":
Driver.SetAttribute (Colors.Menu.Normal);
break;
}
var h = r.Height;
var w = r.Width;
for (int line = r.Y; line < r.Y + h; line++) {
Driver.Move (r.X, line);
for (int col = 0; col < w; col++)
Driver.AddRune (' ');
}
ColorScheme = current;
}
}
public void GrabToView (MouseEvent mouseEvent, int startX, Point? dragPos, Rect frame, out int nx, out int ny)
{
var dx = mouseEvent.X - dragPos.Value.X - startX + frame.Left;
var dy = mouseEvent.Y - dragPos.Value.Y;
nx = dx;
ny = frame.Y + dy;
if (nx < 0)
nx = 0;
if (ny < 1)
ny = frame.Y;
}
/// <summary>
/// Converts the (col,row) position from the view into a screen (col,row). The values are clamped to (0..ScreenDim-1)
/// </summary>
@@ -971,7 +934,9 @@ namespace Terminal.Gui {
if (!view.NeedDisplay.IsEmpty || view.childNeedsDisplay) {
if (view.Frame.IntersectsWith (clipRect) && view.Frame.IntersectsWith (region)) {
// TODO: optimize this by computing the intersection of region and view.Bounds
// FIXED: optimize this by computing the intersection of region and view.Bounds
if (view.layoutNeeded)
view.LayoutSubviews ();
view.Redraw (view.Bounds);
}
view.NeedDisplay = Rect.Empty;
@@ -1362,7 +1327,7 @@ namespace Terminal.Gui {
/// <param name="frame">Frame.</param>
public Toplevel (Rect frame) : base (frame)
{
ColorScheme = Colors.Base;
Initialize ();
}
/// <summary>
@@ -1370,11 +1335,16 @@ namespace Terminal.Gui {
/// </summary>
public Toplevel () : base ()
{
ColorScheme = Colors.Base;
Initialize ();
Width = Dim.Fill ();
Height = Dim.Fill ();
}
void Initialize ()
{
ColorScheme = Colors.Base;
}
/// <summary>
/// Convenience factory method that creates a new toplevel with the current terminal dimensions.
/// </summary>
@@ -1395,6 +1365,16 @@ namespace Terminal.Gui {
/// </summary>
public bool Modal { get; set; }
/// <summary>
/// Check id current toplevel has menu bar
/// </summary>
public bool HasMenuBar { get; set; }
/// <summary>
/// Check id current toplevel has status bar
/// </summary>
public bool HasStatusBar { get; set; }
public override bool ProcessKey (KeyEvent keyEvent)
{
if (base.ProcessKey (keyEvent))
@@ -1444,6 +1424,100 @@ namespace Terminal.Gui {
return false;
}
public override void Add (View view)
{
if (this == Application.Top) {
if (view is MenuBar)
HasMenuBar = true;
if (view is StatusBar)
HasStatusBar = true;
}
base.Add (view);
}
public override void Remove (View view)
{
if (this == Application.Top) {
if (view is MenuBar)
HasMenuBar = true;
if (view is StatusBar)
HasStatusBar = true;
}
base.Remove (view);
}
public override void RemoveAll ()
{
if (this == Application.Top) {
HasMenuBar = false;
HasStatusBar = false;
}
base.RemoveAll ();
}
internal void EnsureVisibleBounds (Toplevel top, int x, int y, out int nx, out int ny)
{
nx = Math.Max (x, 0);
nx = nx + top.Frame.Width > Driver.Cols ? Math.Max(Driver.Cols - top.Frame.Width, 0) : nx;
bool m, s;
if (SuperView == null)
m = Application.Top.HasMenuBar;
else
m = ((Toplevel)SuperView).HasMenuBar;
int l = m ? 1 : 0;
ny = Math.Max (y, l);
if (SuperView == null)
s = Application.Top.HasStatusBar;
else
s = ((Toplevel)SuperView).HasStatusBar;
l = s ? Driver.Rows - 1 : Driver.Rows;
ny = Math.Min (ny, l);
ny = ny + top.Frame.Height > l ? Math.Max(l - top.Frame.Height, m ? 1 : 0) : ny;
}
//Dictionary<View, Rect> subViews;
internal void PositionToplevels ()
{
if (this != Application.Top) {
EnsureVisibleBounds (this, Frame.X, Frame.Y, out int nx, out int ny);
if (nx != Frame.X || ny != Frame.Y) {
X = nx;
Y = ny;
}
} else {
foreach (var top in Subviews) {
if (top is Toplevel) {
EnsureVisibleBounds ((Toplevel)top, top.Frame.X, top.Frame.Y, out int nx, out int ny);
if (nx != top.Frame.X || ny != top.Frame.Y) {
top.X = nx;
top.Y = ny;
}
}
}
}
}
public override void Redraw (Rect region)
{
if (this == Application.Top) {
if (!NeedDisplay.IsEmpty) {
Driver.SetAttribute (Colors.TopLevel.Normal);
Clear (region);
Driver.SetAttribute (Colors.Base.Normal);
}
foreach (var view in Subviews) {
if (view.Frame.IntersectsWith (region)) {
//view.SetNeedsLayout ();
view.SetNeedsDisplay (view.Bounds);
}
}
ClearNeedsDisplay ();
}
base.Redraw (base.Bounds);
}
/// <summary>
/// This method is invoked by Application.Begin as part of the Application.Run after
/// the views have been laid out, and before the views are drawn for the first time.
@@ -1628,73 +1702,58 @@ namespace Terminal.Gui {
// FIXED:It does not look like the event is raised on clicked-drag
// need to figure that out.
//
Point? dragPosition;
int startX;
public override bool MouseEvent(MouseEvent mouseEvent)
internal static Point? dragPosition;
Point start;
public override bool MouseEvent (MouseEvent mouseEvent)
{
// FIXED:The code is currently disabled, because the
// Driver.UncookMouse does not seem to have an effect if there is
// a pending mouse event activated.
if ((mouseEvent.Flags == (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition) ||
int nx, ny;
if ((mouseEvent.Flags == (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition) ||
mouseEvent.Flags == MouseFlags.Button4Pressed)) {
if (dragPosition.HasValue) {
int nx, ny;
GrabToView (mouseEvent, startX, dragPosition, Frame, out nx, out ny);
dragPosition = new Point (nx, ny);
if (SuperView == null) {
Application.Top.SetNeedsDisplay (Frame);
Application.Top.Redraw (Frame);
} else {
SuperView.SetNeedsDisplay (Frame);
}
EnsureVisibleBounds (this, mouseEvent.X + mouseEvent.OfX - start.X,
mouseEvent.Y + mouseEvent.OfY, out nx, out ny);
//System.Diagnostics.Debug.WriteLine ($"dragging: {mouseEvent}");
//System.Diagnostics.Debug.WriteLine ($"dx: {dx}, dy: {dy}");
//System.Diagnostics.Debug.WriteLine ($"nx: {nx}, ny: {ny}");
dragPosition = new Point (nx, ny);
Frame = new Rect (nx, ny, Frame.Width, Frame.Height);
X = nx;
Y = ny;
//Demo.ml2.Text = $"{dx},{dy}";
// TODO: optimize, only SetNeedsDisplay on the before/after regions.
if (SuperView == null)
Application.Refresh ();
else
SuperView.SetNeedsDisplay ();
Frame = new Rect (nx, ny, Frame.Width, Frame.Height);
Rect top = new Rect () {
X = 0,
Y = 0,
Width = Driver.Cols,
Height = ny
};
Rect left = new Rect () {
X = 0,
Y = ny,
Width = nx,
Height = Driver.Rows
};
ClearContainer (top);
ClearContainer (left);
// FIXED: optimize, only SetNeedsDisplay on the before/after regions.
SetNeedsDisplay ();
return true;
} else {
// Only start grabbing if the user clicks on the title bar.
if (mouseEvent.Y == 0) {
startX = mouseEvent.X;
dragPosition = new Point (mouseEvent.X, mouseEvent.Y);
start = new Point (mouseEvent.X, mouseEvent.Y);
dragPosition = new Point ();
nx = mouseEvent.X - mouseEvent.OfX;
ny = mouseEvent.Y - mouseEvent.OfY;
dragPosition = new Point (nx, ny);
Application.GrabMouse (this);
}
//System.Diagnostics.Debug.WriteLine ($"Starting at {dragPosition}");
//Demo.ml2.Text = $"Starting at {dragPosition}";
return true;
}
}
if (mouseEvent.Flags == MouseFlags.Button1Released) {
if (mouseEvent.Flags == MouseFlags.Button1Released && dragPosition.HasValue) {
Application.UngrabMouse ();
Driver.UncookMouse ();
dragPosition = null;
//Driver.StopReportingMouseMoves ();
}
//System.Diagnostics.Debug.WriteLine ($"mouseEvent {mouseEvent.ToString ()}");
//Demo.ml.Text = me.ToString ();
return false;
}
@@ -1784,9 +1843,9 @@ namespace Terminal.Gui {
{
mainLoop.AddIdle (() => {
d (state);
mainLoop.Driver.Wakeup ();
return false;
});
mainLoop.Driver.Wakeup ();
}
public override void Send (SendOrPostCallback d, object state)
@@ -1902,7 +1961,7 @@ namespace Terminal.Gui {
}
}
internal static View FindDeepestView (View start, int x, int y, out int resx, out int resy)
static View FindDeepestView (View start, int x, int y, out int resx, out int resy)
{
var startFrame = start.Frame;
@@ -1933,7 +1992,7 @@ namespace Terminal.Gui {
return start;
}
static View mouseGrabView;
internal static View mouseGrabView;
/// <summary>
/// Grabs the mouse, forcing all mouse events to be routed to the specified view until UngrabMouse is called.
@@ -1964,20 +2023,22 @@ namespace Terminal.Gui {
static void ProcessMouseEvent (MouseEvent me)
{
var view = FindDeepestView (Current, me.X, me.Y, out int rx, out int ry);
RootMouseEvent?.Invoke (me);
if (mouseGrabView != null) {
var newxy = mouseGrabView.ScreenToView (me.X, me.Y);
var nme = new MouseEvent () {
X = newxy.X,
Y = newxy.Y,
Flags = me.Flags
Flags = me.Flags,
OfX = me.X - newxy.X,
OfY = me.Y - newxy.Y,
View = view
};
mouseGrabView.MouseEvent (me);
mouseGrabView.MouseEvent (nme);
return;
}
int rx, ry;
var view = FindDeepestView (Current, me.X, me.Y, out rx, out ry);
if (view != null) {
if (!view.WantMousePositionReports && me.Flags == MouseFlags.ReportMousePosition)
return;
@@ -1985,7 +2046,10 @@ namespace Terminal.Gui {
var nme = new MouseEvent () {
X = rx,
Y = ry,
Flags = me.Flags
Flags = me.Flags,
OfX = rx,
OfY = ry,
View = view
};
// Should we bubbled up the event, if it is not handled?
view.MouseEvent (nme);
@@ -2035,7 +2099,7 @@ namespace Terminal.Gui {
}
/// <summary>
/// Building block API: completes the exection of a Toplevel that was started with Begin.
/// Building block API: completes the execution of a Toplevel that was started with Begin.
/// </summary>
/// <param name="runState">The runstate returned by the <see cref="Begin(Toplevel)"/> method.</param>
static public void End (RunState runState)
@@ -2046,6 +2110,9 @@ namespace Terminal.Gui {
runState.Dispose ();
}
/// <summary>
/// Finalize the driver.
/// </summary>
public static void Shutdown ()
{
Driver.End ();
@@ -2122,40 +2189,11 @@ namespace Terminal.Gui {
DrawBounds (state.Toplevel);
state.Toplevel.PositionCursor ();
Driver.Refresh ();
} else if (CheckLayoutNeeded (state.Toplevel)) {
TerminalResized ();
layoutNeeded = false;
toplevel = null;
} else
Driver.UpdateCursor ();
}
}
static bool layoutNeeded;
static View toplevel;
static bool CheckLayoutNeeded (View view)
{
if (view is Toplevel && ((Toplevel)view).Modal)
return false;
if (view is Toplevel)
toplevel = view;
return CheckTopLevelLayoutNeeded (view);
}
private static bool CheckTopLevelLayoutNeeded (View view)
{
if (!(view is Toplevel) && view == toplevel && view.layoutNeeded)
return layoutNeeded = view.layoutNeeded;
for (int i = 0; view.Subviews.Count > i; i++) {
CheckLayoutNeeded (view.Subviews [i]);
if (layoutNeeded)
return layoutNeeded;
}
return layoutNeeded;
}
internal static bool DebugDrawBounds;
// Need to look into why this does not work properly.
@@ -2229,6 +2267,7 @@ namespace Terminal.Gui {
var full = new Rect (0, 0, Driver.Cols, Driver.Rows);
Driver.Clip = full;
foreach (var t in toplevels) {
t.PositionToplevels ();
t.RelativeLayout (full);
t.LayoutSubviews ();
}

View File

@@ -110,6 +110,11 @@ namespace Terminal.Gui {
this.background = background;
}
/// <summary>
/// Initializes a new instance of the <see cref="T:Terminal.Gui.Attribute"/> struct.
/// </summary>
/// <param name="foreground">Foreground</param>
/// <param name="background">Background</param>
public Attribute (Color foreground = new Color (), Color background = new Color ())
{
this.value = value = ((int)foreground | (int)background << 4);
@@ -156,6 +161,7 @@ namespace Terminal.Gui {
private Attribute _hotNormal;
private Attribute _hotFocus;
private Attribute _disabled;
internal string caller = "";
/// <summary>
/// The default color for text, when the view is not focused.
@@ -182,8 +188,6 @@ namespace Terminal.Gui {
/// </summary>
public Attribute Disabled { get { return _disabled; } set { _disabled = SetAttribute (value); } }
public string Caller = "";
private bool preparingScheme = false;
private Attribute SetAttribute (Attribute attribute, [CallerMemberName]string callerMemberName = null)
@@ -195,7 +199,26 @@ namespace Terminal.Gui {
return attribute;
preparingScheme = true;
switch (Caller) {
switch (caller) {
case "TopLevel":
switch (callerMemberName) {
case "Normal":
HotNormal = Application.Driver.MakeAttribute (HotNormal.foreground, attribute.background);
break;
case "Focus":
HotFocus = Application.Driver.MakeAttribute (HotFocus.foreground, attribute.background);
break;
case "HotNormal":
HotFocus = Application.Driver.MakeAttribute (attribute.foreground, HotFocus.background);
break;
case "HotFocus":
HotNormal = Application.Driver.MakeAttribute (attribute.foreground, HotNormal.background);
if (Focus.foreground != attribute.background)
Focus = Application.Driver.MakeAttribute (Focus.foreground, attribute.background);
break;
}
break;
case "Base":
switch (callerMemberName) {
case "Normal":
@@ -298,11 +321,17 @@ namespace Terminal.Gui {
/// The default ColorSchemes for the application.
/// </summary>
public static class Colors {
private static ColorScheme _toplevel;
private static ColorScheme _base;
private static ColorScheme _dialog;
private static ColorScheme _menu;
private static ColorScheme _error;
/// <summary>
/// The application toplevel color scheme, for the default toplevel views.
/// </summary>
public static ColorScheme TopLevel { get { return _toplevel; } set { _toplevel = SetColorScheme (value); } }
/// <summary>
/// The base color scheme, for the default toplevel views.
/// </summary>
@@ -325,7 +354,7 @@ namespace Terminal.Gui {
private static ColorScheme SetColorScheme (ColorScheme colorScheme, [CallerMemberName]string callerMemberName = null)
{
colorScheme.Caller = callerMemberName;
colorScheme.caller = callerMemberName;
return colorScheme;
}
}
@@ -400,6 +429,9 @@ namespace Terminal.Gui {
/// ConsoleDriver is an abstract class that defines the requirements for a console driver. One implementation if the CursesDriver, and another one uses the .NET Console one.
/// </summary>
public abstract class ConsoleDriver {
/// <summary>
/// The handler fired when the terminal is resized.
/// </summary>
protected Action TerminalResized;
/// <summary>
@@ -431,6 +463,12 @@ namespace Terminal.Gui {
/// </summary>
/// <param name="str">String.</param>
public abstract void AddStr (ustring str);
/// <summary>
/// Prepare the driver and set the key and mouse events handlers.
/// </summary>
/// <param name="mainLoop"></param>
/// <param name="keyHandler"></param>
/// <param name="mouseHandler"></param>
public abstract void PrepareToRun (MainLoop mainLoop, Action<KeyEvent> keyHandler, Action<MouseEvent> mouseHandler);
/// <summary>
@@ -459,7 +497,11 @@ namespace Terminal.Gui {
/// <param name="c">C.</param>
public abstract void SetAttribute (Attribute c);
// Set Colors from limit sets of colors
/// <summary>
/// Set Colors from limit sets of colors.
/// </summary>
/// <param name="foreground">Foreground.</param>
/// <param name="background">Background.</param>
public abstract void SetColors (ConsoleColor foreground, ConsoleColor background);
// Advanced uses - set colors to any pre-set pairs, you would need to init_color
@@ -472,6 +514,10 @@ namespace Terminal.Gui {
/// <param name="backgroundColorId">Background color identifier.</param>
public abstract void SetColors (short foregroundColorId, short backgroundColorId);
/// <summary>
/// Set the handler when the terminal is resized.
/// </summary>
/// <param name="terminalResized"></param>
public void SetTerminalResized(Action terminalResized)
{
TerminalResized = terminalResized;
@@ -555,7 +601,14 @@ namespace Terminal.Gui {
set => this.clip = value;
}
/// <summary>
/// Start of mouse moves.
/// </summary>
public abstract void StartReportingMouseMoves ();
/// <summary>
/// Stop reporting mouses moves.
/// </summary>
public abstract void StopReportingMouseMoves ();
/// <summary>
@@ -628,6 +681,12 @@ namespace Terminal.Gui {
/// </summary>
public Rune BottomTee;
/// <summary>
/// Make the attribute for the foreground and background colors.
/// </summary>
/// <param name="fore">Foreground.</param>
/// <param name="back">Background.</param>
/// <returns></returns>
public abstract Attribute MakeAttribute (Color fore, Color back);
}
}

View File

@@ -437,10 +437,17 @@ namespace Terminal.Gui {
public WindowsDriver ()
{
Colors.TopLevel = new ColorScheme ();
Colors.TopLevel.Normal = MakeColor (ConsoleColor.Green, ConsoleColor.Black);
Colors.TopLevel.Focus = MakeColor (ConsoleColor.White, ConsoleColor.DarkCyan);
Colors.TopLevel.HotNormal = MakeColor (ConsoleColor.DarkYellow, ConsoleColor.Black);
Colors.TopLevel.HotFocus = MakeColor (ConsoleColor.DarkYellow, ConsoleColor.DarkCyan);
winConsole = new WindowsConsole ();
cols = Console.WindowWidth;
rows = Console.WindowHeight - 1;
rows = Console.WindowHeight;
WindowsConsole.SmallRect.MakeEmpty (ref damageRegion);
ResizeScreen ();
@@ -520,7 +527,6 @@ namespace Terminal.Gui {
} finally {
eventReady.Reset();
}
//Debug.WriteLine("Events ready");
if (!tokenSource.IsCancellationRequested)
return result != null;
@@ -574,16 +580,17 @@ namespace Terminal.Gui {
private WindowsConsole.ButtonState? LastMouseButtonPressed = null;
private bool IsButtonReleased = false;
private bool IsButtonDoubleClicked = false;
private object token;
private MouseEvent ToDriverMouse (WindowsConsole.MouseEventRecord mouseEvent)
{
MouseFlags mouseFlag = MouseFlags.AllEvents;
if (token != null)
Application.MainLoop.RemoveTimeout (token);
if (IsButtonDoubleClicked)
token = Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (300), timer);
if (IsButtonDoubleClicked) {
Task.Run (async () => {
await Task.Delay (300);
_ = new Action (() => IsButtonDoubleClicked = false);
});
}
// The ButtonState member of the MouseEvent structure has bit corresponding to each mouse button.
// This will tell when a mouse button is pressed. When the button is released this event will
@@ -595,7 +602,6 @@ namespace Terminal.Gui {
IsButtonReleased = false;
}
//Debug.WriteLine ($"MouseEventRecord: {mouseEvent}");
if ((mouseEvent.EventFlags == 0 && LastMouseButtonPressed == null && !IsButtonDoubleClicked) ||
(mouseEvent.EventFlags == WindowsConsole.EventFlags.MouseMoved &&
mouseEvent.ButtonState != 0 && !IsButtonDoubleClicked)) {
@@ -696,7 +702,6 @@ namespace Terminal.Gui {
mouseFlag = SetControlKeyStates (mouseEvent, mouseFlag);
Debug.WriteLine ($"MouseFlags: {mouseFlag}");
return new MouseEvent () {
X = mouseEvent.MousePosition.X,
Y = mouseEvent.MousePosition.Y,
@@ -719,12 +724,6 @@ namespace Terminal.Gui {
return mouseFlag;
}
bool timer (MainLoop caller)
{
IsButtonDoubleClicked = false;
return false;
}
public ConsoleKeyInfoEx ToConsoleKeyInfoEx (WindowsConsole.KeyEventRecord keyEvent)
{
var state = keyEvent.dwControlKeyState;
@@ -818,9 +817,12 @@ namespace Terminal.Gui {
return (Key)((uint)Key.ControlA + delta);
if (keyInfo.Modifiers == ConsoleModifiers.Alt)
return (Key)(((uint)Key.AltMask) | ((uint)'A' + delta));
// TODO: Only apply after pull requests at NStack are merged.
//if ((keyInfo.Modifiers & (ConsoleModifiers.Alt | ConsoleModifiers.Control)) != 0)
// return (Key)((uint)keyInfo.KeyChar);
if ((keyInfo.Modifiers & (ConsoleModifiers.Alt | ConsoleModifiers.Control)) != 0) {
if (keyInfo.KeyChar == 0)
return (Key)(((uint)Key.AltMask) + ((uint)Key.ControlA + delta));
else
return (Key)((uint)keyInfo.KeyChar);
}
return (Key)((uint)alphaBase + delta);
}
if (key >= ConsoleKey.D0 && key <= ConsoleKey.D9) {
@@ -900,7 +902,7 @@ namespace Terminal.Gui {
for (int row = 0; row < rows; row++)
for (int col = 0; col < cols; col++) {
int position = row * cols + col;
OutputBuffer [position].Attributes = (ushort)MakeColor (ConsoleColor.White, ConsoleColor.Blue);
OutputBuffer [position].Attributes = (ushort)Colors.TopLevel.Normal;
OutputBuffer [position].Char.UnicodeChar = ' ';
}
}

View File

@@ -448,6 +448,21 @@ namespace Terminal.Gui {
/// </summary>
public MouseFlags Flags;
/// <summary>
/// The offset X (column) location for the mouse event.
/// </summary>
public int OfX;
/// <summary>
/// The offset Y (column) location for the mouse event.
/// </summary>
public int OfY;
/// <summary>
/// The current view at the location for the mouse event.
/// </summary>
public View View;
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:Terminal.Gui.MouseEvent"/>.
/// </summary>