diff --git a/Terminal.Gui/Application/Application.Initialization.cs b/Terminal.Gui/Application/Application.Initialization.cs index 4fb11621d..02351612f 100644 --- a/Terminal.Gui/Application/Application.Initialization.cs +++ b/Terminal.Gui/Application/Application.Initialization.cs @@ -178,9 +178,9 @@ public static partial class Application // Initialization (Init/Shutdown) } private static void Driver_SizeChanged (object? sender, SizeChangedEventArgs e) { OnSizeChanging (e); } - private static void Driver_KeyDown (object? sender, Key e) { OnKeyDown (e); } - private static void Driver_KeyUp (object? sender, Key e) { OnKeyUp (e); } - private static void Driver_MouseEvent (object? sender, MouseEvent e) { OnMouseEvent (e); } + private static void Driver_KeyDown (object? sender, Key e) { RaiseKeyDownEvent (e); } + private static void Driver_KeyUp (object? sender, Key e) { RaiseKeyUpEvent (e); } + private static void Driver_MouseEvent (object? sender, MouseEventArgs e) { RaiseMouseEvent (e); } /// Gets of list of types that are available. /// diff --git a/Terminal.Gui/Application/Application.Keyboard.cs b/Terminal.Gui/Application/Application.Keyboard.cs index 01545dedd..c9fa96c63 100644 --- a/Terminal.Gui/Application/Application.Keyboard.cs +++ b/Terminal.Gui/Application/Application.Keyboard.cs @@ -3,20 +3,101 @@ namespace Terminal.Gui; public static partial class Application // Keyboard handling { - private static Key _nextTabGroupKey = Key.F6; // Resources/config.json overrrides - private static Key _nextTabKey = Key.Tab; // Resources/config.json overrrides - private static Key _prevTabGroupKey = Key.F6.WithShift; // Resources/config.json overrrides - private static Key _prevTabKey = Key.Tab.WithShift; // Resources/config.json overrrides - private static Key _quitKey = Key.Esc; // Resources/config.json overrrides - private static Key _arrangeKey = Key.F5.WithCtrl; // Resources/config.json overrrides + /// + /// Called when the user presses a key (by the ). Raises the cancelable + /// event, then calls on all top level views, and finally + /// if the key was not handled, invokes any Application-scoped . + /// + /// Can be used to simulate key press events. + /// + /// if the key was handled. + public static bool RaiseKeyDownEvent (Key key) + { + KeyDown?.Invoke (null, key); - static Application () { AddApplicationKeyBindings (); } + if (key.Handled) + { + return true; + } - /// Gets the key bindings for this view. - public static KeyBindings KeyBindings { get; internal set; } = new (); + if (Top is null) + { + foreach (Toplevel topLevel in TopLevels.ToList ()) + { + if (topLevel.NewKeyDownEvent (key)) + { + return true; + } + + if (topLevel.Modal) + { + break; + } + } + } + else + { + if (Top.NewKeyDownEvent (key)) + { + return true; + } + } + + // Invoke any Application-scoped KeyBindings. + // The first view that handles the key will stop the loop. + foreach (KeyValuePair binding in KeyBindings.Bindings.Where (b => b.Key == key.KeyCode)) + { + if (binding.Value.BoundView is { }) + { + bool? handled = binding.Value.BoundView?.InvokeCommands (binding.Value.Commands, binding.Key, binding.Value); + + if (handled != null && (bool)handled) + { + return true; + } + } + else + { + if (!KeyBindings.TryGet (key, KeyBindingScope.Application, out KeyBinding appBinding)) + { + continue; + } + + bool? toReturn = null; + + foreach (Command command in appBinding.Commands) + { + toReturn = InvokeCommand (command, key, appBinding); + } + + return toReturn ?? true; + } + } + + return false; + + static bool? InvokeCommand (Command command, Key key, KeyBinding appBinding) + { + if (!CommandImplementations!.ContainsKey (command)) + { + throw new NotSupportedException ( + @$"A KeyBinding was set up for the command {command} ({key}) but that command is not supported by Application." + ); + } + + if (CommandImplementations.TryGetValue (command, out View.CommandImplementation? implementation)) + { + var context = new CommandContext (command, key, appBinding); // Create the context here + + return implementation (context); + } + + return false; + } + } /// - /// Event fired when the user presses a key. Fired by . + /// Raised when the user presses a key. /// /// Set to to indicate the key was handled and to prevent /// additional processing. @@ -30,179 +111,30 @@ public static partial class Application // Keyboard handling public static event EventHandler? KeyDown; /// - /// Event fired when the user releases a key. Fired by . - /// - /// Set to to indicate the key was handled and to prevent - /// additional processing. - /// + /// Called when the user releases a key (by the ). Raises the cancelable + /// event + /// then calls on all top level views. Called after . /// - /// - /// All drivers support firing the event. Some drivers (Curses) do not support firing the - /// and events. - /// Fired after . - /// - public static event EventHandler? KeyUp; - - /// Alternative key to navigate forwards through views. Ctrl+Tab is the primary key. - [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] - public static Key NextTabGroupKey - { - get => _nextTabGroupKey; - set - { - if (_nextTabGroupKey != value) - { - ReplaceKey (_nextTabGroupKey, value); - _nextTabGroupKey = value; - } - } - } - - /// Alternative key to navigate forwards through views. Ctrl+Tab is the primary key. - [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] - public static Key NextTabKey - { - get => _nextTabKey; - set - { - if (_nextTabKey != value) - { - ReplaceKey (_nextTabKey, value); - _nextTabKey = value; - } - } - } - - /// - /// Called by the when the user presses a key. Fires the event - /// then calls on all top level views. Called after and - /// before . - /// - /// Can be used to simulate key press events. - /// + /// Can be used to simulate key release events. + /// /// if the key was handled. - public static bool OnKeyDown (Key keyEvent) - { - //if (!IsInitialized) - //{ - // return true; - //} - - KeyDown?.Invoke (null, keyEvent); - - if (keyEvent.Handled) - { - return true; - } - - if (Top is null) - { - foreach (Toplevel topLevel in TopLevels.ToList ()) - { - if (topLevel.NewKeyDownEvent (keyEvent)) - { - return true; - } - - if (topLevel.Modal) - { - break; - } - } - } - else - { - if (Top.NewKeyDownEvent (keyEvent)) - { - return true; - } - } - - // Invoke any Application-scoped KeyBindings. - // The first view that handles the key will stop the loop. - foreach (KeyValuePair binding in KeyBindings.Bindings.Where (b => b.Key == keyEvent.KeyCode)) - { - if (binding.Value.BoundView is { }) - { - bool? handled = binding.Value.BoundView?.InvokeCommands (binding.Value.Commands, binding.Key, binding.Value); - - if (handled != null && (bool)handled) - { - return true; - } - } - else - { - if (!KeyBindings.TryGet (keyEvent, KeyBindingScope.Application, out KeyBinding appBinding)) - { - continue; - } - - bool? toReturn = null; - - foreach (Command command in appBinding.Commands) - { - toReturn = InvokeCommand (command, keyEvent, appBinding); - } - - return toReturn ?? true; - } - } - - return false; - } - - /// - /// INTENRAL method to invoke one of the commands in - /// - /// - /// - /// - /// - /// - private static bool? InvokeCommand (Command command, Key keyEvent, KeyBinding appBinding) - { - if (!CommandImplementations!.ContainsKey (command)) - { - throw new NotSupportedException ( - @$"A KeyBinding was set up for the command {command} ({keyEvent}) but that command is not supported by Application." - ); - } - - if (CommandImplementations.TryGetValue (command, out View.CommandImplementation? implementation)) - { - var context = new CommandContext (command, keyEvent, appBinding); // Create the context here - - return implementation (context); - } - - return false; - } - - /// - /// Called by the when the user releases a key. Fires the event - /// then calls on all top level views. Called after . - /// - /// Can be used to simulate key press events. - /// - /// if the key was handled. - public static bool OnKeyUp (Key a) + public static bool RaiseKeyUpEvent (Key key) { if (!IsInitialized) { return true; } - KeyUp?.Invoke (null, a); + KeyUp?.Invoke (null, key); - if (a.Handled) + if (key.Handled) { return true; } foreach (Toplevel topLevel in TopLevels.ToList ()) { - if (topLevel.NewKeyUpEvent (a)) + if (topLevel.NewKeyUpEvent (key)) { return true; } @@ -216,65 +148,12 @@ public static partial class Application // Keyboard handling return false; } - /// Alternative key to navigate backwards through views. Shift+Ctrl+Tab is the primary key. - [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] - public static Key PrevTabGroupKey - { - get => _prevTabGroupKey; - set - { - if (_prevTabGroupKey != value) - { - ReplaceKey (_prevTabGroupKey, value); - _prevTabGroupKey = value; - } - } - } + #region Application-scoped KeyBindings - /// Alternative key to navigate backwards through views. Shift+Ctrl+Tab is the primary key. - [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] - public static Key PrevTabKey - { - get => _prevTabKey; - set - { - if (_prevTabKey != value) - { - ReplaceKey (_prevTabKey, value); - _prevTabKey = value; - } - } - } + static Application () { AddApplicationKeyBindings (); } - /// Gets or sets the key to quit the application. - [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] - public static Key QuitKey - { - get => _quitKey; - set - { - if (_quitKey != value) - { - ReplaceKey (_quitKey, value); - _quitKey = value; - } - } - } - - /// Gets or sets the key to activate arranging views using the keyboard. - [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] - public static Key ArrangeKey - { - get => _arrangeKey; - set - { - if (_arrangeKey != value) - { - ReplaceKey (_arrangeKey, value); - _arrangeKey = value; - } - } - } + /// Gets the Application-scoped key bindings. + public static KeyBindings KeyBindings { get; internal set; } = new (); internal static void AddApplicationKeyBindings () { @@ -286,6 +165,7 @@ public static partial class Application // Keyboard handling static () => { RequestStop (); + return true; } ); @@ -348,7 +228,7 @@ public static partial class Application // Keyboard handling KeyBindings.Clear (); - // Resources/config.json overrrides + // Resources/config.json overrides NextTabKey = Key.Tab; PrevTabKey = Key.Tab.WithShift; NextTabGroupKey = Key.F6; @@ -397,6 +277,26 @@ public static partial class Application // Keyboard handling .ToList (); } + private static void ReplaceKey (Key oldKey, Key newKey) + { + if (KeyBindings.Bindings.Count == 0) + { + return; + } + + if (newKey == Key.Empty) + { + KeyBindings.Remove (oldKey); + } + else + { + KeyBindings.ReplaceKey (oldKey, newKey); + } + } + + + #endregion Application-scoped KeyBindings + /// /// /// Sets the function that will be invoked for a . @@ -420,20 +320,4 @@ public static partial class Application // Keyboard handling /// private static Dictionary? CommandImplementations { get; set; } - private static void ReplaceKey (Key oldKey, Key newKey) - { - if (KeyBindings.Bindings.Count == 0) - { - return; - } - - if (newKey == Key.Empty) - { - KeyBindings.Remove (oldKey); - } - else - { - KeyBindings.ReplaceKey (oldKey, newKey); - } - } } diff --git a/Terminal.Gui/Application/Application.Mouse.cs b/Terminal.Gui/Application/Application.Mouse.cs index ab1cf428d..c4477ac85 100644 --- a/Terminal.Gui/Application/Application.Mouse.cs +++ b/Terminal.Gui/Application/Application.Mouse.cs @@ -1,6 +1,5 @@ #nullable enable using System.ComponentModel; -using System.Diagnostics; namespace Terminal.Gui; @@ -45,12 +44,12 @@ public static partial class Application // Mouse handling /// View that will receive all mouse events until is invoked. public static void GrabMouse (View? view) { - if (view is null || OnGrabbingMouse (view)) + if (view is null || RaiseGrabbingMouseEvent (view)) { return; } - OnGrabbedMouse (view); + RaiseGrabbedMouseEvent (view); MouseGrabView = view; } @@ -66,16 +65,16 @@ public static partial class Application // Mouse handling ObjectDisposedException.ThrowIf (MouseGrabView.WasDisposed, MouseGrabView); #endif - if (!OnUnGrabbingMouse (MouseGrabView)) + if (!RaiseUnGrabbingMouseEvent (MouseGrabView)) { View view = MouseGrabView; MouseGrabView = null; - OnUnGrabbedMouse (view); + RaiseUnGrabbedMouseEvent (view); } } /// A delegate callback throws an exception. - private static bool OnGrabbingMouse (View? view) + private static bool RaiseGrabbingMouseEvent (View? view) { if (view is null) { @@ -89,7 +88,7 @@ public static partial class Application // Mouse handling } /// A delegate callback throws an exception. - private static bool OnUnGrabbingMouse (View? view) + private static bool RaiseUnGrabbingMouseEvent (View? view) { if (view is null) { @@ -103,7 +102,7 @@ public static partial class Application // Mouse handling } /// A delegate callback throws an exception. - private static void OnGrabbedMouse (View? view) + private static void RaiseGrabbedMouseEvent (View? view) { if (view is null) { @@ -114,7 +113,7 @@ public static partial class Application // Mouse handling } /// A delegate callback throws an exception. - private static void OnUnGrabbedMouse (View? view) + private static void RaiseUnGrabbedMouseEvent (View? view) { if (view is null) { @@ -124,20 +123,14 @@ public static partial class Application // Mouse handling UnGrabbedMouse?.Invoke (view, new (view)); } - /// Event fired when a mouse move or click occurs. Coordinates are screen relative. - /// - /// - /// Use this event to receive mouse events in screen coordinates. Use to - /// receive mouse events relative to a . - /// - /// The will contain the that contains the mouse coordinates. - /// - public static event EventHandler? MouseEvent; - /// Called when a mouse event is raised by the driver. + /// + /// INTERNAL API: Called when a mouse event is raised by the driver. Determines the view under the mouse and + /// calls the appropriate View mouse event handlers. + /// /// This method can be used to simulate a mouse event, e.g. in unit tests. /// The mouse event with coordinates relative to the screen. - internal static void OnMouseEvent (MouseEvent mouseEvent) + internal static void RaiseMouseEvent (MouseEventArgs mouseEvent) { _lastMousePosition = mouseEvent.ScreenPosition; @@ -177,9 +170,6 @@ public static partial class Application // Mouse handling return; } - // We can combine this into the switch expression to reduce cognitive complexity even more and likely - // avoid one or two of these checks in the process, as well. - WantContinuousButtonPressedView = deepestViewUnderMouse switch { { WantContinuousButtonPressed: true } => deepestViewUnderMouse, @@ -194,7 +184,7 @@ public static partial class Application // Mouse handling } // Create a view-relative mouse event to send to the view that is under the mouse. - MouseEvent? viewMouseEvent; + MouseEventArgs? viewMouseEvent; if (deepestViewUnderMouse is Adornment adornment) { @@ -208,7 +198,7 @@ public static partial class Application // Mouse handling View = deepestViewUnderMouse }; } - else if (deepestViewUnderMouse.ViewportToScreen (Rectangle.Empty with { Size = deepestViewUnderMouse.Viewport.Size }).Contains (mouseEvent.Position)) + else if (deepestViewUnderMouse.ViewportToScreen (Rectangle.Empty with { Size = deepestViewUnderMouse.Viewport.Size }).Contains (mouseEvent.ScreenPosition)) { Point viewportLocation = deepestViewUnderMouse.ScreenToViewport (mouseEvent.ScreenPosition); @@ -224,7 +214,7 @@ public static partial class Application // Mouse handling { // The mouse was outside any View's Viewport. - // Debug.Fail ("This should never happen. If it does please file an Issue!!"); + // Debug.Fail ("This should never happen. If it does please file an Issue!!"); return; } @@ -261,7 +251,29 @@ public static partial class Application // Mouse handling } } - internal static bool HandleMouseGrab (View? deepestViewUnderMouse, MouseEvent mouseEvent) + +#pragma warning disable CS1574 // XML comment has cref attribute that could not be resolved + /// + /// Raised when a mouse event occurs. Can be cancelled by setting to . + /// + /// + /// + /// coordinates are screen-relative. + /// + /// + /// will be the deepest view under the under the mouse. + /// + /// + /// coordinates are view-relative. Only valid if is set. + /// + /// + /// Use this evento to handle mouse events at the application level, before View-specific handling. + /// + /// + public static event EventHandler? MouseEvent; +#pragma warning restore CS1574 // XML comment has cref attribute that could not be resolved + + internal static bool HandleMouseGrab (View? deepestViewUnderMouse, MouseEventArgs mouseEvent) { if (MouseGrabView is { }) { @@ -276,7 +288,7 @@ public static partial class Application // Mouse handling // The coordinates are relative to the Bounds of the view that grabbed the mouse. Point frameLoc = MouseGrabView.ScreenToViewport (mouseEvent.ScreenPosition); - var viewRelativeMouseEvent = new MouseEvent + var viewRelativeMouseEvent = new MouseEventArgs { Position = frameLoc, Flags = mouseEvent.Flags, @@ -303,7 +315,6 @@ public static partial class Application // Mouse handling internal static readonly List _cachedViewsUnderMouse = new (); - // TODO: Refactor MouseEnter/LeaveEvents to not take MouseEvent param. /// /// INTERNAL: Raises the MouseEnter and MouseLeave events for the views that are under the mouse. /// diff --git a/Terminal.Gui/Application/Application.Navigation.cs b/Terminal.Gui/Application/Application.Navigation.cs index 440cd4b42..a4f9dcc54 100644 --- a/Terminal.Gui/Application/Application.Navigation.cs +++ b/Terminal.Gui/Application/Application.Navigation.cs @@ -7,4 +7,83 @@ public static partial class Application // Navigation stuff /// Gets the instance for the current . /// public static ApplicationNavigation? Navigation { get; internal set; } + + private static Key _nextTabGroupKey = Key.F6; // Resources/config.json overrides + private static Key _nextTabKey = Key.Tab; // Resources/config.json overrides + private static Key _prevTabGroupKey = Key.F6.WithShift; // Resources/config.json overrides + private static Key _prevTabKey = Key.Tab.WithShift; // Resources/config.json overrides + + /// Alternative key to navigate forwards through views. Ctrl+Tab is the primary key. + [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] + public static Key NextTabGroupKey + { + get => _nextTabGroupKey; + set + { + if (_nextTabGroupKey != value) + { + ReplaceKey (_nextTabGroupKey, value); + _nextTabGroupKey = value; + } + } + } + + /// Alternative key to navigate forwards through views. Ctrl+Tab is the primary key. + [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] + public static Key NextTabKey + { + get => _nextTabKey; + set + { + if (_nextTabKey != value) + { + ReplaceKey (_nextTabKey, value); + _nextTabKey = value; + } + } + } + + + /// + /// Raised when the user releases a key. + /// + /// Set to to indicate the key was handled and to prevent + /// additional processing. + /// + /// + /// + /// All drivers support firing the event. Some drivers (Curses) do not support firing the + /// and events. + /// Fired after . + /// + public static event EventHandler? KeyUp; + /// Alternative key to navigate backwards through views. Shift+Ctrl+Tab is the primary key. + [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] + public static Key PrevTabGroupKey + { + get => _prevTabGroupKey; + set + { + if (_prevTabGroupKey != value) + { + ReplaceKey (_prevTabGroupKey, value); + _prevTabGroupKey = value; + } + } + } + + /// Alternative key to navigate backwards through views. Shift+Ctrl+Tab is the primary key. + [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] + public static Key PrevTabKey + { + get => _prevTabKey; + set + { + if (_prevTabKey != value) + { + ReplaceKey (_prevTabKey, value); + _prevTabKey = value; + } + } + } } diff --git a/Terminal.Gui/Application/Application.Run.cs b/Terminal.Gui/Application/Application.Run.cs index d6c9cbb0d..966fb04c6 100644 --- a/Terminal.Gui/Application/Application.Run.cs +++ b/Terminal.Gui/Application/Application.Run.cs @@ -6,6 +6,41 @@ namespace Terminal.Gui; public static partial class Application // Run (Begin, Run, End, Stop) { + private static Key _quitKey = Key.Esc; // Resources/config.json overrides + + /// Gets or sets the key to quit the application. + [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] + public static Key QuitKey + { + get => _quitKey; + set + { + if (_quitKey != value) + { + ReplaceKey (_quitKey, value); + _quitKey = value; + } + } + } + + private static Key _arrangeKey = Key.F5.WithCtrl; // Resources/config.json overrides + + + /// Gets or sets the key to activate arranging views using the keyboard. + [SerializableConfigurationProperty (Scope = typeof (SettingsScope))] + public static Key ArrangeKey + { + get => _arrangeKey; + set + { + if (_arrangeKey != value) + { + ReplaceKey (_arrangeKey, value); + _arrangeKey = value; + } + } + } + // When `End ()` is called, it is possible `RunState.Toplevel` is a different object than `Top`. // This variable is set in `End` in this case so that `Begin` correctly sets `Top`. private static Toplevel? _cachedRunStateToplevel; diff --git a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs index 9f2a45465..7d6de3834 100644 --- a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs @@ -588,11 +588,11 @@ public abstract class ConsoleDriver public void OnKeyUp (Key a) { KeyUp?.Invoke (this, a); } /// Event fired when a mouse event occurs. - public event EventHandler? MouseEvent; + public event EventHandler? MouseEvent; /// Called when a mouse event occurs. Fires the event. /// - public void OnMouseEvent (MouseEvent a) + public void OnMouseEvent (MouseEventArgs a) { // Ensure ScreenPosition is set a.ScreenPosition = a.Position; diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs index 0b11949a9..b806457d4 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs @@ -1004,7 +1004,7 @@ internal class CursesDriver : ConsoleDriver _lastMouseFlags = mouseFlag; - var me = new MouseEvent { Flags = mouseFlag, Position = pos }; + var me = new MouseEventArgs { Flags = mouseFlag, Position = pos }; //Debug.WriteLine ($"CursesDriver: ({me.Position}) - {me.Flags}"); OnMouseEvent (me); diff --git a/Terminal.Gui/ConsoleDrivers/NetDriver.cs b/Terminal.Gui/ConsoleDrivers/NetDriver.cs index 1298c1c35..8aaddc321 100644 --- a/Terminal.Gui/ConsoleDrivers/NetDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/NetDriver.cs @@ -1154,7 +1154,7 @@ internal class NetDriver : ConsoleDriver break; case EventType.Mouse: - MouseEvent me = ToDriverMouse (inputEvent.MouseEvent); + MouseEventArgs me = ToDriverMouse (inputEvent.MouseEvent); //Debug.WriteLine ($"NetDriver: ({me.X},{me.Y}) - {me.Flags}"); OnMouseEvent (me); @@ -1393,7 +1393,7 @@ internal class NetDriver : ConsoleDriver } } - private MouseEvent ToDriverMouse (NetEvents.MouseEvent me) + private MouseEventArgs ToDriverMouse (NetEvents.MouseEvent me) { //System.Diagnostics.Debug.WriteLine ($"X: {me.Position.X}; Y: {me.Position.Y}; ButtonState: {me.ButtonState}"); @@ -1539,7 +1539,7 @@ internal class NetDriver : ConsoleDriver mouseFlag |= MouseFlags.ButtonAlt; } - return new MouseEvent { Position = me.Position, Flags = mouseFlag }; + return new MouseEventArgs { Position = me.Position, Flags = mouseFlag }; } #endregion Mouse Handling diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index 2a9bef081..fd5c6901c 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -1483,7 +1483,7 @@ internal class WindowsDriver : ConsoleDriver break; case WindowsConsole.EventType.Mouse: - MouseEvent me = ToDriverMouse (inputEvent.MouseEvent); + MouseEventArgs me = ToDriverMouse (inputEvent.MouseEvent); if (me is null || me.Flags == MouseFlags.None) { @@ -1827,9 +1827,9 @@ internal class WindowsDriver : ConsoleDriver } await Task.Delay (delay); - var me = new MouseEvent + var me = new MouseEventArgs { - Position = _pointMove, + ScreenPosition = _pointMove, Flags = mouseFlag }; @@ -1883,7 +1883,7 @@ internal class WindowsDriver : ConsoleDriver } [CanBeNull] - private MouseEvent ToDriverMouse (WindowsConsole.MouseEventRecord mouseEvent) + private MouseEventArgs ToDriverMouse (WindowsConsole.MouseEventRecord mouseEvent) { var mouseFlag = MouseFlags.AllEvents; @@ -2127,7 +2127,7 @@ internal class WindowsDriver : ConsoleDriver //System.Diagnostics.Debug.WriteLine ( // $"point.X:{(point is { } ? ((Point)point).X : -1)};point.Y:{(point is { } ? ((Point)point).Y : -1)}"); - return new MouseEvent + return new MouseEventArgs { Position = new (mouseEvent.MousePosition.X, mouseEvent.MousePosition.Y), Flags = mouseFlag diff --git a/Terminal.Gui/Input/MouseEventArgs.cs b/Terminal.Gui/Input/MouseEventArgs.cs new file mode 100644 index 000000000..cdf3aafb1 --- /dev/null +++ b/Terminal.Gui/Input/MouseEventArgs.cs @@ -0,0 +1,101 @@ +#nullable enable +using System.ComponentModel; + +namespace Terminal.Gui; + +/// +/// Specifies the event arguments for . This is a higher-level construct than +/// the wrapped class and is used for the events defined on +/// and subclasses +/// of View (e.g. and ). +/// +public class MouseEventArgs : HandledEventArgs +{ + /// + /// Flags indicating the state of the mouse buttons and the type of event that occurred. + /// + public MouseFlags Flags { get; set; } + + /// + /// The screen-relative mouse position. + /// + public Point ScreenPosition { get; set; } + + /// The deepest View who's contains . + public View? View { get; set; } + + /// + /// The position of the mouse in 's Viewport-relative coordinates. Only valid if + /// is set. + /// + public Point Position { get; set; } + + /// + /// Gets whether contains any of the button pressed related flags. + /// + public bool IsPressed => Flags.HasFlag (MouseFlags.Button1Pressed) + || Flags.HasFlag (MouseFlags.Button2Pressed) + || Flags.HasFlag (MouseFlags.Button3Pressed) + || Flags.HasFlag (MouseFlags.Button4Pressed); + + /// + /// Gets whether contains any of the button released related flags. + /// + public bool IsReleased => Flags.HasFlag (MouseFlags.Button1Released) + || Flags.HasFlag (MouseFlags.Button2Released) + || Flags.HasFlag (MouseFlags.Button3Released) + || Flags.HasFlag (MouseFlags.Button4Released); + + /// + /// Gets whether contains any of the single-clicked related flags. + /// + public bool IsSingleClicked => Flags.HasFlag (MouseFlags.Button1Clicked) + || Flags.HasFlag (MouseFlags.Button2Clicked) + || Flags.HasFlag (MouseFlags.Button3Clicked) + || Flags.HasFlag (MouseFlags.Button4Clicked); + + /// + /// Gets whether contains any of the double-clicked related flags. + /// + public bool IsDoubleClicked => Flags.HasFlag (MouseFlags.Button1DoubleClicked) + || Flags.HasFlag (MouseFlags.Button2DoubleClicked) + || Flags.HasFlag (MouseFlags.Button3DoubleClicked) + || Flags.HasFlag (MouseFlags.Button4DoubleClicked); + + /// + /// Gets whether contains any of the triple-clicked related flags. + /// + public bool IsTripleClicked => Flags.HasFlag (MouseFlags.Button1TripleClicked) + || Flags.HasFlag (MouseFlags.Button2TripleClicked) + || Flags.HasFlag (MouseFlags.Button3TripleClicked) + || Flags.HasFlag (MouseFlags.Button4TripleClicked); + + /// + /// Gets whether contains any of the mouse button clicked related flags. + /// + public bool IsSingleDoubleOrTripleClicked => + Flags.HasFlag (MouseFlags.Button1Clicked) + || Flags.HasFlag (MouseFlags.Button2Clicked) + || Flags.HasFlag (MouseFlags.Button3Clicked) + || Flags.HasFlag (MouseFlags.Button4Clicked) + || Flags.HasFlag (MouseFlags.Button1DoubleClicked) + || Flags.HasFlag (MouseFlags.Button2DoubleClicked) + || Flags.HasFlag (MouseFlags.Button3DoubleClicked) + || Flags.HasFlag (MouseFlags.Button4DoubleClicked) + || Flags.HasFlag (MouseFlags.Button1TripleClicked) + || Flags.HasFlag (MouseFlags.Button2TripleClicked) + || Flags.HasFlag (MouseFlags.Button3TripleClicked) + || Flags.HasFlag (MouseFlags.Button4TripleClicked); + + /// + /// Gets whether contains any of the mouse wheel related flags. + /// + public bool IsWheel => Flags.HasFlag (MouseFlags.WheeledDown) + || Flags.HasFlag (MouseFlags.WheeledUp) + || Flags.HasFlag (MouseFlags.WheeledLeft) + || Flags.HasFlag (MouseFlags.WheeledRight); + + /// Returns a that represents the current . + /// A that represents the current . + public override string ToString () { return $"({ScreenPosition}):{Flags}:{View?.Id}:{Position}"; } +} diff --git a/Terminal.Gui/Input/MouseEventEventArgs.cs b/Terminal.Gui/Input/MouseEventEventArgs.cs deleted file mode 100644 index 89fc168a7..000000000 --- a/Terminal.Gui/Input/MouseEventEventArgs.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace Terminal.Gui; - -/// -/// Specifies the event arguments for . This is a higher-level construct than -/// the wrapped class and is used for the events defined on and subclasses -/// of View (e.g. and ). -/// -public class MouseEventEventArgs : EventArgs -{ - /// Constructs. - /// The mouse event. - public MouseEventEventArgs (MouseEvent me) { MouseEvent = me; } - - /// - /// Indicates if the current mouse event has already been processed and the driver should stop notifying any other - /// event subscriber. It's important to set this value to true specially when updating any View's layout from inside the - /// subscriber method. - /// - /// - /// This property forwards to the property and is provided as a convenience and - /// for backwards compatibility - /// - public bool Handled - { - get => MouseEvent.Handled; - set => MouseEvent.Handled = value; - } - - // TODO: Merge MouseEvent and MouseEventEventArgs into a single class. - /// The for the event. - public MouseEvent MouseEvent { get; set; } -} diff --git a/Terminal.Gui/Input/Mouse.cs b/Terminal.Gui/Input/MouseFlags.cs similarity index 59% rename from Terminal.Gui/Input/Mouse.cs rename to Terminal.Gui/Input/MouseFlags.cs index 3c8c98e91..56bed6e88 100644 --- a/Terminal.Gui/Input/Mouse.cs +++ b/Terminal.Gui/Input/MouseFlags.cs @@ -1,12 +1,12 @@ namespace Terminal.Gui; -/// Mouse flags reported in . +/// Mouse flags reported in . /// They just happen to map to the ncurses ones. [Flags] public enum MouseFlags { /// - /// No mouse event. This is the default value for when no mouse event is being reported. + /// No mouse event. This is the default value for when no mouse event is being reported. /// None = 0, @@ -97,50 +97,3 @@ public enum MouseFlags /// Mask that captures all the events. AllEvents = 0x7ffffff } - -// TODO: Merge MouseEvent and MouseEventEventArgs into a single class. - -/// -/// Conveys the details of mouse events, such as coordinates and button state, from -/// ConsoleDrivers up to and Views. -/// -/// -/// The class includes the event which takes a -/// MouseEvent argument. -/// -public class MouseEvent -{ - /// Flags indicating the kind of mouse event that is being posted. - public MouseFlags Flags { get; set; } - - /// The View at the location for the mouse event. - public View View { get; set; } - - /// The position of the mouse in -relative coordinates. - public Point Position { get; set; } - - /// - /// The screen-relative mouse position. - /// - /// - /// - /// is -relative. When the mouse is grabbed by a view, - /// provides the mouse position screen-relative coordinates, enabling the grabbed view to know how much the - /// mouse has moved. - /// - /// - /// Calculated and processed in . - /// - /// - public Point ScreenPosition { get; set; } - - /// - /// Indicates if the current mouse event has been processed. Set this value to to indicate the mouse - /// event was handled. - /// - public bool Handled { get; set; } - - /// Returns a that represents the current . - /// A that represents the current . - public override string ToString () { return $"({Position}):{Flags}"; } -} diff --git a/Terminal.Gui/Input/ShortcutHelper.cs b/Terminal.Gui/Input/ShortcutHelper.cs deleted file mode 100644 index d5e776a53..000000000 --- a/Terminal.Gui/Input/ShortcutHelper.cs +++ /dev/null @@ -1,173 +0,0 @@ -using System.Diagnostics; - -namespace Terminal.Gui; - -// TODO: Nuke when #2975 is completed -/// Represents a helper to manipulate shortcut keys used on views. -public class ShortcutHelper -{ - // TODO: Update this to use Key, not KeyCode - private KeyCode shortcut; - - /// This is the global setting that can be used as a global shortcut to invoke the action on the view. - public virtual KeyCode Shortcut - { - get => shortcut; - set - { - if (shortcut != value && (PostShortcutValidation (value) || value is KeyCode.Null)) - { - shortcut = value; - } - } - } - - /// The keystroke combination used in the as string. - public virtual string ShortcutTag => Key.ToString (shortcut, Key.Separator); - - /// Lookup for a on range of keys. - /// The source key. - /// First key in range. - /// Last key in range. - public static bool CheckKeysFlagRange (KeyCode key, KeyCode first, KeyCode last) - { - for (var i = (uint)first; i < (uint)last; i++) - { - if ((key | (KeyCode)i) == key) - { - return true; - } - } - - return false; - } - - /// Allows to retrieve a from a - /// The key as string. - /// The delimiter string. - public static KeyCode GetShortcutFromTag (string tag, Rune delimiter = default) - { - string sCut = tag; - - if (string.IsNullOrEmpty (sCut)) - { - return default (KeyCode); - } - - var key = KeyCode.Null; - - //var hasCtrl = false; - if (delimiter == default (Rune)) - { - delimiter = Key.Separator; - } - - string [] keys = sCut.Split (delimiter.ToString ()); - - for (var i = 0; i < keys.Length; i++) - { - string k = keys [i]; - - if (k == "Ctrl") - { - //hasCtrl = true; - key |= KeyCode.CtrlMask; - } - else if (k == "Shift") - { - key |= KeyCode.ShiftMask; - } - else if (k == "Alt") - { - key |= KeyCode.AltMask; - } - else if (k.StartsWith ("F") && k.Length > 1) - { - int.TryParse (k.Substring (1), out int n); - - for (var j = (uint)KeyCode.F1; j <= (uint)KeyCode.F12; j++) - { - int.TryParse (((KeyCode)j).ToString ().Substring (1), out int f); - - if (f == n) - { - key |= (KeyCode)j; - } - } - } - else - { - key |= (KeyCode)Enum.Parse (typeof (KeyCode), k); - } - } - - return key; - } - - /// Used at key up validation. - /// The key to validate. - /// true if is valid.falseotherwise. - public static bool PostShortcutValidation (KeyCode key) - { - GetKeyToString (key, out KeyCode knm); - - if (CheckKeysFlagRange (key, KeyCode.F1, KeyCode.F12) || ((key & (KeyCode.CtrlMask | KeyCode.ShiftMask | KeyCode.AltMask)) != 0 && knm != KeyCode.Null)) - { - return true; - } - - return false; - } - - /// Used at key down or key press validation. - /// The key to validate. - /// true if is valid.falseotherwise. - public static bool PreShortcutValidation (KeyCode key) - { - if ((key & (KeyCode.CtrlMask | KeyCode.ShiftMask | KeyCode.AltMask)) == 0 - && !CheckKeysFlagRange (key, KeyCode.F1, KeyCode.F12)) - { - return false; - } - - return true; - } - - /// Return key as string. - /// The key to extract. - /// Correspond to the non modifier key. - private static string GetKeyToString (KeyCode key, out KeyCode knm) - { - if (key == KeyCode.Null) - { - knm = KeyCode.Null; - - return ""; - } - - knm = key; - KeyCode mK = key & (KeyCode.AltMask | KeyCode.CtrlMask | KeyCode.ShiftMask); - knm &= ~mK; - - for (var i = (uint)KeyCode.F1; i < (uint)KeyCode.F12; i++) - { - if (knm == (KeyCode)i) - { - mK |= (KeyCode)i; - } - } - - knm &= ~mK; - uint.TryParse (knm.ToString (), out uint c); - string s = mK == KeyCode.Null ? "" : mK.ToString (); - - if (s != "" && (knm != KeyCode.Null || c > 0)) - { - s += ","; - } - - s += c == 0 ? knm == KeyCode.Null ? "" : knm.ToString () : ((char)c).ToString (); - - return s; - } -} diff --git a/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs index 2fa920e70..9602776f5 100644 --- a/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs @@ -59,7 +59,7 @@ public class AppendAutocomplete : AutocompleteBase } /// - public override bool OnMouseEvent (MouseEvent me, bool fromHost = false) { return false; } + public override bool OnMouseEvent (MouseEventArgs me, bool fromHost = false) { return false; } /// public override bool ProcessKey (Key a) diff --git a/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs b/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs index 39d725ca4..ad51d5e22 100644 --- a/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs +++ b/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs @@ -49,7 +49,7 @@ public abstract class AutocompleteBase : IAutocomplete public virtual AutocompleteContext Context { get; set; } /// - public abstract bool OnMouseEvent (MouseEvent me, bool fromHost = false); + public abstract bool OnMouseEvent (MouseEventArgs me, bool fromHost = false); /// public abstract bool ProcessKey (Key a); diff --git a/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs index 6305386bd..88d3a8026 100644 --- a/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs @@ -45,7 +45,7 @@ public interface IAutocomplete /// The mouse event. /// If was called from the popup or from the host. /// trueif the mouse can be handled falseotherwise. - bool OnMouseEvent (MouseEvent me, bool fromHost = false); + bool OnMouseEvent (MouseEventArgs me, bool fromHost = false); /// Gets or sets where the popup will be displayed. bool PopupInsideContainer { get; set; } diff --git a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.PopUp.cs b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.PopUp.cs index 622e6620b..39bdd7522 100644 --- a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.PopUp.cs +++ b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.PopUp.cs @@ -25,6 +25,6 @@ public abstract partial class PopupAutocomplete _autoComplete.RenderOverlay (_autoComplete.LastPopupPos.Value); } - protected internal override bool OnMouseEvent (MouseEvent mouseEvent) { return _autoComplete.OnMouseEvent (mouseEvent); } + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { return _autoComplete.OnMouseEvent (mouseEvent); } } } diff --git a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs index c17695ee7..4f332bd54 100644 --- a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs @@ -105,7 +105,7 @@ public abstract partial class PopupAutocomplete : AutocompleteBase /// The mouse event. /// If was called from the popup or from the host. /// trueif the mouse can be handled falseotherwise. - public override bool OnMouseEvent (MouseEvent me, bool fromHost = false) + public override bool OnMouseEvent (MouseEventArgs me, bool fromHost = false) { if (fromHost) { @@ -488,7 +488,7 @@ public abstract partial class PopupAutocomplete : AutocompleteBase /// Render the current selection in the Autocomplete context menu by the mouse reporting. /// - protected void RenderSelectedIdxByMouse (MouseEvent me) + protected void RenderSelectedIdxByMouse (MouseEventArgs me) { if (SelectedIdx != me.Position.Y - ScrollOffset) { diff --git a/Terminal.Gui/View/Adornment/Border.cs b/Terminal.Gui/View/Adornment/Border.cs index 082df687f..add7527e6 100644 --- a/Terminal.Gui/View/Adornment/Border.cs +++ b/Terminal.Gui/View/Adornment/Border.cs @@ -262,13 +262,8 @@ public class Border : Adornment private Point _startGrabPoint; /// - protected internal override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { - if (base.OnMouseEvent (mouseEvent)) - { - return true; - } - // BUGBUG: See https://github.com/gui-cs/Terminal.Gui/issues/3312 if (!_dragPosition.HasValue && mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed) // HACK: Prevents Window from being draggable if it's Top @@ -1370,7 +1365,7 @@ public class Border : Adornment KeyBindings.Add (Key.Tab.WithShift, KeyBindingScope.HotKey, Command.BackTab); } - private void ApplicationOnMouseEvent (object? sender, MouseEvent e) + private void ApplicationOnMouseEvent (object? sender, MouseEventArgs e) { if (e.Flags != MouseFlags.Button1Clicked) { diff --git a/Terminal.Gui/View/Adornment/Padding.cs b/Terminal.Gui/View/Adornment/Padding.cs index 8f51a4f9b..7dbc1cd70 100644 --- a/Terminal.Gui/View/Adornment/Padding.cs +++ b/Terminal.Gui/View/Adornment/Padding.cs @@ -50,7 +50,7 @@ public class Padding : Adornment /// /// /// , if the event was handled, otherwise. - protected internal override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { if (Parent is null) { diff --git a/Terminal.Gui/View/Orientation/OrientationHelper.cs b/Terminal.Gui/View/Orientation/OrientationHelper.cs index 33c33c70f..380dfbb53 100644 --- a/Terminal.Gui/View/Orientation/OrientationHelper.cs +++ b/Terminal.Gui/View/Orientation/OrientationHelper.cs @@ -69,7 +69,7 @@ public class OrientationHelper return; } - // Best practice is to invoke the virtual method first. + // Best practice is to call the virtual method first. // This allows derived classes to handle the event and potentially cancel it. if (_owner?.OnOrientationChanging (value, _orientation) ?? false) { @@ -98,10 +98,8 @@ public class OrientationHelper } } - // Best practice is to invoke the virtual method first. + // Best practice is to call the virtual method first, then raise the event. _owner?.OnOrientationChanged (_orientation); - - // Even though Changed is not cancelable, it is still a good practice to raise the event after. OrientationChanged?.Invoke (_owner, new (in _orientation)); } } diff --git a/Terminal.Gui/View/View.Keyboard.cs b/Terminal.Gui/View/View.Keyboard.cs index f9c835512..87c5a1ce6 100644 --- a/Terminal.Gui/View/View.Keyboard.cs +++ b/Terminal.Gui/View/View.Keyboard.cs @@ -26,7 +26,7 @@ public partial class View // Keyboard APIs #region HotKey Support - /// Invoked when the is changed. + /// Raised when the is changed. public event EventHandler? HotKeyChanged; private Key _hotKey = new (); @@ -73,7 +73,7 @@ public partial class View // Keyboard APIs /// If the hot key is changed, the event is fired. /// Set to to disable the hot key. /// - public virtual Key HotKey + public Key HotKey { get => _hotKey; set @@ -218,7 +218,7 @@ public partial class View // Keyboard APIs private void SetHotKeyFromTitle () { - if (TitleTextFormatter == null || HotKeySpecifier == new Rune ('\xFFFF')) + if (HotKeySpecifier == new Rune ('\xFFFF')) { return; // throw new InvalidOperationException ("Can't set HotKey unless a TextFormatter has been created"); } @@ -243,7 +243,8 @@ public partial class View // Keyboard APIs #region Key Down Event /// - /// If the view is enabled, processes a new key down event and returns if the event was + /// If the view is enabled, raises the related key down events on the view, and returns if the + /// event was /// handled. /// /// @@ -252,74 +253,95 @@ public partial class View // Keyboard APIs /// first. /// /// - /// If the focused sub view does not handle the key press, this method calls to allow the - /// view to pre-process the key press. If returns , this method then - /// calls to invoke any key bindings. Then, only if no key bindings are - /// handled, will be called allowing the view to process the key press. + /// If a more focused subview does not handle the key press, this method raises / + /// to allow the + /// view to pre-process the key press. If / is not handled any commands bound to the key will be invoked. + /// Then, only if no key bindings are + /// handled, / will be raised allowing the view to + /// process the key press. + /// + /// + /// Calling this method for a key bound to the view via an Application-scoped keybinding will have no effect. + /// Instead, + /// use . /// /// See for an overview of Terminal.Gui keyboard APIs. /// - /// + /// /// if the event was handled. - public bool NewKeyDownEvent (Key keyEvent) + public bool NewKeyDownEvent (Key key) { if (!Enabled) { return false; } - // By default the KeyBindingScope is View - - if (Focused?.NewKeyDownEvent (keyEvent) == true) + // If there's a Focused subview, give it a chance (this recurses down the hierarchy) + if (Focused?.NewKeyDownEvent (key) == true) { return true; } // Before (fire the cancellable event) - if (OnKeyDown (keyEvent)) + if (RaiseKeyDown (key) || key.Handled) { return true; } // During (this is what can be cancelled) - InvokingKeyBindings?.Invoke (this, keyEvent); - if (keyEvent.Handled) + // TODO: NewKeyDownEvent returns bool. It should be bool? so state of InvokeCommands can be reflected up stack + if (InvokeCommandsBoundToKey (key) is true || key.Handled) { return true; } - // TODO: NewKeyDownEvent returns bool. It should be bool? so state of InvokeCommand can be reflected up stack - - bool? handled = OnInvokingKeyBindings (keyEvent, KeyBindingScope.HotKey | KeyBindingScope.Focused); - - if (handled is { } && (bool)handled) + // After + if (RaiseKeyDownNotHandled (key) || key.Handled) { return true; } - // TODO: The below is not right. OnXXX handlers are supposed to fire the events. - // TODO: But I've moved it outside of the v-function to test something. - // After (fire the cancellable event) - // fire event - ProcessKeyDown?.Invoke (this, keyEvent); + return key.Handled; - if (!keyEvent.Handled && OnProcessKeyDown (keyEvent)) + bool RaiseKeyDown (Key k) { - return true; + // Before (fire the cancellable event) + if (OnKeyDown (k) || k.Handled) + { + return true; + } + + // fire event + KeyDown?.Invoke (this, k); + + return k.Handled; } - return keyEvent.Handled; + bool RaiseKeyDownNotHandled (Key k) + { + if (OnKeyDownNotHandled (k) || k.Handled) + { + return true; + } + + KeyDownNotHandled?.Invoke (this, k); + + return false; + } } /// - /// Low-level API called when the user presses a key, allowing a view to pre-process the key down event. This is - /// called from before . + /// Called when the user presses a key, allowing subscribers to pre-process the key down event. Called + /// before key bindings are invoked and is raised. Set + /// + /// to true to + /// stop the key from being processed further. /// - /// Contains the details about the key that produced the event. + /// The key that produced the event. /// - /// if the key press was not handled. if the keypress was handled - /// and no other view should see it. + /// if the key down event was not handled. if the event was handled + /// and processing should stop. /// /// /// @@ -328,18 +350,14 @@ public partial class View // Keyboard APIs /// /// Fires the event. /// - public virtual bool OnKeyDown (Key keyEvent) - { - // fire event - KeyDown?.Invoke (this, keyEvent); - - return keyEvent.Handled; - } + protected virtual bool OnKeyDown (Key key) { return false; } /// - /// Invoked when the user presses a key, allowing subscribers to pre-process the key down event. This is fired - /// from before . Set to true to - /// stop the key from being processed by other views. + /// Raised when the user presses a key, allowing subscribers to pre-process the key down event. Called + /// before key bindings are invoked and is raised. Set + /// + /// to true to + /// stop the key from being processed further. /// /// /// @@ -351,60 +369,49 @@ public partial class View // Keyboard APIs public event EventHandler? KeyDown; /// - /// Low-level API called when the user presses a key, allowing views do things during key down events. This is - /// called from after . + /// Called when the user has pressed key it wasn't handled by and was not bound to a key binding. /// - /// Contains the details about the key that produced the event. - /// - /// if the key press was not handled. if the keypress was handled - /// and no other view should see it. - /// /// /// - /// Override to override the behavior of how the base class processes key down - /// events. - /// - /// /// For processing s and commands, use and /// instead. /// - /// Fires the event. /// /// Not all terminals support distinct key up notifications; applications should avoid depending on distinct /// KeyUp events. /// /// - public virtual bool OnProcessKeyDown (Key keyEvent) - { - //ProcessKeyDown?.Invoke (this, keyEvent); - return keyEvent.Handled; - } + /// Contains the details about the key that produced the event. + /// + /// if the key press was not handled. if the keypress was handled + /// and no other view should see it. + /// + protected virtual bool OnKeyDownNotHandled (Key key) { return key.Handled; } /// - /// Invoked when the user presses a key, allowing subscribers to do things during key down events. Set - /// to true to stop the key from being processed by other views. Invoked after - /// and before . + /// Raised when the user has pressed key it wasn't handled by and was not bound to a key binding. /// /// /// - /// SubViews can use the of their super view override the default behavior of when - /// key bindings are invoked. + /// For processing s and commands, use and + /// instead. /// /// - /// Not all terminals support distinct key up notifications; applications should avoid depending on distinct - /// KeyUp events. + /// SubViews can use the of their super view override the default behavior of when + /// key bindings are invoked. /// /// See for an overview of Terminal.Gui keyboard APIs. /// - public event EventHandler? ProcessKeyDown; + public event EventHandler? KeyDownNotHandled; #endregion KeyDown Event #region KeyUp Event /// - /// If the view is enabled, processes a new key up event and returns if the event was - /// handled. Called before . + /// If the view is enabled, raises the related key up events on the view, and returns if the + /// event was + /// handled. /// /// /// @@ -416,44 +423,52 @@ public partial class View // Keyboard APIs /// first. /// /// - /// If the focused sub view does not handle the key press, this method calls , which is - /// cancellable. + /// If the focused sub view does not handle the key press, this method raises / + /// to allow the + /// view to pre-process the key press. /// /// See for an overview of Terminal.Gui keyboard APIs. /// - /// + /// /// if the event was handled. - public bool NewKeyUpEvent (Key keyEvent) + public bool NewKeyUpEvent (Key key) { if (!Enabled) { return false; } - if (Focused?.NewKeyUpEvent (keyEvent) == true) + // Before + if (RaiseKeyUp (key) || key.Handled) { return true; } - // Before (fire the cancellable event) - if (OnKeyUp (keyEvent)) - { - return true; - } + // During - // During (this is what can be cancelled) - // TODO: Until there's a clear use-case, we will not define 'during' event (e.g. OnDuringKeyUp). - - // After (fire the cancellable event InvokingKeyBindings) - // TODO: Until there's a clear use-case, we will not define an 'after' event (e.g. OnAfterKeyUp). + // After return false; + + bool RaiseKeyUp (Key k) + { + // Before (fire the cancellable event) + if (OnKeyUp (k) || k.Handled) + { + return true; + } + + // fire event + KeyUp?.Invoke (this, k); + + return k.Handled; + } } - /// Method invoked when a key is released. This method is called from . - /// Contains the details about the key that produced the event. + /// Called when a key is released. This method is called from . + /// Contains the details about the key that produced the event. /// - /// if the key stroke was not handled. if no other view should see + /// if the keys up event was not handled. if no other view should see /// it. /// /// @@ -465,21 +480,10 @@ public partial class View // Keyboard APIs /// /// See for an overview of Terminal.Gui keyboard APIs. /// - public virtual bool OnKeyUp (Key keyEvent) - { - // fire event - KeyUp?.Invoke (this, keyEvent); - - if (keyEvent.Handled) - { - return true; - } - - return false; - } + public virtual bool OnKeyUp (Key key) { return false; } /// - /// Invoked when a key is released. Set to true to stop the key up event from being processed + /// Raised when a key is released. Set to true to stop the key up event from being processed /// by other views. /// /// Not all terminals support key distinct down/up notifications, Applications should avoid depending on @@ -501,32 +505,20 @@ public partial class View // Keyboard APIs private Dictionary CommandImplementations { get; } = new (); /// - /// Low-level API called when a user presses a key; invokes any key bindings set on the view. This is called - /// during after has returned. + /// INTERNAL API: Invokes any commands bound to on this view, adornments, and subviews. /// - /// - /// Fires the event. - /// See for an overview of Terminal.Gui keyboard APIs. - /// - /// Contains the details about the key that produced the event. - /// The scope. + /// /// - /// if no event was raised; input proessing should continue. - /// if the event was raised and was not handled (or cancelled); input proessing should continue. - /// if the event was raised and handled (or cancelled); input proessing should stop. + /// if no command was invoked or there was no matching key binding; input processing should + /// continue. + /// if a command was invoked and was not handled (or cancelled); input processing should + /// continue. + /// if at least one command was invoked and handled (or + /// cancelled); input processing should stop. /// - public virtual bool? OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) + internal bool? InvokeCommandsBoundToKey (Key key) { - // fire event only if there's a hotkey binding for the key - if (KeyBindings.TryGet (keyEvent, scope, out KeyBinding kb)) - { - InvokingKeyBindings?.Invoke (this, keyEvent); - - if (keyEvent.Handled) - { - return true; - } - } + KeyBindingScope scope = KeyBindingScope.Focused | KeyBindingScope.HotKey; // * If no key binding was found, `InvokeKeyBindings` returns `null`. // Continue passing the event (return `false` from `OnInvokeKeyBindings`). @@ -534,31 +526,31 @@ public partial class View // Keyboard APIs // `InvokeKeyBindings` returns `false`. Continue passing the event (return `false` from `OnInvokeKeyBindings`).. // * If key bindings were found, and any handled the key (at least one `Command` returned `true`), // `InvokeKeyBindings` returns `true`. Continue passing the event (return `false` from `OnInvokeKeyBindings`). - bool? handled = InvokeKeyBindings (keyEvent, scope); + bool? handled = InvokeCommands (key, scope); - if (handled is { } && (bool)handled) + if (handled is true) { // Stop processing if any key binding handled the key. // DO NOT stop processing if there are no matching key bindings or none of the key bindings handled the key - return true; + return handled; } - if (Margin is { } && ProcessAdornmentKeyBindings (Margin, keyEvent, scope, ref handled)) + if (Margin is { } && InvokeCommandsBoundToKeyOnAdornment (Margin, key, scope, ref handled)) { return true; } - if (Padding is { } && ProcessAdornmentKeyBindings (Padding, keyEvent, scope, ref handled)) + if (Padding is { } && InvokeCommandsBoundToKeyOnAdornment (Padding, key, scope, ref handled)) { return true; } - if (Border is { } && ProcessAdornmentKeyBindings (Border, keyEvent, scope, ref handled)) + if (Border is { } && InvokeCommandsBoundToKeyOnAdornment (Border, key, scope, ref handled)) { return true; } - if (ProcessSubViewKeyBindings (keyEvent, scope, ref handled)) + if (InvokeCommandsBoundToKeyOnSubviews (key, scope, ref handled)) { return true; } @@ -566,9 +558,9 @@ public partial class View // Keyboard APIs return handled; } - private bool ProcessAdornmentKeyBindings (Adornment adornment, Key keyEvent, KeyBindingScope scope, ref bool? handled) + private static bool InvokeCommandsBoundToKeyOnAdornment (Adornment adornment, Key key, KeyBindingScope scope, ref bool? handled) { - bool? adornmentHandled = adornment.OnInvokingKeyBindings (keyEvent, scope); + bool? adornmentHandled = adornment.InvokeCommandsBoundToKey (key); if (adornmentHandled is true) { @@ -582,7 +574,7 @@ public partial class View // Keyboard APIs foreach (View subview in adornment.Subviews) { - bool? subViewHandled = subview.OnInvokingKeyBindings (keyEvent, scope); + bool? subViewHandled = subview.InvokeCommandsBoundToKey (key); if (subViewHandled is { }) { @@ -598,7 +590,7 @@ public partial class View // Keyboard APIs return false; } - private bool ProcessSubViewKeyBindings (Key keyEvent, KeyBindingScope scope, ref bool? handled, bool invoke = true) + private bool InvokeCommandsBoundToKeyOnSubviews (Key key, KeyBindingScope scope, ref bool? handled, bool invoke = true) { // Now, process any key bindings in the subviews that are tagged to KeyBindingScope.HotKey. foreach (View subview in Subviews) @@ -608,7 +600,7 @@ public partial class View // Keyboard APIs continue; } - if (subview.KeyBindings.TryGet (keyEvent, scope, out KeyBinding binding)) + if (subview.KeyBindings.TryGet (key, scope, out KeyBinding binding)) { if (binding.Scope == KeyBindingScope.Focused && !subview.HasFocus) { @@ -620,7 +612,7 @@ public partial class View // Keyboard APIs return true; } - bool? subViewHandled = subview.OnInvokingKeyBindings (keyEvent, scope); + bool? subViewHandled = subview.InvokeCommandsBoundToKey (key); if (subViewHandled is { }) { @@ -633,7 +625,7 @@ public partial class View // Keyboard APIs } } - bool recurse = subview.ProcessSubViewKeyBindings (keyEvent, scope, ref handled, invoke); + bool recurse = subview.InvokeCommandsBoundToKeyOnSubviews (key, scope, ref handled, invoke); if (recurse || (handled is { } && (bool)handled)) { @@ -653,7 +645,7 @@ public partial class View // Keyboard APIs /// The key to test. /// Returns the view the key is bound to. /// - public bool IsHotKeyKeyBound (Key key, out View? boundView) + public bool IsHotKeyBound (Key key, out View? boundView) { // recurse through the subviews to find the views that has the key bound boundView = null; @@ -667,7 +659,7 @@ public partial class View // Keyboard APIs return true; } - if (subview.IsHotKeyKeyBound (key, out boundView)) + if (subview.IsHotKeyBound (key, out boundView)) { return true; } @@ -677,26 +669,20 @@ public partial class View // Keyboard APIs } /// - /// Raised when a key is pressed that may be mapped to a key binding. Set to true to - /// stop the key from being processed by other views. - /// - public event EventHandler? InvokingKeyBindings; - - /// - /// Invokes any binding that is registered on this and matches the + /// Invokes the Commands bound to . /// See for an overview of Terminal.Gui keyboard APIs. /// /// The key event passed. /// The scope. /// - /// if no command was invoked; input proessing should continue. - /// if at least one command was invoked and was not handled (or cancelled); input proessing should continue. - /// if at least one command was invoked and handled (or cancelled); input proessing should stop. + /// if no command was invoked; input processing should continue. + /// if at least one command was invoked and was not handled (or cancelled); input processing + /// should continue. + /// if at least one command was invoked and handled (or cancelled); input processing should + /// stop. /// - protected bool? InvokeKeyBindings (Key key, KeyBindingScope scope) + protected bool? InvokeCommands (Key key, KeyBindingScope scope) { - bool? toReturn = null; - if (!KeyBindings.TryGet (key, scope, out KeyBinding binding)) { return null; @@ -704,49 +690,22 @@ public partial class View // Keyboard APIs #if DEBUG - // TODO: Determine if App scope bindings should be fired first or last (currently last). if (Application.KeyBindings.TryGet (key, KeyBindingScope.Focused | KeyBindingScope.HotKey, out KeyBinding b)) { - //var boundView = views [0]; - //var commandBinding = boundView.KeyBindings.Get (key); Debug.WriteLine ( - $"WARNING: InvokeKeyBindings ({key}) - An Application scope binding exists for this key. The registered view will not invoke Command."); //{commandBinding.Commands [0]}: {boundView}."); + $"WARNING: InvokeKeyBindings ({key}) - An Application scope binding exists for this key. The registered view will not invoke Command."); } // TODO: This is a "prototype" debug check. It may be too annoying vs. useful. // Scour the bindings up our View hierarchy // to ensure that the key is not already bound to a different set of commands. - if (SuperView?.IsHotKeyKeyBound (key, out View? previouslyBoundView) ?? false) + if (SuperView?.IsHotKeyBound (key, out View? previouslyBoundView) ?? false) { Debug.WriteLine ($"WARNING: InvokeKeyBindings ({key}) - A subview or peer has bound this Key and will not see it: {previouslyBoundView}."); } #endif return InvokeCommands (binding.Commands, key, binding); - - foreach (Command command in binding.Commands) - { - if (!CommandImplementations.ContainsKey (command)) - { - throw new NotSupportedException ( - @$"A KeyBinding was set up for the command {command} ({key}) but that command is not supported by this View ({GetType ().Name})" - ); - } - - // each command has its own return value - bool? thisReturn = InvokeCommand (command, key, binding); - - // if we haven't got anything yet, the current command result should be used - toReturn ??= thisReturn; - - // if ever see a true then that's what we will return - if (thisReturn ?? false) - { - toReturn = true; - } - } - - return toReturn; } #endregion Key Bindings diff --git a/Terminal.Gui/View/View.Layout.cs b/Terminal.Gui/View/View.Layout.cs index 2d8fdfeda..318b5c993 100644 --- a/Terminal.Gui/View/View.Layout.cs +++ b/Terminal.Gui/View/View.Layout.cs @@ -28,7 +28,6 @@ public partial class View // Layout APIs /// The target y location. /// The new x location that will ensure will be fully visible. /// The new y location that will ensure will be fully visible. - /// The new top most statusBar /// /// Either (if does not have a Super View) or /// 's SuperView. This can be used to ensure LayoutSubviews is called on the correct View. diff --git a/Terminal.Gui/View/View.Mouse.cs b/Terminal.Gui/View/View.Mouse.cs index 2fc180ece..a76de77b3 100644 --- a/Terminal.Gui/View/View.Mouse.cs +++ b/Terminal.Gui/View/View.Mouse.cs @@ -11,7 +11,7 @@ public partial class View // Mouse APIs private ColorScheme? _savedNonHoverColorScheme; /// - /// INTERNAL Called by when the mouse moves over the View's . + /// INTERNAL Called by when the mouse moves over the View's . /// will /// be raised when the mouse is no longer over the . If another View occludes this View, the /// that View will also receive MouseEnter/Leave events. @@ -126,7 +126,7 @@ public partial class View // Mouse APIs public event EventHandler? MouseEnter; /// - /// INTERNAL Called by when the mouse leaves , or is occluded + /// INTERNAL Called by when the mouse leaves , or is occluded /// by another non-SubView. /// /// @@ -196,16 +196,15 @@ public partial class View // Mouse APIs #region Low Level Mouse Events - /// Event fired when a mouse event occurs. - /// - /// - /// The coordinates are relative to . - /// - /// - public event EventHandler? MouseEvent; + /// 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 bool WantMousePositionReports { get; set; } /// - /// Processes a . This method is called by when a mouse + /// Processes a new . This method is called by when a mouse /// event occurs. /// /// @@ -213,20 +212,20 @@ public partial class View // Mouse APIs /// A view must be both enabled and visible to receive mouse events. /// /// - /// This method calls to process the event. If the event is not handled, and one of the - /// mouse buttons was clicked, it calls to process the click. + /// This method raises /; if not handled, and one of the + /// mouse buttons was clicked, the / event will be raised /// /// /// See for more information. /// /// - /// If is , the event - /// will be invoked repeatedly while the button is pressed. + /// If is , the / event + /// will be raised on any new mouse event where indicates a button is pressed. /// /// /// /// if the event was handled, otherwise. - public bool? NewMouseEvent (MouseEvent mouseEvent) + public bool? NewMouseEvent (MouseEventArgs mouseEvent) { // Pre-conditions if (!Enabled) @@ -246,17 +245,13 @@ public partial class View // Mouse APIs } // Cancellable event - if (OnMouseEvent (mouseEvent)) + if (RaiseMouseEvent (mouseEvent) || mouseEvent.Handled) { - // Technically mouseEvent.Handled should already be true if implementers of OnMouseEvent - // follow the rules. But we'll update it just in case. - return mouseEvent.Handled = true; + return true; } - // BUGBUG: MouseEvent should be fired from here. Fix this in https://github.com/gui-cs/Terminal.Gui/issues/3029 - // Post-Conditions - if (HighlightStyle != HighlightStyle.None || (WantContinuousButtonPressed && WantMousePositionReports)) + if (HighlightStyle != HighlightStyle.None || WantContinuousButtonPressed) { if (WhenGrabbedHandlePressed (mouseEvent)) { @@ -274,35 +269,33 @@ public partial class View // Mouse APIs } } - if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button2Clicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button4Clicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button1DoubleClicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button2DoubleClicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button3DoubleClicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button4DoubleClicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button1TripleClicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button2TripleClicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button3TripleClicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button4TripleClicked) - ) + if (mouseEvent.IsSingleDoubleOrTripleClicked) { // If it's a click, and we didn't handle it, then we need to generate a click event // We get here if the view did not handle the mouse event via OnMouseEvent/MouseEvent and // it did not handle the press/release/clicked events via HandlePress/HandleRelease/HandleClicked - return OnMouseClick (new (mouseEvent)); + return RaiseMouseClickEvent (mouseEvent); } return false; } - /// Gets or sets whether the wants continuous button pressed events. - public virtual bool WantContinuousButtonPressed { get; set; } + /// + /// Raises the / event. + /// + /// + /// , if the event was handled, otherwise. + public bool RaiseMouseEvent (MouseEventArgs mouseEvent) + { + if (OnMouseEvent (mouseEvent) || mouseEvent.Handled == true) + { + return true; + } - /// Gets or sets whether the wants mouse position reports. - /// if mouse position reports are wanted; otherwise, . - public virtual bool WantMousePositionReports { get; set; } + MouseEvent?.Invoke (this, mouseEvent); + + return mouseEvent.Handled; + } /// Called when a mouse event occurs within the view's . /// @@ -312,44 +305,36 @@ public partial class View // Mouse APIs /// /// /// , if the event was handled, otherwise. - protected internal virtual bool OnMouseEvent (MouseEvent mouseEvent) + protected virtual bool OnMouseEvent (MouseEventArgs mouseEvent) { - var args = new MouseEventEventArgs (mouseEvent); - - MouseEvent?.Invoke (this, args); - - return args.Handled; + return false; } + /// Raised when a mouse event occurs. + /// + /// + /// The coordinates are relative to . + /// + /// + public event EventHandler? MouseEvent; + #endregion Low Level Mouse Events #region Mouse Click Events - /// Event fired when a mouse click occurs. - /// + /// Raises the / event. /// /// - /// Fired when the mouse is either clicked or double-clicked. Check - /// to see which button was clicked. + /// Called when the mouse is either clicked or double-clicked. /// /// - /// The coordinates are relative to . - /// - /// - public event EventHandler? MouseClick; - - /// Invokes the MouseClick event. - /// - /// - /// Called when the mouse is either clicked or double-clicked. Check - /// to see which button was clicked. + /// If is , will be invoked on every mouse event where + /// the mouse button is pressed. /// /// /// , if the event was handled, otherwise. - protected bool OnMouseClick (MouseEventEventArgs args) + protected bool RaiseMouseClickEvent (MouseEventArgs args) { - // BUGBUG: This should be named NewMouseClickEvent. Fix this in https://github.com/gui-cs/Terminal.Gui/issues/3029 - // Pre-conditions if (!Enabled) { @@ -359,7 +344,10 @@ public partial class View // Mouse APIs // Cancellable event - // BUGBUG: There should be a call to a protected virtual OnMouseClick here. Fix this in https://github.com/gui-cs/Terminal.Gui/issues/3029 + if (OnMouseClick (args) || args.Handled) + { + return args.Handled; + } MouseClick?.Invoke (this, args); @@ -372,11 +360,39 @@ public partial class View // Mouse APIs // Always invoke Select command on MouseClick // By default, this will raise Selecting/OnSelecting - Subclasses can override this via AddCommand (Command.Select ...). - args.Handled = InvokeCommand (Command.Select, ctx: new (Command.Select, key: null, data: args.MouseEvent)) == true; + args.Handled = InvokeCommand (Command.Select, ctx: new (Command.Select, key: null, data: args)) == true; return args.Handled; } + /// + /// Called when a mouse click occurs. Check to see which button was clicked. + /// + /// + /// + /// Called when the mouse is either clicked or double-clicked. + /// + /// + /// If is , will be called on every mouse event where + /// the mouse button is pressed. + /// + /// + /// + /// , if the event was handled, otherwise. + protected virtual bool OnMouseClick (MouseEventArgs args) { return false; } + + /// Raised when a mouse click occurs. + /// + /// + /// Raised when the mouse is either clicked or double-clicked. + /// + /// + /// If is , will be raised on every mouse event where + /// the mouse button is pressed. + /// + /// + public event EventHandler? MouseClick; + /// /// INTERNAL For cases where the view is grabbed and the mouse is clicked, this method handles the click event (typically /// when or are set). @@ -386,13 +402,11 @@ public partial class View // Mouse APIs /// /// /// , if the event was handled, otherwise. - internal bool WhenGrabbedHandleClicked (MouseEvent mouseEvent) + internal bool WhenGrabbedHandleClicked (MouseEventArgs mouseEvent) { - if (Application.MouseGrabView == this - && (mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button2Clicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked) - || mouseEvent.Flags.HasFlag (MouseFlags.Button4Clicked))) + mouseEvent.Handled = false; + + if (Application.MouseGrabView == this && mouseEvent.IsSingleClicked) { // We're grabbed. Clicked event comes after the last Release. This is our signal to ungrab Application.UngrabMouse (); @@ -405,7 +419,7 @@ public partial class View // Mouse APIs // If mouse is still in bounds, generate a click if (!WantMousePositionReports && Viewport.Contains (mouseEvent.Position)) { - return OnMouseClick (new (mouseEvent)); + return RaiseMouseClickEvent (mouseEvent); } return mouseEvent.Handled = true; @@ -423,12 +437,11 @@ public partial class View // Mouse APIs /// /// /// , if the event was handled, otherwise. - internal bool WhenGrabbedHandleReleased (MouseEvent mouseEvent) + internal bool WhenGrabbedHandleReleased (MouseEventArgs mouseEvent) { - if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Released) - || mouseEvent.Flags.HasFlag (MouseFlags.Button2Released) - || mouseEvent.Flags.HasFlag (MouseFlags.Button3Released) - || mouseEvent.Flags.HasFlag (MouseFlags.Button4Released)) + mouseEvent.Handled = false; + + if (mouseEvent.IsReleased) { if (Application.MouseGrabView == this) { @@ -452,12 +465,11 @@ public partial class View // Mouse APIs /// /// /// , if the event was handled, otherwise. - private bool WhenGrabbedHandlePressed (MouseEvent mouseEvent) + private bool WhenGrabbedHandlePressed (MouseEventArgs mouseEvent) { - if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed) - || mouseEvent.Flags.HasFlag (MouseFlags.Button2Pressed) - || mouseEvent.Flags.HasFlag (MouseFlags.Button3Pressed) - || mouseEvent.Flags.HasFlag (MouseFlags.Button4Pressed)) + mouseEvent.Handled = false; + + if (mouseEvent.IsPressed) { // The first time we get pressed event, grab the mouse and set focus if (Application.MouseGrabView != this) @@ -493,8 +505,7 @@ public partial class View // Mouse APIs if (WantContinuousButtonPressed && Application.MouseGrabView == this) { - // If this is not the first pressed event, generate a click - return OnMouseClick (new (mouseEvent)); + return RaiseMouseClickEvent (mouseEvent); } return mouseEvent.Handled = true; diff --git a/Terminal.Gui/Views/Bar.cs b/Terminal.Gui/Views/Bar.cs index ddaa44436..1511cd68a 100644 --- a/Terminal.Gui/Views/Bar.cs +++ b/Terminal.Gui/Views/Bar.cs @@ -45,27 +45,27 @@ public class Bar : View, IOrientation, IDesignable } } - private void OnMouseEvent (object? sender, MouseEventEventArgs e) + private void OnMouseEvent (object? sender, MouseEventArgs e) { NavigationDirection direction = NavigationDirection.Backward; - if (e.MouseEvent.Flags == MouseFlags.WheeledDown) + if (e.Flags == MouseFlags.WheeledDown) { e.Handled = true; } - if (e.MouseEvent.Flags == MouseFlags.WheeledUp) + if (e.Flags == MouseFlags.WheeledUp) { direction = NavigationDirection.Forward; e.Handled = true; } - if (e.MouseEvent.Flags == MouseFlags.WheeledRight) + if (e.Flags == MouseFlags.WheeledRight) { e.Handled = true; } - if (e.MouseEvent.Flags == MouseFlags.WheeledLeft) + if (e.Flags == MouseFlags.WheeledLeft) { direction = NavigationDirection.Forward; e.Handled = true; diff --git a/Terminal.Gui/Views/Button.cs b/Terminal.Gui/Views/Button.cs index e29043ed9..f642f23d9 100644 --- a/Terminal.Gui/Views/Button.cs +++ b/Terminal.Gui/Views/Button.cs @@ -125,7 +125,7 @@ public class Button : View, IDesignable } } - private void Button_MouseClick (object sender, MouseEventEventArgs e) + private void Button_MouseClick (object sender, MouseEventArgs e) { if (e.Handled) { diff --git a/Terminal.Gui/Views/ColorBar.cs b/Terminal.Gui/Views/ColorBar.cs index 066ad72b2..581606d17 100644 --- a/Terminal.Gui/Views/ColorBar.cs +++ b/Terminal.Gui/Views/ColorBar.cs @@ -110,7 +110,7 @@ internal abstract class ColorBar : View, IColorBar public event EventHandler>? ValueChanged; /// - protected internal override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed)) { @@ -123,10 +123,9 @@ internal abstract class ColorBar : View, IColorBar mouseEvent.Handled = true; SetFocus (); - return true; } - return base.OnMouseEvent (mouseEvent); + return mouseEvent.Handled; } /// diff --git a/Terminal.Gui/Views/ColorPicker.16.cs b/Terminal.Gui/Views/ColorPicker.16.cs index c0ae78717..c1cb72cc2 100644 --- a/Terminal.Gui/Views/ColorPicker.16.cs +++ b/Terminal.Gui/Views/ColorPicker.16.cs @@ -181,11 +181,11 @@ public class ColorPicker16 : View // TODO: Decouple Cursor from SelectedColor so that mouse press-and-hold can show the color under the cursor. - private void ColorPicker_MouseClick (object sender, MouseEventEventArgs me) + private void ColorPicker_MouseClick (object sender, MouseEventArgs me) { // if (CanFocus) { - Cursor = new (me.MouseEvent.Position.X / _boxWidth, me.MouseEvent.Position.Y / _boxHeight); + Cursor = new (me.Position.X / _boxWidth, me.Position.Y / _boxHeight); SetFocus (); me.Handled = true; } diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 3f92174c8..996056068 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -253,7 +253,7 @@ public class ComboBox : View, IDesignable public event EventHandler Expanded; /// - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { if (me.Position.X == Viewport.Right - 1 && me.Position.Y == Viewport.Top @@ -836,14 +836,15 @@ public class ComboBox : View, IDesignable set => _hideDropdownListOnClick = WantContinuousButtonPressed = value; } - // BUGBUG: OnMouseEvent is internal! - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { - var res = false; bool isMousePositionValid = IsMousePositionValid (me); + var res = false; + if (isMousePositionValid) { + // We're derived from ListView and it overrides OnMouseEvent, so we need to call it res = base.OnMouseEvent (me); } @@ -984,7 +985,7 @@ public class ComboBox : View, IDesignable return res; } - private bool IsMousePositionValid (MouseEvent me) + private bool IsMousePositionValid (MouseEventArgs me) { if (me.Position.X >= 0 && me.Position.X < Frame.Width && me.Position.Y >= 0 && me.Position.Y < Frame.Height) { diff --git a/Terminal.Gui/Views/DateField.cs b/Terminal.Gui/Views/DateField.cs index 2e07f0afa..9490a7b28 100644 --- a/Terminal.Gui/Views/DateField.cs +++ b/Terminal.Gui/Views/DateField.cs @@ -114,16 +114,19 @@ public class DateField : TextField } /// - protected internal override bool OnMouseEvent (MouseEvent ev) + protected override bool OnMouseEvent (MouseEventArgs ev) { - bool result = base.OnMouseEvent (ev); + if (base.OnMouseEvent (ev) || ev.Handled) + { + return true; + } - if (result && SelectedLength == 0 && ev.Flags.HasFlag (MouseFlags.Button1Pressed)) + if (SelectedLength == 0 && ev.Flags.HasFlag (MouseFlags.Button1Pressed)) { AdjCursorPosition (ev.Position.X); } - return result; + return ev.Handled; } /// Event firing method for the event. @@ -131,7 +134,7 @@ public class DateField : TextField public virtual void OnDateChanged (DateTimeEventArgs args) { DateChanged?.Invoke (this, args); } /// - public override bool OnProcessKeyDown (Key a) + protected override bool OnKeyDownNotHandled (Key a) { // Ignore non-numeric characters. if (a >= Key.D0 && a <= Key.D9) @@ -169,7 +172,7 @@ public class DateField : TextField CursorPosition = newPoint; } - while (Text [CursorPosition].ToString () == _separator) + while (CursorPosition < Text.GetColumns () - 1 && Text [CursorPosition].ToString () == _separator) { if (increment) { diff --git a/Terminal.Gui/Views/FileDialog.cs b/Terminal.Gui/Views/FileDialog.cs index d0022fea0..2ded19418 100644 --- a/Terminal.Gui/Views/FileDialog.cs +++ b/Terminal.Gui/Views/FileDialog.cs @@ -233,7 +233,7 @@ public class FileDialog : Dialog _tbPath.TextChanged += (s, e) => PathChanged (); _tableView.CellActivated += CellActivate; - _tableView.KeyUp += (s, k) => k.Handled = TableView_KeyUp (k); + _tableView.KeyDown += (s, k) => k.Handled = TableView_KeyUp (k); _tableView.SelectedCellChanged += TableView_SelectedCellChanged; _tableView.KeyBindings.ReplaceCommands (Key.Home, Command.Start); @@ -670,11 +670,11 @@ public class FileDialog : Dialog FinishAccept (); } - private void AcceptIf (Key keyEvent, KeyCode isKey) + private void AcceptIf (Key key, KeyCode isKey) { - if (!keyEvent.Handled && keyEvent.KeyCode == isKey) + if (!key.Handled && key.KeyCode == isKey) { - keyEvent.Handled = true; + key.Handled = true; // User hit Enter in text box so probably wants the // contents of the text box as their selection not @@ -1007,18 +1007,18 @@ public class FileDialog : Dialog } } - private void OnTableViewMouseClick (object sender, MouseEventEventArgs e) + private void OnTableViewMouseClick (object sender, MouseEventArgs e) { - Point? clickedCell = _tableView.ScreenToCell (e.MouseEvent.Position.X, e.MouseEvent.Position.Y, out int? clickedCol); + Point? clickedCell = _tableView.ScreenToCell (e.Position.X, e.Position.Y, out int? clickedCol); if (clickedCol is { }) { - if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) + if (e.Flags.HasFlag (MouseFlags.Button1Clicked)) { // left click in a header SortColumn (clickedCol.Value); } - else if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked)) + else if (e.Flags.HasFlag (MouseFlags.Button3Clicked)) { // right click in a header ShowHeaderContextMenu (clickedCol.Value, e); @@ -1026,7 +1026,7 @@ public class FileDialog : Dialog } else { - if (clickedCell is { } && e.MouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked)) + if (clickedCell is { } && e.Flags.HasFlag (MouseFlags.Button3Clicked)) { // right click in rest of table ShowCellContextMenu (clickedCell, e); @@ -1198,7 +1198,7 @@ public class FileDialog : Dialog private FileSystemInfoStats RowToStats (int rowIndex) { return State?.Children [rowIndex]; } - private void ShowCellContextMenu (Point? clickedCell, MouseEventEventArgs e) + private void ShowCellContextMenu (Point? clickedCell, MouseEventArgs e) { if (clickedCell is null) { @@ -1207,7 +1207,7 @@ public class FileDialog : Dialog var contextMenu = new ContextMenu { - Position = new Point (e.MouseEvent.Position.X + 1, e.MouseEvent.Position.Y + 1) + Position = new Point (e.Position.X + 1, e.Position.Y + 1) }; var menuItems = new MenuBarItem ( @@ -1222,13 +1222,13 @@ public class FileDialog : Dialog contextMenu.Show (menuItems); } - private void ShowHeaderContextMenu (int clickedCol, MouseEventEventArgs e) + private void ShowHeaderContextMenu (int clickedCol, MouseEventArgs e) { string sort = GetProposedNewSortOrder (clickedCol, out bool isAsc); var contextMenu = new ContextMenu { - Position = new Point (e.MouseEvent.Position.X + 1, e.MouseEvent.Position.Y + 1) + Position = new Point (e.Position.X + 1, e.Position.Y + 1) }; var menuItems = new MenuBarItem ( diff --git a/Terminal.Gui/Views/FrameView.cs b/Terminal.Gui/Views/FrameView.cs index f8b1ffc8b..de2f86215 100644 --- a/Terminal.Gui/Views/FrameView.cs +++ b/Terminal.Gui/Views/FrameView.cs @@ -22,7 +22,7 @@ public class FrameView : View MouseClick += FrameView_MouseClick; } - private void FrameView_MouseClick (object sender, MouseEventEventArgs e) + private void FrameView_MouseClick (object sender, MouseEventArgs e) { // base sets focus on HotKey e.Handled = InvokeCommand (Command.HotKey, ctx: new (Command.HotKey, key: null, data: this)) == true; diff --git a/Terminal.Gui/Views/HexView.cs b/Terminal.Gui/Views/HexView.cs index f439499cb..8c614062b 100644 --- a/Terminal.Gui/Views/HexView.cs +++ b/Terminal.Gui/Views/HexView.cs @@ -327,7 +327,7 @@ public class HexView : View, IDesignable public void DiscardEdits () { _edits = new (); } /// - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { if (_source is null) { @@ -591,7 +591,7 @@ public class HexView : View, IDesignable public event EventHandler? PositionChanged; /// - public override bool OnProcessKeyDown (Key keyEvent) + protected override bool OnKeyDownNotHandled (Key keyEvent) { if (!AllowEdits || _source is null) { diff --git a/Terminal.Gui/Views/Label.cs b/Terminal.Gui/Views/Label.cs index 3a76a8a71..07eca7983 100644 --- a/Terminal.Gui/Views/Label.cs +++ b/Terminal.Gui/Views/Label.cs @@ -32,7 +32,7 @@ public class Label : View, IDesignable } // TODO: base raises Select, but we want to raise HotKey. This can be simplified? - private void Label_MouseClick (object sender, MouseEventEventArgs e) + private void Label_MouseClick (object sender, MouseEventArgs e) { if (!CanFocus) { diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index 0c54aa261..925bc203c 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -147,7 +147,7 @@ public class ListView : View, IDesignable if (OnOpenSelectedItem ()) { - return true; + return true; } return false; @@ -189,6 +189,7 @@ public class ListView : View, IDesignable return !SetFocus (); }); + AddCommand (Command.SelectAll, (ctx) => MarkAll((bool)ctx.KeyBinding?.Context!)); // Default keybindings for all ListViews KeyBindings.Add (Key.CursorUp, Command.Up); @@ -205,6 +206,13 @@ public class ListView : View, IDesignable KeyBindings.Add (Key.Home, Command.Start); KeyBindings.Add (Key.End, Command.End); + + // Key.Space is already bound to Command.Select; this gives us select then move down + KeyBindings.Add (Key.Space.WithShift, [Command.Select, Command.Down]); + + // Use the form of Add that lets us pass context to the handler + KeyBindings.Add (Key.A.WithCtrl, new KeyBinding ([Command.SelectAll], KeyBindingScope.Focused, true)); + KeyBindings.Add (Key.U.WithCtrl, new KeyBinding ([Command.SelectAll], KeyBindingScope.Focused, false)); } /// Gets or sets whether this allows items to be marked. @@ -370,6 +378,31 @@ public class ListView : View, IDesignable } } + /// + /// If and are both , + /// marks all items. + /// + /// marks all items; otherwise unmarks all items. + /// if marking was successful. + public bool MarkAll (bool mark) + { + if (!_allowsMarking) + { + return false; + } + + if (AllowsMultipleSelection) + { + for (var i = 0; i < Source.Count; i++) + { + Source.SetMark (i, mark); + } + return true; + } + + return false; + } + /// /// If and are both , /// unmarks all marked items other than . @@ -439,7 +472,7 @@ public class ListView : View, IDesignable } /// - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) && !me.Flags.HasFlag (MouseFlags.Button1DoubleClicked) @@ -784,7 +817,6 @@ public class ListView : View, IDesignable } } - // TODO: This should be cancelable /// Invokes the event if it is defined. /// if the event was fired. public bool OnOpenSelectedItem () @@ -803,8 +835,28 @@ public class ListView : View, IDesignable } /// - public override bool OnProcessKeyDown (Key a) + protected override bool OnKeyDown (Key a) { + // If marking is enabled and the user presses the space key don't let CollectionNavigator + // at it + if (AllowsMarking) + { + var keys = KeyBindings.GetKeysFromCommands (Command.Select); + + if (keys.Contains (a)) + { + return false; + } + + keys = KeyBindings.GetKeysFromCommands ([Command.Select, Command.Down]); + + if (keys.Contains (a)) + { + return false; + } + + } + // Enable user to find & select an item by typing text if (CollectionNavigatorBase.IsCompatibleKey (a)) { diff --git a/Terminal.Gui/Views/Menu/Menu.cs b/Terminal.Gui/Views/Menu/Menu.cs index 1744251f3..a8c50755b 100644 --- a/Terminal.Gui/Views/Menu/Menu.cs +++ b/Terminal.Gui/Views/Menu/Menu.cs @@ -1,5 +1,7 @@ #nullable enable +using static System.Formats.Asn1.AsnWriter; + namespace Terminal.Gui; /// @@ -305,19 +307,11 @@ internal sealed class Menu : View return true; } - /// - public override bool? OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) + /// + protected override bool OnKeyDownNotHandled (Key keyEvent) { - bool? handled = base.OnInvokingKeyBindings (keyEvent, scope); - - if (handled is { } && (bool)handled) - { - return true; - } - - // TODO: Determine if there's a cleaner way to handle this. - // This supports the case where the menu bar is a context menu - return _host.OnInvokingKeyBindings (keyEvent, scope); + // We didn't handle the key, pass it on to host + return _host.InvokeCommandsBoundToKey (keyEvent) == true; } private void Current_TerminalResized (object? sender, SizeChangedEventArgs e) @@ -343,7 +337,7 @@ internal sealed class Menu : View } } - private void Application_RootMouseEvent (object? sender, MouseEvent a) + private void Application_RootMouseEvent (object? sender, MouseEventArgs a) { if (a.View is { } and (MenuBar or not Menu)) { @@ -359,7 +353,7 @@ internal sealed class Menu : View Point boundsPoint = view.ScreenToViewport (new (a.Position.X, a.Position.Y)); - var me = new MouseEvent + var me = new MouseEventArgs { Position = boundsPoint, Flags = a.Flags, @@ -814,7 +808,7 @@ internal sealed class Menu : View _host.SetNeedsDisplay (); } - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { if (!_host._handled && !_host.HandleGrabView (me, this)) { diff --git a/Terminal.Gui/Views/Menu/MenuBar.cs b/Terminal.Gui/Views/Menu/MenuBar.cs index 731edc11c..a15d1e463 100644 --- a/Terminal.Gui/Views/Menu/MenuBar.cs +++ b/Terminal.Gui/Views/Menu/MenuBar.cs @@ -137,7 +137,7 @@ public class MenuBar : View, IDesignable }); AddCommand (Command.Select, ctx => { - if (ctx.Data is MouseEvent) + if (ctx.Data is MouseEventArgs) { // HACK: Work around the fact that View.MouseClick always invokes Select return false; @@ -1400,7 +1400,7 @@ public class MenuBar : View, IDesignable } /// - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { if (!_handled && !HandleGrabView (me, this)) { @@ -1513,7 +1513,7 @@ public class MenuBar : View, IDesignable internal bool _isContextMenuLoading; private MenuBarItem [] _menus = []; - internal bool HandleGrabView (MouseEvent me, View current) + internal bool HandleGrabView (MouseEventArgs me, View current) { if (Application.MouseGrabView is { }) { @@ -1541,7 +1541,7 @@ public class MenuBar : View, IDesignable Application.UngrabMouse (); View v = me.View; Application.GrabMouse (v); - MouseEvent nme; + MouseEventArgs nme; if (me.Position.Y > -1) { diff --git a/Terminal.Gui/Views/RadioGroup.cs b/Terminal.Gui/Views/RadioGroup.cs index 5cfd9f72b..f929d0ce5 100644 --- a/Terminal.Gui/Views/RadioGroup.cs +++ b/Terminal.Gui/Views/RadioGroup.cs @@ -220,12 +220,12 @@ public class RadioGroup : View, IDesignable, IOrientation /// public bool DoubleClickAccepts { get; set; } = true; - private void RadioGroup_MouseClick (object? sender, MouseEventEventArgs e) + private void RadioGroup_MouseClick (object? sender, MouseEventArgs e) { - if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) + if (e.Flags.HasFlag (MouseFlags.Button1Clicked)) { - int viewportX = e.MouseEvent.Position.X; - int viewportY = e.MouseEvent.Position.Y; + int viewportX = e.Position.X; + int viewportY = e.Position.Y; int pos = Orientation == Orientation.Horizontal ? viewportX : viewportY; @@ -249,7 +249,7 @@ public class RadioGroup : View, IDesignable, IOrientation return; } - if (DoubleClickAccepts && e.MouseEvent.Flags.HasFlag (MouseFlags.Button1DoubleClicked)) + if (DoubleClickAccepts && e.Flags.HasFlag (MouseFlags.Button1DoubleClicked)) { // NOTE: Drivers ALWAYS generate a Button1Clicked event before Button1DoubleClicked // NOTE: So, we've already selected an item. diff --git a/Terminal.Gui/Views/ScrollBarView.cs b/Terminal.Gui/Views/ScrollBarView.cs index ce7bd62eb..f6e8da296 100644 --- a/Terminal.Gui/Views/ScrollBarView.cs +++ b/Terminal.Gui/Views/ScrollBarView.cs @@ -270,7 +270,7 @@ public class ScrollBarView : View public event EventHandler ChangedPosition; /// - protected internal override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { if (mouseEvent.Flags != MouseFlags.Button1Pressed && mouseEvent.Flags != MouseFlags.Button1DoubleClicked @@ -777,16 +777,16 @@ public class ScrollBarView : View // } //} - private void ContentBottomRightCorner_MouseClick (object sender, MouseEventEventArgs me) + private void ContentBottomRightCorner_MouseClick (object sender, MouseEventArgs me) { - if (me.MouseEvent.Flags == MouseFlags.WheeledDown - || me.MouseEvent.Flags == MouseFlags.WheeledUp - || me.MouseEvent.Flags == MouseFlags.WheeledRight - || me.MouseEvent.Flags == MouseFlags.WheeledLeft) + if (me.Flags == MouseFlags.WheeledDown + || me.Flags == MouseFlags.WheeledUp + || me.Flags == MouseFlags.WheeledRight + || me.Flags == MouseFlags.WheeledLeft) { - NewMouseEvent (me.MouseEvent); + NewMouseEvent (me); } - else if (me.MouseEvent.Flags == MouseFlags.Button1Clicked) + else if (me.Flags == MouseFlags.Button1Clicked) { Host.SetFocus (); } diff --git a/Terminal.Gui/Views/ScrollView.cs b/Terminal.Gui/Views/ScrollView.cs index 576973ed6..35d4409e5 100644 --- a/Terminal.Gui/Views/ScrollView.cs +++ b/Terminal.Gui/Views/ScrollView.cs @@ -388,14 +388,14 @@ public class ScrollView : View } /// - public override bool OnKeyDown (Key a) + protected override bool OnKeyDown (Key a) { if (base.OnKeyDown (a)) { return true; } - bool? result = InvokeKeyBindings (a, KeyBindingScope.HotKey | KeyBindingScope.Focused); + bool? result = InvokeCommands (a, KeyBindingScope.HotKey | KeyBindingScope.Focused); if (result is { }) { @@ -406,7 +406,7 @@ public class ScrollView : View } /// - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { if (!Enabled) { @@ -416,19 +416,19 @@ public class ScrollView : View if (me.Flags == MouseFlags.WheeledDown && ShowVerticalScrollIndicator) { - ScrollDown (1); + return ScrollDown (1); } else if (me.Flags == MouseFlags.WheeledUp && ShowVerticalScrollIndicator) { - ScrollUp (1); + return ScrollUp (1); } else if (me.Flags == MouseFlags.WheeledRight && _showHorizontalScrollIndicator) { - ScrollRight (1); + return ScrollRight (1); } else if (me.Flags == MouseFlags.WheeledLeft && ShowVerticalScrollIndicator) { - ScrollLeft (1); + return ScrollLeft (1); } else if (me.Position.X == _vertical.Frame.X && ShowVerticalScrollIndicator) { @@ -443,7 +443,7 @@ public class ScrollView : View Application.UngrabMouse (); } - return base.OnMouseEvent (me); + return me.Handled; } /// diff --git a/Terminal.Gui/Views/Slider.cs b/Terminal.Gui/Views/Slider.cs index 4c331251b..9cbc785d1 100644 --- a/Terminal.Gui/Views/Slider.cs +++ b/Terminal.Gui/Views/Slider.cs @@ -1282,7 +1282,7 @@ public class Slider : View, IOrientation private Point? _moveRenderPosition; /// - protected internal override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { // Note(jmperricone): Maybe we click to focus the cursor, and on next click we set the option. // That will make OptionFocused Event more relevant. @@ -1381,11 +1381,9 @@ public class Slider : View, IOrientation mouseEvent.Handled = true; - // BUGBUG: OnMouseClick is/should be internal. - return OnMouseClick (new (mouseEvent)); } - return false; + return mouseEvent.Handled; Point ClampMovePosition (Point position) { diff --git a/Terminal.Gui/Views/TabMouseEventArgs.cs b/Terminal.Gui/Views/TabMouseEventArgs.cs index 6b91a3531..22a23ad01 100644 --- a/Terminal.Gui/Views/TabMouseEventArgs.cs +++ b/Terminal.Gui/Views/TabMouseEventArgs.cs @@ -6,17 +6,17 @@ public class TabMouseEventArgs : EventArgs /// Creates a new instance of the class. /// that the mouse was over when the event occurred. /// The mouse activity being reported - public TabMouseEventArgs (Tab tab, MouseEvent mouseEvent) + public TabMouseEventArgs (Tab tab, MouseEventArgs mouseEvent) { Tab = tab; MouseEvent = mouseEvent; } /// - /// Gets the actual mouse event. Use to cancel this event and perform custom + /// Gets the actual mouse event. Use to cancel this event and perform custom /// behavior (e.g. show a context menu). /// - public MouseEvent MouseEvent { get; } + public MouseEventArgs MouseEvent { get; } /// Gets the (if any) that the mouse was over when the occurred. /// This will be null if the click is after last tab or before first. diff --git a/Terminal.Gui/Views/TabView.cs b/Terminal.Gui/Views/TabView.cs index 3e63dde53..d605b6fa0 100644 --- a/Terminal.Gui/Views/TabView.cs +++ b/Terminal.Gui/Views/TabView.cs @@ -508,9 +508,9 @@ public class TabView : View return Style.ShowTopLine ? 3 : 2; } - private void Tab_MouseClick (object sender, MouseEventEventArgs e) + private void Tab_MouseClick (object sender, MouseEventArgs e) { - e.Handled = _tabsBar.NewMouseEvent (e.MouseEvent) == true; + e.Handled = _tabsBar.NewMouseEvent (e) == true; } private void UnSetCurrentTabs () @@ -569,15 +569,11 @@ public class TabView : View Add (_rightScrollIndicator, _leftScrollIndicator); } - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { Tab hit = me.View is Tab ? (Tab)me.View : null; - bool isClick = me.Flags.HasFlag (MouseFlags.Button1Clicked) - || me.Flags.HasFlag (MouseFlags.Button2Clicked) - || me.Flags.HasFlag (MouseFlags.Button3Clicked); - - if (isClick) + if (me.IsSingleClicked) { _host.OnTabClicked (new TabMouseEventArgs (hit, me)); @@ -588,9 +584,7 @@ public class TabView : View } } - if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) - && !me.Flags.HasFlag (MouseFlags.Button1DoubleClicked) - && !me.Flags.HasFlag (MouseFlags.Button1TripleClicked)) + if (!me.IsSingleDoubleOrTripleClicked) { return false; } @@ -600,9 +594,7 @@ public class TabView : View SetFocus (); } - if (me.Flags.HasFlag (MouseFlags.Button1Clicked) - || me.Flags.HasFlag (MouseFlags.Button1DoubleClicked) - || me.Flags.HasFlag (MouseFlags.Button1TripleClicked)) + if (me.IsSingleDoubleOrTripleClicked) { var scrollIndicatorHit = 0; diff --git a/Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs b/Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs index 8be294c1a..abbb2c704 100644 --- a/Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs +++ b/Terminal.Gui/Views/TableView/CheckBoxTableSourceWrapper.cs @@ -150,15 +150,15 @@ public abstract class CheckBoxTableSourceWrapperBase : ITableSource tableView.SetNeedsDisplay (); } - private void TableView_MouseClick (object sender, MouseEventEventArgs e) + private void TableView_MouseClick (object sender, MouseEventArgs e) { // we only care about clicks (not movements) - if (!e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) + if (!e.Flags.HasFlag (MouseFlags.Button1Clicked)) { return; } - Point? hit = tableView.ScreenToCell (e.MouseEvent.Position.X, e.MouseEvent.Position.Y, out int? headerIfAny); + Point? hit = tableView.ScreenToCell (e.Position.X, e.Position.Y, out int? headerIfAny); if (headerIfAny.HasValue && headerIfAny.Value == 0) { diff --git a/Terminal.Gui/Views/TableView/TableView.cs b/Terminal.Gui/Views/TableView/TableView.cs index 1717b35d6..a33903d0b 100644 --- a/Terminal.Gui/Views/TableView/TableView.cs +++ b/Terminal.Gui/Views/TableView/TableView.cs @@ -801,7 +801,7 @@ public class TableView : View } /// - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) && !me.Flags.HasFlag (MouseFlags.Button1DoubleClicked) @@ -902,11 +902,11 @@ public class TableView : View if (hit is { }) { - OnCellActivated (new CellActivatedEventArgs (Table, hit.Value.X, hit.Value.Y)); + return OnCellActivated (new CellActivatedEventArgs (Table, hit.Value.X, hit.Value.Y)); } } - return base.OnMouseEvent (me); + return me.Handled; } /// @@ -988,7 +988,7 @@ public class TableView : View } /// - public override bool OnProcessKeyDown (Key keyEvent) + protected override bool OnKeyDown (Key key) { if (TableIsNullOrInvisible ()) { @@ -998,12 +998,14 @@ public class TableView : View if (CollectionNavigator != null && HasFocus && Table.Rows != 0 - && CollectionNavigatorBase.IsCompatibleKey (keyEvent) - && !keyEvent.KeyCode.HasFlag (KeyCode.CtrlMask) - && !keyEvent.KeyCode.HasFlag (KeyCode.AltMask) - && Rune.IsLetterOrDigit ((Rune)keyEvent)) + && key != KeyBindings.GetKeyFromCommands (Command.Accept) + && key != CellActivationKey + && CollectionNavigatorBase.IsCompatibleKey (key) + && !key.KeyCode.HasFlag (KeyCode.CtrlMask) + && !key.KeyCode.HasFlag (KeyCode.AltMask) + && Rune.IsLetterOrDigit ((Rune)key)) { - return CycleToNextTableEntryBeginningWith (keyEvent); + return CycleToNextTableEntryBeginningWith (key); } return false; @@ -1561,7 +1563,7 @@ public class TableView : View /// private TableSelection CreateTableSelection (int x, int y) { return CreateTableSelection (x, y, x, y); } - private bool CycleToNextTableEntryBeginningWith (Key keyEvent) + private bool CycleToNextTableEntryBeginningWith (Key key) { int row = SelectedRow; @@ -1571,7 +1573,7 @@ public class TableView : View return false; } - int match = CollectionNavigator.GetNextMatchingItem (row, (char)keyEvent); + int match = CollectionNavigator.GetNextMatchingItem (row, (char)key); if (match != -1) { @@ -1644,7 +1646,7 @@ public class TableView : View return colStyle is { } ? colStyle.GetRepresentation (value) : value.ToString (); } - private bool HasControlOrAlt (MouseEvent me) { return me.Flags.HasFlag (MouseFlags.ButtonAlt) || me.Flags.HasFlag (MouseFlags.ButtonCtrl); } + private bool HasControlOrAlt (MouseEventArgs me) { return me.Flags.HasFlag (MouseFlags.ButtonAlt) || me.Flags.HasFlag (MouseFlags.ButtonCtrl); } /// /// Returns true if the given indexes a visible column otherwise false. Returns diff --git a/Terminal.Gui/Views/TableView/TreeTableSource.cs b/Terminal.Gui/Views/TableView/TreeTableSource.cs index f2cab6509..c3458b32d 100644 --- a/Terminal.Gui/Views/TableView/TreeTableSource.cs +++ b/Terminal.Gui/Views/TableView/TreeTableSource.cs @@ -166,9 +166,9 @@ public class TreeTableSource : IEnumerableTableSource, IDisposable where T } } - private void Table_MouseClick (object sender, MouseEventEventArgs e) + private void Table_MouseClick (object sender, MouseEventArgs e) { - Point? hit = _tableView.ScreenToCell (e.MouseEvent.Position.X, e.MouseEvent.Position.Y, out int? headerIfAny, out int? offsetX); + Point? hit = _tableView.ScreenToCell (e.Position.X, e.Position.Y, out int? headerIfAny, out int? offsetX); if (hit is null || headerIfAny is { } || !IsInTreeColumn (hit.Value.X, false) || offsetX is null) { diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs index c9d681867..0b08e1f04 100644 --- a/Terminal.Gui/Views/TextField.cs +++ b/Terminal.Gui/Views/TextField.cs @@ -798,16 +798,15 @@ public class TextField : View } /// - protected internal override bool OnMouseEvent (MouseEvent ev) + protected override bool OnMouseEvent (MouseEventArgs ev) { - if (!ev.Flags.HasFlag (MouseFlags.Button1Pressed) + if (ev is { IsPressed: false, IsReleased: false } && !ev.Flags.HasFlag (MouseFlags.ReportMousePosition) - && !ev.Flags.HasFlag (MouseFlags.Button1Released) && !ev.Flags.HasFlag (MouseFlags.Button1DoubleClicked) && !ev.Flags.HasFlag (MouseFlags.Button1TripleClicked) && !ev.Flags.HasFlag (ContextMenu.MouseFlags)) { - return base.OnMouseEvent (ev); + return false; } if (!CanFocus) @@ -1013,18 +1012,6 @@ public class TextField : View _isDrawing = false; } - /// - public override bool? OnInvokingKeyBindings (Key a, KeyBindingScope scope) - { - // Give autocomplete first opportunity to respond to key presses - if (SelectedLength == 0 && Autocomplete.Suggestions.Count > 0 && Autocomplete.ProcessKey (a)) - { - return true; - } - - return base.OnInvokingKeyBindings (a, scope); - } - /// protected override void OnHasFocusChanged (bool newHasFocus, View previousFocusedView, View view) { @@ -1037,25 +1024,20 @@ public class TextField : View // ClearAllSelection (); } - /// TODO: Flush out these docs - /// - /// Processes key presses for the . - /// - /// The control responds to the following keys: - /// - /// - /// Keys Function - /// - /// - /// , - /// Deletes the character before cursor. - /// - /// - /// - /// - /// - /// - public override bool OnProcessKeyDown (Key a) + /// + protected override bool OnKeyDown (Key key) + { + // Give autocomplete first opportunity to respond to key presses + if (SelectedLength == 0 && Autocomplete.Suggestions.Count > 0 && Autocomplete.ProcessKey (key)) + { + return true; + } + + return false; + } + + /// + protected override bool OnKeyDownNotHandled (Key a) { // Remember the cursor position because the new calculated cursor position is needed // to be set BEFORE the TextChanged event is triggered. @@ -1662,7 +1644,7 @@ public class TextField : View return 0; //offB; } - private int PositionCursor (MouseEvent ev) { return PositionCursor (TextModel.GetColFromX (_text, ScrollOffset, ev.Position.X), false); } + private int PositionCursor (MouseEventArgs ev) { return PositionCursor (TextModel.GetColFromX (_text, ScrollOffset, ev.Position.X), false); } private int PositionCursor (int x, bool getX = true) { diff --git a/Terminal.Gui/Views/TextValidateField.cs b/Terminal.Gui/Views/TextValidateField.cs index a6c740d1b..289855c30 100644 --- a/Terminal.Gui/Views/TextValidateField.cs +++ b/Terminal.Gui/Views/TextValidateField.cs @@ -531,7 +531,7 @@ namespace Terminal.Gui } /// - protected internal override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed)) { @@ -597,7 +597,7 @@ namespace Terminal.Gui } /// - public override bool OnProcessKeyDown (Key a) + protected override bool OnKeyDownNotHandled (Key a) { if (_provider is null) { diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs index 674d8328e..132f907a3 100644 --- a/Terminal.Gui/Views/TextView.cs +++ b/Terminal.Gui/Views/TextView.cs @@ -1,10 +1,8 @@ #nullable enable // TextView.cs: multi-line text editing -using System.Diagnostics; using System.Globalization; using System.Runtime.CompilerServices; -using System.Text.Json.Serialization; using Terminal.Gui.Resources; namespace Terminal.Gui; @@ -106,7 +104,7 @@ internal class TextModel public void LoadCells (List cells, Attribute? attribute) { - _lines = Cell.ToCells ((List)cells); + _lines = Cell.ToCells (cells); SetAttributes (attribute); OnLinesLoaded (); } @@ -180,7 +178,7 @@ internal class TextModel { if (_lines.Count > 0 && pos < _lines.Count) { - _lines [pos] = [..runes]; + _lines [pos] = [.. runes]; } else if (_lines.Count == 0 || (_lines.Count > 0 && pos >= _lines.Count)) { @@ -188,8 +186,6 @@ internal class TextModel } } - - public override string ToString () { var sb = new StringBuilder (); @@ -608,8 +604,7 @@ internal class TextModel internal Size GetDisplaySize () { - Size size = Size.Empty; - + var size = Size.Empty; return size; } @@ -799,7 +794,7 @@ internal class TextModel string GetText (List x) { - string txt = Cell.ToString (x); + var txt = Cell.ToString (x); if (!matchCase) { @@ -872,7 +867,7 @@ internal class TextModel for (int i = start.Y; i < linesCount; i++) { List x = _lines [i]; - string txt = Cell.ToString (x); + var txt = Cell.ToString (x); if (!matchCase) { @@ -912,7 +907,7 @@ internal class TextModel for (int i = linesCount; i >= 0; i--) { List x = _lines [i]; - string txt = Cell.ToString (x); + var txt = Cell.ToString (x); if (!matchCase) { @@ -1075,7 +1070,7 @@ internal class TextModel private string ReplaceText (List source, string textToReplace, string matchText, int col) { - string origTxt = Cell.ToString (source); + var origTxt = Cell.ToString (source); (_, int len) = DisplaySize (source, 0, col, false); (_, int len2) = DisplaySize (source, col, col + matchText.Length, false); (_, int len3) = DisplaySize (source, col + matchText.Length, origTxt.GetRuneCount (), false); @@ -1171,10 +1166,11 @@ internal partial class HistoryText _historyTextItems.Clear (); _idxHistoryText = -1; _originalCellsList.Clear (); + // Save a copy of the original, not the reference foreach (List cells in cellsList) { - _originalCellsList.Add ([..cells]); + _originalCellsList.Add ([.. cells]); } OnChangeText (null); @@ -1678,15 +1674,15 @@ internal class WordWrapManager List line = Model.GetLine (i); List> wrappedLines = ToListRune ( - TextFormatter.Format ( - Cell.ToString (line), - width, - Alignment.Start, - true, - preserveTrailingSpaces, - tabWidth - ) - ); + TextFormatter.Format ( + Cell.ToString (line), + width, + Alignment.Start, + true, + preserveTrailingSpaces, + tabWidth + ) + ); var sumColWidth = 0; for (var j = 0; j < wrappedLines.Count; j++) @@ -1885,7 +1881,6 @@ public class TextView : View private WordWrapManager? _wrapManager; private bool _wrapNeeded; - /// /// Initializes a on the specified area, with dimensions controlled with the X, Y, Width /// and Height properties. @@ -1911,7 +1906,7 @@ public class TextView : View // Things this view knows how to do // Note - NewLine is only bound to Enter if Multiline is true - AddCommand (Command.NewLine, (ctx) => ProcessEnterKey (ctx)); + AddCommand (Command.NewLine, ctx => ProcessEnterKey (ctx)); AddCommand ( Command.PageDown, @@ -2376,7 +2371,7 @@ public class TextView : View KeyBindings.Add (Key.C.WithCtrl, Command.Copy); KeyBindings.Add (Key.W.WithCtrl, Command.Cut); // Move to Unix? - KeyBindings.Add (Key.X.WithCtrl, Command.Cut); + KeyBindings.Add (Key.X.WithCtrl, Command.Cut); KeyBindings.Add (Key.CursorLeft.WithCtrl, Command.WordLeft); @@ -2422,10 +2417,7 @@ public class TextView : View KeyBindings.Add ((KeyCode)ContextMenu.Key, KeyBindingScope.HotKey, Command.Context); } - private void TextView_Added1 (object? sender, SuperViewChangedEventArgs e) - { - throw new NotImplementedException (); - } + private void TextView_Added1 (object? sender, SuperViewChangedEventArgs e) { throw new NotImplementedException (); } // BUGBUG: AllowsReturn is mis-named. It should be EnterKeyAccepts. /// @@ -2435,11 +2427,13 @@ public class TextView : View /// /// /// Setting this property alters . - /// If is set to , then is also set to `true` and + /// If is set to , then is also set to + /// `true` and /// vice-versa. /// /// - /// If is set to , then gets set to . + /// If is set to , then gets set to + /// . /// /// public bool AllowsReturn @@ -2458,6 +2452,7 @@ public class TextView : View if (!_allowsReturn && _multiline) { Multiline = false; + // BUGBUG: Setting properties should not have side-effects like this. Multiline and AllowsTab should be independent. AllowsTab = false; } @@ -2532,7 +2527,6 @@ public class TextView : View } } - /// /// Indicates whatever the text has history changes or not. if the text has history changes /// otherwise. @@ -2604,7 +2598,7 @@ public class TextView : View CurrentRow = 0; _savedHeight = Height; - Height = Dim.Auto (DimAutoStyle.Text, minimumContentDim: 1); + Height = Dim.Auto (DimAutoStyle.Text, 1); if (!IsInitialized) { @@ -2805,7 +2799,6 @@ public class TextView : View } } - /// Allows clearing the items updating the original text. public void ClearHistoryChanges () { _historyText?.Clear (_model.GetAllLines ()); } @@ -2855,7 +2848,7 @@ public class TextView : View line [c] = cell; // Assign the modified copy back } - selectedCellsChanged.Add ([..GetLine (r)]); + selectedCellsChanged.Add ([.. GetLine (r)]); } GetSelectedRegion (); @@ -2906,10 +2899,10 @@ public class TextView : View public void PromptForColors () { if (!ColorPicker.Prompt ( - "Colors", - GetSelectedCellAttribute (), - out Attribute newAttribute - )) + "Colors", + GetSelectedCellAttribute (), + out Attribute newAttribute + )) { return; } @@ -3177,10 +3170,7 @@ public class TextView : View public List GetLine (int line) { return _model.GetLine (line); } /// - public override Attribute GetNormalColor () - { - return GetFocusColor (); - } + public override Attribute GetNormalColor () { return GetFocusColor (); } /// /// Inserts the given text at the current cursor position exactly as if the user had just @@ -3284,21 +3274,15 @@ public class TextView : View } /// - protected internal override bool OnMouseEvent (MouseEvent ev) + protected override bool OnMouseEvent (MouseEventArgs ev) { - if (!ev.Flags.HasFlag (MouseFlags.Button1Clicked) - && !ev.Flags.HasFlag (MouseFlags.Button1Pressed) + if (ev is { IsSingleDoubleOrTripleClicked: false, IsPressed: false, IsReleased: false, IsWheel: false } && !ev.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition) - && !ev.Flags.HasFlag (MouseFlags.Button1Released) && !ev.Flags.HasFlag (MouseFlags.Button1Pressed | MouseFlags.ButtonShift) - && !ev.Flags.HasFlag (MouseFlags.WheeledDown) - && !ev.Flags.HasFlag (MouseFlags.WheeledUp) - && !ev.Flags.HasFlag (MouseFlags.Button1DoubleClicked) && !ev.Flags.HasFlag (MouseFlags.Button1DoubleClicked | MouseFlags.ButtonShift) - && !ev.Flags.HasFlag (MouseFlags.Button1TripleClicked) && !ev.Flags.HasFlag (ContextMenu!.MouseFlags)) { - return base.OnMouseEvent (ev); + return false; } if (!CanFocus) @@ -3563,7 +3547,6 @@ public class TextView : View ProcessInheritsPreviousColorScheme (CurrentRow, CurrentColumn); ProcessAutocomplete (); - } /// @@ -3628,6 +3611,7 @@ public class TextView : View else { AddRune (col, row, rune); + // Ensures that cols less than 0 to be 1 because it will be converted to a printable rune cols = Math.Max (cols, 1); } @@ -3663,34 +3647,6 @@ public class TextView : View _isDrawing = false; } - /// - public override bool? OnInvokingKeyBindings (Key a, KeyBindingScope scope) - { - if (!a.IsValid) - { - return false; - } - - // Give autocomplete first opportunity to respond to key presses - if (SelectedLength == 0 && Autocomplete.Suggestions.Count > 0 && Autocomplete.ProcessKey (a)) - { - return true; - } - - return base.OnInvokingKeyBindings (a, scope); - } - - /// - public override bool OnKeyUp (Key key) - { - if (key == Key.Space.WithCtrl) - { - return true; - } - - return base.OnKeyUp (key); - } - /// protected override void OnHasFocusChanged (bool newHasFocus, View? previousFocusedView, View? view) { @@ -3698,12 +3654,27 @@ public class TextView : View { Application.UngrabMouse (); } - - return; } /// - public override bool OnProcessKeyDown (Key a) + protected override bool OnKeyDown (Key key) + { + if (!key.IsValid) + { + return false; + } + + // Give autocomplete first opportunity to respond to key presses + if (SelectedLength == 0 && Autocomplete.Suggestions.Count > 0 && Autocomplete.ProcessKey (key)) + { + return true; + } + + return false; + } + + /// + protected override bool OnKeyDownNotHandled (Key a) { if (!CanFocus) { @@ -3724,6 +3695,17 @@ public class TextView : View return true; } + /// + public override bool OnKeyUp (Key key) + { + if (key == Key.Space.WithCtrl) + { + return true; + } + + return false; + } + /// Invoke the event with the unwrapped . public virtual void OnUnwrappedCursorPosition (int? cRow = null, int? cCol = null) { @@ -3760,7 +3742,7 @@ public class TextView : View List> addedLine = [new (currentLine), runeList]; _historyText.Add ( - [..addedLine], + [.. addedLine], CursorPosition, HistoryText.LineStatus.Added ); @@ -3862,6 +3844,7 @@ public class TextView : View if (posX > -1 && col >= posX && posX < Viewport.Width && _topRow <= CurrentRow && posY < Viewport.Height) { Move (col, CurrentRow - _topRow); + return new (col, CurrentRow - _topRow); } @@ -4481,12 +4464,12 @@ public class TextView : View } else { - _historyText.Add ([ [.. currentLine]], CursorPosition); + _historyText.Add ([[.. currentLine]], CursorPosition); currentLine.RemoveAt (CurrentColumn); _historyText.Add ( - [ [.. currentLine]], + [[.. currentLine]], CursorPosition, HistoryText.LineStatus.Replaced ); @@ -4656,6 +4639,7 @@ public class TextView : View { cells = line.GetRange (startCol, endCol - startCol); cellsList.Add (cells); + return StringFromRunes (cells); } @@ -4668,6 +4652,7 @@ public class TextView : View cellsList.AddRange ([]); cells = model == null ? _model.GetLine (row) : model.GetLine (row); cellsList.Add (cells); + res = res + Environment.NewLine + StringFromRunes (cells); @@ -4703,7 +4688,7 @@ public class TextView : View OnUnwrappedCursorPosition (cRow, cCol); - return GetRegion (out _, sRow: startRow, sCol: startCol, cRow: cRow, cCol: cCol, model: model); + return GetRegion (out _, startRow, startCol, cRow, cCol, model); } private (int Row, int Col) GetUnwrappedPosition (int line, int col) @@ -4897,7 +4882,7 @@ public class TextView : View { _model.AddLine (CurrentRow + i, lines [i]); - addedLines.Add ([..lines [i]]); + addedLines.Add ([.. lines [i]]); } if (rest is { }) @@ -5071,7 +5056,7 @@ public class TextView : View } _historyText.Add ( - [ [.. GetCurrentLine ()]], + [[.. GetCurrentLine ()]], CursorPosition, HistoryText.LineStatus.Replaced ); @@ -5111,7 +5096,7 @@ public class TextView : View return; } - _historyText.Add ([ [.. currentLine]], CursorPosition); + _historyText.Add ([[.. currentLine]], CursorPosition); if (currentLine.Count == 0) { @@ -5178,7 +5163,7 @@ public class TextView : View } _historyText.Add ( - [ [.. GetCurrentLine ()]], + [[.. GetCurrentLine ()]], CursorPosition, HistoryText.LineStatus.Replaced ); @@ -5202,14 +5187,14 @@ public class TextView : View List currentLine = GetCurrentLine (); - _historyText.Add ([ [.. GetCurrentLine ()]], CursorPosition); + _historyText.Add ([[.. GetCurrentLine ()]], CursorPosition); if (CurrentColumn == 0) { DeleteTextBackwards (); _historyText.ReplaceLast ( - [ [.. GetCurrentLine ()]], + [[.. GetCurrentLine ()]], CursorPosition, HistoryText.LineStatus.Replaced ); @@ -5248,7 +5233,7 @@ public class TextView : View } _historyText.Add ( - [ [.. GetCurrentLine ()]], + [[.. GetCurrentLine ()]], CursorPosition, HistoryText.LineStatus.Replaced ); @@ -5270,14 +5255,14 @@ public class TextView : View List currentLine = GetCurrentLine (); - _historyText.Add ([ [.. GetCurrentLine ()]], CursorPosition); + _historyText.Add ([[.. GetCurrentLine ()]], CursorPosition); if (currentLine.Count == 0 || CurrentColumn == currentLine.Count) { DeleteTextForwards (); _historyText.ReplaceLast ( - [ [.. GetCurrentLine ()]], + [[.. GetCurrentLine ()]], CursorPosition, HistoryText.LineStatus.Replaced ); @@ -5307,7 +5292,7 @@ public class TextView : View } _historyText.Add ( - [ [.. GetCurrentLine ()]], + [[.. GetCurrentLine ()]], CursorPosition, HistoryText.LineStatus.Replaced ); @@ -5579,6 +5564,7 @@ public class TextView : View } DoNeededAction (); + return true; } @@ -5883,7 +5869,7 @@ public class TextView : View KillWordForward (); } - private void ProcessMouseClick (MouseEvent ev, out List line) + private void ProcessMouseClick (MouseEventArgs ev, out List line) { List? r = null; @@ -5919,6 +5905,7 @@ public class TextView : View private bool ProcessMoveDown () { ResetContinuousFindTrack (); + if (_shiftSelecting && IsSelecting) { StopSelecting (); @@ -5961,8 +5948,10 @@ public class TextView : View if (IsSelecting) { StopSelecting (); + return true; } + // do not respond (this lets the key press fall through to navigation system - which usually changes focus backward) return false; } @@ -6001,8 +5990,10 @@ public class TextView : View { // In which case clear StopSelecting (); + return true; } + return false; } @@ -6296,7 +6287,6 @@ public class TextView : View _continuousFind = false; } - private void ResetPosition () { _topRow = _leftColumn = CurrentRow = CurrentColumn = 0; @@ -6461,13 +6451,13 @@ public class TextView : View } } - private void TextView_Initialized (object sender, EventArgs e) { if (Autocomplete.HostControl is null) { Autocomplete.HostControl = this; } + OnContentsChanged (); } diff --git a/Terminal.Gui/Views/TileView.cs b/Terminal.Gui/Views/TileView.cs index b6e57dd90..60370b2cb 100644 --- a/Terminal.Gui/Views/TileView.cs +++ b/Terminal.Gui/Views/TileView.cs @@ -286,11 +286,11 @@ public class TileView : View //// BUGBUG: Why is this not handled by a key binding??? /// - public override bool OnProcessKeyDown (Key keyEvent) + protected override bool OnKeyDownNotHandled (Key key) { var focusMoved = false; - if (keyEvent.KeyCode == ToggleResizable) + if (key.KeyCode == ToggleResizable) { foreach (TileViewLineView l in _splitterLines) { @@ -910,7 +910,7 @@ public class TileView : View } } - protected internal override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { if (!dragPosition.HasValue && mouseEvent.Flags == MouseFlags.Button1Pressed) { diff --git a/Terminal.Gui/Views/TimeField.cs b/Terminal.Gui/Views/TimeField.cs index b198d66a0..ecc94a7be 100644 --- a/Terminal.Gui/Views/TimeField.cs +++ b/Terminal.Gui/Views/TimeField.cs @@ -163,21 +163,24 @@ public class TimeField : TextField } /// - protected internal override bool OnMouseEvent (MouseEvent ev) + protected override bool OnMouseEvent (MouseEventArgs ev) { - bool result = base.OnMouseEvent (ev); + if (base.OnMouseEvent (ev) || ev.Handled) + { + return true; + } - if (result && SelectedLength == 0 && ev.Flags.HasFlag (MouseFlags.Button1Pressed)) + if (SelectedLength == 0 && ev.Flags.HasFlag (MouseFlags.Button1Pressed)) { int point = ev.Position.X; AdjCursorPosition (point); } - return result; + return ev.Handled; } /// - public override bool OnProcessKeyDown (Key a) + protected override bool OnKeyDownNotHandled (Key a) { // Ignore non-numeric characters. if (a.KeyCode is >= (KeyCode)(int)KeyCode.D0 and <= (KeyCode)(int)KeyCode.D9) @@ -227,7 +230,7 @@ public class TimeField : TextField CursorPosition = newPoint; } - while (Text [CursorPosition] == _sepChar [0]) + while (CursorPosition < Text.GetColumns() -1 && Text [CursorPosition] == _sepChar [0]) { if (increment) { diff --git a/Terminal.Gui/Views/Toplevel.cs b/Terminal.Gui/Views/Toplevel.cs index cfcdcc14d..ddee6b041 100644 --- a/Terminal.Gui/Views/Toplevel.cs +++ b/Terminal.Gui/Views/Toplevel.cs @@ -62,7 +62,7 @@ public partial class Toplevel : View /// public bool Modal { get; set; } - private void Toplevel_MouseClick (object? sender, MouseEventEventArgs e) { e.Handled = InvokeCommand (Command.HotKey) == true; } + private void Toplevel_MouseClick (object? sender, MouseEventArgs e) { e.Handled = InvokeCommand (Command.HotKey) == true; } #endregion diff --git a/Terminal.Gui/Views/TreeView/TreeView.cs b/Terminal.Gui/Views/TreeView/TreeView.cs index 6a43a3e1e..4e09eba2b 100644 --- a/Terminal.Gui/Views/TreeView/TreeView.cs +++ b/Terminal.Gui/Views/TreeView/TreeView.cs @@ -990,18 +990,14 @@ public class TreeView : View, ITreeView where T : class // BUGBUG: OnMouseEvent is internal. TreeView should not be overriding. /// - protected internal override bool OnMouseEvent (MouseEvent me) + protected override bool OnMouseEvent (MouseEventArgs me) { // If it is not an event we care about - if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) - && !me.Flags.HasFlag (ObjectActivationButton ?? MouseFlags.Button1DoubleClicked) - && !me.Flags.HasFlag (MouseFlags.WheeledDown) - && !me.Flags.HasFlag (MouseFlags.WheeledUp) - && !me.Flags.HasFlag (MouseFlags.WheeledRight) - && !me.Flags.HasFlag (MouseFlags.WheeledLeft)) + if (me is { IsSingleClicked: false, IsPressed: false, IsReleased: false, IsWheel: false } + && !me.Flags.HasFlag (ObjectActivationButton ?? MouseFlags.Button1DoubleClicked)) { // do nothing - return base.OnMouseEvent (me); + return false; } if (!HasFocus && CanFocus) @@ -1182,26 +1178,23 @@ public class TreeView : View, ITreeView where T : class } /// - public override bool OnProcessKeyDown (Key keyEvent) + protected override bool OnKeyDown (Key key) { if (!Enabled) { return false; } - // BUGBUG: this should move to OnInvokingKeyBindings // If not a keybinding, is the key a searchable key press? - if (CollectionNavigatorBase.IsCompatibleKey (keyEvent) && AllowLetterBasedNavigation) + if (CollectionNavigatorBase.IsCompatibleKey (key) && AllowLetterBasedNavigation) { - IReadOnlyCollection> map; - // If there has been a call to InvalidateMap since the last time // we need a new one to reflect the new exposed tree state - map = BuildLineMap (); + IReadOnlyCollection> map = BuildLineMap (); // Find the current selected object within the tree int current = map.IndexOf (b => b.Model == SelectedObject); - int? newIndex = KeystrokeNavigator?.GetNextMatchingItem (current, (char)keyEvent); + int? newIndex = KeystrokeNavigator?.GetNextMatchingItem (current, (char)key); if (newIndex is int && newIndex != -1) { diff --git a/Terminal.Gui/Views/Wizard/Wizard.cs b/Terminal.Gui/Views/Wizard/Wizard.cs index 6c9fe55c1..b9bc49bd5 100644 --- a/Terminal.Gui/Views/Wizard/Wizard.cs +++ b/Terminal.Gui/Views/Wizard/Wizard.cs @@ -381,12 +381,12 @@ public class Wizard : Dialog /// /// is derived from and Dialog causes Esc to call /// , closing the Dialog. Wizard overrides - /// to instead fire the event when Wizard is being used as a + /// to instead fire the event when Wizard is being used as a /// non-modal (see ). /// /// /// - public override bool OnProcessKeyDown (Key key) + protected override bool OnKeyDownNotHandled (Key key) { //// BUGBUG: Why is this not handled by a key binding??? if (!Modal) diff --git a/UICatalog/Scenarios/ASCIICustomButton.cs b/UICatalog/Scenarios/ASCIICustomButton.cs index 661efd80d..45889f3e8 100644 --- a/UICatalog/Scenarios/ASCIICustomButton.cs +++ b/UICatalog/Scenarios/ASCIICustomButton.cs @@ -127,7 +127,7 @@ public class ASCIICustomButtonTest : Scenario } public event Action PointerEnter; - private void This_MouseClick (object sender, MouseEventEventArgs obj) { NewMouseEvent (obj.MouseEvent); } + private void This_MouseClick (object sender, MouseEventArgs obj) { NewMouseEvent (obj); } } public class ScrollViewTestWindow : Window @@ -310,9 +310,9 @@ public class ASCIICustomButtonTest : Scenario } } - private void Button_MouseClick (object sender, MouseEventEventArgs obj) + private void Button_MouseClick (object sender, MouseEventArgs obj) { - if (obj.MouseEvent.Flags == MouseFlags.WheeledDown) + if (obj.Flags == MouseFlags.WheeledDown) { _scrollView.ContentOffset = new Point ( _scrollView.ContentOffset.X, @@ -320,7 +320,7 @@ public class ASCIICustomButtonTest : Scenario ); obj.Handled = true; } - else if (obj.MouseEvent.Flags == MouseFlags.WheeledUp) + else if (obj.Flags == MouseFlags.WheeledUp) { _scrollView.ContentOffset = new Point ( _scrollView.ContentOffset.X, diff --git a/UICatalog/Scenarios/AdornmentsEditor.cs b/UICatalog/Scenarios/AdornmentsEditor.cs index 7bd6ec042..d50714c5f 100644 --- a/UICatalog/Scenarios/AdornmentsEditor.cs +++ b/UICatalog/Scenarios/AdornmentsEditor.cs @@ -108,7 +108,7 @@ public class AdornmentsEditor : View ViewToEdit = Application.Navigation!.GetFocused (); } - private void ApplicationOnMouseEvent (object? sender, MouseEvent e) + private void ApplicationOnMouseEvent (object? sender, MouseEventArgs e) { if (e.Flags != MouseFlags.Button1Clicked || !AutoSelectViewToEdit) { diff --git a/UICatalog/Scenarios/ArrangementEditor.cs b/UICatalog/Scenarios/ArrangementEditor.cs index 13a48380d..396c493d6 100644 --- a/UICatalog/Scenarios/ArrangementEditor.cs +++ b/UICatalog/Scenarios/ArrangementEditor.cs @@ -147,7 +147,7 @@ public sealed class ArrangementEditor : View } } - private void ApplicationOnMouseEvent (object? sender, MouseEvent e) + private void ApplicationOnMouseEvent (object? sender, MouseEventArgs e) { if (e.Flags != MouseFlags.Button1Clicked || !AutoSelectViewToEdit) { diff --git a/UICatalog/Scenarios/Bars.cs b/UICatalog/Scenarios/Bars.cs index 63fdbd85f..b0d226148 100644 --- a/UICatalog/Scenarios/Bars.cs +++ b/UICatalog/Scenarios/Bars.cs @@ -187,12 +187,12 @@ public class Bars : Scenario menuLikeExamples.MouseClick += MenuLikeExamplesMouseClick; - void MenuLikeExamplesMouseClick (object sender, MouseEventEventArgs e) + void MenuLikeExamplesMouseClick (object sender, MouseEventArgs e) { - if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked)) + if (e.Flags.HasFlag (MouseFlags.Button3Clicked)) { - popOverMenu.X = e.MouseEvent.Position.X; - popOverMenu.Y = e.MouseEvent.Position.Y; + popOverMenu.X = e.Position.X; + popOverMenu.Y = e.Position.Y; popOverMenu.Visible = true; //popOverMenu.Enabled = popOverMenu.Visible; popOverMenu.SetFocus (); @@ -275,7 +275,7 @@ public class Bars : Scenario //private void ShowContextMenu (object s, MouseEventEventArgs e) //{ - // if (e.MouseEvent.Flags != MouseFlags.Button3Clicked) + // if (e.Flags != MouseFlags.Button3Clicked) // { // return; // } @@ -283,8 +283,8 @@ public class Bars : Scenario // var contextMenu = new Bar // { // Id = "contextMenu", - // X = e.MouseEvent.Position.X, - // Y = e.MouseEvent.Position.Y, + // X = e.Position.X, + // Y = e.Position.Y, // Width = Dim.Auto (DimAutoStyle.Content), // Height = Dim.Auto (DimAutoStyle.Content), // Orientation = Orientation.Vertical, @@ -387,7 +387,7 @@ public class Bars : Scenario // contextMenu.Initialized += Menu_Initialized; - // void Application_MouseEvent (object sender, MouseEvent e) + // void Application_MouseEvent (object sender, MouseEventArgs e) // { // // If user clicks outside of the menuWindow, close it // if (!contextMenu.Frame.Contains (e.Position.X, e.Position.Y)) diff --git a/UICatalog/Scenarios/CharacterMap.cs b/UICatalog/Scenarios/CharacterMap.cs index 5e246f9df..33c64d003 100644 --- a/UICatalog/Scenarios/CharacterMap.cs +++ b/UICatalog/Scenarios/CharacterMap.cs @@ -98,9 +98,9 @@ public class CharacterMap : Scenario // if user clicks the mouse in TableView _categoryList.MouseClick += (s, e) => { - _categoryList.ScreenToCell (e.MouseEvent.Position, out int? clickedCol); + _categoryList.ScreenToCell (e.Position, out int? clickedCol); - if (clickedCol != null && e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) + if (clickedCol != null && e.Flags.HasFlag (MouseFlags.Button1Clicked)) { EnumerableTableSource table = (EnumerableTableSource)_categoryList.Table; string prevSelection = table.Data.ElementAt (_categoryList.SelectedRow).Category; @@ -527,9 +527,9 @@ internal class CharMap : View Padding.Add (up, down, left, right); } - private void Handle_MouseEvent (object sender, MouseEventEventArgs e) + private void Handle_MouseEvent (object sender, MouseEventArgs e) { - if (e.MouseEvent.Flags == MouseFlags.WheeledDown) + if (e.Flags == MouseFlags.WheeledDown) { ScrollVertical (1); e.Handled = true; @@ -537,7 +537,7 @@ internal class CharMap : View return; } - if (e.MouseEvent.Flags == MouseFlags.WheeledUp) + if (e.Flags == MouseFlags.WheeledUp) { ScrollVertical (-1); e.Handled = true; @@ -545,7 +545,7 @@ internal class CharMap : View return; } - if (e.MouseEvent.Flags == MouseFlags.WheeledRight) + if (e.Flags == MouseFlags.WheeledRight) { ScrollHorizontal (1); e.Handled = true; @@ -553,7 +553,7 @@ internal class CharMap : View return; } - if (e.MouseEvent.Flags == MouseFlags.WheeledLeft) + if (e.Flags == MouseFlags.WheeledLeft) { ScrollHorizontal (-1); e.Handled = true; @@ -839,10 +839,8 @@ internal class CharMap : View private void CopyCodePoint () { Clipboard.Contents = $"U+{SelectedCodePoint:x5}"; } private void CopyGlyph () { Clipboard.Contents = $"{new Rune (SelectedCodePoint)}"; } - private void Handle_MouseClick (object sender, MouseEventEventArgs args) + private void Handle_MouseClick (object sender, MouseEventArgs me) { - MouseEvent me = args.MouseEvent; - if (me.Flags != MouseFlags.ReportMousePosition && me.Flags != MouseFlags.Button1Clicked && me.Flags != MouseFlags.Button1DoubleClicked) { return; @@ -883,7 +881,7 @@ internal class CharMap : View SetFocus (); } - args.Handled = true; + me.Handled = true; if (me.Flags == MouseFlags.Button1Clicked) { diff --git a/UICatalog/Scenarios/ContentScrolling.cs b/UICatalog/Scenarios/ContentScrolling.cs index 028717fcd..b6986067e 100644 --- a/UICatalog/Scenarios/ContentScrolling.cs +++ b/UICatalog/Scenarios/ContentScrolling.cs @@ -52,30 +52,30 @@ public class ContentScrolling : Scenario MouseEvent += VirtualDemoView_MouseEvent; } - private void VirtualDemoView_MouseEvent (object sender, MouseEventEventArgs e) + private void VirtualDemoView_MouseEvent (object sender, MouseEventArgs e) { - if (e.MouseEvent.Flags == MouseFlags.WheeledDown) + if (e.Flags == MouseFlags.WheeledDown) { ScrollVertical (1); return; } - if (e.MouseEvent.Flags == MouseFlags.WheeledUp) + if (e.Flags == MouseFlags.WheeledUp) { ScrollVertical (-1); return; } - if (e.MouseEvent.Flags == MouseFlags.WheeledRight) + if (e.Flags == MouseFlags.WheeledRight) { ScrollHorizontal (1); return; } - if (e.MouseEvent.Flags == MouseFlags.WheeledLeft) + if (e.Flags == MouseFlags.WheeledLeft) { ScrollHorizontal (-1); } diff --git a/UICatalog/Scenarios/ContextMenus.cs b/UICatalog/Scenarios/ContextMenus.cs index 816f80384..63a207d69 100644 --- a/UICatalog/Scenarios/ContextMenus.cs +++ b/UICatalog/Scenarios/ContextMenus.cs @@ -75,16 +75,16 @@ public class ContextMenus : Scenario appWindow.MouseClick += (s, e) => { - if (e.MouseEvent.Flags == _contextMenu.MouseFlags) + if (e.Flags == _contextMenu.MouseFlags) { - ShowContextMenu (e.MouseEvent.Position.X, e.MouseEvent.Position.Y); + ShowContextMenu (e.Position.X, e.Position.Y); e.Handled = true; } }; Application.MouseEvent += ApplicationMouseEvent; - void ApplicationMouseEvent (object sender, MouseEvent a) { mousePos = a.Position; } + void ApplicationMouseEvent (object sender, MouseEventArgs a) { mousePos = a.Position; } appWindow.WantMousePositionReports = true; diff --git a/UICatalog/Scenarios/Keys.cs b/UICatalog/Scenarios/Keys.cs index a96f256bb..f2796a344 100644 --- a/UICatalog/Scenarios/Keys.cs +++ b/UICatalog/Scenarios/Keys.cs @@ -10,120 +10,142 @@ public class Keys : Scenario public override void Main () { Application.Init (); - ObservableCollection keyPressedList = []; - ObservableCollection invokingKeyBindingsList = new (); + ObservableCollection keyDownList = []; + ObservableCollection keyDownNotHandledList = new (); var win = new Window { Title = GetQuitKeyAndName () }; - var editLabel = new Label { X = 0, Y = 0, Text = "Type text here:" }; - win.Add (editLabel); - var edit = new TextField { X = Pos.Right (editLabel) + 1, Y = Pos.Top (editLabel), Width = Dim.Fill (2) }; + var label = new Label + { + X = 0, + Y = 0, + Text = "_Type text here:" + }; + win.Add (label); + + var edit = new TextField + { + X = Pos.Right (label) + 1, + Y = Pos.Top (label), + Width = Dim.Fill (2), + Height = 1, + }; win.Add (edit); - edit.KeyDown += (s, a) => { keyPressedList.Add (a.ToString ()); }; - - edit.InvokingKeyBindings += (s, a) => - { - if (edit.KeyBindings.TryGet (a, out KeyBinding binding)) - { - invokingKeyBindingsList.Add ($"{a}: {string.Join (",", binding.Commands)}"); - } - }; - - // Last KeyPress: ______ - var keyPressedLabel = new Label + label = new Label { - X = Pos.Left (editLabel), Y = Pos.Top (editLabel) + 1, Text = "Last TextView.KeyPressed:" + X = 0, + Y = Pos.Bottom (label), + Text = "Last _Application.KeyDown:" }; - win.Add (keyPressedLabel); - var labelTextViewKeypress = new Label { X = Pos.Right (keyPressedLabel) + 1, Y = Pos.Top (keyPressedLabel) }; - win.Add (labelTextViewKeypress); - - edit.KeyDown += (s, e) => labelTextViewKeypress.Text = e.ToString (); - - keyPressedLabel = new Label + win.Add (label); + var labelAppKeypress = new Label { - X = Pos.Left (keyPressedLabel), Y = Pos.Bottom (keyPressedLabel), Text = "Last Application.KeyDown:" + X = Pos.Right (label) + 1, + Y = Pos.Top (label) }; - win.Add (keyPressedLabel); - var labelAppKeypress = new Label { X = Pos.Right (keyPressedLabel) + 1, Y = Pos.Top (keyPressedLabel) }; win.Add (labelAppKeypress); Application.KeyDown += (s, e) => labelAppKeypress.Text = e.ToString (); - // Key stroke log: - var keyLogLabel = new Label - { - X = Pos.Left (editLabel), Y = Pos.Top (editLabel) + 4, Text = "Application Key Events:" - }; - win.Add (keyLogLabel); - int maxKeyString = Key.CursorRight.WithAlt.WithCtrl.WithShift.ToString ().Length; - var yOffset = 1; - ObservableCollection keyEventlist = new (); - - var keyEventListView = new ListView + label = new () { X = 0, - Y = Pos.Top (keyLogLabel) + yOffset, - Width = "Key Down:".Length + maxKeyString, + Y = Pos.Bottom (label), + Text = "_Last TextField.KeyDown:" + }; + win.Add (label); + + var lastTextFieldKeyDownLabel = new Label + { + X = Pos.Right (label) + 1, + Y = Pos.Top (label), + Height = 1, + }; + win.Add (lastTextFieldKeyDownLabel); + + edit.KeyDown += (s, e) => lastTextFieldKeyDownLabel.Text = e.ToString (); + + // Application key event log: + label = new Label + { + X = 0, + Y = Pos.Bottom (label) + 1, + Text = "Application Key Events:" + }; + win.Add (label); + int maxKeyString = Key.CursorRight.WithAlt.WithCtrl.WithShift.ToString ().Length; + + ObservableCollection keyList = new (); + + var appKeyListView = new ListView + { + X = 0, + Y = Pos.Bottom (label), + Width = "KeyDown:".Length + maxKeyString, Height = Dim.Fill (), - Source = new ListWrapper (keyEventlist) + Source = new ListWrapper (keyList) }; - keyEventListView.ColorScheme = Colors.ColorSchemes ["TopLevel"]; - win.Add (keyEventListView); + appKeyListView.ColorScheme = Colors.ColorSchemes ["TopLevel"]; + win.Add (appKeyListView); - // OnKeyPressed - var onKeyPressedLabel = new Label + // View key events... + edit.KeyDown += (s, a) => { keyDownList.Add (a.ToString ()); }; + + edit.KeyDownNotHandled += (s, a) => + { + keyDownNotHandledList.Add ($"{a}"); + }; + + // KeyDown + label = new Label { - X = Pos.Right (keyEventListView) + 1, Y = Pos.Top (editLabel) + 4, Text = "TextView KeyDown:" + X = Pos.Right (appKeyListView) + 1, + Y = Pos.Top (label), + Text = "TextView Key Down:" }; - win.Add (onKeyPressedLabel); + win.Add (label); - yOffset = 1; - - var onKeyPressedListView = new ListView + var onKeyDownListView = new ListView { - X = Pos.Left (onKeyPressedLabel), - Y = Pos.Top (onKeyPressedLabel) + yOffset, + X = Pos.Left (label), + Y = Pos.Bottom (label), Width = maxKeyString, Height = Dim.Fill (), - Source = new ListWrapper (keyPressedList) + Source = new ListWrapper (keyDownList) }; - onKeyPressedListView.ColorScheme = Colors.ColorSchemes ["TopLevel"]; - win.Add (onKeyPressedListView); + onKeyDownListView.ColorScheme = Colors.ColorSchemes ["TopLevel"]; + win.Add (onKeyDownListView); - // OnInvokeKeyBindings - var onInvokingKeyBindingsLabel = new Label + // KeyDownNotHandled + label = new Label { - X = Pos.Right (onKeyPressedListView) + 1, - Y = Pos.Top (editLabel) + 4, - Text = "TextView InvokingKeyBindings:" + X = Pos.Right (onKeyDownListView) + 1, + Y = Pos.Top (label), + Text = "TextView KeyDownNotHandled:" }; - win.Add (onInvokingKeyBindingsLabel); + win.Add (label); - var onInvokingKeyBindingsListView = new ListView + var onKeyDownNotHandledListView = new ListView { - X = Pos.Left (onInvokingKeyBindingsLabel), - Y = Pos.Top (onInvokingKeyBindingsLabel) + yOffset, - Width = Dim.Fill (1), + X = Pos.Left (label), + Y = Pos.Bottom (label), + Width = maxKeyString, Height = Dim.Fill (), - Source = new ListWrapper (invokingKeyBindingsList) + Source = new ListWrapper (keyDownNotHandledList) }; - onInvokingKeyBindingsListView.ColorScheme = Colors.ColorSchemes ["TopLevel"]; - win.Add (onInvokingKeyBindingsListView); + onKeyDownNotHandledListView.ColorScheme = Colors.ColorSchemes ["TopLevel"]; + win.Add (onKeyDownNotHandledListView); - //Application.KeyDown += (s, a) => KeyDownPressUp (a, "Down"); Application.KeyDown += (s, a) => KeyDownPressUp (a, "Down"); Application.KeyUp += (s, a) => KeyDownPressUp (a, "Up"); void KeyDownPressUp (Key args, string updown) { - // BUGBUG: KeyEvent.ToString is badly broken var msg = $"Key{updown,-7}: {args}"; - keyEventlist.Add (msg); - keyEventListView.MoveDown (); - onKeyPressedListView.MoveDown (); - onInvokingKeyBindingsListView.MoveDown (); + keyList.Add (msg); + appKeyListView.MoveDown (); + onKeyDownNotHandledListView.MoveDown (); } Application.Run (win); diff --git a/UICatalog/Scenarios/LineDrawing.cs b/UICatalog/Scenarios/LineDrawing.cs index 5b2887c59..38ea3bbfb 100644 --- a/UICatalog/Scenarios/LineDrawing.cs +++ b/UICatalog/Scenarios/LineDrawing.cs @@ -8,7 +8,7 @@ namespace UICatalog.Scenarios; public interface ITool { - void OnMouseEvent (DrawingArea area, MouseEvent mouseEvent); + void OnMouseEvent (DrawingArea area, MouseEventArgs mouseEvent); } internal class DrawLineTool : ITool @@ -17,7 +17,7 @@ internal class DrawLineTool : ITool public LineStyle LineStyle { get; set; } = LineStyle.Single; /// - public void OnMouseEvent (DrawingArea area, MouseEvent mouseEvent) + public void OnMouseEvent (DrawingArea area, MouseEventArgs mouseEvent) { if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Pressed)) { @@ -96,6 +96,8 @@ internal class DrawLineTool : ITool area.SetNeedsDisplay (); } } + + mouseEvent.Handled = true; } } @@ -121,7 +123,7 @@ public class LineDrawing : Scenario tools.CurrentColor = canvas.GetNormalColor (); canvas.CurrentAttribute = tools.CurrentColor; - win.KeyDown += (s, e) => { e.Handled = canvas.OnKeyDown (e); }; + win.KeyDown += (s, e) => { e.Handled = canvas.NewKeyDownEvent (e); }; Application.Run (win); win.Dispose (); @@ -290,7 +292,7 @@ public class DrawingArea : View } //// BUGBUG: Why is this not handled by a key binding??? - public override bool OnKeyDown (Key e) + protected override bool OnKeyDown (Key e) { // BUGBUG: These should be implemented with key bindings if (e.KeyCode == (KeyCode.Z | KeyCode.CtrlMask)) @@ -321,11 +323,11 @@ public class DrawingArea : View return false; } - protected override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { CurrentTool.OnMouseEvent (this, mouseEvent); - return base.OnMouseEvent (mouseEvent); + return mouseEvent.Handled; } internal void AddLayer () @@ -429,7 +431,7 @@ public class AttributeView : View } /// - protected override bool OnMouseEvent (MouseEvent mouseEvent) + protected override bool OnMouseEvent (MouseEventArgs mouseEvent) { if (mouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) { @@ -441,9 +443,11 @@ public class AttributeView : View { ClickedInBackground (); } + + mouseEvent.Handled = true; } - return base.OnMouseEvent (mouseEvent); + return mouseEvent.Handled; } private bool IsForegroundPoint (int x, int y) { return ForegroundPoints.Contains ((x, y)); } diff --git a/UICatalog/Scenarios/ListColumns.cs b/UICatalog/Scenarios/ListColumns.cs index 6bd6dd4be..05859bfbc 100644 --- a/UICatalog/Scenarios/ListColumns.cs +++ b/UICatalog/Scenarios/ListColumns.cs @@ -248,7 +248,7 @@ public class ListColumns : Scenario }; // if user clicks the mouse in TableView - _listColView.MouseClick += (s, e) => { _listColView.ScreenToCell (e.MouseEvent.Position, out int? clickedCol); }; + _listColView.MouseClick += (s, e) => { _listColView.ScreenToCell (e.Position, out int? clickedCol); }; _listColView.KeyBindings.ReplaceCommands (Key.Space, Command.Accept); diff --git a/UICatalog/Scenarios/Mouse.cs b/UICatalog/Scenarios/Mouse.cs index 0b07c48e3..dd1a08789 100644 --- a/UICatalog/Scenarios/Mouse.cs +++ b/UICatalog/Scenarios/Mouse.cs @@ -251,18 +251,18 @@ public class Mouse : Scenario win.MouseEvent += (sender, a) => { - int i = filterSlider.Options.FindIndex (o => o.Data == a.MouseEvent.Flags); + int i = filterSlider.Options.FindIndex (o => o.Data == a.Flags); if (filterSlider.GetSetOptions ().Contains (i)) { - winLogList.Add ($"MouseEvent: ({a.MouseEvent.Position}) - {a.MouseEvent.Flags} {count++}"); + winLogList.Add ($"MouseEvent: ({a.Position}) - {a.Flags} {count++}"); winLog.MoveDown (); } }; win.MouseClick += (sender, a) => { - winLogList.Add ($"MouseClick: ({a.MouseEvent.Position}) - {a.MouseEvent.Flags} {count++}"); + winLogList.Add ($"MouseClick: ({a.Position}) - {a.Flags} {count++}"); winLog.MoveDown (); }; diff --git a/UICatalog/Scenarios/Snake.cs b/UICatalog/Scenarios/Snake.cs index 0a16aed95..906bc931d 100644 --- a/UICatalog/Scenarios/Snake.cs +++ b/UICatalog/Scenarios/Snake.cs @@ -357,30 +357,30 @@ public class Snake : Scenario } // BUGBUG: Should (can) this use key bindings instead. - public override bool OnKeyDown (Key keyEvent) + protected override bool OnKeyDown (Key key) { - if (keyEvent.KeyCode == KeyCode.CursorUp) + if (key.KeyCode == KeyCode.CursorUp) { State.PlannedDirection = Direction.Up; return true; } - if (keyEvent.KeyCode == KeyCode.CursorDown) + if (key.KeyCode == KeyCode.CursorDown) { State.PlannedDirection = Direction.Down; return true; } - if (keyEvent.KeyCode == KeyCode.CursorLeft) + if (key.KeyCode == KeyCode.CursorLeft) { State.PlannedDirection = Direction.Left; return true; } - if (keyEvent.KeyCode == KeyCode.CursorRight) + if (key.KeyCode == KeyCode.CursorRight) { State.PlannedDirection = Direction.Right; diff --git a/UICatalog/Scenarios/TableEditor.cs b/UICatalog/Scenarios/TableEditor.cs index d127f8610..c676eac23 100644 --- a/UICatalog/Scenarios/TableEditor.cs +++ b/UICatalog/Scenarios/TableEditor.cs @@ -752,16 +752,16 @@ public class TableEditor : Scenario return; } - _tableView.ScreenToCell (e.MouseEvent.Position, out int? clickedCol); + _tableView.ScreenToCell (e.Position, out int? clickedCol); if (clickedCol != null) { - if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button1Clicked)) + if (e.Flags.HasFlag (MouseFlags.Button1Clicked)) { // left click in a header SortColumn (clickedCol.Value); } - else if (e.MouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked)) + else if (e.Flags.HasFlag (MouseFlags.Button3Clicked)) { // right click in a header ShowHeaderContextMenu (clickedCol.Value, e); @@ -1254,7 +1254,7 @@ public class TableEditor : Scenario _tableView.Update (); } - private void ShowHeaderContextMenu (int clickedCol, MouseEventEventArgs e) + private void ShowHeaderContextMenu (int clickedCol, MouseEventArgs e) { if (HasCheckboxes () && clickedCol == 0) { @@ -1266,7 +1266,7 @@ public class TableEditor : Scenario var contextMenu = new ContextMenu { - Position = new (e.MouseEvent.Position.X + 1, e.MouseEvent.Position.Y + 1) + Position = new (e.Position.X + 1, e.Position.Y + 1) }; MenuBarItem menuItems = new ( diff --git a/UICatalog/Scenarios/TreeViewFileSystem.cs b/UICatalog/Scenarios/TreeViewFileSystem.cs index 590af81b1..6c46a7996 100644 --- a/UICatalog/Scenarios/TreeViewFileSystem.cs +++ b/UICatalog/Scenarios/TreeViewFileSystem.cs @@ -484,12 +484,12 @@ public class TreeViewFileSystem : Scenario } } - private void TreeViewFiles_MouseClick (object sender, MouseEventEventArgs obj) + private void TreeViewFiles_MouseClick (object sender, MouseEventArgs obj) { // if user right clicks - if (obj.MouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked)) + if (obj.Flags.HasFlag (MouseFlags.Button3Clicked)) { - IFileSystemInfo rightClicked = _treeViewFiles.GetObjectOnRow (obj.MouseEvent.Position.Y); + IFileSystemInfo rightClicked = _treeViewFiles.GetObjectOnRow (obj.Position.Y); // nothing was clicked if (rightClicked == null) @@ -499,8 +499,8 @@ public class TreeViewFileSystem : Scenario ShowContextMenu ( new Point ( - obj.MouseEvent.Position.X + _treeViewFiles.Frame.X, - obj.MouseEvent.Position.Y + _treeViewFiles.Frame.Y + 2 + obj.Position.X + _treeViewFiles.Frame.X, + obj.Position.Y + _treeViewFiles.Frame.Y + 2 ), rightClicked ); diff --git a/UICatalog/Scenarios/VkeyPacketSimulator.cs b/UICatalog/Scenarios/VkeyPacketSimulator.cs index 94a8618fe..1659eaebc 100644 --- a/UICatalog/Scenarios/VkeyPacketSimulator.cs +++ b/UICatalog/Scenarios/VkeyPacketSimulator.cs @@ -108,11 +108,11 @@ public class VkeyPacketSimulator : Scenario if (_outputStarted) { // If the key wasn't handled by the TextView will popup a Dialog with the keys pressed. - bool? handled = tvOutput.OnInvokingKeyBindings (e, KeyBindingScope.HotKey | KeyBindingScope.Focused); + bool? handled = tvOutput.NewKeyDownEvent (e); if (handled == null || handled == false) { - if (!tvOutput.OnProcessKeyDown (e)) + if (!tvOutput.NewKeyDownEvent (e)) { Application.Invoke ( () => MessageBox.Query ( @@ -148,7 +148,7 @@ public class VkeyPacketSimulator : Scenario } }; - tvInput.InvokingKeyBindings += (s, e) => + tvInput.KeyDownNotHandled += (s, e) => { Key ev = e; diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs index f0b84d866..63dc511fc 100644 --- a/UICatalog/UICatalog.cs +++ b/UICatalog/UICatalog.cs @@ -621,28 +621,28 @@ public class UICatalogApp ); ScenarioList.Style.ColumnStyles.Add (1, new () { MaxWidth = 1 }); - // Enable user to find & select a scenario by typing text - // TableView does not (currently) have built-in CollectionNavigator support (the ability for the - // user to type and the items that match get selected). We implement it in the app instead. - ScenarioList.KeyDown += (s, a) => - { - if (CollectionNavigatorBase.IsCompatibleKey (a)) - { - int? newItem = - _scenarioCollectionNav?.GetNextMatchingItem ( - ScenarioList.SelectedRow, - (char)a - ); + //// Enable user to find & select a scenario by typing text + //// TableView does not (currently) have built-in CollectionNavigator support (the ability for the + //// user to type and the items that match get selected). We implement it in the app instead. + //ScenarioList.KeyDown += (s, a) => + // { + // if (CollectionNavigatorBase.IsCompatibleKey (a)) + // { + // int? newItem = + // _scenarioCollectionNav?.GetNextMatchingItem ( + // ScenarioList.SelectedRow, + // (char)a + // ); - if (newItem is int v && newItem != -1) - { - ScenarioList.SelectedRow = v; - ScenarioList.EnsureSelectedCellIsVisible (); - ScenarioList.SetNeedsDisplay (); - a.Handled = true; - } - } - }; + // if (newItem is int v && newItem != -1) + // { + // ScenarioList.SelectedRow = v; + // ScenarioList.EnsureSelectedCellIsVisible (); + // ScenarioList.SetNeedsDisplay (); + // a.Handled = true; + // } + // } + // }; ScenarioList.CellActivated += ScenarioView_OpenSelectedItem; // TableView typically is a grid where nav keys are biased for moving left/right. diff --git a/UnitTests/Application/ApplicationTests.cs b/UnitTests/Application/ApplicationTests.cs index bb3e2e3ab..9fe01a892 100644 --- a/UnitTests/Application/ApplicationTests.cs +++ b/UnitTests/Application/ApplicationTests.cs @@ -856,7 +856,7 @@ public class ApplicationTests } else if (iteration < 3) { - Application.OnMouseEvent (new () { Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new () { Flags = MouseFlags.ReportMousePosition }); Assert.False (top.NeedsDisplay); Assert.False (top.SubViewNeedsDisplay); Assert.False (top.LayoutNeeded); @@ -895,12 +895,12 @@ public class ApplicationTests // Don't use visuals to test as style of border can change over time. Assert.Equal (new (0, 0), w.Frame.Location); - Application.OnMouseEvent (new () { Flags = MouseFlags.Button1Pressed }); + Application.RaiseMouseEvent (new () { Flags = MouseFlags.Button1Pressed }); Assert.Equal (w.Border, Application.MouseGrabView); Assert.Equal (new (0, 0), w.Frame.Location); // Move down and to the right. - Application.OnMouseEvent (new () { ScreenPosition = new (1, 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (1, 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition }); Assert.Equal (new (1, 1), w.Frame.Location); Application.End (rs); diff --git a/UnitTests/Application/KeyboardTests.cs b/UnitTests/Application/KeyboardTests.cs index 09b1bf7a3..ba472d3ab 100644 --- a/UnitTests/Application/KeyboardTests.cs +++ b/UnitTests/Application/KeyboardTests.cs @@ -64,14 +64,14 @@ public class KeyboardTests Assert.True (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); - Application.OnKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); Assert.True (win2.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); Assert.True (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); - Application.OnKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); Assert.False (win.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); @@ -117,14 +117,14 @@ public class KeyboardTests Assert.False (win2.HasFocus); Assert.Equal ("win", ((Window)top.Subviews [^1]).Title); - Application.OnKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); Assert.True (win.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); Assert.True (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [^1]).Title); - Application.OnKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); Assert.True (win.CanFocus); Assert.True (win.HasFocus); Assert.True (win2.CanFocus); @@ -163,39 +163,39 @@ public class KeyboardTests public void KeyBinding_OnKeyDown () { var view = new ScopedKeyBindingView (); - var invoked = false; - view.InvokingKeyBindings += (s, e) => invoked = true; + var keyWasHandled = false; + view.KeyDownNotHandled += (s, e) => keyWasHandled = true; var top = new Toplevel (); top.Add (view); Application.Begin (top); - Application.OnKeyDown (Key.A); - Assert.False (invoked); + Application.RaiseKeyDownEvent (Key.A); + Assert.False (keyWasHandled); Assert.True (view.ApplicationCommand); - invoked = false; + keyWasHandled = false; view.ApplicationCommand = false; Application.KeyBindings.Remove (KeyCode.A); - Application.OnKeyDown (Key.A); // old - Assert.False (invoked); + Application.RaiseKeyDownEvent (Key.A); // old + Assert.False (keyWasHandled); Assert.False (view.ApplicationCommand); Application.KeyBindings.Add (Key.A.WithCtrl, view, Command.Save); - Application.OnKeyDown (Key.A); // old - Assert.False (invoked); + Application.RaiseKeyDownEvent (Key.A); // old + Assert.False (keyWasHandled); Assert.False (view.ApplicationCommand); - Application.OnKeyDown (Key.A.WithCtrl); // new - Assert.False (invoked); + Application.RaiseKeyDownEvent (Key.A.WithCtrl); // new + Assert.False (keyWasHandled); Assert.True (view.ApplicationCommand); - invoked = false; - Application.OnKeyDown (Key.H); - Assert.True (invoked); + keyWasHandled = false; + Application.RaiseKeyDownEvent (Key.H); + Assert.False (keyWasHandled); - invoked = false; + keyWasHandled = false; Assert.False (view.HasFocus); - Application.OnKeyDown (Key.F); - Assert.False (invoked); + Application.RaiseKeyDownEvent (Key.F); + Assert.False (keyWasHandled); Assert.True (view.ApplicationCommand); Assert.True (view.HotKeyCommand); @@ -208,23 +208,23 @@ public class KeyboardTests public void KeyBinding_OnKeyDown_Negative () { var view = new ScopedKeyBindingView (); - var invoked = false; - view.InvokingKeyBindings += (s, e) => invoked = true; + var keyWasHandled = false; + view.KeyDownNotHandled += (s, e) => keyWasHandled = true; var top = new Toplevel (); top.Add (view); Application.Begin (top); - Application.OnKeyDown (Key.A.WithCtrl); - Assert.False (invoked); + Application.RaiseKeyDownEvent (Key.A.WithCtrl); + Assert.False (keyWasHandled); Assert.False (view.ApplicationCommand); Assert.False (view.HotKeyCommand); Assert.False (view.FocusedCommand); - invoked = false; + keyWasHandled = false; Assert.False (view.HasFocus); - Application.OnKeyDown (Key.Z); - Assert.False (invoked); + Application.RaiseKeyDownEvent (Key.Z); + Assert.False (keyWasHandled); Assert.False (view.ApplicationCommand); Assert.False (view.HotKeyCommand); Assert.False (view.FocusedCommand); @@ -399,7 +399,7 @@ public class KeyboardTests Assert.True (subView1.HasFocus); // Act - Application.OnKeyDown (Application.NextTabGroupKey); + Application.RaiseKeyDownEvent (Application.NextTabGroupKey); // Assert Assert.True (view2.HasFocus); @@ -432,24 +432,24 @@ public class KeyboardTests Assert.True (v1.HasFocus); // Across TabGroups - Application.OnKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); Assert.True (v3.HasFocus); - Application.OnKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); Assert.True (v1.HasFocus); - Application.OnKeyDown (Key.F6.WithShift); + Application.RaiseKeyDownEvent (Key.F6.WithShift); Assert.True (v3.HasFocus); - Application.OnKeyDown (Key.F6.WithShift); + Application.RaiseKeyDownEvent (Key.F6.WithShift); Assert.True (v1.HasFocus); // Restore? - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); Assert.True (v2.HasFocus); - Application.OnKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); Assert.True (v3.HasFocus); - Application.OnKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); Assert.True (v1.HasFocus); Application.RequestStop (); @@ -485,7 +485,7 @@ public class KeyboardTests view1.SetFocus (); // Act - Application.OnKeyDown (Application.NextTabKey); + Application.RaiseKeyDownEvent (Application.NextTabKey); // Assert Assert.True (view2.HasFocus); @@ -539,7 +539,7 @@ public class KeyboardTests Assert.True (subView1.HasFocus); // Act - Application.OnKeyDown (Application.PrevTabGroupKey); + Application.RaiseKeyDownEvent (Application.PrevTabGroupKey); // Assert Assert.True (view2.HasFocus); @@ -562,7 +562,7 @@ public class KeyboardTests view1.SetFocus (); // Act - Application.OnKeyDown (Application.NextTabKey); + Application.RaiseKeyDownEvent (Application.NextTabKey); // Assert Assert.True (view2.HasFocus); @@ -605,21 +605,21 @@ public class KeyboardTests Key prevKey = Application.QuitKey; - Application.OnKeyDown (Application.QuitKey); + Application.RaiseKeyDownEvent (Application.QuitKey); Assert.True (isQuiting); isQuiting = false; - Application.OnKeyDown (Application.QuitKey); + Application.RaiseKeyDownEvent (Application.QuitKey); Assert.True (isQuiting); isQuiting = false; Application.QuitKey = Key.C.WithCtrl; - Application.OnKeyDown (prevKey); // Should not quit + Application.RaiseKeyDownEvent (prevKey); // Should not quit Assert.False (isQuiting); - Application.OnKeyDown (Key.Q.WithCtrl); // Should not quit + Application.RaiseKeyDownEvent (Key.Q.WithCtrl); // Should not quit Assert.False (isQuiting); - Application.OnKeyDown (Application.QuitKey); + Application.RaiseKeyDownEvent (Application.QuitKey); Assert.True (isQuiting); // Reset the QuitKey to avoid throws errors on another tests @@ -728,7 +728,7 @@ public class KeyboardTests if (Application.IsInitialized) { _output.WriteLine (" Pressing QuitKey"); - Application.OnKeyDown (Application.QuitKey); + Application.RaiseKeyDownEvent (Application.QuitKey); } } } diff --git a/UnitTests/Application/Mouse/ApplicationMouseEnterLeaveTests.cs b/UnitTests/Application/Mouse/ApplicationMouseEnterLeaveTests.cs index f1d0a7847..60eb8b25e 100644 --- a/UnitTests/Application/Mouse/ApplicationMouseEnterLeaveTests.cs +++ b/UnitTests/Application/Mouse/ApplicationMouseEnterLeaveTests.cs @@ -47,7 +47,7 @@ public class ApplicationMouseEnterLeaveTests var mousePosition = new Point (1, 1); List currentViewsUnderMouse = new () { view }; - var mouseEvent = new MouseEvent + var mouseEvent = new MouseEventArgs { Position = mousePosition, ScreenPosition = mousePosition @@ -80,7 +80,7 @@ public class ApplicationMouseEnterLeaveTests Application.Top.Add (view); var mousePosition = new Point (0, 0); List currentViewsUnderMouse = new (); - var mouseEvent = new MouseEvent (); + var mouseEvent = new MouseEventArgs (); Application._cachedViewsUnderMouse.Clear (); Application._cachedViewsUnderMouse.Add (view); @@ -203,7 +203,7 @@ public class ApplicationMouseEnterLeaveTests Application.Top.Add (view); var mousePosition = new Point (0, 0); List currentViewsUnderMouse = new (); - var mouseEvent = new MouseEvent (); + var mouseEvent = new MouseEventArgs (); Application._cachedViewsUnderMouse.Clear (); diff --git a/UnitTests/Application/Mouse/ApplicationMouseTests.cs b/UnitTests/Application/Mouse/ApplicationMouseTests.cs index c5a86a85c..64000649d 100644 --- a/UnitTests/Application/Mouse/ApplicationMouseTests.cs +++ b/UnitTests/Application/Mouse/ApplicationMouseTests.cs @@ -42,10 +42,10 @@ public class ApplicationMouseTests bool expectedClicked ) { - var mouseEvent = new MouseEvent { ScreenPosition = new (clickX, clickY), Flags = MouseFlags.Button1Pressed }; + var mouseEvent = new MouseEventArgs { ScreenPosition = new (clickX, clickY), Flags = MouseFlags.Button1Pressed }; var clicked = false; - void OnApplicationOnMouseEvent (object s, MouseEvent e) + void OnApplicationOnMouseEvent (object s, MouseEventArgs e) { Assert.Equal (expectedX, e.ScreenPosition.X); Assert.Equal (expectedY, e.ScreenPosition.Y); @@ -54,7 +54,7 @@ public class ApplicationMouseTests Application.MouseEvent += OnApplicationOnMouseEvent; - Application.OnMouseEvent (mouseEvent); + Application.RaiseMouseEvent (mouseEvent); Assert.Equal (expectedClicked, clicked); Application.MouseEvent -= OnApplicationOnMouseEvent; } @@ -116,12 +116,12 @@ public class ApplicationMouseTests Height = size.Height }; - var mouseEvent = new MouseEvent { ScreenPosition = new (clickX, clickY), Flags = MouseFlags.Button1Clicked }; + var mouseEvent = new MouseEventArgs { ScreenPosition = new (clickX, clickY), Flags = MouseFlags.Button1Clicked }; view.MouseClick += (s, e) => { - Assert.Equal (expectedX, e.MouseEvent.Position.X); - Assert.Equal (expectedY, e.MouseEvent.Position.Y); + Assert.Equal (expectedX, e.Position.X); + Assert.Equal (expectedY, e.Position.Y); clicked = true; }; @@ -129,7 +129,7 @@ public class ApplicationMouseTests top.Add (view); Application.Begin (top); - Application.OnMouseEvent (mouseEvent); + Application.RaiseMouseEvent (mouseEvent); Assert.Equal (expectedClicked, clicked); top.Dispose (); } @@ -218,16 +218,16 @@ public class ApplicationMouseTests Application.Top.Add (view); - var mouseEvent = new MouseEvent { Position = new (clickX, clickY), ScreenPosition = new (clickX, clickY), Flags = MouseFlags.Button1Clicked }; + var mouseEvent = new MouseEventArgs { Position = new (clickX, clickY), ScreenPosition = new (clickX, clickY), Flags = MouseFlags.Button1Clicked }; view.MouseClick += (s, e) => { - Assert.Equal (expectedX, e.MouseEvent.Position.X); - Assert.Equal (expectedY, e.MouseEvent.Position.Y); + Assert.Equal (expectedX, e.Position.X); + Assert.Equal (expectedY, e.Position.Y); clicked = true; }; - Application.OnMouseEvent (mouseEvent); + Application.RaiseMouseEvent (mouseEvent); Assert.Equal (expectedClicked, clicked); Application.Top.Dispose (); Application.ResetState (ignoreDisposed: true); @@ -261,7 +261,7 @@ public class ApplicationMouseTests Assert.True (tf.HasFocus); Assert.Null (Application.MouseGrabView); - Application.OnMouseEvent (new () { ScreenPosition = new (5, 5), Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (5, 5), Flags = MouseFlags.ReportMousePosition }); Assert.Equal (sv, Application.MouseGrabView); @@ -275,15 +275,15 @@ public class ApplicationMouseTests // another toplevel (Dialog) was opened Assert.Null (Application.MouseGrabView); - Application.OnMouseEvent (new () { ScreenPosition = new (5, 5), Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (5, 5), Flags = MouseFlags.ReportMousePosition }); Assert.Null (Application.MouseGrabView); - Application.OnMouseEvent (new () { ScreenPosition = new (40, 12), Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (40, 12), Flags = MouseFlags.ReportMousePosition }); Assert.Null (Application.MouseGrabView); - Application.OnMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Pressed }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Pressed }); Assert.Null (Application.MouseGrabView); @@ -402,7 +402,7 @@ public class ApplicationMouseTests Assert.True (view.WasDisposed); #endif - Application.OnMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Pressed }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Pressed }); Assert.Null (Application.MouseGrabView); Assert.Equal (0, count); top.Dispose (); diff --git a/UnitTests/Dialogs/MessageBoxTests.cs b/UnitTests/Dialogs/MessageBoxTests.cs index 541ecd9e4..caad58da5 100644 --- a/UnitTests/Dialogs/MessageBoxTests.cs +++ b/UnitTests/Dialogs/MessageBoxTests.cs @@ -33,14 +33,14 @@ public class MessageBoxTests case 2: // Tab to btn2 - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); Button btn = Application.Navigation!.GetFocused () as Button; btn.Accepting += (sender, e) => { btnAcceptCount++; }; // Click - Application.OnKeyDown (Key.Enter); + Application.RaiseKeyDownEvent (Key.Enter); break; @@ -77,7 +77,7 @@ public class MessageBoxTests break; case 2: - Application.OnKeyDown (Key.Esc); + Application.RaiseKeyDownEvent (Key.Esc); break; @@ -116,13 +116,13 @@ public class MessageBoxTests case 2: // Tab to btn2 - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); Button btn = Application.Navigation!.GetFocused () as Button; btn.Accepting += (sender, e) => { btnAcceptCount++; }; - Application.OnKeyDown (Key.Space); + Application.RaiseKeyDownEvent (Key.Space); break; diff --git a/UnitTests/FileServices/FileDialogTests.cs b/UnitTests/FileServices/FileDialogTests.cs index f446f5be9..cb31b7462 100644 --- a/UnitTests/FileServices/FileDialogTests.cs +++ b/UnitTests/FileServices/FileDialogTests.cs @@ -140,7 +140,7 @@ public class FileDialogTests () AssertIsTheStartingDirectory (dlg.Path); Assert.IsType (dlg.MostFocused); - Send ('v', ConsoleKey.DownArrow); + Application.RaiseKeyDownEvent (Key.CursorDown); var tv = GetTableView(dlg); tv.SetFocus (); @@ -152,15 +152,17 @@ public class FileDialogTests () AssertIsTheStartingDirectory (dlg.Path); // Accept navigation up a directory - Send ('\n', ConsoleKey.Enter); + Application.RaiseKeyDownEvent (Key.Enter); AssertIsTheRootDirectory (dlg.Path); Assert.True (dlg.Canceled); Assert.False (selected); - // Now press the back button (in table view) - Send ('<', ConsoleKey.Backspace); + Assert.IsType (dlg.MostFocused); + + // Now press Backspace (in table view) + Application.RaiseKeyDownEvent (Key.Backspace); // Should move us back to the root AssertIsTheStartingDirectory (dlg.Path); diff --git a/UnitTests/Input/EscSeqUtilsTests.cs b/UnitTests/Input/EscSeqUtilsTests.cs index 3ac8e4c60..9b811f002 100644 --- a/UnitTests/Input/EscSeqUtilsTests.cs +++ b/UnitTests/Input/EscSeqUtilsTests.cs @@ -696,7 +696,7 @@ public class EscSeqUtilsTests top.Add (view); Application.Begin (top); - Application.OnMouseEvent (new() { Position = new (0, 0), Flags = 0 }); + Application.RaiseMouseEvent (new() { Position = new (0, 0), Flags = 0 }); ClearAll (); @@ -753,7 +753,7 @@ public class EscSeqUtilsTests // set Application.WantContinuousButtonPressedView to null view.WantContinuousButtonPressed = false; - Application.OnMouseEvent (new() { Position = new (0, 0), Flags = 0 }); + Application.RaiseMouseEvent (new() { Position = new (0, 0), Flags = 0 }); Application.RequestStop (); } diff --git a/UnitTests/Input/ResponderTests.cs b/UnitTests/Input/ResponderTests.cs index cd02fa0ed..183e06885 100644 --- a/UnitTests/Input/ResponderTests.cs +++ b/UnitTests/Input/ResponderTests.cs @@ -205,11 +205,11 @@ public class ResponderTests var r = new View (); var args = new Key { KeyCode = KeyCode.Null }; - Assert.False (r.OnKeyDown (args)); + Assert.False (r.NewKeyDownEvent (args)); Assert.False (args.Handled); r.KeyDown += (s, a) => a.Handled = true; - Assert.True (r.OnKeyDown (args)); + Assert.True (r.NewKeyDownEvent (args)); Assert.True (args.Handled); r.Dispose (); @@ -232,9 +232,9 @@ public class ResponderTests var r = new View (); //Assert.False (r.OnKeyDown (new KeyEventArgs () { Key = Key.Unknown })); - Assert.False (r.OnKeyDown (new Key { KeyCode = KeyCode.Null })); - Assert.False (r.OnKeyUp (new Key { KeyCode = KeyCode.Null })); - Assert.False (r.NewMouseEvent (new MouseEvent { Flags = MouseFlags.AllEvents })); + Assert.False (r.NewKeyDownEvent (new Key { KeyCode = KeyCode.Null })); + Assert.False (r.NewKeyDownEvent (new Key { KeyCode = KeyCode.Null })); + Assert.False (r.NewMouseEvent (new MouseEventArgs { Flags = MouseFlags.AllEvents })); var v = new View (); //Assert.False (r.OnEnter (v)); @@ -293,6 +293,6 @@ public class ResponderTests public class DerivedView : View { - public override bool OnKeyDown (Key keyEvent) { return true; } + protected override bool OnKeyDown (Key keyEvent) { return true; } } } diff --git a/UnitTests/UICatalog/ScenarioTests.cs b/UnitTests/UICatalog/ScenarioTests.cs index d7549b594..87735fda6 100644 --- a/UnitTests/UICatalog/ScenarioTests.cs +++ b/UnitTests/UICatalog/ScenarioTests.cs @@ -132,7 +132,7 @@ public class ScenarioTests : TestsAllViews { // Press QuitKey //_output.WriteLine ($"Forcing Quit with {Application.QuitKey}"); - Application.OnKeyDown (Application.QuitKey); + Application.RaiseKeyDownEvent (Application.QuitKey); } } } diff --git a/UnitTests/View/HotKeyTests.cs b/UnitTests/View/Keyboard/HotKeyTests.cs similarity index 95% rename from UnitTests/View/HotKeyTests.cs rename to UnitTests/View/Keyboard/HotKeyTests.cs index c7032347c..4c1e7812c 100644 --- a/UnitTests/View/HotKeyTests.cs +++ b/UnitTests/View/Keyboard/HotKeyTests.cs @@ -95,7 +95,7 @@ public class HotKeyTests { var view = new View (); view.KeyBindings.Add (Key.A, Command.HotKey); // implies KeyBindingScope.Focused - so this should not be invoked - view.InvokingKeyBindings += (s, e) => { Assert.Fail (); }; + view.KeyDownNotHandled += (s, e) => { Assert.Fail (); }; var superView = new View (); superView.Add (view); @@ -109,8 +109,11 @@ public class HotKeyTests { var view = new View (); view.KeyBindings.Add (Key.A, KeyBindingScope.HotKey, Command.HotKey); - bool invoked = false; - view.InvokingKeyBindings += (s, e) => { invoked = true; }; + bool hotKeyInvoked = false; + view.HandlingHotKey += (s, e) => { hotKeyInvoked = true; }; + + bool notHandled = false; + view.KeyDownNotHandled += (s, e) => { notHandled = true; }; var superView = new View (); superView.Add (view); @@ -118,7 +121,8 @@ public class HotKeyTests var ke = Key.A; superView.NewKeyDownEvent (ke); - Assert.True (invoked); + Assert.False (notHandled); + Assert.True (hotKeyInvoked); } @@ -362,20 +366,20 @@ public class HotKeyTests view.Selecting += (s, e) => selectRaised = true; Assert.Equal (KeyCode.T, view.HotKey); - Assert.True (Application.OnKeyDown (Key.T)); + Assert.True (Application.RaiseKeyDownEvent (Key.T)); Assert.True (hotKeyRaised); Assert.False (acceptRaised); Assert.False (selectRaised); hotKeyRaised = false; - Assert.True (Application.OnKeyDown (Key.T.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.T.WithAlt)); Assert.True (hotKeyRaised); Assert.False (acceptRaised); Assert.False (selectRaised); hotKeyRaised = false; view.HotKey = KeyCode.E; - Assert.True (Application.OnKeyDown (Key.E.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.E.WithAlt)); Assert.True (hotKeyRaised); Assert.False (acceptRaised); Assert.False (selectRaised); diff --git a/UnitTests/View/Keyboard/KeyboardEventTests.cs b/UnitTests/View/Keyboard/KeyboardEventTests.cs new file mode 100644 index 000000000..12cffb9a7 --- /dev/null +++ b/UnitTests/View/Keyboard/KeyboardEventTests.cs @@ -0,0 +1,329 @@ +using Xunit.Abstractions; + +// Alias Console to MockConsole so we don't accidentally use Console + +namespace Terminal.Gui.ViewTests; + +public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews +{ + /// + /// This tests that when a new key down event is sent to the view will fire the key-down related + /// events: KeyDown and KeyDownNotHandled. Note that KeyUp is independent. + /// + [Theory] + [MemberData (nameof (AllViewTypes))] + public void AllViews_NewKeyDownEvent_All_EventsFire (Type viewType) + { + var view = CreateInstanceIfNotGeneric (viewType); + + if (view == null) + { + output.WriteLine ($"ERROR: Skipping generic view: {viewType}"); + + return; + } + + output.WriteLine ($"Testing {viewType}"); + + var keyDown = false; + + view.KeyDown += (s, a) => + { + a.Handled = false; // don't handle it so the other events are called + keyDown = true; + }; + + var keyDownNotHandled = false; + + view.KeyDownNotHandled += (s, a) => + { + a.Handled = true; + keyDownNotHandled = true; + }; + + // Key.Empty is invalid, but it's used here to test that the event is fired + Assert.True (view.NewKeyDownEvent (Key.Empty)); // this will be true because the ProcessKeyDown event handled it + Assert.True (keyDown); + Assert.True (keyDownNotHandled); + view.Dispose (); + } + + /// + /// This tests that when a new key up event is sent to the view the view will fire the 1 key-up related event: + /// KeyUp + /// + [Theory] + [MemberData (nameof (AllViewTypes))] + public void AllViews_NewKeyUpEvent_All_EventsFire (Type viewType) + { + var view = CreateInstanceIfNotGeneric (viewType); + + if (view == null) + { + output.WriteLine ($"ERROR: Generic view {viewType}"); + + return; + } + + output.WriteLine ($"Testing {view.GetType ().Name}"); + + var keyUp = false; + + view.KeyUp += (s, a) => + { + a.Handled = true; + keyUp = true; + }; + + Assert.True (view.NewKeyUpEvent (Key.A)); // this will be true because the KeyUp event handled it + Assert.True (keyUp); + view.Dispose (); + } + + [Theory] + [InlineData (true, false, false)] + [InlineData (true, true, false)] + [InlineData (true, true, true)] + public void NewKeyDownUpEvents_Events_Are_Raised_With_Only_Key_Modifiers (bool shift, bool alt, bool control) + { + var keyDown = false; + var keyDownNotHandled = false; + var keyUp = false; + + var view = new OnNewKeyTestView (); + view.CancelVirtualMethods = false; + + view.KeyDown += (s, e) => + { + Assert.Equal (KeyCode.Null, e.KeyCode & ~KeyCode.CtrlMask & ~KeyCode.AltMask & ~KeyCode.ShiftMask); + Assert.Equal (shift, e.IsShift); + Assert.Equal (alt, e.IsAlt); + Assert.Equal (control, e.IsCtrl); + Assert.False (keyDown); + Assert.True (view.OnKeyDownCalled); + keyDown = true; + }; + view.KeyDownNotHandled += (s, e) => { keyDownNotHandled = true; }; + + view.KeyUp += (s, e) => + { + Assert.Equal (KeyCode.Null, e.KeyCode & ~KeyCode.CtrlMask & ~KeyCode.AltMask & ~KeyCode.ShiftMask); + Assert.Equal (shift, e.IsShift); + Assert.Equal (alt, e.IsAlt); + Assert.Equal (control, e.IsCtrl); + Assert.False (keyUp); + Assert.True (view.OnKeyUpCalled); + keyUp = true; + }; + + view.NewKeyDownEvent ( + new ( + KeyCode.Null + | (shift ? KeyCode.ShiftMask : 0) + | (alt ? KeyCode.AltMask : 0) + | (control ? KeyCode.CtrlMask : 0) + ) + ); + Assert.True (keyDownNotHandled); + Assert.True (view.OnKeyDownCalled); + Assert.True (view.OnProcessKeyDownCalled); + + view.NewKeyUpEvent ( + new ( + KeyCode.Null + | (shift ? KeyCode.ShiftMask : 0) + | (alt ? KeyCode.AltMask : 0) + | (control ? KeyCode.CtrlMask : 0) + ) + ); + Assert.True (keyUp); + Assert.True (view.OnKeyUpCalled); + } + + [Fact] + public void NewKeyDownEvent_Handled_True_Stops_Processing () + { + var keyDown = false; + var keyDownNotHandled = false; + + var view = new OnNewKeyTestView (); + Assert.True (view.CanFocus); + view.CancelVirtualMethods = false; + + view.KeyDown += (s, e) => + { + Assert.Equal (KeyCode.A, e.KeyCode); + Assert.False (keyDown); + Assert.True (view.OnKeyDownCalled); + e.Handled = true; + keyDown = true; + }; + + + view.KeyDownNotHandled += (s, e) => + { + Assert.Equal (KeyCode.A, e.KeyCode); + Assert.False (keyDownNotHandled); + Assert.False (view.OnProcessKeyDownCalled); + e.Handled = true; + keyDownNotHandled = true; + }; + + view.NewKeyDownEvent (Key.A); + Assert.True (keyDown); + Assert.False (keyDownNotHandled); + + Assert.True (view.OnKeyDownCalled); + Assert.False (view.OnProcessKeyDownCalled); + } + + [Fact] + public void NewKeyDownEvent_KeyDown_Handled_Stops_Processing () + { + var view = new View (); + var keyDownNotHandled = false; + var setHandledTo = false; + + view.KeyDown += (s, e) => + { + e.Handled = setHandledTo; + Assert.Equal (setHandledTo, e.Handled); + Assert.Equal (KeyCode.N, e.KeyCode); + }; + + view.KeyDownNotHandled += (s, e) => + { + keyDownNotHandled = true; + Assert.False (e.Handled); + Assert.Equal (KeyCode.N, e.KeyCode); + }; + + view.NewKeyDownEvent (Key.N); + Assert.True (keyDownNotHandled); + + keyDownNotHandled = false; + setHandledTo = true; + view.NewKeyDownEvent (Key.N); + Assert.False (keyDownNotHandled); + } + + [Fact] + public void NewKeyDownEvent_ProcessKeyDown_Handled_Stops_Processing () + { + var keyDown = false; + var keyDownNotHandled = false; + + var view = new OnNewKeyTestView (); + Assert.True (view.CanFocus); + view.CancelVirtualMethods = false; + + view.KeyDown += (s, e) => + { + Assert.Equal (KeyCode.A, e.KeyCode); + Assert.False (keyDown); + Assert.True (view.OnKeyDownCalled); + e.Handled = false; + keyDown = true; + }; + + view.KeyDownNotHandled += (s, e) => + { + Assert.Equal (KeyCode.A, e.KeyCode); + Assert.False (keyDownNotHandled); + Assert.True (view.OnProcessKeyDownCalled); + e.Handled = true; + keyDownNotHandled = true; + }; + + view.NewKeyDownEvent (Key.A); + Assert.True (keyDown); + Assert.True (keyDownNotHandled); + + Assert.True (view.OnKeyDownCalled); + Assert.True (view.OnProcessKeyDownCalled); + } + + [Fact] + public void NewKeyUpEvent_KeyUp_Handled_True_Stops_Processing () + { + var keyUp = false; + + var view = new OnNewKeyTestView (); + Assert.True (view.CanFocus); + view.CancelVirtualMethods = false; + + view.KeyUp += (s, e) => + { + Assert.Equal (KeyCode.A, e.KeyCode); + Assert.False (keyUp); + Assert.False (view.OnProcessKeyDownCalled); + e.Handled = true; + keyUp = true; + }; + + view.NewKeyUpEvent (Key.A); + Assert.True (keyUp); + + Assert.True (view.OnKeyUpCalled); + Assert.False (view.OnKeyDownCalled); + Assert.False (view.OnProcessKeyDownCalled); + } + + [Theory] + [InlineData (null, null)] + [InlineData (true, true)] + [InlineData (false, false)] + public void InvokeCommandsBoundToKey_Returns_Nullable_Properly (bool? toReturn, bool? expected) + { + var view = new KeyBindingsTestView (); + view.CommandReturns = toReturn; + + bool? result = view.InvokeCommandsBoundToKey (Key.A); + Assert.Equal (expected, result); + } + + /// A view that overrides the OnKey* methods so we can test that they are called. + public class KeyBindingsTestView : View + { + public KeyBindingsTestView () + { + CanFocus = true; + AddCommand (Command.HotKey, () => CommandReturns); + KeyBindings.Add (Key.A, Command.HotKey); + } + + public bool? CommandReturns { get; set; } + } + + /// A view that overrides the OnKey* methods so we can test that they are called. + public class OnNewKeyTestView : View + { + public OnNewKeyTestView () { CanFocus = true; } + public bool CancelVirtualMethods { set; private get; } + public bool OnKeyDownCalled { get; set; } + public bool OnProcessKeyDownCalled { get; set; } + public bool OnKeyUpCalled { get; set; } + public override string Text { get; set; } + + protected override bool OnKeyDown (Key keyEvent) + { + OnKeyDownCalled = true; + + return CancelVirtualMethods; + } + + public override bool OnKeyUp (Key keyEvent) + { + OnKeyUpCalled = true; + + return CancelVirtualMethods; + } + + protected override bool OnKeyDownNotHandled (Key keyEvent) + { + OnProcessKeyDownCalled = true; + + return CancelVirtualMethods; + } + } +} diff --git a/UnitTests/View/ViewKeyBindingTests.cs b/UnitTests/View/Keyboard/ViewKeyBindingTests.cs similarity index 64% rename from UnitTests/View/ViewKeyBindingTests.cs rename to UnitTests/View/Keyboard/ViewKeyBindingTests.cs index 2ac278a7b..b1483c4da 100644 --- a/UnitTests/View/ViewKeyBindingTests.cs +++ b/UnitTests/View/Keyboard/ViewKeyBindingTests.cs @@ -11,37 +11,38 @@ public class ViewKeyBindingTests (ITestOutputHelper output) public void Focus_KeyBinding () { var view = new ScopedKeyBindingView (); - var invoked = false; - view.InvokingKeyBindings += (s, e) => invoked = true; + var keyWasHandled = false; + view.KeyDownNotHandled += (s, e) => keyWasHandled = true; var top = new Toplevel (); top.Add (view); Application.Begin (top); - Application.OnKeyDown (Key.A); - Assert.False (invoked); + Application.RaiseKeyDownEvent (Key.A); + Assert.False (keyWasHandled); Assert.True (view.ApplicationCommand); - invoked = false; - Application.OnKeyDown (Key.H); - Assert.True (invoked); + keyWasHandled = false; + Application.RaiseKeyDownEvent (Key.H); + Assert.True (view.HotKeyCommand); + Assert.False (keyWasHandled); - invoked = false; + keyWasHandled = false; Assert.False (view.HasFocus); - Application.OnKeyDown (Key.F); - Assert.False (invoked); + Application.RaiseKeyDownEvent (Key.F); + Assert.False (keyWasHandled); Assert.False (view.FocusedCommand); - invoked = false; + keyWasHandled = false; view.CanFocus = true; view.SetFocus (); Assert.True (view.HasFocus); - Application.OnKeyDown (Key.F); - Assert.True (invoked); + Application.RaiseKeyDownEvent (Key.F); + Assert.True (view.FocusedCommand); + Assert.False (keyWasHandled); // Command was invoked, but wasn't handled Assert.True (view.ApplicationCommand); Assert.True (view.HotKeyCommand); - Assert.True (view.FocusedCommand); top.Dispose (); } @@ -50,23 +51,23 @@ public class ViewKeyBindingTests (ITestOutputHelper output) public void Focus_KeyBinding_Negative () { var view = new ScopedKeyBindingView (); - var invoked = false; - view.InvokingKeyBindings += (s, e) => invoked = true; + var keyWasHandled = false; + view.KeyDownNotHandled += (s, e) => keyWasHandled = true; var top = new Toplevel (); top.Add (view); Application.Begin (top); - Application.OnKeyDown (Key.Z); - Assert.False (invoked); + Application.RaiseKeyDownEvent (Key.Z); + Assert.False (keyWasHandled); Assert.False (view.ApplicationCommand); Assert.False (view.HotKeyCommand); Assert.False (view.FocusedCommand); - invoked = false; + keyWasHandled = false; Assert.False (view.HasFocus); - Application.OnKeyDown (Key.F); - Assert.False (invoked); + Application.RaiseKeyDownEvent (Key.F); + Assert.False (keyWasHandled); Assert.False (view.ApplicationCommand); Assert.False (view.HotKeyCommand); Assert.False (view.FocusedCommand); @@ -78,28 +79,29 @@ public class ViewKeyBindingTests (ITestOutputHelper output) public void HotKey_KeyBinding () { var view = new ScopedKeyBindingView (); - var invoked = false; - view.InvokingKeyBindings += (s, e) => invoked = true; + var keyWasHandled = false; + view.KeyDownNotHandled += (s, e) => keyWasHandled = true; var top = new Toplevel (); top.Add (view); Application.Begin (top); - invoked = false; - Application.OnKeyDown (Key.H); - Assert.True (invoked); + keyWasHandled = false; + Application.RaiseKeyDownEvent (Key.H); Assert.True (view.HotKeyCommand); + Assert.False (keyWasHandled); view.HotKey = KeyCode.Z; - invoked = false; + keyWasHandled = false; view.HotKeyCommand = false; - Application.OnKeyDown (Key.H); // old hot key - Assert.False (invoked); + Application.RaiseKeyDownEvent (Key.H); // old hot key + Assert.False (keyWasHandled); Assert.False (view.HotKeyCommand); - Application.OnKeyDown (Key.Z); // new hot key - Assert.True (invoked); + Application.RaiseKeyDownEvent (Key.Z); // new hot key Assert.True (view.HotKeyCommand); + Assert.False (keyWasHandled); + top.Dispose (); } @@ -108,19 +110,19 @@ public class ViewKeyBindingTests (ITestOutputHelper output) public void HotKey_KeyBinding_Negative () { var view = new ScopedKeyBindingView (); - var invoked = false; - view.InvokingKeyBindings += (s, e) => invoked = true; + var keyWasHandled = false; + view.KeyDownNotHandled += (s, e) => keyWasHandled = true; var top = new Toplevel (); top.Add (view); Application.Begin (top); - Application.OnKeyDown (Key.Z); - Assert.False (invoked); + Application.RaiseKeyDownEvent (Key.Z); + Assert.False (keyWasHandled); Assert.False (view.HotKeyCommand); - invoked = false; - Application.OnKeyDown (Key.F); + keyWasHandled = false; + Application.RaiseKeyDownEvent (Key.F); Assert.False (view.HotKeyCommand); top.Dispose (); } diff --git a/UnitTests/View/KeyboardEventTests.cs b/UnitTests/View/KeyboardEventTests.cs deleted file mode 100644 index ec7eec6aa..000000000 --- a/UnitTests/View/KeyboardEventTests.cs +++ /dev/null @@ -1,502 +0,0 @@ -using Xunit.Abstractions; - -// Alias Console to MockConsole so we don't accidentally use Console - -namespace Terminal.Gui.ViewTests; - -public class KeyboardEventTests (ITestOutputHelper output) : TestsAllViews -{ - /// - /// This tests that when a new key down event is sent to the view will fire the 3 key-down related - /// events: KeyDown, InvokingKeyBindings, and ProcessKeyDown. Note that KeyUp is independent. - /// - [Theory] - [MemberData (nameof (AllViewTypes))] - public void AllViews_KeyDown_All_EventsFire (Type viewType) - { - var view = CreateInstanceIfNotGeneric (viewType); - - if (view == null) - { - output.WriteLine ($"ERROR: Skipping generic view: {viewType}"); - - return; - } - - output.WriteLine ($"Testing {viewType}"); - - var keyDown = false; - - view.KeyDown += (s, a) => - { - a.Handled = false; // don't handle it so the other events are called - keyDown = true; - }; - - var invokingKeyBindings = false; - - view.InvokingKeyBindings += (s, a) => - { - a.Handled = false; // don't handle it so the other events are called - invokingKeyBindings = true; - }; - - var keyDownProcessed = false; - - view.ProcessKeyDown += (s, a) => - { - a.Handled = true; - keyDownProcessed = true; - }; - - Assert.True (view.NewKeyDownEvent (Key.A)); // this will be true because the ProcessKeyDown event handled it - Assert.True (keyDown); - Assert.True (invokingKeyBindings); - Assert.True (keyDownProcessed); - view.Dispose (); - } - - /// - /// This tests that when a new key up event is sent to the view the view will fire the 1 key-up related event: - /// KeyUp - /// - [Theory] - [MemberData (nameof (AllViewTypes))] - public void AllViews_KeyUp_All_EventsFire (Type viewType) - { - var view = CreateInstanceIfNotGeneric (viewType); - - if (view == null) - { - output.WriteLine ($"ERROR: Generic view {viewType}"); - - return; - } - - output.WriteLine ($"Testing {view.GetType ().Name}"); - - var keyUp = false; - - view.KeyUp += (s, a) => - { - a.Handled = true; - keyUp = true; - }; - - Assert.True (view.NewKeyUpEvent (Key.A)); // this will be true because the KeyUp event handled it - Assert.True (keyUp); - view.Dispose (); - } - - [Theory] - [InlineData (true, false, false)] - [InlineData (true, true, false)] - [InlineData (true, true, true)] - public void Events_Are_Called_With_Only_Key_Modifiers (bool shift, bool alt, bool control) - { - var keyDown = false; - var keyPressed = false; - var keyUp = false; - - var view = new OnKeyTestView (); - view.CancelVirtualMethods = false; - - view.KeyDown += (s, e) => - { - Assert.Equal (KeyCode.Null, e.KeyCode & ~KeyCode.CtrlMask & ~KeyCode.AltMask & ~KeyCode.ShiftMask); - Assert.Equal (shift, e.IsShift); - Assert.Equal (alt, e.IsAlt); - Assert.Equal (control, e.IsCtrl); - Assert.False (keyDown); - Assert.False (view.OnKeyDownContinued); - keyDown = true; - }; - view.ProcessKeyDown += (s, e) => { keyPressed = true; }; - - view.KeyUp += (s, e) => - { - Assert.Equal (KeyCode.Null, e.KeyCode & ~KeyCode.CtrlMask & ~KeyCode.AltMask & ~KeyCode.ShiftMask); - Assert.Equal (shift, e.IsShift); - Assert.Equal (alt, e.IsAlt); - Assert.Equal (control, e.IsCtrl); - Assert.False (keyUp); - Assert.False (view.OnKeyUpContinued); - keyUp = true; - }; - - //view.ProcessKeyDownEvent (new (Key.Null | (shift ? Key.ShiftMask : 0) | (alt ? Key.AltMask : 0) | (control ? Key.CtrlMask : 0))); - //Assert.True (keyDown); - //Assert.True (view.OnKeyDownWasCalled); - //Assert.True (view.OnProcessKeyDownWasCalled); - - view.NewKeyDownEvent ( - new ( - KeyCode.Null - | (shift ? KeyCode.ShiftMask : 0) - | (alt ? KeyCode.AltMask : 0) - | (control ? KeyCode.CtrlMask : 0) - ) - ); - Assert.True (keyPressed); - Assert.True (view.OnKeyDownContinued); - Assert.True (view.OnKeyPressedContinued); - - view.NewKeyUpEvent ( - new ( - KeyCode.Null - | (shift ? KeyCode.ShiftMask : 0) - | (alt ? KeyCode.AltMask : 0) - | (control ? KeyCode.CtrlMask : 0) - ) - ); - Assert.True (keyUp); - Assert.True (view.OnKeyUpContinued); - } - - [Fact] - public void InvokingKeyBindings_Handled_Cancels () - { - var view = new View (); - var keyPressInvoked = false; - var invokingKeyBindingsInvoked = false; - var processKeyPressInvoked = false; - var setHandledTo = false; - - view.KeyDown += (s, e) => - { - keyPressInvoked = true; - Assert.False (e.Handled); - Assert.Equal (KeyCode.N, e.KeyCode); - }; - - view.InvokingKeyBindings += (s, e) => - { - invokingKeyBindingsInvoked = true; - e.Handled = setHandledTo; - Assert.Equal (setHandledTo, e.Handled); - Assert.Equal (KeyCode.N, e.KeyCode); - }; - - view.ProcessKeyDown += (s, e) => - { - processKeyPressInvoked = true; - processKeyPressInvoked = true; - Assert.False (e.Handled); - Assert.Equal (KeyCode.N, e.KeyCode); - }; - - view.NewKeyDownEvent (Key.N); - Assert.True (keyPressInvoked); - Assert.True (invokingKeyBindingsInvoked); - Assert.True (processKeyPressInvoked); - - keyPressInvoked = false; - invokingKeyBindingsInvoked = false; - processKeyPressInvoked = false; - setHandledTo = true; - view.NewKeyDownEvent (Key.N); - Assert.True (keyPressInvoked); - Assert.True (invokingKeyBindingsInvoked); - Assert.False (processKeyPressInvoked); - } - - [Fact] - public void InvokingKeyBindings_Handled_True_Stops_Processing () - { - var keyDown = false; - var invokingKeyBindings = false; - var keyPressed = false; - - var view = new OnKeyTestView (); - Assert.True (view.CanFocus); - view.CancelVirtualMethods = false; - - view.KeyDown += (s, e) => - { - Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (keyDown); - Assert.False (view.OnKeyDownContinued); - e.Handled = false; - keyDown = true; - }; - - view.InvokingKeyBindings += (s, e) => - { - Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (keyPressed); - Assert.False (view.OnInvokingKeyBindingsContinued); - e.Handled = true; - invokingKeyBindings = true; - }; - - view.ProcessKeyDown += (s, e) => - { - Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (keyPressed); - Assert.False (view.OnKeyPressedContinued); - e.Handled = true; - keyPressed = true; - }; - - view.NewKeyDownEvent (Key.A); - Assert.True (keyDown); - Assert.True (invokingKeyBindings); - Assert.False (keyPressed); - - Assert.True (view.OnKeyDownContinued); - Assert.False (view.OnInvokingKeyBindingsContinued); - Assert.False (view.OnKeyPressedContinued); - } - - [Fact] - public void KeyDown_Handled_True_Stops_Processing () - { - var keyDown = false; - var invokingKeyBindings = false; - var keyPressed = false; - - var view = new OnKeyTestView (); - Assert.True (view.CanFocus); - view.CancelVirtualMethods = false; - - view.KeyDown += (s, e) => - { - Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (keyDown); - Assert.False (view.OnKeyDownContinued); - e.Handled = true; - keyDown = true; - }; - - view.InvokingKeyBindings += (s, e) => - { - Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (keyPressed); - Assert.False (view.OnInvokingKeyBindingsContinued); - e.Handled = true; - invokingKeyBindings = true; - }; - - view.ProcessKeyDown += (s, e) => - { - Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (keyPressed); - Assert.False (view.OnKeyPressedContinued); - e.Handled = true; - keyPressed = true; - }; - - view.NewKeyDownEvent (Key.A); - Assert.True (keyDown); - Assert.False (invokingKeyBindings); - Assert.False (keyPressed); - - Assert.False (view.OnKeyDownContinued); - Assert.False (view.OnInvokingKeyBindingsContinued); - Assert.False (view.OnKeyPressedContinued); - } - - [Fact] - public void KeyPress_Handled_Cancels () - { - var view = new View (); - var invokingKeyBindingsInvoked = false; - var processKeyPressInvoked = false; - var setHandledTo = false; - - view.KeyDown += (s, e) => - { - e.Handled = setHandledTo; - Assert.Equal (setHandledTo, e.Handled); - Assert.Equal (KeyCode.N, e.KeyCode); - }; - - view.InvokingKeyBindings += (s, e) => - { - invokingKeyBindingsInvoked = true; - Assert.False (e.Handled); - Assert.Equal (KeyCode.N, e.KeyCode); - }; - - view.ProcessKeyDown += (s, e) => - { - processKeyPressInvoked = true; - Assert.False (e.Handled); - Assert.Equal (KeyCode.N, e.KeyCode); - }; - - view.NewKeyDownEvent (Key.N); - Assert.True (invokingKeyBindingsInvoked); - Assert.True (processKeyPressInvoked); - - invokingKeyBindingsInvoked = false; - processKeyPressInvoked = false; - setHandledTo = true; - view.NewKeyDownEvent (Key.N); - Assert.False (invokingKeyBindingsInvoked); - Assert.False (processKeyPressInvoked); - } - - [Fact] - public void KeyPressed_Handled_True_Stops_Processing () - { - var keyDown = false; - var invokingKeyBindings = false; - var keyPressed = false; - - var view = new OnKeyTestView (); - Assert.True (view.CanFocus); - view.CancelVirtualMethods = false; - - view.KeyDown += (s, e) => - { - Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (keyDown); - Assert.False (view.OnKeyDownContinued); - e.Handled = false; - keyDown = true; - }; - - view.InvokingKeyBindings += (s, e) => - { - Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (keyPressed); - Assert.False (view.OnInvokingKeyBindingsContinued); - e.Handled = false; - invokingKeyBindings = true; - }; - - view.ProcessKeyDown += (s, e) => - { - Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (keyPressed); - Assert.False (view.OnKeyPressedContinued); - e.Handled = true; - keyPressed = true; - }; - - view.NewKeyDownEvent (Key.A); - Assert.True (keyDown); - Assert.True (invokingKeyBindings); - Assert.True (keyPressed); - - Assert.True (view.OnKeyDownContinued); - Assert.True (view.OnInvokingKeyBindingsContinued); - Assert.False (view.OnKeyPressedContinued); - } - - [Fact] - public void KeyUp_Handled_True_Stops_Processing () - { - var keyUp = false; - - var view = new OnKeyTestView (); - Assert.True (view.CanFocus); - view.CancelVirtualMethods = false; - - view.KeyUp += (s, e) => - { - Assert.Equal (KeyCode.A, e.KeyCode); - Assert.False (keyUp); - Assert.False (view.OnKeyPressedContinued); - e.Handled = true; - keyUp = true; - }; - - view.NewKeyUpEvent (Key.A); - Assert.True (keyUp); - - Assert.False (view.OnKeyUpContinued); - Assert.False (view.OnKeyDownContinued); - Assert.False (view.OnInvokingKeyBindingsContinued); - Assert.False (view.OnKeyPressedContinued); - } - - [Theory] - [InlineData (null, null)] - [InlineData (true, true)] - [InlineData (false, false)] - public void OnInvokingKeyBindings_Returns_Nullable_Properly (bool? toReturn, bool? expected) - { - var view = new KeyBindingsTestView (); - view.CommandReturns = toReturn; - - bool? result = view.OnInvokingKeyBindings (Key.A, KeyBindingScope.HotKey | KeyBindingScope.Focused); - Assert.Equal (expected, result); - } - - /// A view that overrides the OnKey* methods so we can test that they are called. - public class KeyBindingsTestView : View - { - public KeyBindingsTestView () - { - CanFocus = true; - AddCommand (Command.HotKey, () => CommandReturns); - KeyBindings.Add (Key.A, Command.HotKey); - } - - public bool? CommandReturns { get; set; } - } - - /// A view that overrides the OnKey* methods so we can test that they are called. - public class OnKeyTestView : View - { - public OnKeyTestView () { CanFocus = true; } - public bool CancelVirtualMethods { set; private get; } - public bool OnInvokingKeyBindingsContinued { get; set; } - public bool OnKeyDownContinued { get; set; } - public bool OnKeyPressedContinued { get; set; } - public bool OnKeyUpContinued { get; set; } - public override string Text { get; set; } - - public override bool? OnInvokingKeyBindings (Key keyEvent, KeyBindingScope scope) - { - bool? handled = base.OnInvokingKeyBindings (keyEvent, scope); - - if (handled != null && (bool)handled) - { - return true; - } - - OnInvokingKeyBindingsContinued = true; - - return CancelVirtualMethods; - } - - public override bool OnKeyDown (Key keyEvent) - { - if (base.OnKeyDown (keyEvent)) - { - return true; - } - - OnKeyDownContinued = true; - - return CancelVirtualMethods; - } - - public override bool OnKeyUp (Key keyEvent) - { - if (base.OnKeyUp (keyEvent)) - { - return true; - } - - OnKeyUpContinued = true; - - return CancelVirtualMethods; - } - - public override bool OnProcessKeyDown (Key keyEvent) - { - if (base.OnProcessKeyDown (keyEvent)) - { - return true; - } - - OnKeyPressedContinued = true; - - return CancelVirtualMethods; - } - } -} diff --git a/UnitTests/View/Mouse/MouseEnterLeaveTests.cs b/UnitTests/View/Mouse/MouseEnterLeaveTests.cs index 28c002eba..e91154c5d 100644 --- a/UnitTests/View/Mouse/MouseEnterLeaveTests.cs +++ b/UnitTests/View/Mouse/MouseEnterLeaveTests.cs @@ -63,7 +63,7 @@ public class MouseEnterLeaveTests Visible = true }; - var mouseEvent = new MouseEvent (); + var mouseEvent = new MouseEventArgs (); var eventArgs = new CancelEventArgs (); @@ -136,7 +136,7 @@ public class MouseEnterLeaveTests Enabled = true, Visible = true }; - var mouseEvent = new MouseEvent (); + var mouseEvent = new MouseEventArgs (); // Act view.NewMouseLeaveEvent (); @@ -159,7 +159,7 @@ public class MouseEnterLeaveTests Visible = false }; - var mouseEvent = new MouseEvent (); + var mouseEvent = new MouseEventArgs (); // Act view.NewMouseLeaveEvent (); @@ -256,7 +256,7 @@ public class MouseEnterLeaveTests Visible = true }; - var mouseEvent = new MouseEvent (); + var mouseEvent = new MouseEventArgs (); // Act view.NewMouseLeaveEvent (); @@ -279,7 +279,7 @@ public class MouseEnterLeaveTests Visible = false }; - var mouseEvent = new MouseEvent (); + var mouseEvent = new MouseEventArgs (); // Act view.NewMouseLeaveEvent (); diff --git a/UnitTests/View/Mouse/MouseTests.cs b/UnitTests/View/Mouse/MouseTests.cs index 8c021e3c4..c4b10fe95 100644 --- a/UnitTests/View/Mouse/MouseTests.cs +++ b/UnitTests/View/Mouse/MouseTests.cs @@ -106,9 +106,9 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews Application.Begin (top); Assert.Equal (new Point (4, 4), testView.Frame.Location); - Application.OnMouseEvent (new () { ScreenPosition = new (xy, xy), Flags = MouseFlags.Button1Pressed }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (xy, xy), Flags = MouseFlags.Button1Pressed }); - Application.OnMouseEvent (new () { ScreenPosition = new (xy + 1, xy + 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (xy + 1, xy + 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition }); Assert.Equal (expectedMoved, new Point (5, 5) == testView.Frame.Location); top.Dispose (); @@ -121,9 +121,9 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews { MouseFlags mouseFlagsFromEvent = MouseFlags.None; var view = new View (); - view.MouseEvent += (s, e) => mouseFlagsFromEvent = e.MouseEvent.Flags; + view.MouseEvent += (s, e) => mouseFlagsFromEvent = e.Flags; - view.NewMouseEvent (new MouseEvent () { Flags = mouseFlags }); + view.NewMouseEvent (new MouseEventArgs () { Flags = mouseFlags }); Assert.Equal (mouseFlagsFromEvent, expectedMouseFlagsFromEvent); } @@ -142,7 +142,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews e.Handled = true; }; - MouseEvent me = new (); + MouseEventArgs me = new (); view.NewMouseEvent (me); Assert.True (mouseEventInvoked); Assert.True (me.Handled); @@ -163,7 +163,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews } view.Enabled = false; - var me = new MouseEvent (); + var me = new MouseEventArgs (); view.NewMouseEvent (me); Assert.False (me.Handled); view.Dispose (); @@ -182,7 +182,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews } view.Enabled = false; - var me = new MouseEvent () + var me = new MouseEventArgs () { Flags = MouseFlags.Button1Clicked }; @@ -198,7 +198,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released, MouseFlags.Button4Clicked)] public void WantContinuousButtonPressed_False_Button_Press_Release_DoesNotClick (MouseFlags pressed, MouseFlags released, MouseFlags clicked) { - var me = new MouseEvent (); + var me = new MouseEventArgs (); var view = new View () { @@ -241,7 +241,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews [InlineData (MouseFlags.Button4Clicked)] public void WantContinuousButtonPressed_True_Button_Clicked_Raises_MouseClick (MouseFlags clicked) { - var me = new MouseEvent (); + var me = new MouseEventArgs (); var view = new View () { @@ -269,7 +269,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews [InlineData (MouseFlags.Button4Clicked)] public void WantContinuousButtonPressed_True_Button_Clicked_Raises_Selecting (MouseFlags clicked) { - var me = new MouseEvent (); + var me = new MouseEventArgs (); var view = new View () { @@ -296,7 +296,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released)] public void WantContinuousButtonPressed_True_And_WantMousePositionReports_True_Button_Press_Release_Clicks (MouseFlags pressed, MouseFlags released) { - var me = new MouseEvent (); + var me = new MouseEventArgs (); var view = new View () { @@ -310,9 +310,15 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews view.MouseClick += (s, e) => clickedCount++; + me.Flags = pressed; + view.NewMouseEvent (me); + Assert.Equal (0, clickedCount); + me.Handled = false; + me.Flags = pressed; view.NewMouseEvent (me); Assert.Equal (1, clickedCount); + me.Handled = false; me.Flags = released; view.NewMouseEvent (me); @@ -328,7 +334,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released, MouseFlags.Button4Clicked)] public void WantContinuousButtonPressed_True_And_WantMousePositionReports_True_Button_Press_Release_Clicks_Repeatedly (MouseFlags pressed, MouseFlags released, MouseFlags clicked) { - var me = new MouseEvent (); + var me = new MouseEventArgs (); var view = new View () { @@ -344,22 +350,22 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews me.Flags = pressed; view.NewMouseEvent (me); - Assert.Equal (1, clickedCount); + Assert.Equal (0, clickedCount); me.Handled = false; me.Flags = pressed; view.NewMouseEvent (me); - Assert.Equal (2, clickedCount); + Assert.Equal (1, clickedCount); me.Handled = false; me.Flags = released; view.NewMouseEvent (me); - Assert.Equal (2, clickedCount); + Assert.Equal (1, clickedCount); me.Handled = false; me.Flags = clicked; view.NewMouseEvent (me); - Assert.Equal (2, clickedCount); + Assert.Equal (1, clickedCount); view.Dispose (); Application.ResetState (ignoreDisposed: true); @@ -368,7 +374,7 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews [Fact] public void WantContinuousButtonPressed_True_And_WantMousePositionReports_True_Move_InViewport_OutOfViewport_Keeps_Counting () { - var me = new MouseEvent (); + var me = new MouseEventArgs (); var view = new View () { @@ -386,21 +392,21 @@ public class MouseTests (ITestOutputHelper output) : TestsAllViews me.Flags = MouseFlags.Button1Pressed; me.Position = me.Position with { X = 0 }; view.NewMouseEvent (me); - Assert.Equal (1, clickedCount); + Assert.Equal (0, clickedCount); me.Handled = false; // Move out of Viewport me.Flags = MouseFlags.Button1Pressed; me.Position = me.Position with { X = 1 }; view.NewMouseEvent (me); - Assert.Equal (2, clickedCount); + Assert.Equal (1, clickedCount); me.Handled = false; // Move into Viewport me.Flags = MouseFlags.Button1Pressed; me.Position = me.Position with { X = 0 }; view.NewMouseEvent (me); - Assert.Equal (3, clickedCount); + Assert.Equal (2, clickedCount); me.Handled = false; view.Dispose (); diff --git a/UnitTests/View/Navigation/CanFocusTests.cs b/UnitTests/View/Navigation/CanFocusTests.cs index 006a84dd4..39fa34ad8 100644 --- a/UnitTests/View/Navigation/CanFocusTests.cs +++ b/UnitTests/View/Navigation/CanFocusTests.cs @@ -354,7 +354,7 @@ public class CanFocusTests () : TestsAllViews Assert.False (label.HasFocus); Assert.True (view.HasFocus); - Assert.True (Application.OnKeyDown (Key.Tab)); + Assert.True (Application.RaiseKeyDownEvent (Key.Tab)); Assert.True (label.HasFocus); Assert.False (view.HasFocus); diff --git a/UnitTests/View/Navigation/NavigationTests.cs b/UnitTests/View/Navigation/NavigationTests.cs index e0b666c7f..97aef5df5 100644 --- a/UnitTests/View/Navigation/NavigationTests.cs +++ b/UnitTests/View/Navigation/NavigationTests.cs @@ -59,10 +59,16 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews case TabBehavior.TabStop: case TabBehavior.NoStop: case TabBehavior.TabGroup: - Application.OnKeyDown (key); + Application.RaiseKeyDownEvent (key); + + if (view.HasFocus) + { + // Try once more (HexView) + Application.RaiseKeyDownEvent (key); + } break; default: - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); break; } @@ -170,18 +176,18 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews case null: case TabBehavior.NoStop: case TabBehavior.TabStop: - if (Application.OnKeyDown (Key.Tab)) + if (Application.RaiseKeyDownEvent (Key.Tab)) { if (view.HasFocus) { // Try another nav key (e.g. for TextView that eats Tab) - Application.OnKeyDown (Key.CursorDown); + Application.RaiseKeyDownEvent (Key.CursorDown); } }; break; case TabBehavior.TabGroup: - Application.OnKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); break; default: @@ -203,18 +209,18 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews break; case TabBehavior.TabStop: - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); break; case TabBehavior.TabGroup: - if (!Application.OnKeyDown (Key.F6)) + if (!Application.RaiseKeyDownEvent (Key.F6)) { view.SetFocus (); } break; case null: - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); break; default: @@ -300,12 +306,12 @@ public class NavigationTests (ITestOutputHelper _output) : TestsAllViews Assert.Equal (0, hasFocusChangingCount); Assert.Equal (0, hasFocusChangedCount); - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); Assert.Equal (0, hasFocusChangingCount); Assert.Equal (0, hasFocusChangedCount); - Application.OnKeyDown (Key.F6); + Application.RaiseKeyDownEvent (Key.F6); Assert.Equal (0, hasFocusChangingCount); Assert.Equal (0, hasFocusChangedCount); diff --git a/UnitTests/View/ViewTests.cs b/UnitTests/View/ViewTests.cs index 6f1392a46..1dc072e3a 100644 --- a/UnitTests/View/ViewTests.cs +++ b/UnitTests/View/ViewTests.cs @@ -870,10 +870,10 @@ At 0,0 { var r = new View (); - Assert.False (r.OnKeyDown (new () { KeyCode = KeyCode.Null })); + Assert.False (r.NewKeyDownEvent (Key.Empty)); //Assert.False (r.OnKeyDown (new KeyEventArgs () { Key = Key.Unknown })); - Assert.False (r.OnKeyUp (new () { KeyCode = KeyCode.Null })); + Assert.False (r.NewKeyUpEvent (Key.Empty)); Assert.False (r.NewMouseEvent (new () { Flags = MouseFlags.AllEvents })); r.Dispose (); @@ -1132,7 +1132,7 @@ At 0,0 ClearNeedsDisplay (); } - public override bool OnKeyDown (Key keyEvent) + protected override bool OnKeyDown (Key keyEvent) { IsKeyDown = true; @@ -1146,7 +1146,7 @@ At 0,0 return true; } - public override bool OnProcessKeyDown (Key keyEvent) + protected override bool OnKeyDownNotHandled (Key keyEvent) { IsKeyPress = true; diff --git a/UnitTests/Views/ButtonTests.cs b/UnitTests/Views/ButtonTests.cs index d7f092e80..1029acfd6 100644 --- a/UnitTests/Views/ButtonTests.cs +++ b/UnitTests/Views/ButtonTests.cs @@ -376,7 +376,7 @@ public class ButtonTests (ITestOutputHelper output) Assert.True (btn.HasFocus); // default keybinding is Space which results in Command.Accept (when focused) - Application.OnKeyDown (new ((KeyCode)' ')); + Application.RaiseKeyDownEvent (new ((KeyCode)' ')); Assert.Equal (1, pressed); // remove the default keybinding (Space) @@ -384,26 +384,26 @@ public class ButtonTests (ITestOutputHelper output) btn.KeyBindings.Clear (Command.Accept); // After clearing the default keystroke the Space button no longer does anything for the Button - Application.OnKeyDown (new ((KeyCode)' ')); + Application.RaiseKeyDownEvent (new ((KeyCode)' ')); Assert.Equal (1, pressed); // Set a new binding of b for the click (Accept) event btn.KeyBindings.Add (Key.B, Command.HotKey); // b will now trigger the Accept command (when focused or not) // now pressing B should call the button click event - Application.OnKeyDown (Key.B); + Application.RaiseKeyDownEvent (Key.B); Assert.Equal (2, pressed); // now pressing Shift-B should NOT call the button click event - Application.OnKeyDown (Key.B.WithShift); + Application.RaiseKeyDownEvent (Key.B.WithShift); Assert.Equal (2, pressed); // now pressing Alt-B should NOT call the button click event - Application.OnKeyDown (Key.B.WithAlt); + Application.RaiseKeyDownEvent (Key.B.WithAlt); Assert.Equal (2, pressed); // now pressing Shift-Alt-B should NOT call the button click event - Application.OnKeyDown (Key.B.WithAlt.WithShift); + Application.RaiseKeyDownEvent (Key.B.WithAlt.WithShift); Assert.Equal (2, pressed); top.Dispose (); } @@ -599,7 +599,7 @@ public class ButtonTests (ITestOutputHelper output) [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released, MouseFlags.Button4Clicked)] public void WantContinuousButtonPressed_True_ButtonClick_Accepts (MouseFlags pressed, MouseFlags released, MouseFlags clicked) { - var me = new MouseEvent (); + var me = new MouseEventArgs (); var button = new Button () { @@ -618,19 +618,19 @@ public class ButtonTests (ITestOutputHelper output) e.Cancel = true; }; - me = new MouseEvent (); + me = new MouseEventArgs (); me.Flags = pressed; button.NewMouseEvent (me); Assert.Equal (0, selectingCount); Assert.Equal (0, acceptedCount); - me = new MouseEvent (); + me = new MouseEventArgs (); me.Flags = released; button.NewMouseEvent (me); Assert.Equal (0, selectingCount); Assert.Equal (0, acceptedCount); - me = new MouseEvent (); + me = new MouseEventArgs (); me.Flags = clicked; button.NewMouseEvent (me); Assert.Equal (1, selectingCount); @@ -646,7 +646,7 @@ public class ButtonTests (ITestOutputHelper output) [InlineData (MouseFlags.Button4Pressed, MouseFlags.Button4Released)] public void WantContinuousButtonPressed_True_ButtonPressRelease_Does_Not_Raise_Selected_Or_Accepted (MouseFlags pressed, MouseFlags released) { - var me = new MouseEvent (); + var me = new MouseEventArgs (); var button = new Button () { diff --git a/UnitTests/Views/ColorPickerTests.cs b/UnitTests/Views/ColorPickerTests.cs index 0b5b050c3..754e9e206 100644 --- a/UnitTests/Views/ColorPickerTests.cs +++ b/UnitTests/Views/ColorPickerTests.cs @@ -64,14 +64,14 @@ public class ColorPickerTests cp.Draw (); - Application.OnKeyDown (Key.CursorRight); + Application.RaiseKeyDownEvent (Key.CursorRight); cp.Draw (); Assert.Equal (3, r.TrianglePosition); Assert.Equal ("#0F0000", hex.Text); - Application.OnKeyDown (Key.CursorRight); + Application.RaiseKeyDownEvent (Key.CursorRight); cp.Draw (); @@ -81,7 +81,7 @@ public class ColorPickerTests // Use cursor to move the triangle all the way to the right for (int i = 0; i < 1000; i++) { - Application.OnKeyDown (Key.CursorRight); + Application.RaiseKeyDownEvent (Key.CursorRight); } cp.Draw (); @@ -120,7 +120,7 @@ public class ColorPickerTests Assert.IsAssignableFrom (cp.Focused); - cp.Focused.OnMouseEvent ( + cp.Focused.RaiseMouseEvent ( new () { Flags = MouseFlags.Button1Pressed, @@ -132,7 +132,7 @@ public class ColorPickerTests Assert.Equal (3, r.TrianglePosition); Assert.Equal ("#0F0000", hex.Text); - cp.Focused.OnMouseEvent ( + cp.Focused.RaiseMouseEvent ( new () { Flags = MouseFlags.Button1Pressed, @@ -269,7 +269,7 @@ public class ColorPickerTests cp.Draw (); // Click at the end of the Red bar - cp.Focused.OnMouseEvent ( + cp.Focused.RaiseMouseEvent ( new () { Flags = MouseFlags.Button1Pressed, @@ -303,7 +303,7 @@ public class ColorPickerTests cp.Draw (); // Click beyond the bar - cp.Focused.OnMouseEvent ( + cp.Focused.RaiseMouseEvent ( new () { Flags = MouseFlags.Button1Pressed, @@ -434,7 +434,7 @@ public class ColorPickerTests cp.Draw (); // Click on Green bar - Application.OnMouseEvent (new () + Application.RaiseMouseEvent (new () { Flags = MouseFlags.Button1Pressed, ScreenPosition = new (0, 1) @@ -453,7 +453,7 @@ public class ColorPickerTests Assert.IsAssignableFrom (cp.Focused); // Click on Blue bar - Application.OnMouseEvent (new () + Application.RaiseMouseEvent (new () { Flags = MouseFlags.Button1Pressed, ScreenPosition = new (0, 2) @@ -713,19 +713,19 @@ public class ColorPickerTests name.Text = ""; Assert.Empty (name.Text); - Application.OnKeyDown (Key.A); - Application.OnKeyDown (Key.Q); + Application.RaiseKeyDownEvent (Key.A); + Application.RaiseKeyDownEvent (Key.Q); Assert.Equal ("aq", name.Text); // Auto complete the color name - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); Assert.Equal ("Aquamarine", name.Text); // Tab out of the text field - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); Assert.False (name.HasFocus); Assert.NotSame (name, cp.Focused); @@ -761,24 +761,24 @@ public class ColorPickerTests Assert.Empty (hex.Text); Assert.Empty (name.Text); - Application.OnKeyDown ('#'); + Application.RaiseKeyDownEvent ('#'); Assert.Empty (name.Text); //7FFFD4 Assert.Equal ("#", hex.Text); - Application.OnKeyDown ('7'); - Application.OnKeyDown ('F'); - Application.OnKeyDown ('F'); - Application.OnKeyDown ('F'); - Application.OnKeyDown ('D'); + Application.RaiseKeyDownEvent ('7'); + Application.RaiseKeyDownEvent ('F'); + Application.RaiseKeyDownEvent ('F'); + Application.RaiseKeyDownEvent ('F'); + Application.RaiseKeyDownEvent ('D'); Assert.Empty (name.Text); - Application.OnKeyDown ('4'); + Application.RaiseKeyDownEvent ('4'); Assert.True (hex.HasFocus); // Tab out of the hex field - should wrap to first focusable subview - Application.OnKeyDown (Key.Tab); + Application.RaiseKeyDownEvent (Key.Tab); Assert.False (hex.HasFocus); Assert.NotSame (hex, cp.Focused); @@ -819,24 +819,24 @@ public class ColorPickerTests Assert.Empty (hex.Text); Assert.Empty (name.Text); - Application.OnKeyDown ('#'); + Application.RaiseKeyDownEvent ('#'); Assert.Empty (name.Text); //7FFFD4 Assert.Equal ("#", hex.Text); - Application.OnKeyDown ('7'); - Application.OnKeyDown ('F'); - Application.OnKeyDown ('F'); - Application.OnKeyDown ('F'); - Application.OnKeyDown ('D'); + Application.RaiseKeyDownEvent ('7'); + Application.RaiseKeyDownEvent ('F'); + Application.RaiseKeyDownEvent ('F'); + Application.RaiseKeyDownEvent ('F'); + Application.RaiseKeyDownEvent ('D'); Assert.Empty (name.Text); - Application.OnKeyDown ('4'); + Application.RaiseKeyDownEvent ('4'); Assert.True (hex.HasFocus); // Should stay in the hex field (because accept not tab) - Application.OnKeyDown (Key.Enter); + Application.RaiseKeyDownEvent (Key.Enter); Assert.True (hex.HasFocus); Assert.Same (hex, cp.Focused); diff --git a/UnitTests/Views/ComboBoxTests.cs b/UnitTests/Views/ComboBoxTests.cs index 92cfb8c51..afc435ca4 100644 --- a/UnitTests/Views/ComboBoxTests.cs +++ b/UnitTests/Views/ComboBoxTests.cs @@ -105,13 +105,13 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal (-1, cb.SelectedItem); Assert.Equal ("", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.NotNull (cb.Source); Assert.True (cb.IsShow); Assert.Equal (-1, cb.SelectedItem); Assert.Equal ("", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.Null (cb.Source); Assert.False (cb.IsShow); Assert.Equal (-1, cb.SelectedItem); @@ -137,7 +137,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal (-1, cb.SelectedItem); Assert.Equal ("", cb.Text); - Assert.True (cb.NewMouseEvent (new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed })); + Assert.True (cb.NewMouseEvent (new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed })); Assert.Equal ("", selected); Assert.True (cb.IsShow); Assert.Equal (0, cb.SelectedItem); @@ -155,7 +155,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal (1, cb.SelectedItem); Assert.Equal ("Two", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.Equal ("Two", selected); Assert.True (cb.IsShow); Assert.Equal (1, cb.SelectedItem); @@ -166,7 +166,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal (2, cb.SelectedItem); Assert.Equal ("Three", cb.Text); - Assert.True (Application.OnKeyDown (Key.Esc)); + Assert.True (Application.RaiseKeyDownEvent (Key.Esc)); Assert.Equal ("Two", selected); Assert.False (cb.IsShow); Assert.Equal (1, cb.SelectedItem); @@ -193,7 +193,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -202,7 +202,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal ("One", cb.Text); Assert.True (cb.Subviews [1].NewKeyDownEvent (Key.CursorDown)); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.Equal ("Two", selected); Assert.False (cb.IsShow); Assert.Equal (1, cb.SelectedItem); @@ -231,7 +231,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -251,7 +251,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal (1, cb.SelectedItem); Assert.Equal ("Two", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.Equal ("Two", selected); Assert.True (cb.IsShow); Assert.Equal (1, cb.SelectedItem); @@ -262,7 +262,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal (2, cb.SelectedItem); Assert.Equal ("Three", cb.Text); - Assert.True (Application.OnKeyDown (Key.Esc)); + Assert.True (Application.RaiseKeyDownEvent (Key.Esc)); Assert.Equal ("Two", selected); Assert.False (cb.IsShow); Assert.Equal (1, cb.SelectedItem); @@ -289,7 +289,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -300,7 +300,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (0, 1), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (0, 1), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -311,7 +311,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (0, 1), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (0, 1), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -324,7 +324,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (0, 2), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (0, 2), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("Three", selected); @@ -334,14 +334,14 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (0, 2), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (0, 2), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("Three", selected); @@ -351,7 +351,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("Three", selected); @@ -362,7 +362,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (0, 0), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (0, 0), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("One", selected); @@ -391,14 +391,14 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -409,7 +409,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (-1, 0), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (-1, 0), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -417,12 +417,12 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal (-1, cb.SelectedItem); Assert.Equal ("", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -433,7 +433,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (0, -1), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (0, -1), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -441,12 +441,12 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal (-1, cb.SelectedItem); Assert.Equal ("", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -457,7 +457,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (cb.Frame.Width, 0), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (cb.Frame.Width, 0), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -465,12 +465,12 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.Equal (-1, cb.SelectedItem); Assert.Equal ("", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -481,7 +481,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.Subviews [1] .NewMouseEvent ( - new MouseEvent { Position = new (0, cb.Frame.Height), Flags = MouseFlags.Button1Clicked } + new MouseEventArgs { Position = new (0, cb.Frame.Height), Flags = MouseFlags.Button1Clicked } ) ); Assert.Equal ("", selected); @@ -515,7 +515,7 @@ public class ComboBoxTests (ITestOutputHelper output) Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -595,7 +595,7 @@ Three ", Assert.Equal (2, cb.SelectedItem); Assert.Equal ("Three", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.Equal ("Three", selected); Assert.True (cb.IsShow); Assert.Equal (2, cb.SelectedItem); @@ -646,7 +646,7 @@ Three ", attributes ); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.Equal ("Three", selected); Assert.False (cb.IsShow); Assert.Equal (2, cb.SelectedItem); @@ -673,7 +673,7 @@ Three ", Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -685,7 +685,7 @@ Three ", Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -695,7 +695,7 @@ Three ", Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -707,7 +707,7 @@ Three ", Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -736,7 +736,7 @@ Three ", Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -756,7 +756,7 @@ Three ", Assert.Equal (1, cb.SelectedItem); Assert.Equal ("Two", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.Equal ("Two", selected); Assert.True (cb.IsShow); Assert.Equal (1, cb.SelectedItem); @@ -767,7 +767,7 @@ Three ", Assert.Equal (1, cb.SelectedItem); Assert.Equal ("Two", cb.Text); - Assert.True (Application.OnKeyDown (Key.Esc)); + Assert.True (Application.RaiseKeyDownEvent (Key.Esc)); Assert.Equal ("Two", selected); Assert.False (cb.IsShow); Assert.Equal (1, cb.SelectedItem); @@ -794,7 +794,7 @@ Three ", Assert.True ( cb.NewMouseEvent ( - new MouseEvent { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } + new MouseEventArgs { Position = new (cb.Viewport.Right - 1, 0), Flags = MouseFlags.Button1Pressed } ) ); Assert.Equal ("", selected); @@ -803,7 +803,7 @@ Three ", Assert.Equal ("", cb.Text); Assert.True (cb.Subviews [1].NewKeyDownEvent (Key.CursorDown)); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.Equal ("", selected); Assert.False (cb.IsShow); Assert.Equal (-1, cb.SelectedItem); @@ -834,32 +834,32 @@ Three ", cb.OpenSelectedItem += (s, _) => opened = true; - Assert.False (Application.OnKeyDown (Key.Enter)); + Assert.False (Application.RaiseKeyDownEvent (Key.Enter)); Assert.False (opened); cb.Text = "Tw"; - Assert.False (Application.OnKeyDown (Key.Enter)); + Assert.False (Application.RaiseKeyDownEvent (Key.Enter)); Assert.True (opened); Assert.Equal ("Tw", cb.Text); Assert.False (cb.IsShow); cb.SetSource (null); Assert.False (cb.IsShow); - Assert.False (Application.OnKeyDown (Key.Enter)); - Assert.True (Application.OnKeyDown (Key.F4)); // with no source also expand empty + Assert.False (Application.RaiseKeyDownEvent (Key.Enter)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); // with no source also expand empty Assert.True (cb.IsShow); Assert.Equal (-1, cb.SelectedItem); cb.SetSource (source); cb.Text = ""; - Assert.True (Application.OnKeyDown (Key.F4)); // collapse + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); // collapse Assert.False (cb.IsShow); - Assert.True (Application.OnKeyDown (Key.F4)); // expand + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); // expand Assert.True (cb.IsShow); cb.Collapse (); Assert.False (cb.IsShow); Assert.True (cb.HasFocus); - Assert.True (Application.OnKeyDown (Key.CursorDown)); // losing focus + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); // losing focus Assert.False (cb.IsShow); Assert.False (cb.HasFocus); cb.SetFocus (); @@ -870,27 +870,27 @@ Three ", Assert.True (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); - Assert.True (Application.OnKeyDown (Key.CursorDown)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); Assert.True (cb.IsShow); Assert.Equal (1, cb.SelectedItem); Assert.Equal ("Two", cb.Text); - Assert.True (Application.OnKeyDown (Key.CursorDown)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); Assert.True (cb.IsShow); Assert.Equal (2, cb.SelectedItem); Assert.Equal ("Three", cb.Text); - Assert.True (Application.OnKeyDown (Key.CursorDown)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); Assert.True (cb.IsShow); Assert.Equal (2, cb.SelectedItem); Assert.Equal ("Three", cb.Text); - Assert.True (Application.OnKeyDown (Key.CursorUp)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp)); Assert.True (cb.IsShow); Assert.Equal (1, cb.SelectedItem); Assert.Equal ("Two", cb.Text); - Assert.True (Application.OnKeyDown (Key.CursorUp)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp)); Assert.True (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); - Assert.True (Application.OnKeyDown (Key.CursorUp)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp)); Assert.True (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); @@ -904,7 +904,7 @@ One output ); - Assert.True (Application.OnKeyDown (Key.PageDown)); + Assert.True (Application.RaiseKeyDownEvent (Key.PageDown)); Assert.True (cb.IsShow); Assert.Equal (1, cb.SelectedItem); Assert.Equal ("Two", cb.Text); @@ -919,7 +919,7 @@ Two output ); - Assert.True (Application.OnKeyDown (Key.PageDown)); + Assert.True (Application.RaiseKeyDownEvent (Key.PageDown)); Assert.True (cb.IsShow); Assert.Equal (2, cb.SelectedItem); Assert.Equal ("Three", cb.Text); @@ -933,43 +933,43 @@ Three ", output ); - Assert.True (Application.OnKeyDown (Key.PageUp)); + Assert.True (Application.RaiseKeyDownEvent (Key.PageUp)); Assert.True (cb.IsShow); Assert.Equal (1, cb.SelectedItem); Assert.Equal ("Two", cb.Text); - Assert.True (Application.OnKeyDown (Key.PageUp)); + Assert.True (Application.RaiseKeyDownEvent (Key.PageUp)); Assert.True (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.False (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); - Assert.True (Application.OnKeyDown (Key.End)); + Assert.True (Application.RaiseKeyDownEvent (Key.End)); Assert.False (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); - Assert.True (Application.OnKeyDown (Key.Home)); + Assert.True (Application.RaiseKeyDownEvent (Key.Home)); Assert.False (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.True (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); - Assert.True (Application.OnKeyDown (Key.End)); + Assert.True (Application.RaiseKeyDownEvent (Key.End)); Assert.True (cb.IsShow); Assert.Equal (2, cb.SelectedItem); Assert.Equal ("Three", cb.Text); - Assert.True (Application.OnKeyDown (Key.Home)); + Assert.True (Application.RaiseKeyDownEvent (Key.Home)); Assert.True (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); - Assert.True (Application.OnKeyDown (Key.Esc)); + Assert.True (Application.RaiseKeyDownEvent (Key.Esc)); Assert.False (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("", cb.Text); - Assert.True (Application.OnKeyDown (Key.CursorDown)); // losing focus + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); // losing focus Assert.False (cb.HasFocus); Assert.False (cb.IsShow); Assert.Equal (-1, cb.SelectedItem); @@ -980,7 +980,7 @@ Three Assert.False (cb.IsShow); Assert.Equal (-1, cb.SelectedItem); Assert.Equal ("One", cb.Text); - Assert.True (Application.OnKeyDown (Key.U.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.U.WithCtrl)); Assert.True (cb.HasFocus); Assert.True (cb.IsShow); Assert.Equal (-1, cb.SelectedItem); @@ -1009,7 +1009,7 @@ Three source.Add ("One"); Assert.Equal (1, cb.Source.Count); Assert.Equal (-1, cb.SelectedItem); - Assert.True (Application.OnKeyDown (Key.F4)); + Assert.True (Application.RaiseKeyDownEvent (Key.F4)); Assert.True (cb.IsShow); Assert.Equal (0, cb.SelectedItem); Assert.Equal ("One", cb.Text); @@ -1020,12 +1020,12 @@ Three Assert.True (cb.IsShow); Assert.Equal (-1, cb.SelectedItem); Assert.Equal ("T", cb.Text); - Assert.True (Application.OnKeyDown (Key.Enter)); + Assert.True (Application.RaiseKeyDownEvent (Key.Enter)); Assert.False (cb.IsShow); Assert.Equal (2, cb.Source.Count); Assert.Equal (-1, cb.SelectedItem); Assert.Equal ("T", cb.Text); - Assert.True (Application.OnKeyDown (Key.Esc)); + Assert.True (Application.RaiseKeyDownEvent (Key.Esc)); Assert.False (cb.IsShow); Assert.Equal (-1, cb.SelectedItem); // retains last accept selected item Assert.Equal ("", cb.Text); // clear text diff --git a/UnitTests/Views/ContextMenuTests.cs b/UnitTests/Views/ContextMenuTests.cs index ab9e1448e..1bd08ed72 100644 --- a/UnitTests/Views/ContextMenuTests.cs +++ b/UnitTests/Views/ContextMenuTests.cs @@ -115,11 +115,11 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True (ContextMenu.IsShow); Assert.Equal (cm.MenuBar, Application.MouseGrabView); Assert.False (menu.IsMenuOpen); - Assert.False (menu.NewMouseEvent (new MouseEvent { Position = new (1, 0), Flags = MouseFlags.ReportMousePosition, View = menu })); + Assert.False (menu.NewMouseEvent (new MouseEventArgs { Position = new (1, 0), Flags = MouseFlags.ReportMousePosition, View = menu })); Assert.True (ContextMenu.IsShow); Assert.Equal (cm.MenuBar, Application.MouseGrabView); Assert.False (menu.IsMenuOpen); - Assert.True (menu.NewMouseEvent (new MouseEvent { Position = new (1, 0), Flags = MouseFlags.Button1Clicked, View = menu })); + Assert.True (menu.NewMouseEvent (new MouseEventArgs { Position = new (1, 0), Flags = MouseFlags.Button1Clicked, View = menu })); Assert.False (ContextMenu.IsShow); Assert.Equal (menu, Application.MouseGrabView); Assert.True (menu.IsMenuOpen); @@ -148,7 +148,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new MouseEvent { ScreenPosition = new (8, 2), Flags = MouseFlags.Button3Clicked }); + Application.RaiseMouseEvent (new MouseEventArgs { ScreenPosition = new (8, 2), Flags = MouseFlags.Button3Clicked }); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -231,7 +231,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new MouseEvent { ScreenPosition = new (9, 3), Flags = MouseFlags.Button3Clicked }); + Application.RaiseMouseEvent (new MouseEventArgs { ScreenPosition = new (9, 3), Flags = MouseFlags.Button3Clicked }); var firstIteration = false; Application.RunIteration (ref rsDialog, ref firstIteration); @@ -287,7 +287,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new MouseEvent { ScreenPosition = new (9, 3), Flags = MouseFlags.Button3Clicked }); + Application.RaiseMouseEvent (new MouseEventArgs { ScreenPosition = new (9, 3), Flags = MouseFlags.Button3Clicked }); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -400,9 +400,9 @@ public class ContextMenuTests (ITestOutputHelper output) top.Add (tf); Application.Begin (top); - Assert.True (Application.OnKeyDown (ContextMenu.DefaultKey)); + Assert.True (Application.RaiseKeyDownEvent (ContextMenu.DefaultKey)); Assert.True (tf.ContextMenu.MenuBar!.IsMenuOpen); - Assert.True (Application.OnKeyDown (ContextMenu.DefaultKey)); + Assert.True (Application.RaiseKeyDownEvent (ContextMenu.DefaultKey)); // The last context menu bar opened is always preserved Assert.NotNull (tf.ContextMenu.MenuBar); @@ -532,7 +532,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True ( top.Subviews [0] .NewMouseEvent ( - new MouseEvent { Position = new (0, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } + new MouseEventArgs { Position = new (0, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } ) ); Application.Refresh (); @@ -580,7 +580,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True ( top.Subviews [0] .NewMouseEvent ( - new MouseEvent { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } + new MouseEventArgs { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } ) ); Application.Refresh (); @@ -627,7 +627,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True ( top.Subviews [0] .NewMouseEvent ( - new MouseEvent { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } + new MouseEventArgs { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } ) ); Application.Refresh (); @@ -671,7 +671,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True ( top.Subviews [0] .NewMouseEvent ( - new MouseEvent { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } + new MouseEventArgs { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } ) ); Application.Refresh (); @@ -715,7 +715,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True ( top.Subviews [0] .NewMouseEvent ( - new MouseEvent { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } + new MouseEventArgs { Position = new (30, 3), Flags = MouseFlags.ReportMousePosition, View = top.Subviews [0] } ) ); Application.Refresh (); @@ -747,7 +747,7 @@ public class ContextMenuTests (ITestOutputHelper output) lbl.MouseClick += (s, e) => { - if (e.MouseEvent.Flags == cm.MouseFlags) + if (e.Flags == cm.MouseFlags) { lbl.Text = "Replaced"; e.Handled = true; @@ -758,12 +758,12 @@ public class ContextMenuTests (ITestOutputHelper output) top.Add (lbl); Application.Begin (top); - Assert.True (lbl.NewMouseEvent (new MouseEvent { Flags = cm.MouseFlags })); + Assert.True (lbl.NewMouseEvent (new MouseEventArgs { Flags = cm.MouseFlags })); Assert.Equal ("Replaced", lbl.Text); lbl.Text = "Original"; cm.MouseFlags = MouseFlags.Button2Clicked; - Assert.True (lbl.NewMouseEvent (new MouseEvent { Flags = cm.MouseFlags })); + Assert.True (lbl.NewMouseEvent (new MouseEventArgs { Flags = cm.MouseFlags })); Assert.Equal ("Replaced", lbl.Text); top.Dispose (); } @@ -1235,7 +1235,7 @@ public class ContextMenuTests (ITestOutputHelper output) ); // X=5 is the border and so need to use at least one more - Application.OnMouseEvent (new MouseEvent { ScreenPosition = new (6, 13), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new MouseEventArgs { ScreenPosition = new (6, 13), Flags = MouseFlags.Button1Clicked }); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1253,7 +1253,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new MouseEvent { ScreenPosition = new (6, 12), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new MouseEventArgs { ScreenPosition = new (6, 12), Flags = MouseFlags.Button1Clicked }); firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1327,7 +1327,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new MouseEvent { ScreenPosition = new (6, 13), Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new MouseEventArgs { ScreenPosition = new (6, 13), Flags = MouseFlags.ReportMousePosition }); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1344,7 +1344,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new MouseEvent { ScreenPosition = new (6, 14), Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new MouseEventArgs { ScreenPosition = new (6, 14), Flags = MouseFlags.ReportMousePosition }); firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1362,7 +1362,7 @@ public class ContextMenuTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new MouseEvent { ScreenPosition = new (6, 13), Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new MouseEventArgs { ScreenPosition = new (6, 13), Flags = MouseFlags.ReportMousePosition }); firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1399,7 +1399,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.Empty (Application._cachedViewsUnderMouse); // Right click on tf2 to open context menu - Application.OnMouseEvent (new () { ScreenPosition = new (1, 3), Flags = MouseFlags.Button3Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (1, 3), Flags = MouseFlags.Button3Clicked }); Assert.False (tf1.HasFocus); Assert.False (tf2.HasFocus); Assert.Equal (5, win.Subviews.Count); @@ -1409,7 +1409,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.Equal (tf2, Application._cachedViewsUnderMouse.LastOrDefault ()); // Click on tf1 to focus it, which cause context menu being closed - Application.OnMouseEvent (new () { ScreenPosition = new (1, 1), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (1, 1), Flags = MouseFlags.Button1Clicked }); Assert.True (tf1.HasFocus); Assert.False (tf2.HasFocus); Assert.Equal (4, win.Subviews.Count); @@ -1421,7 +1421,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.Equal (tf1, Application._cachedViewsUnderMouse.LastOrDefault ()); // Click on tf2 to focus it - Application.OnMouseEvent (new () { ScreenPosition = new (1, 3), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (1, 3), Flags = MouseFlags.Button1Clicked }); Assert.False (tf1.HasFocus); Assert.True (tf2.HasFocus); Assert.Equal (4, win.Subviews.Count); @@ -1473,9 +1473,9 @@ public class ContextMenuTests (ITestOutputHelper output) Application.Begin (top); Assert.Null (cm.MenuBar); - Assert.False (Application.OnKeyDown (Key.N.WithCtrl)); - Assert.False (Application.OnKeyDown (Key.R.WithCtrl)); - Assert.False (Application.OnKeyDown (Key.D.WithCtrl)); + Assert.False (Application.RaiseKeyDownEvent (Key.N.WithCtrl)); + Assert.False (Application.RaiseKeyDownEvent (Key.R.WithCtrl)); + Assert.False (Application.RaiseKeyDownEvent (Key.D.WithCtrl)); Assert.False (newFile); Assert.False (renameFile); Assert.False (deleteFile); @@ -1485,17 +1485,17 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.R.WithCtrl)); Assert.True (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.D.WithCtrl)); - Assert.True (Application.OnKeyDown (Key.N.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.True (newFile); Assert.False (cm.MenuBar!.IsMenuOpen); cm.Show (menuItems); - Assert.True (Application.OnKeyDown (Key.R.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.R.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.True (renameFile); Assert.False (cm.MenuBar.IsMenuOpen); cm.Show (menuItems); - Assert.True (Application.OnKeyDown (Key.D.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.D.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.True (deleteFile); Assert.False (cm.MenuBar.IsMenuOpen); @@ -1507,9 +1507,9 @@ public class ContextMenuTests (ITestOutputHelper output) newFile = false; renameFile = false; deleteFile = false; - Assert.False (Application.OnKeyDown (Key.N.WithCtrl)); - Assert.False (Application.OnKeyDown (Key.R.WithCtrl)); - Assert.False (Application.OnKeyDown (Key.D.WithCtrl)); + Assert.False (Application.RaiseKeyDownEvent (Key.N.WithCtrl)); + Assert.False (Application.RaiseKeyDownEvent (Key.R.WithCtrl)); + Assert.False (Application.RaiseKeyDownEvent (Key.D.WithCtrl)); Assert.False (newFile); Assert.False (renameFile); Assert.False (deleteFile); @@ -1557,8 +1557,8 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.False (menuBar.KeyBindings.Bindings.ContainsKey (Key.R.WithCtrl)); Assert.Null (cm.MenuBar); - Assert.True (Application.OnKeyDown (Key.N.WithCtrl)); - Assert.False (Application.OnKeyDown (Key.R.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithCtrl)); + Assert.False (Application.RaiseKeyDownEvent (Key.R.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.True (newFile); Assert.False (renameFile); @@ -1572,12 +1572,12 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True (cm.MenuBar.KeyBindings.Bindings.ContainsKey (Key.R.WithCtrl)); Assert.True (cm.MenuBar.IsMenuOpen); - Assert.True (Application.OnKeyDown (Key.N.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.True (newFile); Assert.False (cm.MenuBar!.IsMenuOpen); cm.Show (menuItems); - Assert.True (Application.OnKeyDown (Key.R.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.R.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.True (renameFile); Assert.False (cm.MenuBar.IsMenuOpen); @@ -1589,8 +1589,8 @@ public class ContextMenuTests (ITestOutputHelper output) newFile = false; renameFile = false; - Assert.True (Application.OnKeyDown (Key.N.WithCtrl)); - Assert.False (Application.OnKeyDown (Key.R.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithCtrl)); + Assert.False (Application.RaiseKeyDownEvent (Key.R.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.True (newFile); Assert.False (renameFile); @@ -1635,7 +1635,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True (menuBar.KeyBindings.Bindings.ContainsKey (Key.N.WithCtrl)); Assert.Null (cm.MenuBar); - Assert.True (Application.OnKeyDown (Key.N.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.True (newMenuBar); Assert.False (newContextMenu); @@ -1647,7 +1647,7 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True (cm.MenuBar!.KeyBindings.Bindings.ContainsKey (Key.N.WithCtrl)); Assert.True (cm.MenuBar.IsMenuOpen); - Assert.True (Application.OnKeyDown (Key.N.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.False (newMenuBar); @@ -1660,7 +1660,7 @@ public class ContextMenuTests (ITestOutputHelper output) newMenuBar = false; newContextMenu = false; - Assert.True (Application.OnKeyDown (Key.N.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithCtrl)); Application.MainLoop!.RunIteration (); Assert.True (newMenuBar); Assert.False (newContextMenu); @@ -1693,9 +1693,9 @@ public class ContextMenuTests (ITestOutputHelper output) Application.Begin (top); Assert.Null (cm.MenuBar); - Assert.False (Application.OnKeyDown (Key.N.WithAlt)); - Assert.False (Application.OnKeyDown (Key.R.WithAlt)); - Assert.False (Application.OnKeyDown (Key.D.WithAlt)); + Assert.False (Application.RaiseKeyDownEvent (Key.N.WithAlt)); + Assert.False (Application.RaiseKeyDownEvent (Key.R.WithAlt)); + Assert.False (Application.RaiseKeyDownEvent (Key.D.WithAlt)); Assert.False (newFile); Assert.False (renameFile); Assert.False (deleteFile); @@ -1717,17 +1717,17 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True (menus [0].KeyBindings.Bindings.ContainsKey (Key.D.WithAlt)); Assert.True (menus [0].KeyBindings.Bindings.ContainsKey (Key.D.NoShift)); - Assert.True (Application.OnKeyDown (Key.N.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithAlt)); Assert.False (cm.MenuBar!.IsMenuOpen); Application.MainLoop!.RunIteration (); Assert.True (newFile); cm.Show (menuItems); - Assert.True (Application.OnKeyDown (Key.R.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.R.WithAlt)); Assert.False (cm.MenuBar.IsMenuOpen); Application.MainLoop!.RunIteration (); Assert.True (renameFile); cm.Show (menuItems); - Assert.True (Application.OnKeyDown (Key.D.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.D.WithAlt)); Assert.False (cm.MenuBar.IsMenuOpen); Application.MainLoop!.RunIteration (); Assert.True (deleteFile); @@ -1742,9 +1742,9 @@ public class ContextMenuTests (ITestOutputHelper output) newFile = false; renameFile = false; deleteFile = false; - Assert.False (Application.OnKeyDown (Key.N.WithAlt)); - Assert.False (Application.OnKeyDown (Key.R.WithAlt)); - Assert.False (Application.OnKeyDown (Key.D.WithAlt)); + Assert.False (Application.RaiseKeyDownEvent (Key.N.WithAlt)); + Assert.False (Application.RaiseKeyDownEvent (Key.R.WithAlt)); + Assert.False (Application.RaiseKeyDownEvent (Key.D.WithAlt)); Assert.False (newFile); Assert.False (renameFile); Assert.False (deleteFile); @@ -1801,14 +1801,14 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.Empty (menus); Assert.Null (cm.MenuBar); - Assert.True (Application.OnKeyDown (Key.F.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.F.WithAlt)); Assert.True (menuBar.IsMenuOpen); Assert.Equal (2, Application.Top!.Subviews.Count); menus = Application.Top!.Subviews.Where (v => v is Menu m && m.Host == menuBar).ToArray (); Assert.True (menus [0].KeyBindings.Bindings.ContainsKey (Key.N.WithAlt)); - Assert.True (Application.OnKeyDown (Key.N.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithAlt)); Assert.False (menuBar.IsMenuOpen); - Assert.False (Application.OnKeyDown (Key.R.WithAlt)); + Assert.False (Application.RaiseKeyDownEvent (Key.R.WithAlt)); Application.MainLoop!.RunIteration (); Assert.True (newFile); Assert.False (renameFile); @@ -1840,9 +1840,9 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.True (menus [1].KeyBindings.Bindings.ContainsKey (Key.R.WithAlt)); Assert.True (menus [1].KeyBindings.Bindings.ContainsKey (Key.R.NoShift)); Assert.True (cm.MenuBar.IsMenuOpen); - Assert.True (Application.OnKeyDown (Key.F.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.F.WithAlt)); Assert.False (cm.MenuBar.IsMenuOpen); - Assert.True (Application.OnKeyDown (Key.N.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithAlt)); Application.MainLoop!.RunIteration (); Assert.True (newFile); @@ -1858,8 +1858,8 @@ public class ContextMenuTests (ITestOutputHelper output) Assert.False (menus [1].KeyBindings.Bindings.ContainsKey (Key.E.NoShift)); Assert.True (menus [1].KeyBindings.Bindings.ContainsKey (Key.R.WithAlt)); Assert.True (menus [1].KeyBindings.Bindings.ContainsKey (Key.R.NoShift)); - Assert.True (Application.OnKeyDown (Key.E.NoShift)); - Assert.True (Application.OnKeyDown (Key.R.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.E.NoShift)); + Assert.True (Application.RaiseKeyDownEvent (Key.R.WithAlt)); Assert.False (cm.MenuBar.IsMenuOpen); Application.MainLoop!.RunIteration (); Assert.True (renameFile); @@ -1876,9 +1876,9 @@ public class ContextMenuTests (ITestOutputHelper output) newFile = false; renameFile = false; - Assert.True (Application.OnKeyDown (Key.F.WithAlt)); - Assert.True (Application.OnKeyDown (Key.N.WithAlt)); - Assert.False (Application.OnKeyDown (Key.R.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.F.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.N.WithAlt)); + Assert.False (Application.RaiseKeyDownEvent (Key.R.WithAlt)); Application.MainLoop!.RunIteration (); Assert.True (newFile); Assert.False (renameFile); @@ -1923,14 +1923,14 @@ public class ContextMenuTests (ITestOutputHelper output) top.Add (menuBar); Application.Begin (top); - Assert.True (Application.OnKeyDown (Key.F.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.F.WithAlt)); Assert.True (menuBar.IsMenuOpen); cm.Show (menuItems); Assert.False (menuBar.IsMenuOpen); Assert.True (cm.MenuBar!.IsMenuOpen); - Assert.True (Application.OnKeyDown (Key.F.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.F.WithAlt)); Assert.True (menuBar.IsMenuOpen); Assert.False (cm.MenuBar!.IsMenuOpen); diff --git a/UnitTests/Views/DatePickerTests.cs b/UnitTests/Views/DatePickerTests.cs index fd78ac432..75761d94f 100644 --- a/UnitTests/Views/DatePickerTests.cs +++ b/UnitTests/Views/DatePickerTests.cs @@ -82,7 +82,7 @@ public class DatePickerTests Assert.Equal (datePicker.Subviews.First (v => v.Id == "_nextMonthButton"), datePicker.Focused); // Change month to December - Assert.False (Application.OnKeyDown (Key.Enter)); + Assert.False (Application.RaiseKeyDownEvent (Key.Enter)); Assert.Equal (12, datePicker.Date.Month); // Next month button is disabled, so focus advanced to edit field diff --git a/UnitTests/Views/LabelTests.cs b/UnitTests/Views/LabelTests.cs index 2e3982fe7..80f1e2b7c 100644 --- a/UnitTests/Views/LabelTests.cs +++ b/UnitTests/Views/LabelTests.cs @@ -1341,7 +1341,7 @@ e Application.Top.SetFocus (); Assert.True (otherView.HasFocus); - Assert.True (Application.OnKeyDown (label.HotKey)); + Assert.True (Application.RaiseKeyDownEvent (label.HotKey)); Assert.False (otherView.HasFocus); Assert.False (label.HasFocus); Assert.True (nextView.HasFocus); @@ -1364,7 +1364,7 @@ e Application.Top.SetFocus (); // click on label - Application.OnMouseEvent (new () { ScreenPosition = label.Frame.Location, Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = label.Frame.Location, Flags = MouseFlags.Button1Clicked }); Assert.False (label.HasFocus); Assert.True (nextView.HasFocus); @@ -1396,7 +1396,7 @@ e Assert.True (view.HasFocus); // No focused view accepts Tab, and there's no other view to focus, so OnKeyDown returns false - Assert.True (Application.OnKeyDown (label.HotKey)); + Assert.True (Application.RaiseKeyDownEvent (label.HotKey)); Assert.True (label.HasFocus); Assert.False (view.HasFocus); @@ -1442,12 +1442,12 @@ e Assert.True (otherView.HasFocus); // label can focus, so clicking on it set focus - Application.OnMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Clicked }); Assert.True (label.HasFocus); Assert.False (otherView.HasFocus); // click on view - Application.OnMouseEvent (new () { ScreenPosition = new (0, 1), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 1), Flags = MouseFlags.Button1Clicked }); Assert.False (label.HasFocus); Assert.True (otherView.HasFocus); diff --git a/UnitTests/Views/ListViewTests.cs b/UnitTests/Views/ListViewTests.cs index ff84f1b2f..1f5553c2c 100644 --- a/UnitTests/Views/ListViewTests.cs +++ b/UnitTests/Views/ListViewTests.cs @@ -522,7 +522,7 @@ Item 6", } [Fact] - public void ListViewSelectThenDown () + public void AllowsMarking_True_SpaceWithShift_SelectsThenDown () { var lv = new ListView { Source = new ListWrapper (["One", "Two", "Three"]) }; lv.AllowsMarking = true; @@ -537,12 +537,8 @@ Item 6", Assert.False (lv.Source.IsMarked (1)); Assert.False (lv.Source.IsMarked (2)); - lv.KeyBindings.Add (Key.Space.WithShift, Command.Select, Command.Down); - - Key ev = Key.Space.WithShift; - // view should indicate that it has accepted and consumed the event - Assert.True (lv.NewKeyDownEvent (ev)); + Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift)); // first item should now be selected Assert.Equal (0, lv.SelectedItem); @@ -553,7 +549,7 @@ Item 6", Assert.False (lv.Source.IsMarked (2)); // Press key combo again - Assert.True (lv.NewKeyDownEvent (ev)); + Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift)); // second item should now be selected Assert.Equal (1, lv.SelectedItem); @@ -564,21 +560,21 @@ Item 6", Assert.False (lv.Source.IsMarked (2)); // Press key combo again - Assert.True (lv.NewKeyDownEvent (ev)); + Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift)); Assert.Equal (2, lv.SelectedItem); Assert.True (lv.Source.IsMarked (0)); Assert.True (lv.Source.IsMarked (1)); Assert.False (lv.Source.IsMarked (2)); // Press key combo again - Assert.True (lv.NewKeyDownEvent (ev)); + Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift)); Assert.Equal (2, lv.SelectedItem); // cannot move down any further Assert.True (lv.Source.IsMarked (0)); Assert.True (lv.Source.IsMarked (1)); Assert.True (lv.Source.IsMarked (2)); // but can toggle marked // Press key combo again - Assert.True (lv.NewKeyDownEvent (ev)); + Assert.True (lv.NewKeyDownEvent (Key.Space.WithShift)); Assert.Equal (2, lv.SelectedItem); // cannot move down any further Assert.True (lv.Source.IsMarked (0)); Assert.True (lv.Source.IsMarked (1)); @@ -741,11 +737,11 @@ Item 6", └─────┘", output); - Application.OnMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Clicked }); Assert.Equal ("", selected); Assert.Equal (-1, lv.SelectedItem); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (1, 1), Flags = MouseFlags.Button1Clicked @@ -753,7 +749,7 @@ Item 6", Assert.Equal ("One", selected); Assert.Equal (0, lv.SelectedItem); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (1, 2), Flags = MouseFlags.Button1Clicked @@ -761,7 +757,7 @@ Item 6", Assert.Equal ("Two", selected); Assert.Equal (1, lv.SelectedItem); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (1, 3), Flags = MouseFlags.Button1Clicked @@ -769,7 +765,7 @@ Item 6", Assert.Equal ("Three", selected); Assert.Equal (2, lv.SelectedItem); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (1, 4), Flags = MouseFlags.Button1Clicked diff --git a/UnitTests/Views/MenuBarTests.cs b/UnitTests/Views/MenuBarTests.cs index 736e79890..7ef68bfe2 100644 --- a/UnitTests/Views/MenuBarTests.cs +++ b/UnitTests/Views/MenuBarTests.cs @@ -243,7 +243,7 @@ public class MenuBarTests (ITestOutputHelper output) top.Add (menu, btn); Application.Begin (top); - Application.OnMouseEvent (new () { ScreenPosition = new (0, 4), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 4), Flags = MouseFlags.Button1Clicked }); Assert.True (btnClicked); top.Dispose (); } @@ -613,7 +613,7 @@ public class MenuBarTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new () { ScreenPosition = new (20, 5), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (20, 5), Flags = MouseFlags.Button1Clicked }); firstIteration = false; @@ -646,7 +646,7 @@ public class MenuBarTests (ITestOutputHelper output) { menu.OpenMenu (); - Application.OnMouseEvent (new () { ScreenPosition = new (20, 5 + i), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (20, 5 + i), Flags = MouseFlags.Button1Clicked }); firstIteration = false; Application.RunIteration (ref rsDialog, ref firstIteration); @@ -809,7 +809,7 @@ public class MenuBarTests (ITestOutputHelper output) output ); - Application.OnMouseEvent (new () { ScreenPosition = new (20, 5), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (20, 5), Flags = MouseFlags.Button1Clicked }); firstIteration = false; @@ -831,7 +831,7 @@ public class MenuBarTests (ITestOutputHelper output) { menu.OpenMenu (); - Application.OnMouseEvent (new () { ScreenPosition = new (20, 5 + i), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (20, 5 + i), Flags = MouseFlags.Button1Clicked }); firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1384,7 +1384,7 @@ wo foreach (Key key in keys) { - top.NewKeyDownEvent (new (key)); + top.NewKeyDownEvent (key); Application.MainLoop.RunIteration (); } @@ -2666,7 +2666,7 @@ Edit top.Draw (); TestHelpers.AssertDriverContentsAre (expectedMenu.ExpectedSubMenuOpen (0), output); - Assert.True (Application.OnKeyDown (menu.Key)); + Assert.True (Application.RaiseKeyDownEvent (menu.Key)); Assert.False (menu.IsMenuOpen); Assert.True (tf.HasFocus); top.Draw (); @@ -2949,7 +2949,7 @@ Edit top.Add (menu); Application.Begin (top); - Application.OnKeyDown (Key.S.WithCtrl); + Application.RaiseKeyDownEvent (Key.S.WithCtrl); Application.MainLoop.RunIteration (); Assert.True (saveAction); diff --git a/UnitTests/Views/RadioGroupTests.cs b/UnitTests/Views/RadioGroupTests.cs index 48fc88119..ad0ccd630 100644 --- a/UnitTests/Views/RadioGroupTests.cs +++ b/UnitTests/Views/RadioGroupTests.cs @@ -57,7 +57,7 @@ public class RadioGroupTests (ITestOutputHelper output) rg.SetFocus (); Assert.Equal (-1, rg.SelectedItem); - Application.OnKeyDown (Key.Space); + Application.RaiseKeyDownEvent (Key.Space); Assert.Equal (0, rg.SelectedItem); Application.Top.Dispose (); @@ -105,21 +105,21 @@ public class RadioGroupTests (ITestOutputHelper output) // With HasFocus // Test up/down without Select - Assert.False (Application.OnKeyDown (Key.CursorUp)); // Should not change (should focus prev view if there was one, which there isn't) + Assert.False (Application.RaiseKeyDownEvent (Key.CursorUp)); // Should not change (should focus prev view if there was one, which there isn't) Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); Assert.Equal (0, selectedItemChangedCount); Assert.Equal (0, selectingCount); Assert.Equal (0, acceptedCount); - Assert.True (Application.OnKeyDown (Key.CursorDown)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); Assert.Equal (0, rg.SelectedItem); // Cursor changed, but selection didnt Assert.Equal (1, rg.Cursor); Assert.Equal (0, selectedItemChangedCount); Assert.Equal (0, selectingCount); Assert.Equal (0, acceptedCount); - Assert.False (Application.OnKeyDown (Key.CursorDown)); // Should not change selection (should focus next view if there was one, which there isn't) + Assert.False (Application.RaiseKeyDownEvent (Key.CursorDown)); // Should not change selection (should focus next view if there was one, which there isn't) Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); Assert.Equal (0, selectedItemChangedCount); @@ -127,7 +127,7 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (0, acceptedCount); // Test Select (Space) when Cursor != SelectedItem - Should select cursor - Assert.True (Application.OnKeyDown (Key.Space)); + Assert.True (Application.RaiseKeyDownEvent (Key.Space)); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); Assert.Equal (1, selectedItemChangedCount); @@ -135,34 +135,34 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (0, acceptedCount); // Test Select (Space) when Cursor == SelectedItem - Should cycle - Assert.True (Application.OnKeyDown (Key.Space)); + Assert.True (Application.RaiseKeyDownEvent (Key.Space)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); Assert.Equal (2, selectedItemChangedCount); Assert.Equal (2, selectingCount); Assert.Equal (0, acceptedCount); - Assert.True (Application.OnKeyDown (Key.Space)); + Assert.True (Application.RaiseKeyDownEvent (Key.Space)); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); - Assert.True (Application.OnKeyDown (Key.Space)); + Assert.True (Application.RaiseKeyDownEvent (Key.Space)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); - Assert.True (Application.OnKeyDown (Key.Space)); + Assert.True (Application.RaiseKeyDownEvent (Key.Space)); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); - Assert.True (Application.OnKeyDown (Key.Home)); + Assert.True (Application.RaiseKeyDownEvent (Key.Home)); Assert.Equal (1, rg.SelectedItem); Assert.Equal (0, rg.Cursor); - Assert.True (Application.OnKeyDown (Key.Space)); + Assert.True (Application.RaiseKeyDownEvent (Key.Space)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); - Assert.True (Application.OnKeyDown (Key.End)); + Assert.True (Application.RaiseKeyDownEvent (Key.End)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); - Assert.True (Application.OnKeyDown (Key.Space)); + Assert.True (Application.RaiseKeyDownEvent (Key.Space)); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); Assert.Equal (7, selectedItemChangedCount); @@ -174,7 +174,7 @@ public class RadioGroupTests (ITestOutputHelper output) rg.HotKey = Key.L; Assert.Equal (Key.L, rg.HotKey); - Assert.True (Application.OnKeyDown (rg.HotKey)); + Assert.True (Application.RaiseKeyDownEvent (rg.HotKey)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); Assert.Equal (8, selectedItemChangedCount); @@ -182,12 +182,12 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (0, acceptedCount); // Make Selected != Cursor - Assert.True (Application.OnKeyDown (Key.CursorDown)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); // Selected != Cursor - Raise HotKey event - Since we're focused, this should just advance - Assert.True (Application.OnKeyDown (rg.HotKey)); + Assert.True (Application.RaiseKeyDownEvent (rg.HotKey)); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); Assert.Equal (9, selectedItemChangedCount); @@ -239,7 +239,7 @@ public class RadioGroupTests (ITestOutputHelper output) // Selected (0) == Cursor (0) - SetFocus rg.HotKey = Key.L; Assert.Equal (Key.L, rg.HotKey); - Assert.True (Application.OnKeyDown (rg.HotKey)); + Assert.True (Application.RaiseKeyDownEvent (rg.HotKey)); Assert.True (rg.HasFocus); Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); @@ -248,14 +248,14 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (0, acceptCount); // Make Selected != Cursor - Assert.True (Application.OnKeyDown (Key.CursorDown)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); otherView.SetFocus (); // Selected != Cursor - SetFocus - Assert.True (Application.OnKeyDown (rg.HotKey)); + Assert.True (Application.RaiseKeyDownEvent (rg.HotKey)); Assert.True (rg.HasFocus); Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); @@ -263,7 +263,7 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (0, selectCount); Assert.Equal (0, acceptCount); - Assert.True (Application.OnKeyDown (rg.HotKey)); + Assert.True (Application.RaiseKeyDownEvent (rg.HotKey)); Assert.True (rg.HasFocus); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); @@ -314,7 +314,7 @@ public class RadioGroupTests (ITestOutputHelper output) // Test RadioTitem.HotKey - Should never SetFocus // Selected (0) == Cursor (0) - Assert.True (Application.OnKeyDown (Key.A)); + Assert.True (Application.RaiseKeyDownEvent (Key.A)); Assert.False (rg.HasFocus); Assert.Equal (0, rg.SelectedItem); Assert.Equal (0, rg.Cursor); @@ -325,14 +325,14 @@ public class RadioGroupTests (ITestOutputHelper output) rg.SetFocus (); // Make Selected != Cursor - Assert.True (Application.OnKeyDown (Key.CursorDown)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); otherView.SetFocus (); // Selected != Cursor - Assert.True (Application.OnKeyDown (Key.A)); + Assert.True (Application.RaiseKeyDownEvent (Key.A)); Assert.False (rg.HasFocus); Assert.Equal (0, rg.SelectedItem); Assert.Equal (1, rg.Cursor); @@ -341,7 +341,7 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (0, acceptCount); // Selected != Cursor - Should not set focus - Assert.True (Application.OnKeyDown (Key.B)); + Assert.True (Application.RaiseKeyDownEvent (Key.B)); Assert.False (rg.HasFocus); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); @@ -349,7 +349,7 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.Equal (1, selectCount); Assert.Equal (0, acceptCount); - Assert.True (Application.OnKeyDown (Key.B)); + Assert.True (Application.RaiseKeyDownEvent (Key.B)); Assert.False (rg.HasFocus); Assert.Equal (1, rg.SelectedItem); Assert.Equal (1, rg.Cursor); @@ -372,22 +372,22 @@ public class RadioGroupTests (ITestOutputHelper output) Assert.NotEmpty (rg.KeyBindings.GetCommands (KeyCode.L | KeyCode.ShiftMask)); Assert.NotEmpty (rg.KeyBindings.GetCommands (KeyCode.L | KeyCode.AltMask)); - Assert.True (Application.OnKeyDown (Key.T)); + Assert.True (Application.RaiseKeyDownEvent (Key.T)); Assert.Equal (2, rg.SelectedItem); - Assert.True (Application.OnKeyDown (Key.L)); + Assert.True (Application.RaiseKeyDownEvent (Key.L)); Assert.Equal (0, rg.SelectedItem); - Assert.True (Application.OnKeyDown (Key.J)); + Assert.True (Application.RaiseKeyDownEvent (Key.J)); Assert.Equal (3, rg.SelectedItem); - Assert.True (Application.OnKeyDown (Key.R)); + Assert.True (Application.RaiseKeyDownEvent (Key.R)); Assert.Equal (1, rg.SelectedItem); - Assert.True (Application.OnKeyDown (Key.T.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.T.WithAlt)); Assert.Equal (2, rg.SelectedItem); - Assert.True (Application.OnKeyDown (Key.L.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.L.WithAlt)); Assert.Equal (0, rg.SelectedItem); - Assert.True (Application.OnKeyDown (Key.J.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.J.WithAlt)); Assert.Equal (3, rg.SelectedItem); - Assert.True (Application.OnKeyDown (Key.R.WithAlt)); + Assert.True (Application.RaiseKeyDownEvent (Key.R.WithAlt)); Assert.Equal (1, rg.SelectedItem); var superView = new View (); diff --git a/UnitTests/Views/ScrollBarViewTests.cs b/UnitTests/Views/ScrollBarViewTests.cs index 989962d00..51ce8d965 100644 --- a/UnitTests/Views/ScrollBarViewTests.cs +++ b/UnitTests/Views/ScrollBarViewTests.cs @@ -1176,7 +1176,7 @@ This is a test ", _output ); - Application.OnMouseEvent (new MouseEvent { Position = new (15, 0), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new MouseEventArgs { Position = new (15, 0), Flags = MouseFlags.Button1Clicked }); Assert.Null (Application.MouseGrabView); Assert.True (clicked); @@ -1200,7 +1200,7 @@ This is a test ", _output ); - Application.OnMouseEvent (new MouseEvent { Position = new (15, 0), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new MouseEventArgs { Position = new (15, 0), Flags = MouseFlags.Button1Clicked }); Assert.Null (Application.MouseGrabView); Assert.True (clicked); diff --git a/UnitTests/Views/ScrollViewTests.cs b/UnitTests/Views/ScrollViewTests.cs index 149ad2c1d..e7caf1d31 100644 --- a/UnitTests/Views/ScrollViewTests.cs +++ b/UnitTests/Views/ScrollViewTests.cs @@ -579,7 +579,7 @@ public class ScrollViewTests (ITestOutputHelper output) Rectangle pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.CursorRight)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorRight)); top.Draw (); expected = @" @@ -603,7 +603,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.CursorRight)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorRight)); top.Draw (); expected = @" @@ -627,7 +627,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.CursorRight)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorRight)); top.Draw (); expected = @" @@ -651,7 +651,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.CursorRight)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorRight)); top.Draw (); expected = @" @@ -675,7 +675,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.CursorRight)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorRight)); top.Draw (); expected = @" @@ -699,7 +699,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.CursorRight)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorRight)); top.Draw (); expected = @" @@ -723,7 +723,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.CursorRight)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorRight)); top.Draw (); expected = @" @@ -746,7 +746,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.End.WithCtrl)); + Assert.True (scrollView.NewKeyDownEvent (Key.End.WithCtrl)); top.Draw (); expected = @" @@ -769,8 +769,8 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.Home.WithCtrl)); - Assert.True (scrollView.OnKeyDown (Key.CursorDown)); + Assert.True (scrollView.NewKeyDownEvent (Key.Home.WithCtrl)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorDown)); top.Draw (); expected = @" @@ -793,7 +793,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.CursorDown)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorDown)); top.Draw (); expected = @" @@ -816,7 +816,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.CursorDown)); + Assert.True (scrollView.NewKeyDownEvent (Key.CursorDown)); top.Draw (); expected = @" @@ -839,7 +839,7 @@ public class ScrollViewTests (ITestOutputHelper output) pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); Assert.Equal (new (1, 1, 21, 14), pos); - Assert.True (scrollView.OnKeyDown (Key.End)); + Assert.True (scrollView.NewKeyDownEvent (Key.End)); top.Draw (); expected = @" @@ -941,120 +941,120 @@ public class ScrollViewTests (ITestOutputHelper output) Assert.True (sv.KeepContentAlwaysInViewport); Assert.True (sv.AutoHideScrollBars); Assert.Equal (Point.Empty, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.CursorUp)); + Assert.False (sv.NewKeyDownEvent (Key.CursorUp)); Assert.Equal (Point.Empty, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.CursorDown)); + Assert.True (sv.NewKeyDownEvent (Key.CursorDown)); Assert.Equal (new (0, -1), sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.CursorUp)); + Assert.True (sv.NewKeyDownEvent (Key.CursorUp)); Assert.Equal (Point.Empty, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.PageUp)); + Assert.False (sv.NewKeyDownEvent (Key.PageUp)); Assert.Equal (Point.Empty, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.PageDown)); + Assert.True (sv.NewKeyDownEvent (Key.PageDown)); Point point0xMinus10 = new (0, -10); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.PageDown)); + Assert.False (sv.NewKeyDownEvent (Key.PageDown)); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.CursorDown)); + Assert.False (sv.NewKeyDownEvent (Key.CursorDown)); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.V.WithAlt)); + Assert.True (sv.NewKeyDownEvent (Key.V.WithAlt)); Assert.Equal (Point.Empty, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.V.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.V.WithCtrl)); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.CursorLeft)); + Assert.False (sv.NewKeyDownEvent (Key.CursorLeft)); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.CursorRight)); + Assert.True (sv.NewKeyDownEvent (Key.CursorRight)); Assert.Equal (new (-1, -10), sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.CursorLeft)); + Assert.True (sv.NewKeyDownEvent (Key.CursorLeft)); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.PageUp.WithCtrl)); + Assert.False (sv.NewKeyDownEvent (Key.PageUp.WithCtrl)); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.PageDown.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.PageDown.WithCtrl)); Point pointMinus20xMinus10 = new (-20, -10); Assert.Equal (pointMinus20xMinus10, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.CursorRight)); + Assert.False (sv.NewKeyDownEvent (Key.CursorRight)); Assert.Equal (pointMinus20xMinus10, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.Home)); + Assert.True (sv.NewKeyDownEvent (Key.Home)); Point pointMinus20x0 = new (-20, 0); Assert.Equal (pointMinus20x0, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.Home)); + Assert.False (sv.NewKeyDownEvent (Key.Home)); Assert.Equal (pointMinus20x0, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.End)); + Assert.True (sv.NewKeyDownEvent (Key.End)); Assert.Equal (pointMinus20xMinus10, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.End)); + Assert.False (sv.NewKeyDownEvent (Key.End)); Assert.Equal (pointMinus20xMinus10, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.Home.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.Home.WithCtrl)); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.Home.WithCtrl)); + Assert.False (sv.NewKeyDownEvent (Key.Home.WithCtrl)); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.End.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.End.WithCtrl)); Assert.Equal (pointMinus20xMinus10, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.End.WithCtrl)); + Assert.False (sv.NewKeyDownEvent (Key.End.WithCtrl)); Assert.Equal (pointMinus20xMinus10, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.Home)); + Assert.True (sv.NewKeyDownEvent (Key.Home)); Assert.Equal (pointMinus20x0, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.Home.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.Home.WithCtrl)); Assert.Equal (Point.Empty, sv.ContentOffset); sv.KeepContentAlwaysInViewport = false; Assert.False (sv.KeepContentAlwaysInViewport); Assert.True (sv.AutoHideScrollBars); Assert.Equal (Point.Empty, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.CursorUp)); + Assert.False (sv.NewKeyDownEvent (Key.CursorUp)); Assert.Equal (Point.Empty, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.CursorDown)); + Assert.True (sv.NewKeyDownEvent (Key.CursorDown)); Assert.Equal (new (0, -1), sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.CursorUp)); + Assert.True (sv.NewKeyDownEvent (Key.CursorUp)); Assert.Equal (Point.Empty, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.PageUp)); + Assert.False (sv.NewKeyDownEvent (Key.PageUp)); Assert.Equal (Point.Empty, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.PageDown)); + Assert.True (sv.NewKeyDownEvent (Key.PageDown)); Assert.Equal (point0xMinus10, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.PageDown)); + Assert.True (sv.NewKeyDownEvent (Key.PageDown)); Point point0xMinus19 = new (0, -19); Assert.Equal (point0xMinus19, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.PageDown)); + Assert.False (sv.NewKeyDownEvent (Key.PageDown)); Assert.Equal (point0xMinus19, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.CursorDown)); + Assert.False (sv.NewKeyDownEvent (Key.CursorDown)); Assert.Equal (point0xMinus19, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.V.WithAlt)); + Assert.True (sv.NewKeyDownEvent (Key.V.WithAlt)); Assert.Equal (new (0, -9), sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.V.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.V.WithCtrl)); Assert.Equal (point0xMinus19, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.CursorLeft)); + Assert.False (sv.NewKeyDownEvent (Key.CursorLeft)); Assert.Equal (point0xMinus19, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.CursorRight)); + Assert.True (sv.NewKeyDownEvent (Key.CursorRight)); Assert.Equal (new (-1, -19), sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.CursorLeft)); + Assert.True (sv.NewKeyDownEvent (Key.CursorLeft)); Assert.Equal (point0xMinus19, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.PageUp.WithCtrl)); + Assert.False (sv.NewKeyDownEvent (Key.PageUp.WithCtrl)); Assert.Equal (point0xMinus19, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.PageDown.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.PageDown.WithCtrl)); Assert.Equal (new (-20, -19), sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.PageDown.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.PageDown.WithCtrl)); Point pointMinus39xMinus19 = new (-39, -19); Assert.Equal (pointMinus39xMinus19, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.PageDown.WithCtrl)); + Assert.False (sv.NewKeyDownEvent (Key.PageDown.WithCtrl)); Assert.Equal (pointMinus39xMinus19, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.CursorRight)); + Assert.False (sv.NewKeyDownEvent (Key.CursorRight)); Assert.Equal (pointMinus39xMinus19, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.PageUp.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.PageUp.WithCtrl)); var pointMinus19xMinus19 = new Point (-19, -19); Assert.Equal (pointMinus19xMinus19, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.Home)); + Assert.True (sv.NewKeyDownEvent (Key.Home)); Assert.Equal (new (-19, 0), sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.Home)); + Assert.False (sv.NewKeyDownEvent (Key.Home)); Assert.Equal (new (-19, 0), sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.End)); + Assert.True (sv.NewKeyDownEvent (Key.End)); Assert.Equal (pointMinus19xMinus19, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.End)); + Assert.False (sv.NewKeyDownEvent (Key.End)); Assert.Equal (pointMinus19xMinus19, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.Home.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.Home.WithCtrl)); Assert.Equal (point0xMinus19, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.Home.WithCtrl)); + Assert.False (sv.NewKeyDownEvent (Key.Home.WithCtrl)); Assert.Equal (point0xMinus19, sv.ContentOffset); - Assert.True (sv.OnKeyDown (Key.End.WithCtrl)); + Assert.True (sv.NewKeyDownEvent (Key.End.WithCtrl)); Assert.Equal (pointMinus39xMinus19, sv.ContentOffset); - Assert.False (sv.OnKeyDown (Key.End.WithCtrl)); + Assert.False (sv.NewKeyDownEvent (Key.End.WithCtrl)); Assert.Equal (pointMinus39xMinus19, sv.ContentOffset); } diff --git a/UnitTests/Views/ShortcutTests.cs b/UnitTests/Views/ShortcutTests.cs index dc3ab6e1c..160f57439 100644 --- a/UnitTests/Views/ShortcutTests.cs +++ b/UnitTests/Views/ShortcutTests.cs @@ -424,7 +424,7 @@ public class ShortcutTests var accepted = 0; shortcut.Accepting += (s, e) => accepted++; - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (x, 0), @@ -484,7 +484,7 @@ public class ShortcutTests Application.Top.SetRelativeLayout (new (100, 100)); Application.Top.LayoutSubviews (); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (mouseX, 0), @@ -541,7 +541,7 @@ public class ShortcutTests var accepted = 0; shortcut.Accepting += (s, e) => { accepted++; }; - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (mouseX, 0), @@ -616,7 +616,7 @@ public class ShortcutTests e.Cancel = true; }; - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (mouseX, 0), @@ -667,7 +667,7 @@ public class ShortcutTests var selected = 0; shortcut.Selecting += (s, e) => selected++; - Application.OnKeyDown (key); + Application.RaiseKeyDownEvent (key); Assert.Equal (expectedAccept, accepted); Assert.Equal (expectedSelect, selected); @@ -719,7 +719,7 @@ public class ShortcutTests var selected = 0; shortcut.Selecting += (s, e) => selected++; - Application.OnKeyDown (key); + Application.RaiseKeyDownEvent (key); Assert.Equal (expectedAccept, accepted); Assert.Equal (expectedSelect, selected); @@ -751,7 +751,7 @@ public class ShortcutTests var accepted = 0; shortcut.Accepting += (s, e) => accepted++; - Application.OnKeyDown (key); + Application.RaiseKeyDownEvent (key); Assert.Equal (expectedAccept, accepted); @@ -792,7 +792,7 @@ public class ShortcutTests var action = 0; shortcut.Action += () => action++; - Application.OnKeyDown (key); + Application.RaiseKeyDownEvent (key); Assert.Equal (expectedAction, action); @@ -831,7 +831,7 @@ public class ShortcutTests var action = 0; shortcut.Action += () => action++; - Application.OnKeyDown (key); + Application.RaiseKeyDownEvent (key); Assert.Equal (expectedAction, action); diff --git a/UnitTests/Views/StatusBarTests.cs b/UnitTests/Views/StatusBarTests.cs index 2622d807f..f9c6fcd3b 100644 --- a/UnitTests/Views/StatusBarTests.cs +++ b/UnitTests/Views/StatusBarTests.cs @@ -104,7 +104,7 @@ public class StatusBarTests if (iteration == 0) { Assert.Equal ("", msg); - Application.OnKeyDown (Application.QuitKey); + Application.RaiseKeyDownEvent (Application.QuitKey); } else if (iteration == 1) { diff --git a/UnitTests/Views/TabViewTests.cs b/UnitTests/Views/TabViewTests.cs index 660434b66..037f106e4 100644 --- a/UnitTests/Views/TabViewTests.cs +++ b/UnitTests/Views/TabViewTests.cs @@ -138,27 +138,27 @@ public class TabViewTests (ITestOutputHelper output) top.Add (tv); Application.Begin (top); - MouseEvent args; + MouseEventArgs args; // Waving mouse around does not trigger click for (var i = 0; i < 100; i++) { args = new () { ScreenPosition = new (i, 1), Flags = MouseFlags.ReportMousePosition }; - Application.OnMouseEvent (args); + Application.RaiseMouseEvent (args); Application.Refresh (); Assert.Null (clicked); Assert.Equal (tab1, tv.SelectedTab); } args = new () { ScreenPosition = new (3, 1), Flags = MouseFlags.Button1Clicked }; - Application.OnMouseEvent (args); + Application.RaiseMouseEvent (args); Application.Refresh (); Assert.Equal (tab1, clicked); Assert.Equal (tab1, tv.SelectedTab); // Click to tab2 args = new () { ScreenPosition = new (6, 1), Flags = MouseFlags.Button1Clicked }; - Application.OnMouseEvent (args); + Application.RaiseMouseEvent (args); Application.Refresh (); Assert.Equal (tab2, clicked); Assert.Equal (tab2, tv.SelectedTab); @@ -171,7 +171,7 @@ public class TabViewTests (ITestOutputHelper output) }; args = new () { ScreenPosition = new (3, 1), Flags = MouseFlags.Button1Clicked }; - Application.OnMouseEvent (args); + Application.RaiseMouseEvent (args); Application.Refresh (); // Tab 1 was clicked but event handler blocked navigation @@ -179,7 +179,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tab2, tv.SelectedTab); args = new () { ScreenPosition = new (12, 1), Flags = MouseFlags.Button1Clicked }; - Application.OnMouseEvent (args); + Application.RaiseMouseEvent (args); Application.Refresh (); // Clicking beyond last tab should raise event with null Tab @@ -233,8 +233,8 @@ public class TabViewTests (ITestOutputHelper output) Application.Begin (top); // Click the right arrow - var args = new MouseEvent { ScreenPosition = new (6, 2), Flags = MouseFlags.Button1Clicked }; - Application.OnMouseEvent (args); + var args = new MouseEventArgs { ScreenPosition = new (6, 2), Flags = MouseFlags.Button1Clicked }; + Application.RaiseMouseEvent (args); Application.Refresh (); Assert.Null (clicked); Assert.Equal (tab1, oldChanged); @@ -254,7 +254,7 @@ public class TabViewTests (ITestOutputHelper output) // Click the left arrow args = new () { ScreenPosition = new (0, 2), Flags = MouseFlags.Button1Clicked }; - Application.OnMouseEvent (args); + Application.RaiseMouseEvent (args); Application.Refresh (); Assert.Null (clicked); Assert.Equal (tab2, oldChanged); @@ -324,8 +324,8 @@ public class TabViewTests (ITestOutputHelper output) Application.Begin (top); // Click the right arrow - var args = new MouseEvent { ScreenPosition = new (7, 3), Flags = MouseFlags.Button1Clicked }; - Application.OnMouseEvent (args); + var args = new MouseEventArgs { ScreenPosition = new (7, 3), Flags = MouseFlags.Button1Clicked }; + Application.RaiseMouseEvent (args); Application.Refresh (); Assert.Null (clicked); Assert.Equal (tab1, oldChanged); @@ -347,7 +347,7 @@ public class TabViewTests (ITestOutputHelper output) // Click the left arrow args = new () { ScreenPosition = new (1, 3), Flags = MouseFlags.Button1Clicked }; - Application.OnMouseEvent (args); + Application.RaiseMouseEvent (args); Application.Refresh (); Assert.Null (clicked); Assert.Equal (tab2, oldChanged); @@ -398,7 +398,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tv.SelectedTab.View, top.Focused.MostFocused); // Press the cursor up key to focus the selected tab - Application.OnKeyDown (Key.CursorUp); + Application.RaiseKeyDownEvent (Key.CursorUp); Application.Refresh (); // Is the selected tab focused @@ -416,7 +416,7 @@ public class TabViewTests (ITestOutputHelper output) }; // Press the cursor right key to select the next tab - Application.OnKeyDown (Key.CursorRight); + Application.RaiseKeyDownEvent (Key.CursorRight); Application.Refresh (); Assert.Equal (tab1, oldChanged); Assert.Equal (tab2, newChanged); @@ -425,7 +425,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tv.MostFocused, top.Focused.MostFocused); // Press the cursor down key. Since the selected tab has no focusable views, the focus should move to the next view in the toplevel - Application.OnKeyDown (Key.CursorDown); + Application.RaiseKeyDownEvent (Key.CursorDown); Assert.Equal (tab2, tv.SelectedTab); Assert.Equal (btn, top.MostFocused); @@ -439,31 +439,31 @@ public class TabViewTests (ITestOutputHelper output) tv.SelectedTab.View.Add (btnSubView); // Press cursor up. Should focus the subview in the selected tab. - Application.OnKeyDown (Key.CursorUp); + Application.RaiseKeyDownEvent (Key.CursorUp); Assert.Equal (tab2, tv.SelectedTab); Assert.Equal (btnSubView, top.MostFocused); - Application.OnKeyDown (Key.CursorUp); + Application.RaiseKeyDownEvent (Key.CursorUp); Assert.Equal (tab2, top.MostFocused); // Press the cursor down key twice. - Application.OnKeyDown (Key.CursorDown); - Application.OnKeyDown (Key.CursorDown); + Application.RaiseKeyDownEvent (Key.CursorDown); + Application.RaiseKeyDownEvent (Key.CursorDown); Assert.Equal (btn, top.MostFocused); // Press the cursor down key again will focus next view in the toplevel, whic is the TabView - Application.OnKeyDown (Key.CursorDown); + Application.RaiseKeyDownEvent (Key.CursorDown); Assert.Equal (tab2, tv.SelectedTab); Assert.Equal (tv, top.Focused); Assert.Equal (tab1, tv.MostFocused); // Press the cursor down key to focus the selected tab view hosting again - Application.OnKeyDown (Key.CursorDown); + Application.RaiseKeyDownEvent (Key.CursorDown); Assert.Equal (tab2, tv.SelectedTab); Assert.Equal (btnSubView, top.MostFocused); // Press the cursor up key to focus the selected tab - Application.OnKeyDown (Key.CursorUp); + Application.RaiseKeyDownEvent (Key.CursorUp); Application.Refresh (); // Is the selected tab focused @@ -472,7 +472,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tv.MostFocused, top.Focused.MostFocused); // Press the cursor left key to select the previous tab - Application.OnKeyDown (Key.CursorLeft); + Application.RaiseKeyDownEvent (Key.CursorLeft); Application.Refresh (); Assert.Equal (tab2, oldChanged); Assert.Equal (tab1, newChanged); @@ -481,7 +481,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tv.MostFocused, top.Focused.MostFocused); // Press the end key to select the last tab - Application.OnKeyDown (Key.End); + Application.RaiseKeyDownEvent (Key.End); Application.Refresh (); Assert.Equal (tab1, oldChanged); Assert.Equal (tab2, newChanged); @@ -490,7 +490,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tv.MostFocused, top.Focused.MostFocused); // Press the home key to select the first tab - Application.OnKeyDown (Key.Home); + Application.RaiseKeyDownEvent (Key.Home); Application.Refresh (); Assert.Equal (tab2, oldChanged); Assert.Equal (tab1, newChanged); @@ -499,7 +499,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tv.MostFocused, top.Focused.MostFocused); // Press the page down key to select the next set of tabs - Application.OnKeyDown (Key.PageDown); + Application.RaiseKeyDownEvent (Key.PageDown); Application.Refresh (); Assert.Equal (tab1, oldChanged); Assert.Equal (tab2, newChanged); @@ -508,7 +508,7 @@ public class TabViewTests (ITestOutputHelper output) Assert.Equal (tv.MostFocused, top.Focused.MostFocused); // Press the page up key to select the previous set of tabs - Application.OnKeyDown (Key.PageUp); + Application.RaiseKeyDownEvent (Key.PageUp); Application.Refresh (); Assert.Equal (tab2, oldChanged); Assert.Equal (tab1, newChanged); diff --git a/UnitTests/Views/TableViewTests.cs b/UnitTests/Views/TableViewTests.cs index 6bb982988..5c6a3c204 100644 --- a/UnitTests/Views/TableViewTests.cs +++ b/UnitTests/Views/TableViewTests.cs @@ -3215,12 +3215,12 @@ A B C tableView.SelectedColumn = 1; // Pressing left should move us to the first column without changing focus - Application.OnKeyDown (Key.CursorLeft); + Application.RaiseKeyDownEvent (Key.CursorLeft); Assert.Same (tableView, Application.Top!.MostFocused); Assert.True (tableView.HasFocus); // Because we are now on the leftmost cell a further left press should move focus - Application.OnKeyDown (Key.CursorLeft); + Application.RaiseKeyDownEvent (Key.CursorLeft); Assert.NotSame (tableView, Application.Top.MostFocused); Assert.False (tableView.HasFocus); @@ -3240,12 +3240,12 @@ A B C tableView.SelectedRow = 1; // First press should move us up - Application.OnKeyDown (Key.CursorUp); + Application.RaiseKeyDownEvent (Key.CursorUp); Assert.Same (tableView, Application.Top!.MostFocused); Assert.True (tableView.HasFocus); // Because we are now on the top row a further press should move focus - Application.OnKeyDown (Key.CursorUp); + Application.RaiseKeyDownEvent (Key.CursorUp); Assert.NotSame (tableView, Application.Top.MostFocused); Assert.False (tableView.HasFocus); @@ -3264,12 +3264,12 @@ A B C tableView.SelectedColumn = tableView.Table.Columns - 2; // First press should move us to the rightmost column without changing focus - Application.OnKeyDown (Key.CursorRight); + Application.RaiseKeyDownEvent (Key.CursorRight); Assert.Same (tableView, Application.Top!.MostFocused); Assert.True (tableView.HasFocus); // Because we are now on the rightmost cell, a further right press should move focus - Application.OnKeyDown (Key.CursorRight); + Application.RaiseKeyDownEvent (Key.CursorRight); Assert.NotSame (tableView, Application.Top.MostFocused); Assert.False (tableView.HasFocus); @@ -3289,12 +3289,12 @@ A B C tableView.SelectedRow = tableView.Table.Rows - 2; // First press should move us to the bottommost row without changing focus - Application.OnKeyDown (Key.CursorDown); + Application.RaiseKeyDownEvent (Key.CursorDown); Assert.Same (tableView, Application.Top!.MostFocused); Assert.True (tableView.HasFocus); // Because we are now on the bottommost cell, a further down press should move focus - Application.OnKeyDown (Key.CursorDown); + Application.RaiseKeyDownEvent (Key.CursorDown); Assert.NotSame (tableView, Application.Top.MostFocused); Assert.False (tableView.HasFocus); @@ -3315,7 +3315,7 @@ A B C tableView.SelectedColumn = 1; // Pressing shift-left should give us a multi selection - Application.OnKeyDown (Key.CursorLeft.WithShift); + Application.RaiseKeyDownEvent (Key.CursorLeft.WithShift); Assert.Same (tableView, Application.Top!.MostFocused); Assert.True (tableView.HasFocus); Assert.Equal (2, tableView.GetAllSelectedCells ().Count ()); @@ -3323,7 +3323,7 @@ A B C // Because we are now on the leftmost cell a further left press would normally move focus // However there is an ongoing selection so instead the operation clears the selection and // gets swallowed (not resulting in a focus change) - Application.OnKeyDown (Key.CursorLeft); + Application.RaiseKeyDownEvent (Key.CursorLeft); // Selection 'clears' just to the single cell and we remain focused Assert.Single (tableView.GetAllSelectedCells ()); @@ -3331,7 +3331,7 @@ A B C Assert.True (tableView.HasFocus); // A further left will switch focus - Application.OnKeyDown (Key.CursorLeft); + Application.RaiseKeyDownEvent (Key.CursorLeft); Assert.NotSame (tableView, Application.Top.MostFocused); Assert.False (tableView.HasFocus); diff --git a/UnitTests/Views/TextFieldTests.cs b/UnitTests/Views/TextFieldTests.cs index d2f8ba4c5..478e1d00b 100644 --- a/UnitTests/Views/TextFieldTests.cs +++ b/UnitTests/Views/TextFieldTests.cs @@ -524,7 +524,7 @@ public class TextFieldTests (ITestOutputHelper output) Application.Top = new (); Application.Top.Add (tf); tf.SetFocus (); - Application.OnKeyDown (Key.Space); + Application.RaiseKeyDownEvent (Key.Space); Application.Top.Dispose (); Application.ResetState (true); @@ -541,7 +541,7 @@ public class TextFieldTests (ITestOutputHelper output) Application.Top = new (); Application.Top.Add (tf); tf.SetFocus (); - Application.OnKeyDown (Key.Enter); + Application.RaiseKeyDownEvent (Key.Enter); Assert.Equal (0, selectingCount); @@ -560,7 +560,7 @@ public class TextFieldTests (ITestOutputHelper output) Application.Top = new (); Application.Top.Add (tf); tf.SetFocus (); - Application.OnKeyDown (Key.Enter); + Application.RaiseKeyDownEvent (Key.Enter); Assert.Equal (1, acceptedCount); @@ -1178,15 +1178,15 @@ public class TextFieldTests (ITestOutputHelper output) top.Add (tf); Application.Begin (top); - var mouseEvent = new MouseEvent { Flags = MouseFlags.Button1Clicked, View = tf }; + var mouseEvent = new MouseEventArgs { Flags = MouseFlags.Button1Clicked, View = tf }; - Application.OnMouseEvent (mouseEvent); + Application.RaiseMouseEvent (mouseEvent); Assert.Equal (1, clickCounter); // Get a fresh instance that represents a right click. // Should be ignored because of SuppressRightClick callback mouseEvent = new () { Flags = MouseFlags.Button3Clicked, View = tf }; - Application.OnMouseEvent (mouseEvent); + Application.RaiseMouseEvent (mouseEvent); Assert.Equal (1, clickCounter); Application.MouseEvent -= HandleRightClick; @@ -1199,13 +1199,13 @@ public class TextFieldTests (ITestOutputHelper output) // This call causes the context menu to pop, and MouseEvent() returns true. // Thus, the clickCounter is NOT incremented. // Which is correct, because the user did NOT click with the left mouse button. - Application.OnMouseEvent (mouseEvent); + Application.RaiseMouseEvent (mouseEvent); Assert.Equal (1, clickCounter); top.Dispose (); return; - void HandleRightClick (object sender, MouseEvent arg) + void HandleRightClick (object sender, MouseEventArgs arg) { if (arg.Flags.HasFlag (MouseFlags.Button3Clicked)) { @@ -1293,7 +1293,7 @@ public class TextFieldTests (ITestOutputHelper output) { var tf = new TextField { Width = 10, Text = " " }; - var ev = new MouseEvent { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }; + var ev = new MouseEventArgs { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }; tf.NewMouseEvent (ev); Assert.Equal (1, tf.SelectedLength); diff --git a/UnitTests/Views/TextValidateFieldTests.cs b/UnitTests/Views/TextValidateFieldTests.cs index 96a0d6d17..35258bb42 100644 --- a/UnitTests/Views/TextValidateFieldTests.cs +++ b/UnitTests/Views/TextValidateFieldTests.cs @@ -322,7 +322,7 @@ public class TextValidateField_NET_Provider_Tests Assert.False (field.IsValid); Assert.Equal ("--(1 )--", field.Provider.Text); - field.NewMouseEvent (new MouseEvent { Position = new (25, 0), Flags = MouseFlags.Button1Pressed }); + field.NewMouseEvent (new MouseEventArgs { Position = new (25, 0), Flags = MouseFlags.Button1Pressed }); field.NewKeyDownEvent (Key.D1); diff --git a/UnitTests/Views/TextViewTests.cs b/UnitTests/Views/TextViewTests.cs index a912064f6..7dc1f9858 100644 --- a/UnitTests/Views/TextViewTests.cs +++ b/UnitTests/Views/TextViewTests.cs @@ -130,7 +130,7 @@ public class TextViewTests Assert.False (fv.CanFocus); Assert.False (fv.HasFocus); - tv.NewMouseEvent (new MouseEvent { Position = new (1, 0), Flags = MouseFlags.Button1DoubleClicked }); + tv.NewMouseEvent (new MouseEventArgs { Position = new (1, 0), Flags = MouseFlags.Button1DoubleClicked }); Assert.Empty (tv.SelectedText); Assert.False (tv.CanFocus); @@ -140,7 +140,7 @@ public class TextViewTests fv.CanFocus = true; tv.CanFocus = true; - tv.NewMouseEvent (new MouseEvent { Position = new (1, 0), Flags = MouseFlags.Button1DoubleClicked }); + tv.NewMouseEvent (new MouseEventArgs { Position = new (1, 0), Flags = MouseFlags.Button1DoubleClicked }); Assert.Equal ("some ", tv.SelectedText); Assert.True (tv.CanFocus); @@ -149,7 +149,7 @@ public class TextViewTests Assert.True (fv.HasFocus); fv.CanFocus = false; - tv.NewMouseEvent (new MouseEvent { Position = new (1, 0), Flags = MouseFlags.Button1DoubleClicked }); + tv.NewMouseEvent (new MouseEventArgs { Position = new (1, 0), Flags = MouseFlags.Button1DoubleClicked }); Assert.Equal ("some ", tv.SelectedText); // Setting CanFocus to false don't change the SelectedText Assert.True (tv.CanFocus); // v2: CanFocus is not longer automatically changed @@ -1025,7 +1025,7 @@ This is the second line. for (var i = 0; i < 12; i++) { - tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledRight }); + tv.NewMouseEvent (new MouseEventArgs { Flags = MouseFlags.WheeledRight }); Assert.Equal (Math.Min (i + 1, 11), tv.LeftColumn); Application.PositionCursor (); Application.Driver!.GetCursorVisibility (out CursorVisibility cursorVisibility); @@ -1034,7 +1034,7 @@ This is the second line. for (var i = 11; i > 0; i--) { - tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledLeft }); + tv.NewMouseEvent (new MouseEventArgs { Flags = MouseFlags.WheeledLeft }); Assert.Equal (i - 1, tv.LeftColumn); Application.PositionCursor (); @@ -1077,7 +1077,7 @@ This is the second line. for (var i = 0; i < 12; i++) { - tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledDown }); + tv.NewMouseEvent (new MouseEventArgs { Flags = MouseFlags.WheeledDown }); Application.PositionCursor (); Assert.Equal (i + 1, tv.TopRow); Application.Driver!.GetCursorVisibility (out CursorVisibility cursorVisibility); @@ -1086,7 +1086,7 @@ This is the second line. for (var i = 12; i > 0; i--) { - tv.NewMouseEvent (new MouseEvent { Flags = MouseFlags.WheeledUp }); + tv.NewMouseEvent (new MouseEventArgs { Flags = MouseFlags.WheeledUp }); Application.PositionCursor (); Assert.Equal (i - 1, tv.TopRow); @@ -6166,7 +6166,7 @@ This is the second line. Assert.True ( _textView.NewMouseEvent ( - new MouseEvent { Position = new (12, 0), Flags = MouseFlags.Button1Pressed | MouseFlags.ButtonShift } + new MouseEventArgs { Position = new (12, 0), Flags = MouseFlags.Button1Pressed | MouseFlags.ButtonShift } ) ); Assert.Equal (0, _textView.SelectionStartColumn); @@ -6175,7 +6175,7 @@ This is the second line. Assert.True (_textView.IsSelecting); Assert.Equal ("TAB to jump ", _textView.SelectedText); - Assert.True (_textView.NewMouseEvent (new MouseEvent { Position = new (12, 0), Flags = MouseFlags.Button1Clicked })); + Assert.True (_textView.NewMouseEvent (new MouseEventArgs { Position = new (12, 0), Flags = MouseFlags.Button1Clicked })); Assert.Equal (0, _textView.SelectionStartRow); Assert.Equal (0, _textView.SelectionStartRow); Assert.Equal (new Point (12, 0), _textView.CursorPosition); @@ -6184,7 +6184,7 @@ This is the second line. Assert.True ( _textView.NewMouseEvent ( - new MouseEvent { Position = new (19, 0), Flags = MouseFlags.Button1Pressed | MouseFlags.ButtonShift } + new MouseEventArgs { Position = new (19, 0), Flags = MouseFlags.Button1Pressed | MouseFlags.ButtonShift } ) ); Assert.Equal (0, _textView.SelectionStartRow); @@ -6193,7 +6193,7 @@ This is the second line. Assert.True (_textView.IsSelecting); Assert.Equal ("TAB to jump between", _textView.SelectedText); - Assert.True (_textView.NewMouseEvent (new MouseEvent { Position = new (19, 0), Flags = MouseFlags.Button1Clicked })); + Assert.True (_textView.NewMouseEvent (new MouseEventArgs { Position = new (19, 0), Flags = MouseFlags.Button1Clicked })); Assert.Equal (0, _textView.SelectionStartRow); Assert.Equal (0, _textView.SelectionStartRow); Assert.Equal (new Point (19, 0), _textView.CursorPosition); @@ -6202,7 +6202,7 @@ This is the second line. Assert.True ( _textView.NewMouseEvent ( - new MouseEvent { Position = new (24, 0), Flags = MouseFlags.Button1Pressed | MouseFlags.ButtonShift } + new MouseEventArgs { Position = new (24, 0), Flags = MouseFlags.Button1Pressed | MouseFlags.ButtonShift } ) ); Assert.Equal (0, _textView.SelectionStartRow); @@ -6211,14 +6211,14 @@ This is the second line. Assert.True (_textView.IsSelecting); Assert.Equal ("TAB to jump between text", _textView.SelectedText); - Assert.True (_textView.NewMouseEvent (new MouseEvent { Position = new (24, 0), Flags = MouseFlags.Button1Clicked })); + Assert.True (_textView.NewMouseEvent (new MouseEventArgs { Position = new (24, 0), Flags = MouseFlags.Button1Clicked })); Assert.Equal (0, _textView.SelectionStartRow); Assert.Equal (0, _textView.SelectionStartRow); Assert.Equal (new Point (24, 0), _textView.CursorPosition); Assert.True (_textView.IsSelecting); Assert.Equal ("TAB to jump between text", _textView.SelectedText); - Assert.True (_textView.NewMouseEvent (new MouseEvent { Position = new (24, 0), Flags = MouseFlags.Button1Pressed })); + Assert.True (_textView.NewMouseEvent (new MouseEventArgs { Position = new (24, 0), Flags = MouseFlags.Button1Pressed })); Assert.Equal (0, _textView.SelectionStartRow); Assert.Equal (0, _textView.SelectionStartRow); Assert.Equal (new Point (24, 0), _textView.CursorPosition); @@ -6972,12 +6972,12 @@ TAB to jump between text field", { var tv = new TextView { Width = 10, Text = " " }; - var ev = new MouseEvent { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }; + var ev = new MouseEventArgs { Position = new (0, 0), Flags = MouseFlags.Button1DoubleClicked }; tv.NewMouseEvent (ev); Assert.Equal (1, tv.SelectedLength); - ev = new MouseEvent { Position = new (1, 0), Flags = MouseFlags.Button1DoubleClicked }; + ev = new MouseEventArgs { Position = new (1, 0), Flags = MouseFlags.Button1DoubleClicked }; tv.NewMouseEvent (ev); Assert.Equal (1, tv.SelectedLength); @@ -7094,7 +7094,7 @@ line. _output ); - Assert.True (tv.NewMouseEvent (new MouseEvent { Position = new (0, 3), Flags = MouseFlags.Button1Pressed })); + Assert.True (tv.NewMouseEvent (new MouseEventArgs { Position = new (0, 3), Flags = MouseFlags.Button1Pressed })); tv.Draw (); Assert.Equal (new Point (0, 3), tv.CursorPosition); Assert.Equal (new Point (13, 0), cp); diff --git a/UnitTests/Views/ToplevelTests.cs b/UnitTests/Views/ToplevelTests.cs index 12780d219..cbf11e4b2 100644 --- a/UnitTests/Views/ToplevelTests.cs +++ b/UnitTests/Views/ToplevelTests.cs @@ -299,26 +299,26 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (tf1W1, top.MostFocused); Assert.True (isRunning); - Assert.True (Application.OnKeyDown (Application.QuitKey)); + Assert.True (Application.RaiseKeyDownEvent (Application.QuitKey)); Assert.False (isRunning); - Assert.True (Application.OnKeyDown (Key.Z.WithCtrl)); + Assert.True (Application.RaiseKeyDownEvent (Key.Z.WithCtrl)); - Assert.True (Application.OnKeyDown (Key.F5)); // refresh + Assert.True (Application.RaiseKeyDownEvent (Key.F5)); // refresh - Assert.True (Application.OnKeyDown (Key.Tab)); + Assert.True (Application.RaiseKeyDownEvent (Key.Tab)); Assert.Equal (win1, top.Focused); Assert.Equal (tvW1, top.MostFocused); - Assert.True (Application.OnKeyDown (Key.Tab)); + Assert.True (Application.RaiseKeyDownEvent (Key.Tab)); Assert.Equal ($"\tFirst line Win1{Environment.NewLine}Second line Win1", tvW1.Text); - Assert.True (Application.OnKeyDown (Key.Tab.WithShift)); + Assert.True (Application.RaiseKeyDownEvent (Key.Tab.WithShift)); Assert.Equal ($"First line Win1{Environment.NewLine}Second line Win1", tvW1.Text); var prevMostFocusedSubview = top.MostFocused; - Assert.True (Application.OnKeyDown (Key.F6)); // move to next TabGroup (win2) + Assert.True (Application.RaiseKeyDownEvent (Key.F6)); // move to next TabGroup (win2) Assert.Equal (win2, top.Focused); - Assert.True (Application.OnKeyDown (Key.F6.WithShift)); // move to prev TabGroup (win1) + Assert.True (Application.RaiseKeyDownEvent (Key.F6.WithShift)); // move to prev TabGroup (win1) Assert.Equal (win1, top.Focused); Assert.Equal (tf2W1, top.MostFocused); // BUGBUG: Should be prevMostFocusedSubview - We need to cache the last focused view in the TabGroup somehow @@ -327,13 +327,13 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (tvW1, top.MostFocused); tf2W1.SetFocus (); - Assert.True (Application.OnKeyDown (Key.Tab)); // tf2W1 is last subview in win1 - tabbing should take us to first subview of win1 + Assert.True (Application.RaiseKeyDownEvent (Key.Tab)); // tf2W1 is last subview in win1 - tabbing should take us to first subview of win1 Assert.Equal (win1, top.Focused); Assert.Equal (tf1W1, top.MostFocused); - Assert.True (Application.OnKeyDown (Key.CursorRight)); // move char to right in tf1W1. We're at last char so nav to next view + Assert.True (Application.RaiseKeyDownEvent (Key.CursorRight)); // move char to right in tf1W1. We're at last char so nav to next view Assert.Equal (win1, top.Focused); Assert.Equal (tvW1, top.MostFocused); - Assert.True (Application.OnKeyDown (Key.CursorDown)); // move down to next view (tvW1) + Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown)); // move down to next view (tvW1) Assert.Equal (win1, top.Focused); Assert.Equal (tvW1, top.MostFocused); #if UNIX_KEY_BINDINGS @@ -341,34 +341,34 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (win1, top.GetFocused ()); Assert.Equal (tf2W1, top.MostFocused); #endif - Assert.True (Application.OnKeyDown (Key.Tab.WithShift)); // Ignored. TextView eats shift-tab by default + Assert.True (Application.RaiseKeyDownEvent (Key.Tab.WithShift)); // Ignored. TextView eats shift-tab by default Assert.Equal (win1, top.Focused); Assert.Equal (tvW1, top.MostFocused); tvW1.AllowsTab = false; - Assert.True (Application.OnKeyDown (Key.Tab.WithShift)); + Assert.True (Application.RaiseKeyDownEvent (Key.Tab.WithShift)); Assert.Equal (win1, top.Focused); Assert.Equal (tf1W1, top.MostFocused); - Assert.True (Application.OnKeyDown (Key.CursorLeft)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorLeft)); Assert.Equal (win1, top.Focused); Assert.Equal (tf2W1, top.MostFocused); - Assert.True (Application.OnKeyDown (Key.CursorUp)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp)); Assert.Equal (win1, top.Focused); Assert.Equal (tvW1, top.MostFocused); // nav to win2 - Assert.True (Application.OnKeyDown (Key.F6)); + Assert.True (Application.RaiseKeyDownEvent (Key.F6)); Assert.Equal (win2, top.Focused); Assert.Equal (tf1W2, top.MostFocused); - Assert.True (Application.OnKeyDown (Key.F6.WithShift)); + Assert.True (Application.RaiseKeyDownEvent (Key.F6.WithShift)); Assert.Equal (win1, top.Focused); Assert.Equal (tf2W1, top.MostFocused); - Assert.True (Application.OnKeyDown (Application.NextTabGroupKey)); + Assert.True (Application.RaiseKeyDownEvent (Application.NextTabGroupKey)); Assert.Equal (win2, top.Focused); Assert.Equal (tf1W2, top.MostFocused); - Assert.True (Application.OnKeyDown (Application.PrevTabGroupKey)); + Assert.True (Application.RaiseKeyDownEvent (Application.PrevTabGroupKey)); Assert.Equal (win1, top.Focused); Assert.Equal (tf2W1, top.MostFocused); - Assert.True (Application.OnKeyDown (Key.CursorUp)); + Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp)); Assert.Equal (win1, top.Focused); Assert.Equal (tvW1, top.MostFocused); @@ -440,7 +440,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Null (Application.MouseGrabView); // Grab the mouse - Application.OnMouseEvent (new () { ScreenPosition = new (3, 2), Flags = MouseFlags.Button1Pressed }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (3, 2), Flags = MouseFlags.Button1Pressed }); Assert.Equal (Application.Top!.Border, Application.MouseGrabView); Assert.Equal (new (2, 2, 10, 3), Application.Top.Frame); @@ -450,7 +450,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (Application.Top!.Border, Application.MouseGrabView); // Drag to left - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (2, 2), Flags = MouseFlags.Button1Pressed @@ -473,7 +473,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (Application.Top!.Border, Application.MouseGrabView); // Drag up - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (2, 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition @@ -496,7 +496,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (Application.Top!.Border, Application.MouseGrabView); // Ungrab the mouse - Application.OnMouseEvent (new () { ScreenPosition = new (2, 1), Flags = MouseFlags.Button1Released }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (2, 1), Flags = MouseFlags.Button1Released }); Application.Refresh (); Assert.Null (Application.MouseGrabView); @@ -545,7 +545,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Null (Application.MouseGrabView); // Grab the mouse - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (win.Frame.X, win.Frame.Y), Flags = MouseFlags.Button1Pressed @@ -561,7 +561,7 @@ public partial class ToplevelTests (ITestOutputHelper output) movex = 1; movey = 0; - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (win.Frame.X + movex, win.Frame.Y + movey), Flags = @@ -586,7 +586,7 @@ public partial class ToplevelTests (ITestOutputHelper output) movex = 0; movey = -1; - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (win.Frame.X + movex, win.Frame.Y + movey), Flags = @@ -611,7 +611,7 @@ public partial class ToplevelTests (ITestOutputHelper output) movex = 0; movey = 0; - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (win.Frame.X + movex, win.Frame.Y + movey), @@ -743,18 +743,18 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (new (0, 0, 200, 100), scrollView.Subviews [0].Frame); Assert.Equal (new (3, 3, 194, 94), win.Frame); - Application.OnMouseEvent (new () { ScreenPosition = new (6, 6), Flags = MouseFlags.Button1Pressed }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (6, 6), Flags = MouseFlags.Button1Pressed }); Assert.Equal (win.Border, Application.MouseGrabView); Assert.Equal (new (3, 3, 194, 94), win.Frame); - Application.OnMouseEvent (new () { ScreenPosition = new (9, 9), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (9, 9), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition }); Assert.Equal (win.Border, Application.MouseGrabView); top.SetNeedsLayout (); top.LayoutSubviews (); Assert.Equal (new (6, 6, 191, 91), win.Frame); Application.Refresh (); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (5, 5), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition @@ -765,12 +765,12 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (new (2, 2, 195, 95), win.Frame); Application.Refresh (); - Application.OnMouseEvent (new () { ScreenPosition = new (5, 5), Flags = MouseFlags.Button1Released }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (5, 5), Flags = MouseFlags.Button1Released }); // ScrollView always grab the mouse when the container's subview OnMouseEnter don't want grab the mouse Assert.Equal (scrollView, Application.MouseGrabView); - Application.OnMouseEvent (new () { ScreenPosition = new (4, 4), Flags = MouseFlags.ReportMousePosition }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (4, 4), Flags = MouseFlags.ReportMousePosition }); Assert.Equal (scrollView, Application.MouseGrabView); top.Dispose (); } @@ -790,11 +790,11 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Null (Application.MouseGrabView); - Application.OnMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Pressed }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Pressed }); Assert.Equal (window.Border, Application.MouseGrabView); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (-11, -4), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition @@ -807,7 +807,7 @@ public partial class ToplevelTests (ITestOutputHelper output) // Changes Top size to same size as Dialog more menu and scroll bar ((FakeDriver)Application.Driver!).SetBufferSize (20, 3); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (-1, -1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition @@ -820,7 +820,7 @@ public partial class ToplevelTests (ITestOutputHelper output) // Changes Top size smaller than Dialog size ((FakeDriver)Application.Driver!).SetBufferSize (19, 2); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (-1, -1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition @@ -830,7 +830,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (new (0, 0, 19, 2), top.Frame); Assert.Equal (new (-1, -1, 20, 3), window.Frame); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (18, 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition @@ -841,7 +841,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (new (18, 1, 20, 3), window.Frame); // On a real app we can't go beyond the SuperView bounds - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (19, 2), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition @@ -882,7 +882,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Null (Application.MouseGrabView); Assert.Equal (new (0, 0, 10, 3), window.Frame); - Application.OnMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Pressed }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (0, 0), Flags = MouseFlags.Button1Pressed }); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -890,7 +890,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (new (0, 0, 10, 3), window.Frame); - Application.OnMouseEvent ( + Application.RaiseMouseEvent ( new () { ScreenPosition = new (1, 1), Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition @@ -984,7 +984,7 @@ public partial class ToplevelTests (ITestOutputHelper output) Assert.Equal (new (2, 1, 15, 10), testWindow.Frame); - Application.OnMouseEvent (new () { ScreenPosition = new (5, 2), Flags = MouseFlags.Button1Clicked }); + Application.RaiseMouseEvent (new () { ScreenPosition = new (5, 2), Flags = MouseFlags.Button1Clicked }); Application.Refresh (); diff --git a/UnitTests/Views/TreeTableSourceTests.cs b/UnitTests/Views/TreeTableSourceTests.cs index 04fcf420e..345dffeb0 100644 --- a/UnitTests/Views/TreeTableSourceTests.cs +++ b/UnitTests/Views/TreeTableSourceTests.cs @@ -111,7 +111,7 @@ public class TreeTableSourceTests : IDisposable Assert.Equal (0, tv.SelectedRow); Assert.Equal (0, tv.SelectedColumn); - Assert.True (tv.NewMouseEvent (new MouseEvent { Position = new (2, 2), Flags = MouseFlags.Button1Clicked })); + Assert.True (tv.NewMouseEvent (new MouseEventArgs { Position = new (2, 2), Flags = MouseFlags.Button1Clicked })); tv.Draw (); @@ -128,15 +128,15 @@ public class TreeTableSourceTests : IDisposable TestHelpers.AssertDriverContentsAre (expected, _output); // Clicking to the right/left of the expand/collapse does nothing - tv.NewMouseEvent (new MouseEvent { Position = new (3, 2), Flags = MouseFlags.Button1Clicked }); + tv.NewMouseEvent (new MouseEventArgs { Position = new (3, 2), Flags = MouseFlags.Button1Clicked }); tv.Draw (); TestHelpers.AssertDriverContentsAre (expected, _output); - tv.NewMouseEvent (new MouseEvent { Position = new (1, 2), Flags = MouseFlags.Button1Clicked }); + tv.NewMouseEvent (new MouseEventArgs { Position = new (1, 2), Flags = MouseFlags.Button1Clicked }); tv.Draw (); TestHelpers.AssertDriverContentsAre (expected, _output); // Clicking on the + again should collapse - tv.NewMouseEvent (new MouseEvent { Position = new (2, 2), Flags = MouseFlags.Button1Clicked }); + tv.NewMouseEvent (new MouseEventArgs { Position = new (2, 2), Flags = MouseFlags.Button1Clicked }); tv.Draw (); expected = @@ -187,7 +187,7 @@ public class TreeTableSourceTests : IDisposable Assert.Equal (0, tv.SelectedRow); Assert.Equal (1, tv.SelectedColumn); - Application.OnKeyDown (Key.CursorRight); + Application.RaiseKeyDownEvent (Key.CursorRight); tv.Draw (); diff --git a/UnitTests/Views/TreeViewTests.cs b/UnitTests/Views/TreeViewTests.cs index 507ca3541..12d1ecf97 100644 --- a/UnitTests/Views/TreeViewTests.cs +++ b/UnitTests/Views/TreeViewTests.cs @@ -438,7 +438,7 @@ public class TreeViewTests Assert.False (called); // double click triggers activation - tree.NewMouseEvent (new MouseEvent { Flags = MouseFlags.Button1DoubleClicked }); + tree.NewMouseEvent (new MouseEventArgs { Flags = MouseFlags.Button1DoubleClicked }); Assert.True (called); Assert.Same (f, activated); @@ -467,12 +467,12 @@ public class TreeViewTests Assert.False (called); // double click does nothing because we changed button binding to right click - tree.NewMouseEvent (new MouseEvent { Position = new (0, 1), Flags = MouseFlags.Button1DoubleClicked }); + tree.NewMouseEvent (new MouseEventArgs { Position = new (0, 1), Flags = MouseFlags.Button1DoubleClicked }); Assert.Null (activated); Assert.False (called); - tree.NewMouseEvent (new MouseEvent { Position = new (0, 1), Flags = MouseFlags.Button2Clicked }); + tree.NewMouseEvent (new MouseEventArgs { Position = new (0, 1), Flags = MouseFlags.Button2Clicked }); Assert.True (called); Assert.Same (car1, activated); @@ -506,7 +506,7 @@ public class TreeViewTests // double click does nothing because we changed button to null - tree.NewMouseEvent (new MouseEvent { Flags = MouseFlags.Button1DoubleClicked }); + tree.NewMouseEvent (new MouseEventArgs { Flags = MouseFlags.Button1DoubleClicked }); Assert.False (called); Assert.Null (activated); diff --git a/docfx/docs/events.md b/docfx/docs/events.md new file mode 100644 index 000000000..56580a7a4 --- /dev/null +++ b/docfx/docs/events.md @@ -0,0 +1,126 @@ +# Terminal.Gui Event Deep Dive + +Terminal.Gui exposes and uses events in many places. This deep dive covers the patterns used, where they are used, and notes any exceptions. + +## Tenets for Terminal.Gui Events (Unless you know better ones...) + +Tenets higher in the list have precedence over tenets lower in the list. + +* **UI Interaction and Live Data Are Different Beasts** - TG distinguishes between events used for human interaction and events for live data. We don't believe in a one-size-fits-all eventing model. For UI interactions we use `EventHandler`. For data binding we think `INotifyPropertyChanged` is groovy. For some callbacks we use `Action`. + +## Lexicon and Taxonomy + +* *Action* +* *Event* +* *Command* +* *Invoke* +* *Raise* +* *Listen* +* *Handle/Handling/Handled* - Applies to scenarios where an event can either be handled by an event listener (or override) vs not handled. Events that originate from a user action like mouse moves and key presses are examples. +* *Cancel/Cancelling/Cancelled* - Applies to scenarios where something can be cancelled. Changing the `Orientation` of a `Slider` is cancelable. + +## Useful External Documentation + +* [.NET Naming Guidelines - Names of Events](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-type-members?redirectedfrom=MSDN#names-of-events) +* [.NET Design for Extensibility - Events and Callbacks](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/events-and-callbacks) +* [C# Event Implementation Fundamentals, Best Practices and Conventions](https://www.codeproject.com/Articles/20550/C-Event-Implementation-Fundamentals-Best-Practices) + +## Naming + +TG follows the *naming* advice provided in [.NET Naming Guidelines - Names of Events](https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-type-members?redirectedfrom=MSDN#names-of-events). + +## `EventHandler` style event best-practices + +* Implement a helper method for raising the event: `RaisexxxEvent`. + * If the event is cancelable, the return type should be either `bool` or `bool?`. + * Can be `private`, `internal`, or `public` depending on the situation. `internal` should only be used to enable unit tests. +* Raising an event involves FIRST calling the `protected virtual` method, THEN invoking the `EventHandler. + +## `Action` style callback best-practices + +- tbd + +## `INotifyPropertyChanged` style notification best practices + +- tbd + +## Common Patterns + +The primary pattern for events is the `event/EventHandler` idiom. We use the `Action` idiom sparingly. We support `INotifyPropertyChanged` in cases where data binding is relevant. + + + +## Cancellable Event Pattern + +A cancellable event is really two events and some activity that takes place between those events. The "pre-event" happens before the activity. The activity then takes place (or not). If the activity takes place, then the "post-event" is typically raised. So, to be precise, no event is being cancelled even though we say we have a cancellable event. Rather, the activity that takes place between the two events is what is cancelled — and likely prevented from starting at all. + +### **Before** - If any pre-conditions are met raise the "pre-event", typically named in the form of "xxxChanging". e.g. + + - A `protected virtual` method is called. This method is named `OnxxxChanging` and the base implementation simply does `return false`. + - If the `OnxxxChanging` method returns `true` it means a derived class canceled the event. Processing should stop. + - Otherwise, the `xxxChanging` event is invoked via `xxxChanging?.Invoke(args)`. If `args.Cancel/Handled == true` it means a subscriber has cancelled the event. Processing should stop. + + +### **During** - Do work. + +### **After** - Raise the "post-event", typically named in the form of "xxxChanged" + + - A `protected virtual` method is called. This method is named `OnxxxChanged` has a return type of `void`. + - The `xxxChanged` event is invoked via `xxxChanging?.Invoke(args)`. + +The `OrientationHelper` class supporting `IOrientation` and a `View` having an `Orientation` property illustrates the preferred TG pattern for cancelable events. + +```cs + /// + /// Gets or sets the orientation of the View. + /// + public Orientation Orientation + { + get => _orientation; + set + { + if (_orientation == value) + { + return; + } + + // Best practice is to call the virtual method first. + // This allows derived classes to handle the event and potentially cancel it. + if (_owner?.OnOrientationChanging (value, _orientation) ?? false) + { + return; + } + + // If the event is not canceled by the virtual method, raise the event to notify any external subscribers. + CancelEventArgs args = new (in _orientation, ref value); + OrientationChanging?.Invoke (_owner, args); + + if (args.Cancel) + { + return; + } + + // If the event is not canceled, update the value. + Orientation old = _orientation; + + if (_orientation != value) + { + _orientation = value; + + if (_owner is { }) + { + _owner.Orientation = value; + } + } + + // Best practice is to call the virtual method first, then raise the event. + _owner?.OnOrientationChanged (_orientation); + OrientationChanged?.Invoke (_owner, new (in _orientation)); + } + } +``` + + ## `bool` or `bool?` + + + diff --git a/docfx/docs/keyboard.md b/docfx/docs/keyboard.md index 8b29a1a6d..ddace3282 100644 --- a/docfx/docs/keyboard.md +++ b/docfx/docs/keyboard.md @@ -59,22 +59,25 @@ The Command can be invoked even if the `View` that defines them is not focused o ### **Handling Keyboard Events** -Keyboard events are retrieved from [Console Drivers](drivers.md) and passed on -to the [Application](~/api/Terminal.Gui.Application.yml) class by the [Main Loop](mainloop.md). +Keyboard events are retrieved from [Console Drivers](drivers.md) each iteration of the [Application](~/api/Terminal.Gui.Application.yml) [Main Loop](mainloop.md). The console driver raises the @Terminal.Gui.ConsoleDriver.KeyDown and @Terminal.Gui.ConsoleDriver.KeyUp events which invoke @Terminal.Gui.Application.RaiseKeyDown(Terminal.Gui.Key) and @Terminal.Gui.Application.RaiseKeyUp(Terminal.Gui.Key) respectively. -[Application](~/api/Terminal.Gui.Application.yml) then determines the current [Toplevel](~/api/Terminal.Gui.Toplevel.yml) view -(either the default created by calling @Terminal.Gui.Application.Init(Terminal.Gui.ConsoleDriver,System.String), or the one set by calling `Application.Run`). The mouse event, using [Viewport-relative coordinates](xref:Terminal.Gui.View.Viewport) is then passed to the @Terminal.Gui.View.NewKeyDownEvent(Terminal.Gui.Key) method of the current [Toplevel](~/api/Terminal.Gui.Toplevel.yml) view. + NOTE: Not all drivers/platforms support sensing distinct KeyUp events. These drivers will simulate KeyUp events by raising @Terminal.Gui.ConsoleDriver.KeyUp after @Terminal.Gui.ConsoleDriver.KeyDown. -If the view is enabled, the @Terminal.Gui.View.NewKeyDownEvent(Terminal.Gui.Key) method will do the following: +@Terminal.Gui.Application.RaiseKeyDown(Terminal.Gui.Key) raises @Terminal.Gui.Application.KeyDown and then calls @Terminal.Gui.View.NewKeyDownEvent(Terminal.Gui.Key) on all toplevel Views. If no View handles the key event, any Application-scoped key bindings will be invoked. -1) If the view has a subview that has focus, 'ProcessKeyDown' on the focused view will be called. If the focused view handles the key press, processing stops. -2) If there is no focused sub-view, or the focused sub-view does not handle the key press, @Terminal.Gui.View.OnKeyDown(Terminal.Gui.Key) will be called. If the view handles the key press, processing stops. -3) If the view does not handle the key press, @Terminal.Gui.TextField.OnInvokingKeyBindings(Terminal.Gui.Key,Terminal.Gui.KeyBindingScope) will be called. This method calls @Terminal.Gui.View.InvokeKeyBindings(Terminal.Gui.Key,Terminal.Gui.KeyBindingScope) to invoke any keys bound to commands. If the key is bound and any of it's command handlers return true, processing stops. -4) If the key is not bound, or the bound command handlers do not return true, @Terminal.Gui.View.OnProcessKeyDown(Terminal.Gui.Key) is called. If the view handles the key press, processing stops. +@Terminal.Gui.Application.RaiseKeyDown(Terminal.Gui.Key) raises @Terminal.Gui.Application.KeyDown and then calls @Terminal.Gui.View.NewKeyUpEvent(Terminal.Gui.Key) on all toplevel Views. + +If a view is enabled, the @Terminal.Gui.View.NewKeyDownEvent(Terminal.Gui.Key) method will do the following: + +1) If the view has a subview that has focus, 'NewKeyDown' on the focused view will be called. This is recursive. If the most-focused view handles the key press, processing stops. +2) If there is no most-focused sub-view, or a most-focused sub-view does not handle the key press, @Terminal.Gui.View.OnKeyDown(Terminal.Gui.Key) will be called. If the view handles the key press, processing stops. +3) If @Terminal.Gui.View.OnKeyDown(Terminal.Gui.Key) does not handle the event. @Terminal.Gui.View.KeyDown will be raised. +4) If the view does not handle the key down event, any bindings for the key will be invoked (see @Terminal.Gui.View.KeyBindings). If the key is bound and any of it's command handlers return true, processing stops. +5) If the key is not bound, or the bound command handlers do not return true, @Terminal.Gui.View.OnKeyDownNotHandled(Terminal.Gui.Key) is called. ## **Application Key Handling** -To define application key handling logic for an entire application in cases where the methods listed above are not suitable, use the `Application.OnKeyDown` event. +To define application key handling logic for an entire application in cases where the methods listed above are not suitable, use the @Terminal.Gui.Application.KeyDown event. ## **Key Down/Up Events** @@ -90,17 +93,14 @@ To define application key handling logic for an entire application in cases wher - `NewKeyDownEvent` is called on the most-focused SubView (if any) that has focus. If that call returns true, the method returns. - Calls `OnKeyDown`. - **During** - - Assuming `OnKeyDown` call returns false (indicating the key wasn't handled) - - `OnInvokingKeyBindings` is called to invoke any bound commands. - - `OnInvokingKeyBindings` fires the `InvokingKeyBindings` event + - Assuming `OnKeyDown` call returns false (indicating the key wasn't handled) any commands bound to the key will be invoked. - **After** - - Assuming `OnInvokingKeyBindings` returns false (indicating the key wasn't handled) - - `OnProcessKeyDown` is called to process the key. - - `OnProcessKeyDown` fires the `ProcessKeyDown` event + - Assuming no keybinding was found or all invoked commands were not handled: + - `OnKeyDownNotHandled` is called to process the key. + - `KeyDownNotHandled` is raised. -- Subclasses of `View` can (rarely) override `OnKeyDown` to see keys before they are processed by `OnInvokingKeyBindings` and `OnProcessKeyDown -- Subclasses of `View` can (rarely) override `OnInvokingKeyBindings` to see keys before they are processed by `OnProcessKeyDown` -- Subclasses of `View` can (often) override `OnProcessKeyDown` to do normal key processing. +- Subclasses of `View` can (rarely) override `OnKeyDown` (or subscribe to `KeyDown`) to see keys before they are processed +- Subclasses of `View` can (often) override `OnKeyDownNotHandled` to do key processing for keys that were not previously handled. `TextField` and `TextView` are examples. ## ConsoleDriver diff --git a/docfx/docs/migratingfromv1.md b/docfx/docs/migratingfromv1.md index 3318aa448..2239bd7ff 100644 --- a/docfx/docs/migratingfromv1.md +++ b/docfx/docs/migratingfromv1.md @@ -196,7 +196,7 @@ In v1, the `Command` enum had duplicate entries and inconsistent naming. In v2 i The API for mouse input is now internally consistent and easier to use. -* The @Terminal.Gui.MouseEvent class replaces `MouseEventEventArgs`. +* The @Terminal.Gui.MouseEventArgs class replaces `MouseEventEventArgs`. * More granular APIs are provided to ease handling specific mouse actions. See [Mouse API](mouse.md). * Views can use the @Terminal.Gui.View.Highlight event to have the view be visibly highlighted on various mouse events. * Views can set `View.WantContinousButtonPresses = true` to have their @Terminal.Gui.Command.Accept command be invoked repeatedly as the user holds a mouse button down on the view. @@ -213,7 +213,7 @@ The API for mouse input is now internally consistent and easier to use. ```diff - Application.RootMouseEvent(KeyEvent arg) -+ Application.MouseEvent(object? sender, MouseEvent mouseEvent) ++ Application.MouseEvent(object? sender, MouseEventArgs mouseEvent) ``` ## Navigation - `Cursor`, `Focus`, `TabStop` etc... diff --git a/docfx/docs/mouse.md b/docfx/docs/mouse.md index 63ef13696..18ffd2cb0 100644 --- a/docfx/docs/mouse.md +++ b/docfx/docs/mouse.md @@ -10,9 +10,9 @@ Tenets higher in the list have precedence over tenets lower in the list. ## Mouse APIs -At the core of *Terminal.Gui*'s mouse API is the *[MouseEvent](~/api/Terminal.Gui.MouseEvent.yml)* class. The `MouseEvent` class provides a platform-independent abstraction for common mouse events. Every mouse event can be fully described in a `MouseEvent` instance, and most of the mouse-related APIs are simply helper functions for decoding a `MouseEvent`. +At the core of *Terminal.Gui*'s mouse API is the @Terminal.Gui.MouseEventArgs class. The @Terminal.Gui.MouseEventArgs class provides a platform-independent abstraction for common mouse events. Every mouse event can be fully described in a @Terminal.Gui.MouseEventArgs instance, and most of the mouse-related APIs are simply helper functions for decoding a @Terminal.Gui.MouseEventArgs. -When the user does something with the mouse, the `ConsoleDriver` maps the platform-specific mouse event into a `MouseEvent` and calls `Application.OnMouseEvent`. Then, `Application.OnMouseEvent` determines which `View` the event should go to. The `View.OnMouseEvent` method can be overridden or the `View.MouseEvent` event can be subscribed to, to handle the low-level mouse event. If the low-level event is not handled by a view, `Application` will then call the appropriate high-level helper APIs. For example, if the user double-clicks the mouse, `View.OnMouseClick` will be called/`View.MouseClick` will be fired with the event arguments indicating which mouse button was double-clicked. +When the user does something with the mouse, the `ConsoleDriver` maps the platform-specific mouse event into a `MouseEventArgs` and calls `Application.RaiseMouseEvent`. Then, `Application.RaiseMouseEvent` determines which `View` the event should go to. The `View.OnMouseEvent` method can be overridden or the `View.MouseEvent` event can be subscribed to, to handle the low-level mouse event. If the low-level event is not handled by a view, `Application` will then call the appropriate high-level helper APIs. For example, if the user double-clicks the mouse, `View.OnMouseClick` will be called/`View.MouseClick` will be raised with the event arguments indicating which mouse button was double-clicked. ## Mouse Button and Movement Concepts