namespace Terminal.Gui;
public partial class View
{
///
/// Gets or sets whether the will be highlighted visually while the mouse button is
/// pressed.
///
public bool HighlightOnPress { get; set; }
/// Gets or sets whether the wants continuous button pressed events.
public virtual bool WantContinuousButtonPressed { get; set; }
/// Gets or sets whether the wants mouse position reports.
/// if mouse position reports are wanted; otherwise, .
public virtual bool WantMousePositionReports { get; set; }
///
/// Called when the mouse enters the View's . The view will now receive mouse events until the
/// mouse leaves
/// the view. At which time, will be called.
///
///
/// The coordinates are relative to .
///
///
/// , if the event was handled, otherwise.
protected internal virtual bool OnMouseEnter (MouseEvent mouseEvent)
{
if (!Enabled)
{
return true;
}
if (!CanBeVisible (this))
{
return false;
}
var args = new MouseEventEventArgs (mouseEvent);
MouseEnter?.Invoke (this, args);
return args.Handled;
}
/// Event fired when the mouse moves into the View's .
public event EventHandler MouseEnter;
///
/// Called when the mouse has moved out of the View's . The view will no longer receive mouse
/// events (until the
/// mouse moves within the view again and is called).
///
///
/// The coordinates are relative to .
///
///
/// , if the event was handled, otherwise.
protected internal virtual bool OnMouseLeave (MouseEvent mouseEvent)
{
if (!Enabled)
{
return true;
}
if (!CanBeVisible (this))
{
return false;
}
var args = new MouseEventEventArgs (mouseEvent);
MouseLeave?.Invoke (this, args);
return args.Handled;
}
/// Event fired when the mouse leaves the View's .
public event EventHandler MouseLeave;
[CanBeNull]
private ColorScheme _savedColorScheme;
/// Called when a mouse event occurs within the view's .
///
///
/// The coordinates are relative to .
///
///
///
/// , if the event was handled, otherwise.
protected internal virtual bool OnMouseEvent (MouseEvent mouseEvent)
{
if (!Enabled)
{
// A disabled view should not eat mouse events
return false;
}
if (!CanBeVisible (this))
{
return false;
}
var args = new MouseEventEventArgs (mouseEvent);
// Default behavior is to invoke Accept (via HotKey) on clicked.
if (!WantContinuousButtonPressed
&& Application.MouseGrabView != this
&& (mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)
|| mouseEvent.Flags.HasFlag (MouseFlags.Button2Clicked)
|| mouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked)
|| mouseEvent.Flags.HasFlag (MouseFlags.Button4Clicked)))
{
return OnMouseClick (args);
}
if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed)
|| mouseEvent.Flags.HasFlag (MouseFlags.Button2Pressed)
|| mouseEvent.Flags.HasFlag (MouseFlags.Button3Pressed)
|| mouseEvent.Flags.HasFlag (MouseFlags.Button4Pressed))
{
// If WantContinuousButtonPressed is true, and this is not the first pressed event,
// invoke Accept (via HotKey)
if (WantContinuousButtonPressed && Application.MouseGrabView == this)
{
return OnMouseClick (args);
}
// The first time we get pressed event, grab the mouse and invert the colors
if (Application.MouseGrabView != this)
{
Application.GrabMouse (this);
_savedColorScheme = ColorScheme;
if (HighlightOnPress && ColorScheme is { })
{
if (CanFocus)
{
// TODO: Make the inverted color configurable
var cs = new ColorScheme (ColorScheme)
{
Focus = new (ColorScheme.Normal.Foreground, ColorScheme.Focus.Background)
};
ColorScheme = cs;
}
else
{
var cs = new ColorScheme (ColorScheme)
{
Normal = new (ColorScheme.Focus.Background, ColorScheme.Normal.Foreground)
};
ColorScheme = cs;
}
}
if (CanFocus)
{
// Set the focus, but don't invoke Accept
SetFocus ();
}
args.Handled = true;
}
}
if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Released)
|| mouseEvent.Flags.HasFlag (MouseFlags.Button2Released)
|| mouseEvent.Flags.HasFlag (MouseFlags.Button3Released)
|| mouseEvent.Flags.HasFlag (MouseFlags.Button4Released))
{
// When the mouse is released, if WantContinuousButtonPressed is set, invoke Accept one last time.
if (WantContinuousButtonPressed)
{
OnMouseClick (args);
}
if (Application.MouseGrabView == this)
{
Application.UngrabMouse ();
if (HighlightOnPress && _savedColorScheme is { })
{
ColorScheme = _savedColorScheme;
_savedColorScheme = null;
}
args.Handled = true;
}
}
if (args.Handled != true)
{
MouseEvent?.Invoke (this, args);
}
return args.Handled;
}
/// Event fired when a mouse event occurs.
///
///
/// The coordinates are relative to .
///
///
public event EventHandler MouseEvent;
/// Invokes the MouseClick event.
///
///
/// Called when the mouse is either clicked or double-clicked. Check
/// to see which button was clicked.
///
///
protected bool OnMouseClick (MouseEventEventArgs args)
{
if (!Enabled)
{
// QUESTION: Is this right? Should a disabled view eat mouse clicks?
args.Handled = true;
return true;
}
MouseClick?.Invoke (this, args);
if (args.Handled)
{
return true;
}
if (!HasFocus && CanFocus)
{
args.Handled = true;
SetFocus ();
}
return args.Handled;
}
/// Event fired when a mouse click occurs.
///
///
/// Fired when the mouse is either clicked or double-clicked. Check
/// to see which button was clicked.
///
///
/// The coordinates are relative to .
///
///
public event EventHandler MouseClick;
}