From 852043560001908a50a336ecd76900a2f9214db5 Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Wed, 18 Oct 2023 09:42:53 -0400 Subject: [PATCH 001/194] Adds basic MainLoop unit tests --- Terminal.Gui/MainLoop.cs | 17 +- UnitTests/ConsoleDrivers/MainLoopTests.cs | 272 ++++++++++++++++++++++ 2 files changed, 282 insertions(+), 7 deletions(-) create mode 100644 UnitTests/ConsoleDrivers/MainLoopTests.cs diff --git a/Terminal.Gui/MainLoop.cs b/Terminal.Gui/MainLoop.cs index c210bc507b..95671f5a42 100644 --- a/Terminal.Gui/MainLoop.cs +++ b/Terminal.Gui/MainLoop.cs @@ -303,7 +303,10 @@ void RunIdle () } } - bool _running; + /// + /// Used for unit tests. + /// + internal bool Running { get; private set; } /// /// Determines whether there are pending events to be processed. @@ -353,13 +356,13 @@ public void RunIteration () /// public void Run () { - var prev = _running; - _running = true; - while (_running) { + var prev = Running; + Running = true; + while (Running) { EventsPending (); RunIteration (); } - _running = prev; + Running = prev; } /// @@ -367,7 +370,7 @@ public void Run () /// public void Stop () { - _running = false; + Running = false; MainLoopDriver.Wakeup (); } @@ -376,7 +379,7 @@ public void Dispose () { GC.SuppressFinalize (this); Stop (); - _running = false; + Running = false; MainLoopDriver?.TearDown (); MainLoopDriver = null; } diff --git a/UnitTests/ConsoleDrivers/MainLoopTests.cs b/UnitTests/ConsoleDrivers/MainLoopTests.cs new file mode 100644 index 0000000000..9132226258 --- /dev/null +++ b/UnitTests/ConsoleDrivers/MainLoopTests.cs @@ -0,0 +1,272 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using Xunit; +using Xunit.Abstractions; + +// Alias Console to MockConsole so we don't accidentally use Console +using Console = Terminal.Gui.FakeConsole; + +namespace Terminal.Gui.DriverTests; + +public class MainLoopTests { + + public MainLoopTests (ITestOutputHelper output) + { + ConsoleDriver.RunningUnitTests = true; + } + + [Theory] + [InlineData (typeof (FakeDriver), typeof (FakeMainLoop))] + [InlineData (typeof (NetDriver), typeof (NetMainLoop))] + [InlineData (typeof (CursesDriver), typeof (UnixMainLoop))] + [InlineData (typeof (WindowsDriver), typeof (WindowsMainLoop))] + public void MainLoop_Constructs_Disposes (Type driverType, Type mainLoopDriverType) + { + var driver = (ConsoleDriver)Activator.CreateInstance (driverType); + var mainLoopDriver = (IMainLoopDriver)Activator.CreateInstance (mainLoopDriverType, new object [] { driver }); + var mainLoop = new MainLoop (mainLoopDriver); + + // Check default values + Assert.NotNull (mainLoop); + Assert.Equal (mainLoopDriver, mainLoop.MainLoopDriver); + Assert.Empty(mainLoop.IdleHandlers); + Assert.Empty (mainLoop.Timeouts); + Assert.False (mainLoop.Running); + + // Clean up + mainLoop.Dispose (); + // TODO: It'd be nice if we could really verify IMainLoopDriver.TearDown was called + // and that it was actually cleaned up. + Assert.Null (mainLoop.MainLoopDriver); + Assert.Empty (mainLoop.IdleHandlers); + Assert.Empty (mainLoop.Timeouts); + Assert.False (mainLoop.Running); + } + + [Theory] + [InlineData (typeof (FakeDriver), typeof (FakeMainLoop))] + [InlineData (typeof (NetDriver), typeof (NetMainLoop))] + [InlineData (typeof (CursesDriver), typeof (UnixMainLoop))] + [InlineData (typeof (WindowsDriver), typeof (WindowsMainLoop))] + public void MainLoop_AddTimeout_ValidParameters_ReturnsToken (Type driverType, Type mainLoopDriverType) + { + var driver = (ConsoleDriver)Activator.CreateInstance (driverType); + var mainLoopDriver = (IMainLoopDriver)Activator.CreateInstance (mainLoopDriverType, new object [] { driver }); + var mainLoop = new MainLoop (mainLoopDriver); + var callbackInvoked = false; + + var token = mainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), (_) => + { + callbackInvoked = true; + return false; + }); + + Assert.NotNull (token); + mainLoop.RunIteration (); // Run an iteration to process the timeout + Assert.False (callbackInvoked); // Callback should not be invoked immediately + Thread.Sleep (200); // Wait for the timeout + mainLoop.RunIteration(); // Run an iteration to process the timeout + Assert.True (callbackInvoked); // Callback should be invoked after the timeout + mainLoop.Dispose (); + } + + [Theory] + [InlineData (typeof (FakeDriver), typeof (FakeMainLoop))] + [InlineData (typeof (NetDriver), typeof (NetMainLoop))] + [InlineData (typeof (CursesDriver), typeof (UnixMainLoop))] + [InlineData (typeof (WindowsDriver), typeof (WindowsMainLoop))] + public void MainLoop_RemoveTimeout_ValidToken_ReturnsTrue (Type driverType, Type mainLoopDriverType) + { + var driver = (ConsoleDriver)Activator.CreateInstance (driverType); + var mainLoopDriver = (IMainLoopDriver)Activator.CreateInstance (mainLoopDriverType, new object [] { driver }); + var mainLoop = new MainLoop (mainLoopDriver); + + var token = mainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), (_) => false); + var result = mainLoop.RemoveTimeout (token); + + Assert.True (result); + mainLoop.Dispose (); + } + + [Theory] + [InlineData (typeof (FakeDriver), typeof (FakeMainLoop))] + [InlineData (typeof (NetDriver), typeof (NetMainLoop))] + [InlineData (typeof (CursesDriver), typeof (UnixMainLoop))] + [InlineData (typeof (WindowsDriver), typeof (WindowsMainLoop))] + public void MainLoop_RemoveTimeout_InvalidToken_ReturnsFalse (Type driverType, Type mainLoopDriverType) + { + var driver = (ConsoleDriver)Activator.CreateInstance (driverType); + var mainLoopDriver = (IMainLoopDriver)Activator.CreateInstance (mainLoopDriverType, new object [] { driver }); + var mainLoop = new MainLoop (mainLoopDriver); + + var result = mainLoop.RemoveTimeout (new object ()); + + Assert.False (result); + } + + [Theory] + [InlineData (typeof (FakeDriver), typeof (FakeMainLoop))] + [InlineData (typeof (NetDriver), typeof (NetMainLoop))] + [InlineData (typeof (CursesDriver), typeof (UnixMainLoop))] + [InlineData (typeof (WindowsDriver), typeof (WindowsMainLoop))] + public void MainLoop_AddIdle_ValidIdleHandler_ReturnsToken (Type driverType, Type mainLoopDriverType) + { + var driver = (ConsoleDriver)Activator.CreateInstance (driverType); + var mainLoopDriver = (IMainLoopDriver)Activator.CreateInstance (mainLoopDriverType, new object [] { driver }); + var mainLoop = new MainLoop (mainLoopDriver); + var idleHandlerInvoked = false; + + bool IdleHandler () + { + idleHandlerInvoked = true; + return false; + } + + Func token = mainLoop.AddIdle (IdleHandler); + + Assert.NotNull (token); + Assert.False (idleHandlerInvoked); // Idle handler should not be invoked immediately + mainLoop.RunIteration (); // Run an iteration to process the idle handler + Assert.True (idleHandlerInvoked); // Idle handler should be invoked after processing + mainLoop.Dispose (); + } + + [Theory] + [InlineData (typeof (FakeDriver), typeof (FakeMainLoop))] + [InlineData (typeof (NetDriver), typeof (NetMainLoop))] + [InlineData (typeof (CursesDriver), typeof (UnixMainLoop))] + [InlineData (typeof (WindowsDriver), typeof (WindowsMainLoop))] + public void MainLoop_RemoveIdle_ValidToken_ReturnsTrue (Type driverType, Type mainLoopDriverType) + { + var driver = (ConsoleDriver)Activator.CreateInstance (driverType); + var mainLoopDriver = (IMainLoopDriver)Activator.CreateInstance (mainLoopDriverType, new object [] { driver }); + var mainLoop = new MainLoop (mainLoopDriver); + + bool IdleHandler () => false; + Func token = mainLoop.AddIdle (IdleHandler); + var result = mainLoop.RemoveIdle (token); + + Assert.True (result); + mainLoop.Dispose (); + } + + [Theory] + [InlineData (typeof (FakeDriver), typeof (FakeMainLoop))] + [InlineData (typeof (NetDriver), typeof (NetMainLoop))] + [InlineData (typeof (CursesDriver), typeof (UnixMainLoop))] + [InlineData (typeof (WindowsDriver), typeof (WindowsMainLoop))] + public void MainLoop_RemoveIdle_InvalidToken_ReturnsFalse (Type driverType, Type mainLoopDriverType) + { + var driver = (ConsoleDriver)Activator.CreateInstance (driverType); + var mainLoopDriver = (IMainLoopDriver)Activator.CreateInstance (mainLoopDriverType, new object [] { driver }); + var mainLoop = new MainLoop (mainLoopDriver); + + var result = mainLoop.RemoveIdle (() => false); + + Assert.False (result); + mainLoop.Dispose (); + } + + [Theory] + [InlineData (typeof (FakeDriver), typeof (FakeMainLoop))] + [InlineData (typeof (NetDriver), typeof (NetMainLoop))] + [InlineData (typeof (CursesDriver), typeof (UnixMainLoop))] + [InlineData (typeof (WindowsDriver), typeof (WindowsMainLoop))] + public void MainLoop_RunIteration_ValidIdleHandler_CallsIdleHandler (Type driverType, Type mainLoopDriverType) + { + var driver = (ConsoleDriver)Activator.CreateInstance (driverType); + var mainLoopDriver = (IMainLoopDriver)Activator.CreateInstance (mainLoopDriverType, new object [] { driver }); + var mainLoop = new MainLoop (mainLoopDriver); + var idleHandlerInvoked = false; + + Func idleHandler = () => + { + idleHandlerInvoked = true; + return false; + }; + + mainLoop.AddIdle (idleHandler); + mainLoop.RunIteration (); // Run an iteration to process the idle handler + + Assert.True (idleHandlerInvoked); + mainLoop.Dispose(); + } + + [Theory] + [InlineData (typeof (FakeDriver), typeof (FakeMainLoop))] + [InlineData (typeof (NetDriver), typeof (NetMainLoop))] + [InlineData (typeof (CursesDriver), typeof (UnixMainLoop))] + [InlineData (typeof (WindowsDriver), typeof (WindowsMainLoop))] + public void MainLoop_CheckTimersAndIdleHandlers_NoTimersOrIdleHandlers_ReturnsFalse (Type driverType, Type mainLoopDriverType) + { + var driver = (ConsoleDriver)Activator.CreateInstance (driverType); + var mainLoopDriver = (IMainLoopDriver)Activator.CreateInstance (mainLoopDriverType, new object [] { driver }); + var mainLoop = new MainLoop (mainLoopDriver); + + var result = mainLoop.CheckTimersAndIdleHandlers (out var waitTimeout); + + Assert.False (result); + Assert.Equal (-1, waitTimeout); + mainLoop.Dispose (); + } + + [Theory] + [InlineData (typeof (FakeDriver), typeof (FakeMainLoop))] + [InlineData (typeof (NetDriver), typeof (NetMainLoop))] + [InlineData (typeof (CursesDriver), typeof (UnixMainLoop))] + [InlineData (typeof (WindowsDriver), typeof (WindowsMainLoop))] + public void MainLoop_CheckTimersAndIdleHandlers_TimersActive_ReturnsTrue (Type driverType, Type mainLoopDriverType) + { + var driver = (ConsoleDriver)Activator.CreateInstance (driverType); + var mainLoopDriver = (IMainLoopDriver)Activator.CreateInstance (mainLoopDriverType, new object [] { driver }); + var mainLoop = new MainLoop (mainLoopDriver); + + mainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), (_) => false); + var result = mainLoop.CheckTimersAndIdleHandlers (out var waitTimeout); + + Assert.True (result); + Assert.True (waitTimeout >= 0); + mainLoop.Dispose (); + } + + [Theory] + [InlineData (typeof (FakeDriver), typeof (FakeMainLoop))] + [InlineData (typeof (NetDriver), typeof (NetMainLoop))] + [InlineData (typeof (CursesDriver), typeof (UnixMainLoop))] + [InlineData (typeof (WindowsDriver), typeof (WindowsMainLoop))] + public void MainLoop_CheckTimersAndIdleHandlers_IdleHandlersActive_ReturnsTrue (Type driverType, Type mainLoopDriverType) + { + var driver = (ConsoleDriver)Activator.CreateInstance (driverType); + var mainLoopDriver = (IMainLoopDriver)Activator.CreateInstance (mainLoopDriverType, new object [] { driver }); + var mainLoop = new MainLoop (mainLoopDriver); + + mainLoop.AddIdle (() => false); + var result = mainLoop.CheckTimersAndIdleHandlers (out var waitTimeout); + + Assert.True (result); + Assert.Equal (-1, waitTimeout); + mainLoop.Dispose (); + } + + [Theory] + [InlineData (typeof (FakeDriver), typeof (FakeMainLoop))] + [InlineData (typeof (NetDriver), typeof (NetMainLoop))] + [InlineData (typeof (CursesDriver), typeof (UnixMainLoop))] + [InlineData (typeof (WindowsDriver), typeof (WindowsMainLoop))] + public void MainLoop_Invoke_ValidAction_RunsAction (Type driverType, Type mainLoopDriverType) + { + var driver = (ConsoleDriver)Activator.CreateInstance (driverType); + var mainLoopDriver = (IMainLoopDriver)Activator.CreateInstance (mainLoopDriverType, new object [] { driver }); + var mainLoop = new MainLoop (mainLoopDriver); + var actionInvoked = false; + + mainLoop.Invoke (() => { actionInvoked = true; }); + mainLoop.RunIteration (); // Run an iteration to process the action. + + Assert.True (actionInvoked); + mainLoop.Dispose (); + } +} From 80fd49e92838fda6dcd7544242ea9997c80013b6 Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Wed, 18 Oct 2023 11:11:34 -0400 Subject: [PATCH 002/194] Remove WinChange action from Curses --- .../CursesDriver/CursesDriver.cs | 6 +- .../CursesDriver/UnixMainLoop.cs | 7 +- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 4 +- UnitTests/Application/MainLoopTests.cs | 1419 ++++++++--------- ...ainLoopTests.cs => MainLoopDriverTests.cs} | 18 +- 5 files changed, 724 insertions(+), 730 deletions(-) rename UnitTests/ConsoleDrivers/{MainLoopTests.cs => MainLoopDriverTests.cs} (97%) diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs index f7563327ca..76df5fead0 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs @@ -215,7 +215,7 @@ public override void End () if (_mainLoop != null) { _mainLoop.RemoveWatch (_processInputToken); - _mainLoop.WinChanged -= ProcessInput; + //_mainLoop.WinChanged -= ProcessInput; } if (RunningUnitTests) { @@ -371,7 +371,7 @@ KeyModifiers MapKeyModifiers (Key key) return _keyModifiers; } - void ProcessInput () + internal void ProcessInput () { int wch; var code = Curses.get_wch (out wch); @@ -627,7 +627,7 @@ public override void PrepareToRun (MainLoop mainLoop, Action keyHandle return true; }); - _mainLoop.WinChanged = ProcessInput; + //_mainLoop.WinChanged = ProcessInput; } public override void Init (Action terminalResized) diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs index bba17ea3cc..d1dafd11f1 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs @@ -15,9 +15,11 @@ namespace Terminal.Gui { /// can watch file descriptors using the AddWatch methods. /// internal class UnixMainLoop : IMainLoopDriver { + private CursesDriver _cursesDriver; public UnixMainLoop (ConsoleDriver consoleDriver = null) { // UnixDriver doesn't use the consoleDriver parameter, but the WindowsDriver does. + _cursesDriver = (CursesDriver)Application.Driver; } public const int KEY_RESIZE = unchecked((int)0xffffffffffffffff); @@ -86,7 +88,7 @@ class Watch { MainLoop _mainLoop; bool _winChanged; - internal Action WinChanged; + //internal Action WinChanged; void IMainLoopDriver.Wakeup () { @@ -187,7 +189,8 @@ void IMainLoopDriver.Iteration () { if (_winChanged) { _winChanged = false; - WinChanged?.Invoke (); + _cursesDriver.ProcessInput (); + //WinChanged?.Invoke (); } if (_pollMap == null) return; foreach (var p in _pollMap) { diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index 18e6492b9f..6544eeae43 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -861,7 +861,7 @@ public override void PrepareToRun (MainLoop mainLoop, Action keyHandle _mouseHandler = mouseHandler; _mainLoop = mainLoop.MainLoopDriver as WindowsMainLoop; - _mainLoop.ProcessInput = ProcessInput; + _mainLoop.ProcessInput += ProcessInput; #if HACK_CHECK_WINCHANGED _mainLoop.WinChanged = ChangeWin; #endif @@ -1879,7 +1879,7 @@ void IMainLoopDriver.Wakeup () bool IMainLoopDriver.EventsPending () { _waitForProbe.Set (); -#if HACK_CHECK_WINCHANGED +#if HACK_CHECK_WINCHANGED _winChange.Set (); #endif if (_mainLoop.CheckTimersAndIdleHandlers (out var waitTimeout)) { diff --git a/UnitTests/Application/MainLoopTests.cs b/UnitTests/Application/MainLoopTests.cs index 7b15faad53..ca63e3da14 100644 --- a/UnitTests/Application/MainLoopTests.cs +++ b/UnitTests/Application/MainLoopTests.cs @@ -13,828 +13,821 @@ // Alias Console to MockConsole so we don't accidentally use Console using Console = Terminal.Gui.FakeConsole; -namespace Terminal.Gui.ApplicationTests { - /// - /// Tests MainLoop using the FakeMainLoop. - /// - public class MainLoopTests { - - // TODO: Expand to test all the MainLoop implementations. - - [Fact] - public void Constructor_Setups_Driver () - { - var ml = new MainLoop (new FakeMainLoop ()); - Assert.NotNull (ml.MainLoopDriver); - } - - // Idle Handler tests - [Fact] - public void AddIdle_Adds_And_Removes () - { - var ml = new MainLoop (new FakeMainLoop ()); - - Func fnTrue = () => true; - Func fnFalse = () => false; - - ml.AddIdle (fnTrue); - ml.AddIdle (fnFalse); - - Assert.Equal (2, ml.IdleHandlers.Count); - Assert.Equal (fnTrue, ml.IdleHandlers [0]); - Assert.NotEqual (fnFalse, ml.IdleHandlers [0]); - - Assert.True (ml.RemoveIdle (fnTrue)); - Assert.Single (ml.IdleHandlers); - - // BUGBUG: This doesn't throw or indicate an error. Ideally RemoveIdle would either - // throw an exception in this case, or return an error. - // No. Only need to return a boolean. - Assert.False (ml.RemoveIdle (fnTrue)); - - Assert.True (ml.RemoveIdle (fnFalse)); - - // BUGBUG: This doesn't throw an exception or indicate an error. Ideally RemoveIdle would either - // throw an exception in this case, or return an error. - // No. Only need to return a boolean. - Assert.False (ml.RemoveIdle (fnFalse)); - - // Add again, but with dupe - ml.AddIdle (fnTrue); - ml.AddIdle (fnTrue); - - Assert.Equal (2, ml.IdleHandlers.Count); - Assert.Equal (fnTrue, ml.IdleHandlers [0]); - Assert.True (ml.IdleHandlers [0] ()); - Assert.Equal (fnTrue, ml.IdleHandlers [1]); - Assert.True (ml.IdleHandlers [1] ()); - - Assert.True (ml.RemoveIdle (fnTrue)); - Assert.Single (ml.IdleHandlers); - Assert.Equal (fnTrue, ml.IdleHandlers [0]); - Assert.NotEqual (fnFalse, ml.IdleHandlers [0]); - - Assert.True (ml.RemoveIdle (fnTrue)); - Assert.Empty (ml.IdleHandlers); - - // BUGBUG: This doesn't throw an exception or indicate an error. Ideally RemoveIdle would either - // throw an exception in this case, or return an error. - // No. Only need to return a boolean. - Assert.False (ml.RemoveIdle (fnTrue)); - } - - [Fact] - public void AddIdle_Function_GetsCalled_OnIteration () - { - var ml = new MainLoop (new FakeMainLoop ()); - - var functionCalled = 0; - Func fn = () => { - functionCalled++; - return true; - }; - - ml.AddIdle (fn); - ml.RunIteration (); - Assert.Equal (1, functionCalled); - } - - [Fact] - public void RemoveIdle_Function_NotCalled () - { - var ml = new MainLoop (new FakeMainLoop ()); - - var functionCalled = 0; - Func fn = () => { - functionCalled++; - return true; - }; - - Assert.False (ml.RemoveIdle (fn)); - ml.RunIteration (); - Assert.Equal (0, functionCalled); - } - - [Fact] - public void AddThenRemoveIdle_Function_NotCalled () - { - var ml = new MainLoop (new FakeMainLoop ()); - - var functionCalled = 0; - Func fn = () => { - functionCalled++; - return true; - }; +namespace Terminal.Gui.ApplicationTests; +/// +/// Tests MainLoop using the FakeMainLoop. +/// +public class MainLoopTests { + + // See Also ConsoleDRivers/MainLoopDriverTests.cs for tests of the MainLoopDriver + + + // Idle Handler tests + [Fact] + public void AddIdle_Adds_And_Removes () + { + var ml = new MainLoop (new FakeMainLoop ()); + + Func fnTrue = () => true; + Func fnFalse = () => false; + + ml.AddIdle (fnTrue); + ml.AddIdle (fnFalse); + + Assert.Equal (2, ml.IdleHandlers.Count); + Assert.Equal (fnTrue, ml.IdleHandlers [0]); + Assert.NotEqual (fnFalse, ml.IdleHandlers [0]); + + Assert.True (ml.RemoveIdle (fnTrue)); + Assert.Single (ml.IdleHandlers); + + // BUGBUG: This doesn't throw or indicate an error. Ideally RemoveIdle would either + // throw an exception in this case, or return an error. + // No. Only need to return a boolean. + Assert.False (ml.RemoveIdle (fnTrue)); + + Assert.True (ml.RemoveIdle (fnFalse)); + + // BUGBUG: This doesn't throw an exception or indicate an error. Ideally RemoveIdle would either + // throw an exception in this case, or return an error. + // No. Only need to return a boolean. + Assert.False (ml.RemoveIdle (fnFalse)); + + // Add again, but with dupe + ml.AddIdle (fnTrue); + ml.AddIdle (fnTrue); + + Assert.Equal (2, ml.IdleHandlers.Count); + Assert.Equal (fnTrue, ml.IdleHandlers [0]); + Assert.True (ml.IdleHandlers [0] ()); + Assert.Equal (fnTrue, ml.IdleHandlers [1]); + Assert.True (ml.IdleHandlers [1] ()); + + Assert.True (ml.RemoveIdle (fnTrue)); + Assert.Single (ml.IdleHandlers); + Assert.Equal (fnTrue, ml.IdleHandlers [0]); + Assert.NotEqual (fnFalse, ml.IdleHandlers [0]); + + Assert.True (ml.RemoveIdle (fnTrue)); + Assert.Empty (ml.IdleHandlers); + + // BUGBUG: This doesn't throw an exception or indicate an error. Ideally RemoveIdle would either + // throw an exception in this case, or return an error. + // No. Only need to return a boolean. + Assert.False (ml.RemoveIdle (fnTrue)); + } - ml.AddIdle (fn); - Assert.True (ml.RemoveIdle (fn)); - ml.RunIteration (); - Assert.Equal (0, functionCalled); - } + [Fact] + public void AddIdle_Function_GetsCalled_OnIteration () + { + var ml = new MainLoop (new FakeMainLoop ()); - [Fact] - public void AddIdleTwice_Function_CalledTwice () - { - var ml = new MainLoop (new FakeMainLoop ()); + var functionCalled = 0; + Func fn = () => { + functionCalled++; + return true; + }; - var functionCalled = 0; - Func fn = () => { - functionCalled++; - return true; - }; + ml.AddIdle (fn); + ml.RunIteration (); + Assert.Equal (1, functionCalled); + } - ml.AddIdle (fn); - ml.AddIdle (fn); - ml.RunIteration (); - Assert.Equal (2, functionCalled); - Assert.Equal (2, ml.IdleHandlers.Count); - - functionCalled = 0; - Assert.True (ml.RemoveIdle (fn)); - Assert.Single (ml.IdleHandlers); - ml.RunIteration (); - Assert.Equal (1, functionCalled); - - functionCalled = 0; - Assert.True (ml.RemoveIdle (fn)); - Assert.Empty (ml.IdleHandlers); - ml.RunIteration (); - Assert.Equal (0, functionCalled); - Assert.False (ml.RemoveIdle (fn)); - } + [Fact] + public void RemoveIdle_Function_NotCalled () + { + var ml = new MainLoop (new FakeMainLoop ()); - [Fact] - public void False_Idle_Stops_It_Being_Called_Again () - { - var ml = new MainLoop (new FakeMainLoop ()); + var functionCalled = 0; + Func fn = () => { + functionCalled++; + return true; + }; - var functionCalled = 0; - Func fn1 = () => { - functionCalled++; - if (functionCalled == 10) return false; - return true; - }; + Assert.False (ml.RemoveIdle (fn)); + ml.RunIteration (); + Assert.Equal (0, functionCalled); + } - // Force stop if 20 iterations - var stopCount = 0; - Func fnStop = () => { - stopCount++; - if (stopCount == 20) ml.Stop (); - return true; - }; + [Fact] + public void AddThenRemoveIdle_Function_NotCalled () + { + var ml = new MainLoop (new FakeMainLoop ()); + + var functionCalled = 0; + Func fn = () => { + functionCalled++; + return true; + }; + + ml.AddIdle (fn); + Assert.True (ml.RemoveIdle (fn)); + ml.RunIteration (); + Assert.Equal (0, functionCalled); + } - ml.AddIdle (fnStop); - ml.AddIdle (fn1); - ml.Run (); - Assert.True (ml.RemoveIdle (fnStop)); - Assert.False (ml.RemoveIdle (fn1)); + [Fact] + public void AddIdleTwice_Function_CalledTwice () + { + var ml = new MainLoop (new FakeMainLoop ()); + + var functionCalled = 0; + Func fn = () => { + functionCalled++; + return true; + }; + + ml.AddIdle (fn); + ml.AddIdle (fn); + ml.RunIteration (); + Assert.Equal (2, functionCalled); + Assert.Equal (2, ml.IdleHandlers.Count); + + functionCalled = 0; + Assert.True (ml.RemoveIdle (fn)); + Assert.Single (ml.IdleHandlers); + ml.RunIteration (); + Assert.Equal (1, functionCalled); + + functionCalled = 0; + Assert.True (ml.RemoveIdle (fn)); + Assert.Empty (ml.IdleHandlers); + ml.RunIteration (); + Assert.Equal (0, functionCalled); + Assert.False (ml.RemoveIdle (fn)); + } - Assert.Equal (10, functionCalled); - Assert.Equal (20, stopCount); - } + [Fact] + public void False_Idle_Stops_It_Being_Called_Again () + { + var ml = new MainLoop (new FakeMainLoop ()); + + var functionCalled = 0; + Func fn1 = () => { + functionCalled++; + if (functionCalled == 10) return false; + return true; + }; + + // Force stop if 20 iterations + var stopCount = 0; + Func fnStop = () => { + stopCount++; + if (stopCount == 20) ml.Stop (); + return true; + }; + + ml.AddIdle (fnStop); + ml.AddIdle (fn1); + ml.Run (); + Assert.True (ml.RemoveIdle (fnStop)); + Assert.False (ml.RemoveIdle (fn1)); + + Assert.Equal (10, functionCalled); + Assert.Equal (20, stopCount); + } - [Fact] - public void AddIdle_Twice_Returns_False_Called_Twice () - { - var ml = new MainLoop (new FakeMainLoop ()); + [Fact] + public void AddIdle_Twice_Returns_False_Called_Twice () + { + var ml = new MainLoop (new FakeMainLoop ()); + + var functionCalled = 0; + Func fn1 = () => { + functionCalled++; + return false; + }; + + // Force stop if 10 iterations + var stopCount = 0; + Func fnStop = () => { + stopCount++; + if (stopCount == 10) ml.Stop (); + return true; + }; + + ml.AddIdle (fnStop); + ml.AddIdle (fn1); + ml.AddIdle (fn1); + ml.Run (); + Assert.True (ml.RemoveIdle (fnStop)); + Assert.False (ml.RemoveIdle (fn1)); + Assert.False (ml.RemoveIdle (fn1)); + + Assert.Equal (2, functionCalled); + } - var functionCalled = 0; - Func fn1 = () => { - functionCalled++; - return false; - }; + [Fact] + public void Run_Runs_Idle_Stop_Stops_Idle () + { + var ml = new MainLoop (new FakeMainLoop ()); - // Force stop if 10 iterations - var stopCount = 0; - Func fnStop = () => { - stopCount++; - if (stopCount == 10) ml.Stop (); - return true; - }; + var functionCalled = 0; + Func fn = () => { + functionCalled++; + if (functionCalled == 10) { + ml.Stop (); + } + return true; + }; - ml.AddIdle (fnStop); - ml.AddIdle (fn1); - ml.AddIdle (fn1); - ml.Run (); - Assert.True (ml.RemoveIdle (fnStop)); - Assert.False (ml.RemoveIdle (fn1)); - Assert.False (ml.RemoveIdle (fn1)); + ml.AddIdle (fn); + ml.Run (); + Assert.True (ml.RemoveIdle (fn)); - Assert.Equal (2, functionCalled); - } + Assert.Equal (10, functionCalled); + } - [Fact] - public void Run_Runs_Idle_Stop_Stops_Idle () - { - var ml = new MainLoop (new FakeMainLoop ()); + // Timeout Handler Tests + [Fact] + public void AddTimer_Adds_Removes_NoFaults () + { + var ml = new MainLoop (new FakeMainLoop ()); + var ms = 100; - var functionCalled = 0; - Func fn = () => { - functionCalled++; - if (functionCalled == 10) { - ml.Stop (); - } - return true; - }; + var callbackCount = 0; + Func callback = (loop) => { + callbackCount++; + return true; + }; - ml.AddIdle (fn); - ml.Run (); - Assert.True (ml.RemoveIdle (fn)); + var token = ml.AddTimeout (TimeSpan.FromMilliseconds (ms), callback); - Assert.Equal (10, functionCalled); - } + Assert.True (ml.RemoveTimeout (token)); - // Timeout Handler Tests - [Fact] - public void AddTimer_Adds_Removes_NoFaults () - { - var ml = new MainLoop (new FakeMainLoop ()); - var ms = 100; + // BUGBUG: This should probably fault? + // Must return a boolean. + Assert.False (ml.RemoveTimeout (token)); + } - var callbackCount = 0; - Func callback = (loop) => { - callbackCount++; - return true; - }; + // Timeout Handler Tests + [Fact] + public void AddTimer_EventFired () + { + var ml = new MainLoop (new FakeMainLoop ()); + var ms = 100; - var token = ml.AddTimeout (TimeSpan.FromMilliseconds (ms), callback); + var originTicks = DateTime.UtcNow.Ticks; - Assert.True (ml.RemoveTimeout (token)); + var callbackCount = 0; + Func callback = (loop) => { + callbackCount++; + return true; + }; - // BUGBUG: This should probably fault? - // Must return a boolean. - Assert.False (ml.RemoveTimeout (token)); - } + object sender = null; + TimeoutEventArgs args = null; + ml.TimeoutAdded += (s, e) => { + sender = s; + args = e; + }; - // Timeout Handler Tests - [Fact] - public void AddTimer_EventFired () - { - var ml = new MainLoop (new FakeMainLoop ()); - var ms = 100; + var token = ml.AddTimeout (TimeSpan.FromMilliseconds (ms), callback); - var originTicks = DateTime.UtcNow.Ticks; + Assert.Same (ml, sender); + Assert.NotNull (args.Timeout); + Assert.True (args.Ticks - originTicks >= 100 * TimeSpan.TicksPerMillisecond); - var callbackCount = 0; - Func callback = (loop) => { - callbackCount++; - return true; - }; + } + [Fact] + public void AddTimer_Run_Called () + { + var ml = new MainLoop (new FakeMainLoop ()); + var ms = 100; + + var callbackCount = 0; + Func callback = (loop) => { + callbackCount++; + ml.Stop (); + return true; + }; + + var token = ml.AddTimeout (TimeSpan.FromMilliseconds (ms), callback); + ml.Run (); + Assert.True (ml.RemoveTimeout (token)); + + Assert.Equal (1, callbackCount); + } - object sender = null; - TimeoutEventArgs args = null; - ml.TimeoutAdded += (s, e) => { - sender = s; - args = e; - }; + [Fact] + public async Task AddTimer_Duplicate_Keys_Not_Allowed () + { + var ml = new MainLoop (new FakeMainLoop ()); + const int ms = 100; + object token1 = null, token2 = null; + + var callbackCount = 0; + Func callback = (loop) => { + callbackCount++; + if (callbackCount == 2) ml.Stop (); + return true; + }; + + var task1 = new Task (() => token1 = ml.AddTimeout (TimeSpan.FromMilliseconds (ms), callback)); + var task2 = new Task (() => token2 = ml.AddTimeout (TimeSpan.FromMilliseconds (ms), callback)); + Assert.Null (token1); + Assert.Null (token2); + task1.Start (); + task2.Start (); + ml.Run (); + Assert.NotNull (token1); + Assert.NotNull (token2); + await Task.WhenAll (task1, task2); + Assert.True (ml.RemoveTimeout (token1)); + Assert.True (ml.RemoveTimeout (token2)); + + Assert.Equal (2, callbackCount); + } - var token = ml.AddTimeout (TimeSpan.FromMilliseconds (ms), callback); + [Fact] + public void AddTimer_In_Parallel_Wont_Throw () + { + var ml = new MainLoop (new FakeMainLoop ()); + const int ms = 100; + object token1 = null, token2 = null; + + var callbackCount = 0; + Func callback = (loop) => { + callbackCount++; + if (callbackCount == 2) ml.Stop (); + return true; + }; + + Parallel.Invoke ( + () => token1 = ml.AddTimeout (TimeSpan.FromMilliseconds (ms), callback), + () => token2 = ml.AddTimeout (TimeSpan.FromMilliseconds (ms), callback) + ); + ml.Run (); + Assert.NotNull (token1); + Assert.NotNull (token2); + Assert.True (ml.RemoveTimeout (token1)); + Assert.True (ml.RemoveTimeout (token2)); + + Assert.Equal (2, callbackCount); + } - Assert.Same (ml, sender); - Assert.NotNull (args.Timeout); - Assert.True (args.Ticks - originTicks >= 100 * TimeSpan.TicksPerMillisecond); + class MillisecondTolerance : IEqualityComparer { + int _tolerance = 0; + public MillisecondTolerance (int tolerance) { _tolerance = tolerance; } + public bool Equals (TimeSpan x, TimeSpan y) => Math.Abs (x.Milliseconds - y.Milliseconds) <= _tolerance; + public int GetHashCode (TimeSpan obj) => obj.GetHashCode (); + } - } - [Fact] - public void AddTimer_Run_Called () - { - var ml = new MainLoop (new FakeMainLoop ()); - var ms = 100; + [Fact] + public void AddTimer_Run_CalledAtApproximatelyRightTime () + { + var ml = new MainLoop (new FakeMainLoop ()); + var ms = TimeSpan.FromMilliseconds (50); + var watch = new System.Diagnostics.Stopwatch (); + + var callbackCount = 0; + Func callback = (loop) => { + watch.Stop (); + callbackCount++; + ml.Stop (); + return true; + }; + + var token = ml.AddTimeout (ms, callback); + watch.Start (); + ml.Run (); + // +/- 100ms should be good enuf + // https://github.com/xunit/assert.xunit/pull/25 + Assert.Equal (ms * callbackCount, watch.Elapsed, new MillisecondTolerance (100)); + + Assert.True (ml.RemoveTimeout (token)); + Assert.Equal (1, callbackCount); + } - var callbackCount = 0; - Func callback = (loop) => { - callbackCount++; + [Fact] + public void AddTimer_Run_CalledTwiceApproximatelyRightTime () + { + var ml = new MainLoop (new FakeMainLoop ()); + var ms = TimeSpan.FromMilliseconds (50); + var watch = new System.Diagnostics.Stopwatch (); + + var callbackCount = 0; + Func callback = (loop) => { + callbackCount++; + if (callbackCount == 2) { + watch.Stop (); ml.Stop (); - return true; - }; - - var token = ml.AddTimeout (TimeSpan.FromMilliseconds (ms), callback); - ml.Run (); - Assert.True (ml.RemoveTimeout (token)); + } + return true; + }; + + var token = ml.AddTimeout (ms, callback); + watch.Start (); + ml.Run (); + // +/- 100ms should be good enuf + // https://github.com/xunit/assert.xunit/pull/25 + Assert.Equal (ms * callbackCount, watch.Elapsed, new MillisecondTolerance (100)); + + Assert.True (ml.RemoveTimeout (token)); + Assert.Equal (2, callbackCount); + } - Assert.Equal (1, callbackCount); - } + [Fact] + public void AddTimer_Remove_NotCalled () + { + var ml = new MainLoop (new FakeMainLoop ()); + var ms = TimeSpan.FromMilliseconds (50); + + // Force stop if 10 iterations + var stopCount = 0; + Func fnStop = () => { + stopCount++; + if (stopCount == 10) ml.Stop (); + return true; + }; + ml.AddIdle (fnStop); + + var callbackCount = 0; + Func callback = (loop) => { + callbackCount++; + return true; + }; + + var token = ml.AddTimeout (ms, callback); + Assert.True (ml.RemoveTimeout (token)); + ml.Run (); + Assert.Equal (0, callbackCount); + } - [Fact] - public async Task AddTimer_Duplicate_Keys_Not_Allowed () - { - var ml = new MainLoop (new FakeMainLoop ()); - const int ms = 100; - object token1 = null, token2 = null; - - var callbackCount = 0; - Func callback = (loop) => { - callbackCount++; - if (callbackCount == 2) ml.Stop (); - return true; - }; + [Fact] + public void AddTimer_ReturnFalse_StopsBeingCalled () + { + var ml = new MainLoop (new FakeMainLoop ()); + var ms = TimeSpan.FromMilliseconds (50); + + // Force stop if 10 iterations + var stopCount = 0; + Func fnStop = () => { + Thread.Sleep (10); // Sleep to enable timer to fire + stopCount++; + if (stopCount == 10) ml.Stop (); + return true; + }; + ml.AddIdle (fnStop); + + var callbackCount = 0; + Func callback = (loop) => { + callbackCount++; + return false; + }; + + var token = ml.AddTimeout (ms, callback); + ml.Run (); + Assert.Equal (1, callbackCount); + Assert.Equal (10, stopCount); + Assert.False (ml.RemoveTimeout (token)); + } - var task1 = new Task (() => token1 = ml.AddTimeout (TimeSpan.FromMilliseconds (ms), callback)); - var task2 = new Task (() => token2 = ml.AddTimeout (TimeSpan.FromMilliseconds (ms), callback)); - Assert.Null (token1); - Assert.Null (token2); - task1.Start (); - task2.Start (); - ml.Run (); - Assert.NotNull (token1); - Assert.NotNull (token2); - await Task.WhenAll (task1, task2); - Assert.True (ml.RemoveTimeout (token1)); - Assert.True (ml.RemoveTimeout (token2)); - - Assert.Equal (2, callbackCount); - } + // Invoke Tests + // TODO: Test with threading scenarios + [Fact] + public void Invoke_Adds_Idle () + { + var ml = new MainLoop (new FakeMainLoop ()); + + var actionCalled = 0; + ml.Invoke (() => { actionCalled++; }); + ml.RunIteration (); + Assert.Equal (1, actionCalled); + } - [Fact] - public void AddTimer_In_Parallel_Wont_Throw () - { - var ml = new MainLoop (new FakeMainLoop ()); - const int ms = 100; - object token1 = null, token2 = null; - - var callbackCount = 0; - Func callback = (loop) => { - callbackCount++; - if (callbackCount == 2) ml.Stop (); - return true; - }; + [Fact] + public void CheckTimersAndIdleHandlers_NoTimers_Returns_False () + { + var ml = new MainLoop (new FakeMainLoop ()); + var retVal = ml.CheckTimersAndIdleHandlers (out var waitTimeOut); + Assert.False (retVal); + Assert.Equal (-1, waitTimeOut); + } - Parallel.Invoke ( - () => token1 = ml.AddTimeout (TimeSpan.FromMilliseconds (ms), callback), - () => token2 = ml.AddTimeout (TimeSpan.FromMilliseconds (ms), callback) - ); - ml.Run (); - Assert.NotNull (token1); - Assert.NotNull (token2); - Assert.True (ml.RemoveTimeout (token1)); - Assert.True (ml.RemoveTimeout (token2)); - - Assert.Equal (2, callbackCount); - } + [Fact] + public void CheckTimersAndIdleHandlers_NoTimers_WithIdle_Returns_True () + { + var ml = new MainLoop (new FakeMainLoop ()); + Func fnTrue = () => true; - class MillisecondTolerance : IEqualityComparer { - int _tolerance = 0; - public MillisecondTolerance (int tolerance) { _tolerance = tolerance; } - public bool Equals (TimeSpan x, TimeSpan y) => Math.Abs (x.Milliseconds - y.Milliseconds) <= _tolerance; - public int GetHashCode (TimeSpan obj) => obj.GetHashCode (); - } + ml.AddIdle (fnTrue); + var retVal = ml.CheckTimersAndIdleHandlers (out var waitTimeOut); + Assert.True (retVal); + Assert.Equal (-1, waitTimeOut); + } - [Fact] - public void AddTimer_Run_CalledAtApproximatelyRightTime () - { - var ml = new MainLoop (new FakeMainLoop ()); - var ms = TimeSpan.FromMilliseconds (50); - var watch = new System.Diagnostics.Stopwatch (); + [Fact] + public void CheckTimersAndIdleHandlers_With1Timer_Returns_Timer () + { + var ml = new MainLoop (new FakeMainLoop ()); + var ms = TimeSpan.FromMilliseconds (50); - var callbackCount = 0; - Func callback = (loop) => { - watch.Stop (); - callbackCount++; - ml.Stop (); - return true; - }; + static bool Callback (MainLoop loop) => false; - var token = ml.AddTimeout (ms, callback); - watch.Start (); - ml.Run (); - // +/- 100ms should be good enuf - // https://github.com/xunit/assert.xunit/pull/25 - Assert.Equal (ms * callbackCount, watch.Elapsed, new MillisecondTolerance (100)); + _ = ml.AddTimeout (ms, Callback); + var retVal = ml.CheckTimersAndIdleHandlers (out var waitTimeOut); - Assert.True (ml.RemoveTimeout (token)); - Assert.Equal (1, callbackCount); - } + Assert.True (retVal); + // It should take < 10ms to execute to here + Assert.True (ms.TotalMilliseconds <= (waitTimeOut + 10)); + } - [Fact] - public void AddTimer_Run_CalledTwiceApproximatelyRightTime () - { - var ml = new MainLoop (new FakeMainLoop ()); - var ms = TimeSpan.FromMilliseconds (50); - var watch = new System.Diagnostics.Stopwatch (); - - var callbackCount = 0; - Func callback = (loop) => { - callbackCount++; - if (callbackCount == 2) { - watch.Stop (); - ml.Stop (); - } - return true; - }; + [Fact] + public void CheckTimersAndIdleHandlers_With2Timers_Returns_Timer () + { + var ml = new MainLoop (new FakeMainLoop ()); + var ms = TimeSpan.FromMilliseconds (50); - var token = ml.AddTimeout (ms, callback); - watch.Start (); - ml.Run (); - // +/- 100ms should be good enuf - // https://github.com/xunit/assert.xunit/pull/25 - Assert.Equal (ms * callbackCount, watch.Elapsed, new MillisecondTolerance (100)); + static bool Callback (MainLoop loop) => false; - Assert.True (ml.RemoveTimeout (token)); - Assert.Equal (2, callbackCount); - } + _ = ml.AddTimeout (ms, Callback); + _ = ml.AddTimeout (ms, Callback); + var retVal = ml.CheckTimersAndIdleHandlers (out var waitTimeOut); - [Fact] - public void AddTimer_Remove_NotCalled () - { - var ml = new MainLoop (new FakeMainLoop ()); - var ms = TimeSpan.FromMilliseconds (50); - - // Force stop if 10 iterations - var stopCount = 0; - Func fnStop = () => { - stopCount++; - if (stopCount == 10) ml.Stop (); - return true; - }; - ml.AddIdle (fnStop); + Assert.True (retVal); + // It should take < 10ms to execute to here + Assert.True (ms.TotalMilliseconds <= (waitTimeOut + 10)); + } - var callbackCount = 0; - Func callback = (loop) => { - callbackCount++; - return true; - }; + [Fact] + public void Internal_Tests () + { + var testMainloop = new TestMainloop (); + var mainloop = new MainLoop (testMainloop); + Assert.Empty (mainloop._timeouts); + Assert.Empty (mainloop._idleHandlers); + Assert.NotNull (new Timeout () { + Span = new TimeSpan (), + Callback = (_) => true + }); + } - var token = ml.AddTimeout (ms, callback); - Assert.True (ml.RemoveTimeout (token)); - ml.Run (); - Assert.Equal (0, callbackCount); - } + private class TestMainloop : IMainLoopDriver { + private MainLoop mainLoop; - [Fact] - public void AddTimer_ReturnFalse_StopsBeingCalled () + public bool EventsPending () { - var ml = new MainLoop (new FakeMainLoop ()); - var ms = TimeSpan.FromMilliseconds (50); - - // Force stop if 10 iterations - var stopCount = 0; - Func fnStop = () => { - Thread.Sleep (10); // Sleep to enable timer to fire - stopCount++; - if (stopCount == 10) ml.Stop (); - return true; - }; - ml.AddIdle (fnStop); - - var callbackCount = 0; - Func callback = (loop) => { - callbackCount++; - return false; - }; - - var token = ml.AddTimeout (ms, callback); - ml.Run (); - Assert.Equal (1, callbackCount); - Assert.Equal (10, stopCount); - Assert.False (ml.RemoveTimeout (token)); + throw new NotImplementedException (); } - // Invoke Tests - // TODO: Test with threading scenarios - [Fact] - public void Invoke_Adds_Idle () + public void Iteration () { - var ml = new MainLoop (new FakeMainLoop ()); - - var actionCalled = 0; - ml.Invoke (() => { actionCalled++; }); - ml.RunIteration (); - Assert.Equal (1, actionCalled); + throw new NotImplementedException (); } - - [Fact] - public void CheckTimersAndIdleHandlers_NoTimers_Returns_False () + public void TearDown () { - var ml = new MainLoop (new FakeMainLoop ()); - var retVal = ml.CheckTimersAndIdleHandlers (out var waitTimeOut); - Assert.False (retVal); - Assert.Equal (-1, waitTimeOut); + throw new NotImplementedException (); } - [Fact] - public void CheckTimersAndIdleHandlers_NoTimers_WithIdle_Returns_True () + public void Setup (MainLoop mainLoop) { - var ml = new MainLoop (new FakeMainLoop ()); - Func fnTrue = () => true; - - ml.AddIdle (fnTrue); - var retVal = ml.CheckTimersAndIdleHandlers (out var waitTimeOut); - Assert.True (retVal); - Assert.Equal (-1, waitTimeOut); + this.mainLoop = mainLoop; } - [Fact] - public void CheckTimersAndIdleHandlers_With1Timer_Returns_Timer () + public void Wakeup () { - var ml = new MainLoop (new FakeMainLoop ()); - var ms = TimeSpan.FromMilliseconds (50); - - static bool Callback (MainLoop loop) => false; - - _ = ml.AddTimeout (ms, Callback); - var retVal = ml.CheckTimersAndIdleHandlers (out var waitTimeOut); - - Assert.True (retVal); - // It should take < 10ms to execute to here - Assert.True (ms.TotalMilliseconds <= (waitTimeOut + 10)); + throw new NotImplementedException (); } + } - [Fact] - public void CheckTimersAndIdleHandlers_With2Timers_Returns_Timer () - { - var ml = new MainLoop (new FakeMainLoop ()); - var ms = TimeSpan.FromMilliseconds (50); - - static bool Callback (MainLoop loop) => false; + // TODO: EventsPending tests + // - wait = true + // - wait = false - _ = ml.AddTimeout (ms, Callback); - _ = ml.AddTimeout (ms, Callback); - var retVal = ml.CheckTimersAndIdleHandlers (out var waitTimeOut); + // TODO: Add IMainLoop tests - Assert.True (retVal); - // It should take < 10ms to execute to here - Assert.True (ms.TotalMilliseconds <= (waitTimeOut + 10)); - } + volatile static int tbCounter = 0; + static ManualResetEventSlim _wakeUp = new ManualResetEventSlim (false); - [Fact] - public void Internal_Tests () - { - var testMainloop = new TestMainloop (); - var mainloop = new MainLoop (testMainloop); - Assert.Empty (mainloop._timeouts); - Assert.Empty (mainloop._idleHandlers); - Assert.NotNull (new Timeout () { - Span = new TimeSpan (), - Callback = (_) => true + private static void Launch (Random r, TextField tf, int target) + { + Task.Run (() => { + Thread.Sleep (r.Next (2, 4)); + Application.MainLoop.Invoke (() => { + tf.Text = $"index{r.Next ()}"; + Interlocked.Increment (ref tbCounter); + if (target == tbCounter) { + // On last increment wake up the check + _wakeUp.Set (); + } }); - } - - private class TestMainloop : IMainLoopDriver { - private MainLoop mainLoop; - - public bool EventsPending () - { - throw new NotImplementedException (); - } + }); + } - public void Iteration () - { - throw new NotImplementedException (); - } - public void TearDown () - { - throw new NotImplementedException (); - } + private static void RunTest (Random r, TextField tf, int numPasses, int numIncrements, int pollMs) + { + for (int j = 0; j < numPasses; j++) { - public void Setup (MainLoop mainLoop) - { - this.mainLoop = mainLoop; - } + _wakeUp.Reset (); + for (var i = 0; i < numIncrements; i++) Launch (r, tf, (j + 1) * numIncrements); - public void Wakeup () + while (tbCounter != (j + 1) * numIncrements) // Wait for tbCounter to reach expected value { - throw new NotImplementedException (); - } - } - - // TODO: EventsPending tests - // - wait = true - // - wait = false - - // TODO: Add IMainLoop tests - - volatile static int tbCounter = 0; - static ManualResetEventSlim _wakeUp = new ManualResetEventSlim (false); - - private static void Launch (Random r, TextField tf, int target) - { - Task.Run (() => { - Thread.Sleep (r.Next (2, 4)); - Application.MainLoop.Invoke (() => { - tf.Text = $"index{r.Next ()}"; - Interlocked.Increment (ref tbCounter); - if (target == tbCounter) { - // On last increment wake up the check - _wakeUp.Set (); - } - }); - }); - } - - private static void RunTest (Random r, TextField tf, int numPasses, int numIncrements, int pollMs) - { - for (int j = 0; j < numPasses; j++) { - - _wakeUp.Reset (); - for (var i = 0; i < numIncrements; i++) Launch (r, tf, (j + 1) * numIncrements); - - while (tbCounter != (j + 1) * numIncrements) // Wait for tbCounter to reach expected value - { - var tbNow = tbCounter; - _wakeUp.Wait (pollMs); - if (tbCounter == tbNow) { - // No change after wait: Idle handlers added via Application.MainLoop.Invoke have gone missing - Application.MainLoop.Invoke (() => Application.RequestStop ()); - throw new TimeoutException ( - $"Timeout: Increment lost. tbCounter ({tbCounter}) didn't " + - $"change after waiting {pollMs} ms. Failed to reach {(j + 1) * numIncrements} on pass {j + 1}"); - } - }; - } - Application.MainLoop.Invoke (() => Application.RequestStop ()); + var tbNow = tbCounter; + _wakeUp.Wait (pollMs); + if (tbCounter == tbNow) { + // No change after wait: Idle handlers added via Application.MainLoop.Invoke have gone missing + Application.MainLoop.Invoke (() => Application.RequestStop ()); + throw new TimeoutException ( + $"Timeout: Increment lost. tbCounter ({tbCounter}) didn't " + + $"change after waiting {pollMs} ms. Failed to reach {(j + 1) * numIncrements} on pass {j + 1}"); + } + }; } + Application.MainLoop.Invoke (() => Application.RequestStop ()); + } - [Fact] - [AutoInitShutdown] - public async Task InvokeLeakTest () - { - Random r = new (); - TextField tf = new (); - Application.Top.Add (tf); - - const int numPasses = 5; - const int numIncrements = 5000; - const int pollMs = 10000; - - var task = Task.Run (() => RunTest (r, tf, numPasses, numIncrements, pollMs)); - - // blocks here until the RequestStop is processed at the end of the test - Application.Run (); - - await task; // Propagate exception if any occurred + [Fact] + [AutoInitShutdown] + public async Task InvokeLeakTest () + { + Random r = new (); + TextField tf = new (); + Application.Top.Add (tf); - Assert.Equal (numIncrements * numPasses, tbCounter); - } + const int numPasses = 5; + const int numIncrements = 5000; + const int pollMs = 10000; - private static int total; - private static Button btn; - private static string clickMe; - private static string cancel; - private static string pewPew; - private static int zero; - private static int one; - private static int two; - private static int three; - private static int four; - private static bool taskCompleted; - - [Theory, AutoInitShutdown] - [MemberData (nameof (TestAddIdle))] - public void Mainloop_Invoke_Or_AddIdle_Can_Be_Used_For_Events_Or_Actions (Action action, string pclickMe, string pcancel, string ppewPew, int pzero, int pone, int ptwo, int pthree, int pfour) - { - total = 0; - btn = null; - clickMe = pclickMe; - cancel = pcancel; - pewPew = ppewPew; - zero = pzero; - one = pone; - two = ptwo; - three = pthree; - four = pfour; - taskCompleted = false; + var task = Task.Run (() => RunTest (r, tf, numPasses, numIncrements, pollMs)); - var btnLaunch = new Button ("Open Window"); + // blocks here until the RequestStop is processed at the end of the test + Application.Run (); - btnLaunch.Clicked += (s, e) => action (); + await task; // Propagate exception if any occurred - Application.Top.Add (btnLaunch); - - var iterations = -1; + Assert.Equal (numIncrements * numPasses, tbCounter); + } - Application.Iteration += () => { - iterations++; - if (iterations == 0) { + private static int total; + private static Button btn; + private static string clickMe; + private static string cancel; + private static string pewPew; + private static int zero; + private static int one; + private static int two; + private static int three; + private static int four; + private static bool taskCompleted; + + [Theory, AutoInitShutdown] + [MemberData (nameof (TestAddIdle))] + public void Mainloop_Invoke_Or_AddIdle_Can_Be_Used_For_Events_Or_Actions (Action action, string pclickMe, string pcancel, string ppewPew, int pzero, int pone, int ptwo, int pthree, int pfour) + { + total = 0; + btn = null; + clickMe = pclickMe; + cancel = pcancel; + pewPew = ppewPew; + zero = pzero; + one = pone; + two = ptwo; + three = pthree; + four = pfour; + taskCompleted = false; + + var btnLaunch = new Button ("Open Window"); + + btnLaunch.Clicked += (s, e) => action (); + + Application.Top.Add (btnLaunch); + + var iterations = -1; + + Application.Iteration += () => { + iterations++; + if (iterations == 0) { + Assert.Null (btn); + Assert.Equal (zero, total); + Assert.True (btnLaunch.ProcessKey (new KeyEvent (Key.Enter, null))); + if (btn == null) { Assert.Null (btn); Assert.Equal (zero, total); - Assert.True (btnLaunch.ProcessKey (new KeyEvent (Key.Enter, null))); - if (btn == null) { - Assert.Null (btn); - Assert.Equal (zero, total); - } else { - Assert.Equal (clickMe, btn.Text); - Assert.Equal (four, total); - } - } else if (iterations == 1) { + } else { Assert.Equal (clickMe, btn.Text); - Assert.Equal (zero, total); - Assert.True (btn.ProcessKey (new KeyEvent (Key.Enter, null))); - Assert.Equal (cancel, btn.Text); - Assert.Equal (one, total); - } else if (taskCompleted) { - Application.RequestStop (); + Assert.Equal (four, total); } - }; + } else if (iterations == 1) { + Assert.Equal (clickMe, btn.Text); + Assert.Equal (zero, total); + Assert.True (btn.ProcessKey (new KeyEvent (Key.Enter, null))); + Assert.Equal (cancel, btn.Text); + Assert.Equal (one, total); + } else if (taskCompleted) { + Application.RequestStop (); + } + }; - Application.Run (); + Application.Run (); - Assert.True (taskCompleted); - Assert.Equal (clickMe, btn.Text); - Assert.Equal (four, total); - } + Assert.True (taskCompleted); + Assert.Equal (clickMe, btn.Text); + Assert.Equal (four, total); + } - public static IEnumerable TestAddIdle { - get { - // Goes fine - Action a1 = StartWindow; - yield return new object [] { a1, "Click Me", "Cancel", "Pew Pew", 0, 1, 2, 3, 4 }; + public static IEnumerable TestAddIdle { + get { + // Goes fine + Action a1 = StartWindow; + yield return new object [] { a1, "Click Me", "Cancel", "Pew Pew", 0, 1, 2, 3, 4 }; - // Also goes fine - Action a2 = () => Application.MainLoop.Invoke (StartWindow); - yield return new object [] { a2, "Click Me", "Cancel", "Pew Pew", 0, 1, 2, 3, 4 }; - } + // Also goes fine + Action a2 = () => Application.MainLoop.Invoke (StartWindow); + yield return new object [] { a2, "Click Me", "Cancel", "Pew Pew", 0, 1, 2, 3, 4 }; } + } - private static void StartWindow () - { - var startWindow = new Window { - Modal = true - }; + private static void StartWindow () + { + var startWindow = new Window { + Modal = true + }; - btn = new Button { - Text = "Click Me" - }; + btn = new Button { + Text = "Click Me" + }; - btn.Clicked += RunAsyncTest; + btn.Clicked += RunAsyncTest; - var totalbtn = new Button () { - X = Pos.Right (btn), - Text = "total" - }; + var totalbtn = new Button () { + X = Pos.Right (btn), + Text = "total" + }; - totalbtn.Clicked += (s, e) => { - MessageBox.Query ("Count", $"Count is {total}", "Ok"); - }; + totalbtn.Clicked += (s, e) => { + MessageBox.Query ("Count", $"Count is {total}", "Ok"); + }; - startWindow.Add (btn); - startWindow.Add (totalbtn); + startWindow.Add (btn); + startWindow.Add (totalbtn); - Application.Run (startWindow); + Application.Run (startWindow); - Assert.Equal (clickMe, btn.Text); - Assert.Equal (four, total); + Assert.Equal (clickMe, btn.Text); + Assert.Equal (four, total); - Application.RequestStop (); - } + Application.RequestStop (); + } - private static async void RunAsyncTest (object sender, EventArgs e) - { - Assert.Equal (clickMe, btn.Text); - Assert.Equal (zero, total); + private static async void RunAsyncTest (object sender, EventArgs e) + { + Assert.Equal (clickMe, btn.Text); + Assert.Equal (zero, total); - btn.Text = "Cancel"; - Interlocked.Increment (ref total); - btn.SetNeedsDisplay (); + btn.Text = "Cancel"; + Interlocked.Increment (ref total); + btn.SetNeedsDisplay (); - await Task.Run (() => { - try { - Assert.Equal (cancel, btn.Text); - Assert.Equal (one, total); + await Task.Run (() => { + try { + Assert.Equal (cancel, btn.Text); + Assert.Equal (one, total); - RunSql (); - } finally { - SetReadyToRun (); - } - }).ContinueWith (async (s, e) => { + RunSql (); + } finally { + SetReadyToRun (); + } + }).ContinueWith (async (s, e) => { - await Task.Delay (1000); - Assert.Equal (clickMe, btn.Text); - Assert.Equal (three, total); + await Task.Delay (1000); + Assert.Equal (clickMe, btn.Text); + Assert.Equal (three, total); - Interlocked.Increment (ref total); + Interlocked.Increment (ref total); - Assert.Equal (clickMe, btn.Text); - Assert.Equal (four, total); + Assert.Equal (clickMe, btn.Text); + Assert.Equal (four, total); - taskCompleted = true; + taskCompleted = true; - }, TaskScheduler.FromCurrentSynchronizationContext ()); - } + }, TaskScheduler.FromCurrentSynchronizationContext ()); + } - private static void RunSql () - { - Thread.Sleep (100); - Assert.Equal (cancel, btn.Text); - Assert.Equal (one, total); + private static void RunSql () + { + Thread.Sleep (100); + Assert.Equal (cancel, btn.Text); + Assert.Equal (one, total); - Application.MainLoop.Invoke (() => { - btn.Text = "Pew Pew"; - Interlocked.Increment (ref total); - btn.SetNeedsDisplay (); - }); - } + Application.MainLoop.Invoke (() => { + btn.Text = "Pew Pew"; + Interlocked.Increment (ref total); + btn.SetNeedsDisplay (); + }); + } - private static void SetReadyToRun () - { - Thread.Sleep (100); - Assert.Equal (pewPew, btn.Text); - Assert.Equal (two, total); + private static void SetReadyToRun () + { + Thread.Sleep (100); + Assert.Equal (pewPew, btn.Text); + Assert.Equal (two, total); - Application.MainLoop.Invoke (() => { - btn.Text = "Click Me"; - Interlocked.Increment (ref total); - btn.SetNeedsDisplay (); - }); - } + Application.MainLoop.Invoke (() => { + btn.Text = "Click Me"; + Interlocked.Increment (ref total); + btn.SetNeedsDisplay (); + }); } } diff --git a/UnitTests/ConsoleDrivers/MainLoopTests.cs b/UnitTests/ConsoleDrivers/MainLoopDriverTests.cs similarity index 97% rename from UnitTests/ConsoleDrivers/MainLoopTests.cs rename to UnitTests/ConsoleDrivers/MainLoopDriverTests.cs index 9132226258..da6ff96a86 100644 --- a/UnitTests/ConsoleDrivers/MainLoopTests.cs +++ b/UnitTests/ConsoleDrivers/MainLoopDriverTests.cs @@ -11,9 +11,9 @@ namespace Terminal.Gui.DriverTests; -public class MainLoopTests { +public class MainLoopDriverTests { - public MainLoopTests (ITestOutputHelper output) + public MainLoopDriverTests (ITestOutputHelper output) { ConsoleDriver.RunningUnitTests = true; } @@ -32,7 +32,7 @@ public void MainLoop_Constructs_Disposes (Type driverType, Type mainLoopDriverTy // Check default values Assert.NotNull (mainLoop); Assert.Equal (mainLoopDriver, mainLoop.MainLoopDriver); - Assert.Empty(mainLoop.IdleHandlers); + Assert.Empty (mainLoop.IdleHandlers); Assert.Empty (mainLoop.Timeouts); Assert.False (mainLoop.Running); @@ -45,7 +45,7 @@ public void MainLoop_Constructs_Disposes (Type driverType, Type mainLoopDriverTy Assert.Empty (mainLoop.Timeouts); Assert.False (mainLoop.Running); } - + [Theory] [InlineData (typeof (FakeDriver), typeof (FakeMainLoop))] [InlineData (typeof (NetDriver), typeof (NetMainLoop))] @@ -58,8 +58,7 @@ public void MainLoop_AddTimeout_ValidParameters_ReturnsToken (Type driverType, T var mainLoop = new MainLoop (mainLoopDriver); var callbackInvoked = false; - var token = mainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), (_) => - { + var token = mainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), (_) => { callbackInvoked = true; return false; }); @@ -68,7 +67,7 @@ public void MainLoop_AddTimeout_ValidParameters_ReturnsToken (Type driverType, T mainLoop.RunIteration (); // Run an iteration to process the timeout Assert.False (callbackInvoked); // Callback should not be invoked immediately Thread.Sleep (200); // Wait for the timeout - mainLoop.RunIteration(); // Run an iteration to process the timeout + mainLoop.RunIteration (); // Run an iteration to process the timeout Assert.True (callbackInvoked); // Callback should be invoked after the timeout mainLoop.Dispose (); } @@ -182,8 +181,7 @@ public void MainLoop_RunIteration_ValidIdleHandler_CallsIdleHandler (Type driver var mainLoop = new MainLoop (mainLoopDriver); var idleHandlerInvoked = false; - Func idleHandler = () => - { + Func idleHandler = () => { idleHandlerInvoked = true; return false; }; @@ -192,7 +190,7 @@ public void MainLoop_RunIteration_ValidIdleHandler_CallsIdleHandler (Type driver mainLoop.RunIteration (); // Run an iteration to process the idle handler Assert.True (idleHandlerInvoked); - mainLoop.Dispose(); + mainLoop.Dispose (); } [Theory] From 55a5d25d56e48b91cf3c487d667ce2e05da74380 Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Wed, 18 Oct 2023 11:16:21 -0400 Subject: [PATCH 003/194] Remove WinChange action from Curses --- Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs index 76df5fead0..e9aa6c2b77 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs @@ -215,7 +215,6 @@ public override void End () if (_mainLoop != null) { _mainLoop.RemoveWatch (_processInputToken); - //_mainLoop.WinChanged -= ProcessInput; } if (RunningUnitTests) { @@ -626,8 +625,6 @@ public override void PrepareToRun (MainLoop mainLoop, Action keyHandle ProcessInput (); return true; }); - - //_mainLoop.WinChanged = ProcessInput; } public override void Init (Action terminalResized) From 6ff0b6d5334f296350663792ac75113a03700fa0 Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Wed, 18 Oct 2023 11:18:58 -0400 Subject: [PATCH 004/194] Remove ProcessInput action from Windows MainLoop --- .../ConsoleDrivers/CursesDriver/UnixMainLoop.cs | 3 --- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 12 ++---------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs index d1dafd11f1..54ed4e5b97 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs @@ -88,8 +88,6 @@ class Watch { MainLoop _mainLoop; bool _winChanged; - //internal Action WinChanged; - void IMainLoopDriver.Wakeup () { if (!ConsoleDriver.RunningUnitTests) { @@ -190,7 +188,6 @@ void IMainLoopDriver.Iteration () if (_winChanged) { _winChanged = false; _cursesDriver.ProcessInput (); - //WinChanged?.Invoke (); } if (_pollMap == null) return; foreach (var p in _pollMap) { diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index 6544eeae43..077e155517 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -861,7 +861,6 @@ public override void PrepareToRun (MainLoop mainLoop, Action keyHandle _mouseHandler = mouseHandler; _mainLoop = mainLoop.MainLoopDriver as WindowsMainLoop; - _mainLoop.ProcessInput += ProcessInput; #if HACK_CHECK_WINCHANGED _mainLoop.WinChanged = ChangeWin; #endif @@ -893,7 +892,7 @@ private void ChangeWin (Object s, SizeChangedEventArgs e) } #endif - void ProcessInput (WindowsConsole.InputRecord inputEvent) + internal void ProcessInput (WindowsConsole.InputRecord inputEvent) { switch (inputEvent.EventType) { case WindowsConsole.EventType.Key: @@ -1754,7 +1753,6 @@ public override void SendKeys (char keyChar, ConsoleKey key, bool shift, bool al public override void End () { if (_mainLoop != null) { - _mainLoop.ProcessInput -= ProcessInput; #if HACK_CHECK_WINCHANGED //_mainLoop.WinChanged -= ChangeWin; #endif @@ -1797,11 +1795,6 @@ internal class WindowsMainLoop : IMainLoopDriver { // The records that we keep fetching readonly Queue _resultQueue = new Queue (); - /// - /// Invoked when a Key is pressed or released. - /// - public Action ProcessInput; - /// /// Invoked when the window is changed. /// @@ -1916,8 +1909,7 @@ void IMainLoopDriver.Iteration () while (_resultQueue.Count > 0) { var inputRecords = _resultQueue.Dequeue (); if (inputRecords is { Length: > 0 }) { - var inputEvent = inputRecords [0]; - ProcessInput?.Invoke (inputEvent); + ((WindowsDriver)_consoleDriver).ProcessInput (inputRecords [0]); } } #if HACK_CHECK_WINCHANGED From 9eab13bd22f740900937fd7696af9c00063f6501 Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Wed, 18 Oct 2023 20:04:11 -0400 Subject: [PATCH 005/194] Simplified MainLoop/ConsoleDriver by making MainLoop internal and moving impt fns to Application --- ReactiveExample/TerminalScheduler.cs | 6 +- Terminal.Gui/Application.cs | 153 ++++++++++-------- .../Configuration/ConfigurationManager.cs | 2 +- Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs | 35 ++-- .../CursesDriver/CursesDriver.cs | 31 ++-- .../CursesDriver/UnixMainLoop.cs | 5 +- .../ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs | 2 +- .../ConsoleDrivers/FakeDriver/FakeDriver.cs | 18 ++- Terminal.Gui/ConsoleDrivers/NetDriver.cs | 18 ++- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 24 +-- Terminal.Gui/MainLoop.cs | 66 ++++---- Terminal.Gui/Timeout.cs | 2 +- Terminal.Gui/TimeoutEventArgs.cs | 2 +- Terminal.Gui/Views/FileDialog.cs | 4 +- Terminal.Gui/Views/Slider.cs | 1 + Terminal.Gui/Views/SpinnerView/SpinnerView.cs | 10 +- Terminal.Gui/Views/Toplevel.cs | 2 +- UICatalog/KeyBindingsDialog.cs | 2 +- UICatalog/Scenarios/Animation.cs | 2 +- UICatalog/Scenarios/CharacterMap.cs | 2 +- UICatalog/Scenarios/GraphViewExample.cs | 4 +- UICatalog/Scenarios/ProcessTable.cs | 4 +- UICatalog/Scenarios/Progress.cs | 12 +- UICatalog/Scenarios/ProgressBarStyles.cs | 4 +- UICatalog/Scenarios/Scrolling.cs | 4 +- UICatalog/Scenarios/Snake.cs | 2 +- UICatalog/Scenarios/Threading.cs | 2 +- UICatalog/Scenarios/TreeViewFileSystem.cs | 2 +- UICatalog/Scenarios/VkeyPacketSimulator.cs | 6 +- UnitTests/Application/ApplicationTests.cs | 20 ++- UnitTests/Application/MainLoopTests.cs | 51 +++--- .../Application/SynchronizatonContextTests.cs | 4 +- .../ConsoleDrivers/ConsoleDriverTests.cs | 6 +- .../ConsoleDrivers/MainLoopDriverTests.cs | 42 ++--- UnitTests/Dialogs/DialogTests.cs | 16 +- UnitTests/Dialogs/WizardTests.cs | 10 +- UnitTests/UICatalog/ScenarioTests.cs | 8 +- UnitTests/View/FrameTests.cs | 16 +- UnitTests/View/Layout/LayoutTests.cs | 8 +- UnitTests/View/ViewTests.cs | 2 +- UnitTests/Views/ContextMenuTests.cs | 10 +- UnitTests/Views/MenuTests.cs | 20 +-- UnitTests/Views/ToplevelTests.cs | 12 +- 43 files changed, 354 insertions(+), 298 deletions(-) diff --git a/ReactiveExample/TerminalScheduler.cs b/ReactiveExample/TerminalScheduler.cs index 49f2170594..38631d5250 100644 --- a/ReactiveExample/TerminalScheduler.cs +++ b/ReactiveExample/TerminalScheduler.cs @@ -15,7 +15,7 @@ public override IDisposable Schedule ( IDisposable PostOnMainLoop() { var composite = new CompositeDisposable(2); var cancellation = new CancellationDisposable(); - Application.MainLoop.Invoke (() => { + Application.Invoke (() => { if (!cancellation.Token.IsCancellationRequested) composite.Add(action(this, state)); }); @@ -25,11 +25,11 @@ IDisposable PostOnMainLoop() { IDisposable PostOnMainLoopAsTimeout () { var composite = new CompositeDisposable (2); - var timeout = Application.MainLoop.AddTimeout (dueTime, args => { + var timeout = Application.AddTimeout (dueTime, () => { composite.Add(action (this, state)); return false; }); - composite.Add (Disposable.Create (() => Application.MainLoop.RemoveTimeout (timeout))); + composite.Add (Disposable.Create (() => Application.RemoveTimeout (timeout))); return composite; } diff --git a/Terminal.Gui/Application.cs b/Terminal.Gui/Application.cs index 5019058bf4..0cf61c715b 100644 --- a/Terminal.Gui/Application.cs +++ b/Terminal.Gui/Application.cs @@ -108,19 +108,15 @@ private static List GetSupportedCultures () /// returned) to ensure resources are cleaned up and terminal settings restored. /// /// - /// The function - /// combines and - /// into a single call. An application cam use - /// without explicitly calling . + /// The function + /// combines and + /// into a single call. An application cam use + /// without explicitly calling . /// /// /// The to use. If not specified the default driver for the /// platform will be used (see , , and ). - /// - /// Specifies the to use. - /// Must not be if is not . - /// - public static void Init (ConsoleDriver driver = null, IMainLoopDriver mainLoopDriver = null) => InternalInit (() => Toplevel.Create (), driver, mainLoopDriver); + public static void Init (ConsoleDriver driver = null) => InternalInit (() => Toplevel.Create (), driver); internal static bool _initialized = false; internal static int _mainThreadId = -1; @@ -134,7 +130,7 @@ private static List GetSupportedCultures () // Unit Tests - To initialize the app with a custom Toplevel, using the FakeDriver. calledViaRunT will be false, causing all state to be reset. // // calledViaRunT: If false (default) all state will be reset. If true the state will not be reset. - internal static void InternalInit (Func topLevelFactory, ConsoleDriver driver = null, IMainLoopDriver mainLoopDriver = null, bool calledViaRunT = false) + internal static void InternalInit (Func topLevelFactory, ConsoleDriver driver = null, bool calledViaRunT = false) { if (_initialized && driver == null) { return; @@ -179,23 +175,7 @@ internal static void InternalInit (Func topLevelFactory, ConsoleDriver } } - if (mainLoopDriver == null) { - // TODO: Move this logic into ConsoleDriver - if (Driver is FakeDriver) { - mainLoopDriver = new FakeMainLoop (Driver); - } else if (Driver is NetDriver) { - mainLoopDriver = new NetMainLoop (Driver); - } else if (Driver is WindowsDriver) { - mainLoopDriver = new WindowsMainLoop (Driver); - } else if (Driver is CursesDriver) { - mainLoopDriver = new UnixMainLoop (Driver); - } - if (mainLoopDriver == null) { - throw new InvalidOperationException ("Init could not determine the MainLoopDriver to use."); - } - } - - MainLoop = new MainLoop (mainLoopDriver); + MainLoop = Driver.CreateMainLoop (); try { Driver.Init (OnTerminalResized); @@ -207,7 +187,9 @@ internal static void InternalInit (Func topLevelFactory, ConsoleDriver throw new InvalidOperationException ("Unable to initialize the console. This can happen if the console is already in use by another process or in unit tests.", ex); } - SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext (MainLoop)); + Driver.PrepareToRun (ProcessKeyEvent, ProcessKeyDownEvent, ProcessKeyUpEvent, ProcessMouseEvent); + + SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext ()); Top = topLevelFactory (); Current = Top; @@ -218,10 +200,10 @@ internal static void InternalInit (Func topLevelFactory, ConsoleDriver /// - /// Shutdown an application initialized with . + /// Shutdown an application initialized with . /// /// - /// Shutdown must be called for every call to or + /// Shutdown must be called for every call to or /// to ensure all resources are cleaned up (Disposed) and terminal settings are restored. /// public static void Shutdown () @@ -274,14 +256,14 @@ static void ResetState () #endregion Initialization (Init/Shutdown) - #region Run (Begin, Run, End) + #region Run (Begin, Run, End, Stop) /// /// Notify that a new was created ( was called). The token is created in /// and this event will be fired before that function exits. /// /// - /// If is callers to + /// If is callers to /// must also subscribe to /// and manually dispose of the token when the application is done. /// @@ -291,7 +273,7 @@ static void ResetState () /// Notify that a existent is stopping ( was called). /// /// - /// If is callers to + /// If is callers to /// must also subscribe to /// and manually dispose of the token when the application is done. /// @@ -304,8 +286,7 @@ static void ResetState () /// The to prepare execution for. /// /// This method prepares the provided for running with the focus, - /// it adds this to the list of s, sets up the to process the - /// event, lays out the Subviews, focuses the first element, and draws the + /// it adds this to the list of s, lays out the Subviews, focuses the first element, and draws the /// in the screen. This is usually followed by executing /// the method, and then the method upon termination which will /// undo these changes. @@ -383,7 +364,6 @@ public static RunState Begin (Toplevel Toplevel) MoveCurrent (Current); } - Driver.PrepareToRun (MainLoop, ProcessKeyEvent, ProcessKeyDownEvent, ProcessKeyUpEvent, ProcessMouseEvent); if (Toplevel.LayoutStyle == LayoutStyle.Computed) { Toplevel.SetRelativeLayout (new Rect (0, 0, Driver.Cols, Driver.Rows)); } @@ -415,7 +395,7 @@ public static RunState Begin (Toplevel Toplevel) /// Runs the application by calling /// with a new instance of the specified -derived class. /// - /// Calling first is not needed as this function will initialize the application. + /// Calling first is not needed as this function will initialize the application. /// /// /// must be called when the application is closing (typically after Run> has @@ -428,10 +408,9 @@ public static RunState Begin (Toplevel Toplevel) /// /// The to use. If not specified the default driver for the /// platform will be used (, , or ). - /// Must be if has already been called. + /// Must be if has already been called. /// - /// Specifies the to use. - public static void Run (Func errorHandler = null, ConsoleDriver driver = null, IMainLoopDriver mainLoopDriver = null) where T : Toplevel, new() + public static void Run (Func errorHandler = null, ConsoleDriver driver = null) where T : Toplevel, new() { if (_initialized) { if (Driver != null) { @@ -451,7 +430,7 @@ public static RunState Begin (Toplevel Toplevel) } } else { // Init() has NOT been called. - InternalInit (() => new T (), driver, mainLoopDriver, calledViaRunT: true); + InternalInit (() => new T (), driver, calledViaRunT: true); Run (Top, errorHandler); } } @@ -496,12 +475,12 @@ public static void Run (Toplevel view, Func errorHandler = null try { #endif resume = false; - var runToken = Begin (view); + var runState = Begin (view); // If ExitRunLoopAfterFirstIteration is true then the user must dispose of the runToken // by using NotifyStopRunState event. - RunLoop (runToken); - if (!ExitRunLoopAfterFirstIteration) { - End (runToken); + RunLoop (runState); + if (!EndAfterFirstIteration) { + End (runState); } #if !DEBUG } @@ -517,6 +496,49 @@ public static void Run (Toplevel view, Func errorHandler = null } } + /// + /// Adds a timeout to the application. + /// + /// + /// When time specified passes, the callback will be invoked. + /// If the callback returns true, the timeout will be reset, repeating + /// the invocation. If it returns false, the timeout will stop and be removed. + /// + /// The returned value is a token that can be used to stop the timeout + /// by calling . + /// + public static object AddTimeout (TimeSpan time, Func callback) => MainLoop?.AddTimeout (time, callback); + + /// + /// Removes a previously scheduled timeout + /// + /// + /// The token parameter is the value returned by . + /// + /// Returns trueif the timeout is successfully removed; otherwise, false. + /// This method also returns false if the timeout is not found. + public static bool RemoveTimeout (object token) => MainLoop?.RemoveTimeout (token) ?? false; + + + /// + /// Runs on the thread that is processing events + /// + /// the action to be invoked on the main processing thread. + public static void Invoke (Action action) + { + MainLoop?.AddIdle (() => { + action (); + return false; + }); + } + + // TODO: Determine if this is really needed. The only code that calls WakeUp I can find + // is ProgressBarStyles and it's not clear it needs to. + /// + /// Wakes up the running application that might be waiting on input. + /// + public static void Wakeup () => MainLoop?.Wakeup (); + /// /// Triggers a refresh of the entire display. /// @@ -549,13 +571,13 @@ public static void Refresh () /// The driver for the application /// /// The main loop. - public static MainLoop MainLoop { get; private set; } + internal static MainLoop MainLoop { get; private set; } /// - /// Set to true to cause the RunLoop method to exit after the first iterations. - /// Set to false (the default) to cause the RunLoop to continue running until Application.RequestStop() is called. + /// Set to true to cause to be called after the first iteration. + /// Set to false (the default) to cause the application to continue running until Application.RequestStop () is called. /// - public static bool ExitRunLoopAfterFirstIteration { get; set; } = false; + public static bool EndAfterFirstIteration { get; set; } = false; // // provides the sync context set while executing code in Terminal.Gui, to let @@ -564,19 +586,14 @@ public static void Refresh () class MainLoopSyncContext : SynchronizationContext { readonly MainLoop _mainLoop; - public MainLoopSyncContext (MainLoop mainLoop) - { - this._mainLoop = mainLoop; - } - public override SynchronizationContext CreateCopy () { - return new MainLoopSyncContext (MainLoop); + return new MainLoopSyncContext (); } public override void Post (SendOrPostCallback d, object state) { - _mainLoop.AddIdle (() => { + MainLoop.AddIdle (() => { d (state); return false; }); @@ -589,7 +606,7 @@ public override void Send (SendOrPostCallback d, object state) d (state); } else { var wasExecuted = false; - _mainLoop.Invoke (() => { + Invoke (() => { d (state); wasExecuted = true; }); @@ -600,6 +617,15 @@ public override void Send (SendOrPostCallback d, object state) } } + /// + /// Determines whether there are pending events to be processed. + /// + /// + /// Use this method to probe if events are pending. Typically used to flush the input queue while still + /// running code on the main thread. + /// + public static bool EventsPending () => MainLoop.EventsPending (); + /// /// Building block API: Runs the for the created . /// @@ -615,20 +641,20 @@ public static void RunLoop (RunState state) var firstIteration = true; for (state.Toplevel.Running = true; state.Toplevel.Running;) { - if (ExitRunLoopAfterFirstIteration && !firstIteration) { + if (EndAfterFirstIteration && !firstIteration) { return; } - RunMainLoopIteration (ref state, ref firstIteration); + RunIteration (ref state, ref firstIteration); } } /// - /// Run one iteration of the . + /// Run one application iteration. /// /// The state returned by . /// Set to if this is the first run loop iteration. Upon return, /// it will be set to if at least one iteration happened. - public static void RunMainLoopIteration (ref RunState state, ref bool firstIteration) + public static void RunIteration (ref RunState state, ref bool firstIteration) { if (MainLoop.EventsPending ()) { // Notify Toplevel it's ready @@ -774,7 +800,7 @@ public static void RequestStop (Toplevel top = null) static void OnNotifyStopRunState (Toplevel top) { - if (ExitRunLoopAfterFirstIteration) { + if (EndAfterFirstIteration) { NotifyStopRunState?.Invoke (top, new ToplevelEventArgs (top)); } } @@ -785,8 +811,9 @@ static void OnNotifyStopRunState (Toplevel top) /// The returned by the method. public static void End (RunState runState) { - if (runState == null) + if (runState == null) { throw new ArgumentNullException (nameof (runState)); + } if (OverlappedTop != null) { OverlappedTop.OnChildUnloaded (runState.Toplevel); diff --git a/Terminal.Gui/Configuration/ConfigurationManager.cs b/Terminal.Gui/Configuration/ConfigurationManager.cs index 228b2efb25..5e05ecfb42 100644 --- a/Terminal.Gui/Configuration/ConfigurationManager.cs +++ b/Terminal.Gui/Configuration/ConfigurationManager.cs @@ -251,7 +251,7 @@ public static void OnUpdated () /// /// Resets the state of . Should be called whenever a new app session - /// (e.g. in starts. Called by + /// (e.g. in starts. Called by /// if the reset parameter is . /// /// diff --git a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs index 3f4dcb7e42..634a1aaeb3 100644 --- a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs @@ -32,15 +32,35 @@ public abstract class ConsoleDriver { /// internal static bool RunningUnitTests { get; set; } + #region Setup & Teardown + + /// + /// Returns an instance of using the for the driver. + /// + /// + internal abstract MainLoop CreateMainLoop (); + + /// + /// Initializes the driver + /// + /// Method to invoke when the terminal is resized. + internal abstract void Init (Action terminalResized); + /// /// Prepare the driver and set the key and mouse events handlers. /// - /// The main loop. /// The handler for ProcessKey /// The handler for key down events /// The handler for key up events /// The handler for mouse events - public abstract void PrepareToRun (MainLoop mainLoop, Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler); + internal abstract void PrepareToRun (Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler); + + /// + /// Ends the execution of the console driver. + /// + internal abstract void End (); + + #endregion /// /// The handler fired when the terminal is resized. @@ -90,12 +110,6 @@ public abstract class ConsoleDriver { ///// public Cell [,] Contents { get; internal set; } - /// - /// Initializes the driver - /// - /// Method to invoke when the terminal is resized. - public abstract void Init (Action terminalResized); - /// /// Gets the column last set by . and /// are used by and to determine where to add content. @@ -513,11 +527,6 @@ public void FillRect (Rect rect, Rune rune = default) /// public void FillRect (Rect rect, char c) => FillRect (rect, new Rune (c)); - /// - /// Ends the execution of the console driver. - /// - public abstract void End (); - /// /// Returns the name of the driver and relevant library version information. /// diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs index e9aa6c2b77..50b1f4a798 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs @@ -22,7 +22,12 @@ internal class CursesDriver : ConsoleDriver { CursorVisibility? _currentCursorVisibility = null; public override string GetVersionInfo () => $"{Curses.curses_version ()}"; - + UnixMainLoop _mainLoopDriver = null; + internal override MainLoop CreateMainLoop () + { + _mainLoopDriver = new UnixMainLoop (this); + return new MainLoop (_mainLoopDriver); + } public override bool SupportsTrueColor => false; public override void Move (int col, int row) @@ -208,13 +213,13 @@ public override void UpdateCursor () } } - public override void End () + internal override void End () { StopReportingMouseMoves (); SetCursorVisibility (CursorVisibility.Default); - if (_mainLoop != null) { - _mainLoop.RemoveWatch (_processInputToken); + if (_mainLoopDriver != null) { + _mainLoopDriver.RemoveWatch (_processInputToken); } if (RunningUnitTests) { @@ -605,29 +610,27 @@ void ProcessContinuousButtonPressed (MouseFlags mouseFlag, Point pos) Action _keyUpHandler; Action _mouseHandler; - UnixMainLoop _mainLoop; object _processInputToken; - public override void PrepareToRun (MainLoop mainLoop, Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler) + internal override void PrepareToRun (Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler) { if (!RunningUnitTests) { - // Note: Curses doesn't support keydown/up events and thus any passed keyDown/UpHandlers will never be called Curses.timeout (0); } - this._keyHandler = keyHandler; - this._keyDownHandler = keyDownHandler; - this._keyUpHandler = keyUpHandler; - this._mouseHandler = mouseHandler; - _mainLoop = mainLoop.MainLoopDriver as UnixMainLoop; + _keyHandler = keyHandler; + // Note: Curses doesn't support keydown/up events and thus any passed keyDown/UpHandlers will never be called + _keyDownHandler = keyDownHandler; + _keyUpHandler = keyUpHandler; + _mouseHandler = mouseHandler; - _processInputToken = _mainLoop?.AddWatch (0, UnixMainLoop.Condition.PollIn, x => { + _processInputToken = _mainLoopDriver?.AddWatch (0, UnixMainLoop.Condition.PollIn, x => { ProcessInput (); return true; }); } - public override void Init (Action terminalResized) + internal override void Init (Action terminalResized) { if (!RunningUnitTests) { diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs index 54ed4e5b97..8904b2a731 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs @@ -119,7 +119,7 @@ void IMainLoopDriver.Setup (MainLoop mainLoop) /// /// The token parameter is the value returned from AddWatch /// - public void RemoveWatch (object token) + internal void RemoveWatch (object token) { if (!ConsoleDriver.RunningUnitTests) { if (token is not Watch watch) { @@ -140,7 +140,7 @@ public void RemoveWatch (object token) /// The return value is a token that represents this watch, you can /// use this token to remove the watch by calling RemoveWatch. /// - public object AddWatch (int fileDescriptor, Condition condition, Func callback) + internal object AddWatch (int fileDescriptor, Condition condition, Func callback) { if (callback == null) { throw new ArgumentNullException (nameof (callback)); @@ -188,6 +188,7 @@ void IMainLoopDriver.Iteration () if (_winChanged) { _winChanged = false; _cursesDriver.ProcessInput (); + //WinChanged?.Invoke (); } if (_pollMap == null) return; foreach (var p in _pollMap) { diff --git a/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs b/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs index 5626d002b5..68c770d126 100644 --- a/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs +++ b/Terminal.Gui/ConsoleDrivers/EscSeqUtils/EscSeqUtils.cs @@ -1060,7 +1060,7 @@ private static async Task ProcessContinuousButtonPressedAsync (MouseFlags mouseF if (view == null) break; if (isButtonPressed && lastMouseButtonPressed != null && (mouseFlag & MouseFlags.ReportMousePosition) == 0) { - Application.MainLoop.Invoke (() => continuousButtonPressedHandler (mouseFlag, point)); + Application.Invoke (() => continuousButtonPressedHandler (mouseFlag, point)); } } } diff --git a/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs b/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs index b08958bd69..53a0669652 100644 --- a/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs @@ -57,13 +57,20 @@ public FakeDriver () } } - public override void End () + internal override void End () { FakeConsole.ResetColor (); FakeConsole.Clear (); } - public override void Init (Action terminalResized) + FakeMainLoop _mainLoopDriver = null; + internal override MainLoop CreateMainLoop () + { + _mainLoopDriver = new FakeMainLoop (this); + return new MainLoop (_mainLoopDriver); + } + + internal override void Init (Action terminalResized) { FakeConsole.MockKeyPresses.Clear (); @@ -346,14 +353,15 @@ private Key MapKeyModifiers (ConsoleKeyInfo keyInfo, Key key) Action _keyUpHandler; private CursorVisibility _savedCursorVisibility; - public override void PrepareToRun (MainLoop mainLoop, Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler) + internal override void PrepareToRun (Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler) { - _keyDownHandler = keyDownHandler; _keyHandler = keyHandler; + _keyDownHandler = keyDownHandler; _keyUpHandler = keyUpHandler; + //_mouseHandler = mouseHandler; // Note: Net doesn't support keydown/up events and thus any passed keyDown/UpHandlers will never be called - (mainLoop.MainLoopDriver as FakeMainLoop).KeyPressed = (consoleKey) => ProcessInput (consoleKey); + _mainLoopDriver.KeyPressed = (consoleKey) => ProcessInput (consoleKey); } void ProcessInput (ConsoleKeyInfo consoleKey) diff --git a/Terminal.Gui/ConsoleDrivers/NetDriver.cs b/Terminal.Gui/ConsoleDrivers/NetDriver.cs index 2a9019b272..26158a6fea 100644 --- a/Terminal.Gui/ConsoleDrivers/NetDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/NetDriver.cs @@ -628,12 +628,19 @@ internal class NetDriver : ConsoleDriver { const int COLOR_BRIGHT_CYAN = 96; const int COLOR_BRIGHT_WHITE = 97; + NetMainLoop _mainLoopDriver = null; + internal override MainLoop CreateMainLoop () + { + _mainLoopDriver = new NetMainLoop (this); + return new MainLoop (_mainLoopDriver); + } + public override bool SupportsTrueColor => Environment.OSVersion.Platform == PlatformID.Unix || (IsWinPlatform && Environment.OSVersion.Version.Build >= 14931); public NetWinVTConsole NetWinConsole { get; private set; } public bool IsWinPlatform { get; private set; } - public override void End () + internal override void End () { if (IsWinPlatform) { NetWinConsole?.Cleanup (); @@ -653,7 +660,7 @@ public override void End () } } - public override void Init (Action terminalResized) + internal override void Init (Action terminalResized) { var p = Environment.OSVersion.Platform; if (p == PlatformID.Win32NT || p == PlatformID.Win32S || p == PlatformID.Win32Windows) { @@ -1110,19 +1117,16 @@ Key MapKeyModifiers (ConsoleKeyInfo keyInfo, Key key) Action _keyDownHandler; Action _keyUpHandler; Action _mouseHandler; - NetMainLoop _mainLoop; - public override void PrepareToRun (MainLoop mainLoop, Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler) + internal override void PrepareToRun (Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler) { _keyHandler = keyHandler; _keyDownHandler = keyDownHandler; _keyUpHandler = keyUpHandler; _mouseHandler = mouseHandler; - _mainLoop = mainLoop.MainLoopDriver as NetMainLoop; - // Note: .Net API doesn't support keydown/up events and thus any passed keyDown/UpHandlers will be simulated to be called. - _mainLoop.ProcessInput = ProcessInput; + _mainLoopDriver.ProcessInput = ProcessInput; } volatile bool _winSizeChanging; diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index 077e155517..5eec387bef 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -793,6 +793,13 @@ internal class WindowsDriver : ConsoleDriver { readonly bool _isWindowsTerminal = false; readonly string _parentProcessName = "WindowsTerminal"; + WindowsMainLoop _mainLoopDriver = null; + internal override MainLoop CreateMainLoop () + { + _mainLoopDriver = new WindowsMainLoop (this); + return new MainLoop (_mainLoopDriver); + } + public WindowsDriver () { if (Environment.OSVersion.Platform == PlatformID.Win32NT) { @@ -851,18 +858,15 @@ private static string GetParentProcessName () #pragma warning restore CA1416 // Validate platform compatibility } - WindowsMainLoop _mainLoop; - - public override void PrepareToRun (MainLoop mainLoop, Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler) + internal override void PrepareToRun (Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler) { _keyHandler = keyHandler; _keyDownHandler = keyDownHandler; _keyUpHandler = keyUpHandler; _mouseHandler = mouseHandler; - _mainLoop = mainLoop.MainLoopDriver as WindowsMainLoop; #if HACK_CHECK_WINCHANGED - _mainLoop.WinChanged = ChangeWin; + _mainLoopDriver.WinChanged = ChangeWin; #endif } @@ -1257,7 +1261,7 @@ async Task ProcessContinuousButtonPressedAsync (MouseFlags mouseFlag) break; } if (_isButtonPressed && (mouseFlag & MouseFlags.ReportMousePosition) == 0) { - Application.MainLoop.Invoke (() => _mouseHandler (me)); + Application.Invoke (() => _mouseHandler (me)); } } } @@ -1504,7 +1508,7 @@ public override bool IsRuneSupported (Rune rune) return base.IsRuneSupported (rune) && rune.IsBmp; } - public override void Init (Action terminalResized) + internal override void Init (Action terminalResized) { TerminalResized = terminalResized; @@ -1750,14 +1754,14 @@ public override void SendKeys (char keyChar, ConsoleKey key, bool shift, bool al } } - public override void End () + internal override void End () { - if (_mainLoop != null) { + if (_mainLoopDriver != null) { #if HACK_CHECK_WINCHANGED //_mainLoop.WinChanged -= ChangeWin; #endif } - _mainLoop = null; + _mainLoopDriver = null; WinConsole?.Cleanup (); WinConsole = null; diff --git a/Terminal.Gui/MainLoop.cs b/Terminal.Gui/MainLoop.cs index 95671f5a42..78275887fc 100644 --- a/Terminal.Gui/MainLoop.cs +++ b/Terminal.Gui/MainLoop.cs @@ -12,7 +12,7 @@ namespace Terminal.Gui { /// /// Public interface to create a platform specific driver. /// - public interface IMainLoopDriver { + internal interface IMainLoopDriver { /// /// Initializes the , gets the calling main loop for the initialization. /// @@ -44,6 +44,7 @@ public interface IMainLoopDriver { void TearDown (); } + /// /// The MainLoop monitors timers and idle handlers. /// @@ -51,7 +52,7 @@ public interface IMainLoopDriver { /// Monitoring of file descriptors is only available on Unix, there /// does not seem to be a way of supporting this on Windows. /// - public class MainLoop : IDisposable { + internal class MainLoop : IDisposable { internal SortedList _timeouts = new SortedList (); readonly object _timeoutsLockToken = new object (); @@ -67,12 +68,12 @@ public class MainLoop : IDisposable { /// A shorter limit time can be added at the end, but it will be called before an /// earlier addition that has a longer limit time. /// - public SortedList Timeouts => _timeouts; + internal SortedList Timeouts => _timeouts; /// /// Gets a copy of the list of all idle handlers. /// - public ReadOnlyCollection> IdleHandlers { + internal ReadOnlyCollection> IdleHandlers { get { lock (_idleHandlersLock) { return new List> (_idleHandlers).AsReadOnly (); @@ -84,13 +85,13 @@ public ReadOnlyCollection> IdleHandlers { /// The current in use. /// /// The main loop driver. - public IMainLoopDriver MainLoopDriver { get; private set; } + internal IMainLoopDriver MainLoopDriver { get; private set; } /// /// Invoked when a new timeout is added. To be used in the case - /// when is . + /// when is . /// - public event EventHandler TimeoutAdded; + internal event EventHandler TimeoutAdded; /// /// Creates a new MainLoop. @@ -100,24 +101,12 @@ public ReadOnlyCollection> IdleHandlers { /// /// The instance /// (one of the implementations FakeMainLoop, UnixMainLoop, NetMainLoop or WindowsMainLoop). - public MainLoop (IMainLoopDriver driver) + internal MainLoop (IMainLoopDriver driver) { MainLoopDriver = driver; driver.Setup (this); } - /// - /// Runs on the thread that is processing events - /// - /// the action to be invoked on the main processing thread. - public void Invoke (Action action) - { - AddIdle (() => { - action (); - return false; - }); - } - /// /// Adds specified idle handler function to processing. /// The handler function will be called once per iteration of the main loop after other events have been handled. @@ -131,7 +120,7 @@ public void Invoke (Action action) /// /// /// Token that can be used to remove the idle handler with . - public Func AddIdle (Func idleHandler) + internal Func AddIdle (Func idleHandler) { lock (_idleHandlersLock) { _idleHandlers.Add (idleHandler); @@ -147,7 +136,7 @@ public Func AddIdle (Func idleHandler) /// A token returned by /// Returns trueif the idle handler is successfully removed; otherwise, false. /// This method also returns false if the idle handler is not found. - public bool RemoveIdle (Func token) + internal bool RemoveIdle (Func token) { lock (_idleHandlersLock) { return _idleHandlers.Remove (token); @@ -174,7 +163,7 @@ void AddTimeout (TimeSpan time, Timeout timeout) /// The returned value is a token that can be used to stop the timeout /// by calling . /// - public object AddTimeout (TimeSpan time, Func callback) + internal object AddTimeout (TimeSpan time, Func callback) { if (callback == null) { throw new ArgumentNullException (nameof (callback)); @@ -195,7 +184,7 @@ public object AddTimeout (TimeSpan time, Func callback) /// /// Returns trueif the timeout is successfully removed; otherwise, false. /// This method also returns false if the timeout is not found. - public bool RemoveTimeout (object token) + internal bool RemoveTimeout (object token) { lock (_timeoutsLockToken) { var idx = _timeouts.IndexOfValue (token as Timeout); @@ -223,7 +212,7 @@ void RunTimers () foreach ((var k, var timeout) in copy) { if (k < now) { - if (timeout.Callback (this)) { + if (timeout.Callback ()) { AddTimeout (timeout.Span, timeout); } } else { @@ -240,7 +229,7 @@ void RunTimers () /// Returns the number of milliseconds remaining in the current timer (if any). Will be -1 if /// there are no active timers. /// if there is a timer or idle handler active. - public bool CheckTimersAndIdleHandlers (out int waitTimeout) + internal bool CheckTimersAndIdleHandlers (out int waitTimeout) { var now = DateTime.UtcNow.Ticks; @@ -275,7 +264,7 @@ public bool CheckTimersAndIdleHandlers (out int waitTimeout) /// /// /// - private long NudgeToUniqueKey (long k) + long NudgeToUniqueKey (long k) { lock (_timeoutsLockToken) { while (_timeouts.ContainsKey (k)) { @@ -316,7 +305,7 @@ void RunIdle () /// Typically used if you need to flush the input queue while still /// running some of your own code in your main thread. /// - public bool EventsPending () + internal bool EventsPending () { return MainLoopDriver.EventsPending (); } @@ -331,14 +320,14 @@ public bool EventsPending () /// while (main.EventsPending ()) RunIteration (); /// /// - public void RunIteration () + internal void RunIteration () { lock (_timeouts) { if (_timeouts.Count > 0) { RunTimers (); } } - + MainLoopDriver.Iteration (); var runIdle = false; @@ -352,9 +341,9 @@ public void RunIteration () } /// - /// Runs the . + /// Runs the . Used only for unit tests. /// - public void Run () + internal void Run () { var prev = Running; Running = true; @@ -366,14 +355,19 @@ public void Run () } /// - /// Stops the main loop driver and calls . + /// Wakes up the that might be waiting on input. + /// + internal void Wakeup () => MainLoopDriver?.Wakeup (); + + /// + /// Stops the main loop driver and calls . Used only for unit tests. /// - public void Stop () + internal void Stop () { Running = false; - MainLoopDriver.Wakeup (); + Wakeup (); } - + /// public void Dispose () { diff --git a/Terminal.Gui/Timeout.cs b/Terminal.Gui/Timeout.cs index 4273e034ae..cd26ad9735 100644 --- a/Terminal.Gui/Timeout.cs +++ b/Terminal.Gui/Timeout.cs @@ -19,5 +19,5 @@ public sealed class Timeout { /// /// The function that will be invoked. /// - public Func Callback; + public Func Callback; } diff --git a/Terminal.Gui/TimeoutEventArgs.cs b/Terminal.Gui/TimeoutEventArgs.cs index 876dde6782..80f9d83575 100644 --- a/Terminal.Gui/TimeoutEventArgs.cs +++ b/Terminal.Gui/TimeoutEventArgs.cs @@ -5,7 +5,7 @@ namespace Terminal.Gui { /// /// for timeout events (e.g. ) /// - public class TimeoutEventArgs : EventArgs { + internal class TimeoutEventArgs : EventArgs { /// /// Gets the timeout callback handler /// diff --git a/Terminal.Gui/Views/FileDialog.cs b/Terminal.Gui/Views/FileDialog.cs index 11832d4ec8..c727b71a2d 100644 --- a/Terminal.Gui/Views/FileDialog.cs +++ b/Terminal.Gui/Views/FileDialog.cs @@ -1438,7 +1438,7 @@ private void UpdateChildren () UpdateChildrenToFound (); } - Application.MainLoop.Invoke (() => { + Application.Invoke (() => { Parent.spinnerView.Visible = false; }); } @@ -1450,7 +1450,7 @@ private void UpdateChildrenToFound () Children = found.ToArray (); } - Application.MainLoop.Invoke (() => { + Application.Invoke (() => { Parent.tbPath.Autocomplete.GenerateSuggestions ( new AutocompleteFilepathContext (Parent.tbPath.Text, Parent.tbPath.CursorPosition, this) ); diff --git a/Terminal.Gui/Views/Slider.cs b/Terminal.Gui/Views/Slider.cs index d6d67fc129..a490516c5f 100644 --- a/Terminal.Gui/Views/Slider.cs +++ b/Terminal.Gui/Views/Slider.cs @@ -337,6 +337,7 @@ public virtual void OnOptionsChanged () /// /// /// if the focus change was cancelled. + /// public virtual bool OnOptionFocused (int newFocusedOption, SliderEventArgs args) { if (newFocusedOption > _options.Count - 1 || newFocusedOption < 0) { diff --git a/Terminal.Gui/Views/SpinnerView/SpinnerView.cs b/Terminal.Gui/Views/SpinnerView/SpinnerView.cs index cf00352ade..ef16d4eb9a 100644 --- a/Terminal.Gui/Views/SpinnerView/SpinnerView.cs +++ b/Terminal.Gui/Views/SpinnerView/SpinnerView.cs @@ -153,7 +153,7 @@ private bool GetIsAsciiOnly () /// ignored based on . /// /// Ensure this method is called on the main UI - /// thread e.g. via + /// thread e.g. via /// public void AdvanceAnimation() { @@ -221,9 +221,9 @@ private void AddAutoSpinTimeout () return; } - _timeout = Application.MainLoop.AddTimeout ( - TimeSpan.FromMilliseconds (SpinDelay), (m) => { - Application.MainLoop.Invoke (this.AdvanceAnimation); + _timeout = Application.AddTimeout ( + TimeSpan.FromMilliseconds (SpinDelay), () => { + Application.Invoke (this.AdvanceAnimation); return true; }); } @@ -232,7 +232,7 @@ private void AddAutoSpinTimeout () private void RemoveAutoSpinTimeout () { if (_timeout != null) { - Application.MainLoop.RemoveTimeout (_timeout); + Application.RemoveTimeout (_timeout); _timeout = null; } } diff --git a/Terminal.Gui/Views/Toplevel.cs b/Terminal.Gui/Views/Toplevel.cs index c8b35f80b3..fa2d56096b 100644 --- a/Terminal.Gui/Views/Toplevel.cs +++ b/Terminal.Gui/Views/Toplevel.cs @@ -15,7 +15,7 @@ namespace Terminal.Gui { /// been called (which sets the property to false). /// /// - /// A Toplevel is created when an application initializes Terminal.Gui by calling . + /// A Toplevel is created when an application initializes Terminal.Gui by calling . /// The application Toplevel can be accessed via . Additional Toplevels can be created /// and run (e.g. s. To run a Toplevel, create the and /// call . diff --git a/UICatalog/KeyBindingsDialog.cs b/UICatalog/KeyBindingsDialog.cs index f133f1b57b..efce13b427 100644 --- a/UICatalog/KeyBindingsDialog.cs +++ b/UICatalog/KeyBindingsDialog.cs @@ -35,7 +35,7 @@ public ViewTracker (View top) RecordView (top); // Refresh known windows - Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), (m) => { + Application.AddTimeout (TimeSpan.FromMilliseconds (100), () => { lock (lockKnownViews) { RecordView (Application.Top); diff --git a/UICatalog/Scenarios/Animation.cs b/UICatalog/Scenarios/Animation.cs index 7bb15d2e01..0758dd4610 100644 --- a/UICatalog/Scenarios/Animation.cs +++ b/UICatalog/Scenarios/Animation.cs @@ -53,7 +53,7 @@ public override void Setup () Task.Run (() => { while (!isDisposed) { // When updating from a Thread/Task always use Invoke - Application.MainLoop.Invoke (() => { + Application.Invoke (() => { imageView.NextFrame (); imageView.SetNeedsDisplay (); }); diff --git a/UICatalog/Scenarios/CharacterMap.cs b/UICatalog/Scenarios/CharacterMap.cs index 7c220312d2..6f2370209e 100644 --- a/UICatalog/Scenarios/CharacterMap.cs +++ b/UICatalog/Scenarios/CharacterMap.cs @@ -604,7 +604,7 @@ void ShowDetails () decResponse = await client.GetCodepointDec ((int)SelectedCodePoint); } catch (HttpRequestException e) { (s as Dialog).Text = e.Message; - Application.MainLoop.Invoke (() => { + Application.Invoke (() => { spinner.Visible = false; errorLabel.Text = e.Message; errorLabel.ColorScheme = Colors.ColorSchemes ["Error"]; diff --git a/UICatalog/Scenarios/GraphViewExample.cs b/UICatalog/Scenarios/GraphViewExample.cs index be945b7dbe..9f79be4c29 100644 --- a/UICatalog/Scenarios/GraphViewExample.cs +++ b/UICatalog/Scenarios/GraphViewExample.cs @@ -566,7 +566,7 @@ private void SetupDisco () var series = new DiscoBarSeries (); var bars = new List (); - Func genSample = (l) => { + Func genSample = () => { bars.Clear (); // generate an imaginary sample @@ -582,7 +582,7 @@ private void SetupDisco () return graphView.Series.Contains (series); }; - Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (250), genSample); + Application.AddTimeout (TimeSpan.FromMilliseconds (250), genSample); series.Bars = bars; diff --git a/UICatalog/Scenarios/ProcessTable.cs b/UICatalog/Scenarios/ProcessTable.cs index d07f16bcbd..3826038898 100644 --- a/UICatalog/Scenarios/ProcessTable.cs +++ b/UICatalog/Scenarios/ProcessTable.cs @@ -31,8 +31,8 @@ public override void Setup () CreateProcessTable (); // Then every second - Application.MainLoop.AddTimeout (TimeSpan.FromSeconds (1), - (s) => { + Application.AddTimeout (TimeSpan.FromSeconds (1), + () => { CreateProcessTable (); return true; }); diff --git a/UICatalog/Scenarios/Progress.cs b/UICatalog/Scenarios/Progress.cs index 2755e625d4..1b2faf8a72 100644 --- a/UICatalog/Scenarios/Progress.cs +++ b/UICatalog/Scenarios/Progress.cs @@ -123,7 +123,7 @@ internal void Start () { Started = true; StartBtnClick?.Invoke (); - Application.MainLoop.Invoke(()=>{ + Application.Invoke(()=>{ Spinner.Visible = true; ActivityProgressBar.Width = Dim.Fill () - Spinner.Width; this.LayoutSubviews(); @@ -135,7 +135,7 @@ internal void Stop () Started = false; StopBtnClick?.Invoke (); - Application.MainLoop.Invoke(()=>{ + Application.Invoke(()=>{ Spinner.Visible = false; ActivityProgressBar.Width = Dim.Fill () - Spinner.Width; this.LayoutSubviews(); @@ -182,7 +182,7 @@ public override void Setup () _systemTimer = new Timer ((o) => { // Note the check for Mainloop being valid. System.Timers can run after they are Disposed. // This code must be defensive for that. - Application.MainLoop?.Invoke (() => systemTimerDemo.Pulse ()); + Application.Invoke (() => systemTimerDemo.Pulse ()); }, null, 0, _systemTimerTick); }; @@ -209,7 +209,7 @@ public override void Setup () }; Win.Add (systemTimerDemo); - // Demo #2 - Use Application.MainLoop.AddTimeout (no threads) + // Demo #2 - Use Application.AddTimeout (no threads) var mainLoopTimeoutDemo = new ProgressDemo ("Application.AddTimer (no threads)") { X = 0, Y = Pos.Bottom (systemTimerDemo), @@ -221,7 +221,7 @@ public override void Setup () mainLoopTimeoutDemo.ActivityProgressBar.Fraction = 0F; mainLoopTimeoutDemo.PulseProgressBar.Fraction = 0F; - _mainLoopTimeout = Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (_mainLooopTimeoutTick), (loop) => { + _mainLoopTimeout = Application.AddTimeout (TimeSpan.FromMilliseconds (_mainLooopTimeoutTick), () => { mainLoopTimeoutDemo.Pulse (); return true; @@ -229,7 +229,7 @@ public override void Setup () }; mainLoopTimeoutDemo.StopBtnClick = () => { if (_mainLoopTimeout != null) { - Application.MainLoop.RemoveTimeout (_mainLoopTimeout); + Application.RemoveTimeout (_mainLoopTimeout); _mainLoopTimeout = null; } diff --git a/UICatalog/Scenarios/ProgressBarStyles.cs b/UICatalog/Scenarios/ProgressBarStyles.cs index 022d0adba5..a4f0af3baa 100644 --- a/UICatalog/Scenarios/ProgressBarStyles.cs +++ b/UICatalog/Scenarios/ProgressBarStyles.cs @@ -79,7 +79,7 @@ public override void Setup () _fractionTimer = null; button.Enabled = true; } - Application.MainLoop.MainLoopDriver.Wakeup (); + Application.Wakeup (); }, null, 0, _timerTick); } }; @@ -128,7 +128,7 @@ public override void Setup () marqueesBlocksPB.Text = marqueesContinuousPB.Text = DateTime.Now.TimeOfDay.ToString (); marqueesBlocksPB.Pulse (); marqueesContinuousPB.Pulse (); - Application.MainLoop.MainLoopDriver.Wakeup (); + Application.Wakeup (); }, null, 0, 300); Application.Top.Unloaded += Top_Unloaded; diff --git a/UICatalog/Scenarios/Scrolling.cs b/UICatalog/Scenarios/Scrolling.cs index a685116f69..48b2d75fb5 100644 --- a/UICatalog/Scenarios/Scrolling.cs +++ b/UICatalog/Scenarios/Scrolling.cs @@ -303,12 +303,12 @@ void Top_Loaded (object sender, EventArgs args) Win.Add (progress); bool pulsing = true; - bool timer (MainLoop caller) + bool timer () { progress.Pulse (); return pulsing; } - Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (300), timer); + Application.AddTimeout (TimeSpan.FromMilliseconds (300), timer); void Top_Unloaded (object sender, EventArgs args) { diff --git a/UICatalog/Scenarios/Snake.cs b/UICatalog/Scenarios/Snake.cs index 25978ea574..327480ba8c 100644 --- a/UICatalog/Scenarios/Snake.cs +++ b/UICatalog/Scenarios/Snake.cs @@ -38,7 +38,7 @@ public override void Setup () if (state.AdvanceState ()) { // When updating from a Thread/Task always use Invoke - Application.MainLoop?.Invoke (() => { + Application.Invoke (() => { snakeView.SetNeedsDisplay (); }); } diff --git a/UICatalog/Scenarios/Threading.cs b/UICatalog/Scenarios/Threading.cs index 6bf0049646..4a064ae717 100644 --- a/UICatalog/Scenarios/Threading.cs +++ b/UICatalog/Scenarios/Threading.cs @@ -45,7 +45,7 @@ public override void Setup () }; _btnActionCancel = new Button (1, 1, "Cancelable Load Items"); - _btnActionCancel.Clicked += (s, e) => Application.MainLoop.Invoke (CallLoadItemsAsync); + _btnActionCancel.Clicked += (s, e) => Application.Invoke (CallLoadItemsAsync); Win.Add (new Label ("Data Items:") { X = Pos.X (_btnActionCancel), diff --git a/UICatalog/Scenarios/TreeViewFileSystem.cs b/UICatalog/Scenarios/TreeViewFileSystem.cs index 0f5cc497f8..87906d243d 100644 --- a/UICatalog/Scenarios/TreeViewFileSystem.cs +++ b/UICatalog/Scenarios/TreeViewFileSystem.cs @@ -206,7 +206,7 @@ private void ShowContextMenu (Point screenPoint, IFileSystemInfo forObject) menu.MenuItems = new MenuBarItem (new [] { new MenuItem ("Properties", null, () => ShowPropertiesOf (forObject)) }); - Application.MainLoop.Invoke (menu.Show); + Application.Invoke (menu.Show); } class DetailsFrame : FrameView { diff --git a/UICatalog/Scenarios/VkeyPacketSimulator.cs b/UICatalog/Scenarios/VkeyPacketSimulator.cs index af32bd1cbb..1153887ba5 100644 --- a/UICatalog/Scenarios/VkeyPacketSimulator.cs +++ b/UICatalog/Scenarios/VkeyPacketSimulator.cs @@ -102,7 +102,7 @@ public override void Setup () var ev = ShortcutHelper.GetModifiersKey (e.KeyEvent); //System.Diagnostics.Debug.WriteLine ($"Output - KeyPress: {ev}"); if (!tvOutput.ProcessKey (e.KeyEvent)) { - Application.MainLoop.Invoke (() => { + Application.Invoke (() => { MessageBox.Query ("Keys", $"'{ShortcutHelper.GetShortcutTag (ev)}' pressed!", "Ok"); }); } @@ -186,7 +186,7 @@ public override void Setup () } //} } catch (Exception) { - Application.MainLoop.Invoke (() => { + Application.Invoke (() => { MessageBox.ErrorQuery ("Error", "Couldn't send the keystrokes!", "Ok"); Application.RequestStop (); }); @@ -196,7 +196,7 @@ public override void Setup () _keyboardStrokes.RemoveAt (0); if (_keyboardStrokes.Count == 0) { _outputStarted = false; - Application.MainLoop.Invoke (() => { + Application.Invoke (() => { tvOutput.ReadOnly = true; tvInput.SetFocus (); }); diff --git a/UnitTests/Application/ApplicationTests.cs b/UnitTests/Application/ApplicationTests.cs index a9c8d53557..b3a2df2885 100644 --- a/UnitTests/Application/ApplicationTests.cs +++ b/UnitTests/Application/ApplicationTests.cs @@ -286,7 +286,7 @@ public void Run_T_After_InitNullDriver_with_TestTopLevel_Throws () { Application._forceFakeConsole = true; - Application.Init (null, null); + Application.Init (null); Assert.Equal (typeof (FakeDriver), Application.Driver.GetType ()); Application.Iteration = () => { @@ -859,6 +859,24 @@ public void EnsuresTopOnFront_CanFocus_False_By_Keyboard_And_Mouse () #endregion + // Invoke Tests + // TODO: Test with threading scenarios + [Fact] + public void Invoke_Adds_Idle () + { + Application.Init (new FakeDriver ()); + var top = new Toplevel (); + var rs = Application.Begin (top); + bool firstIteration = false; + + var actionCalled = 0; + Application.Invoke (() => { actionCalled++; }); + Application.RunIteration (ref rs, ref firstIteration); + Assert.Equal (1, actionCalled); + Application.Shutdown (); + } + + #region mousegrabtests [Fact, AutoInitShutdown] public void MouseGrabView_WithNullMouseEventView () diff --git a/UnitTests/Application/MainLoopTests.cs b/UnitTests/Application/MainLoopTests.cs index ca63e3da14..9bc4236a9c 100644 --- a/UnitTests/Application/MainLoopTests.cs +++ b/UnitTests/Application/MainLoopTests.cs @@ -246,7 +246,7 @@ public void AddTimer_Adds_Removes_NoFaults () var ms = 100; var callbackCount = 0; - Func callback = (loop) => { + Func callback = () => { callbackCount++; return true; }; @@ -270,7 +270,7 @@ public void AddTimer_EventFired () var originTicks = DateTime.UtcNow.Ticks; var callbackCount = 0; - Func callback = (loop) => { + Func callback = () => { callbackCount++; return true; }; @@ -296,7 +296,7 @@ public void AddTimer_Run_Called () var ms = 100; var callbackCount = 0; - Func callback = (loop) => { + Func callback = () => { callbackCount++; ml.Stop (); return true; @@ -317,7 +317,7 @@ public async Task AddTimer_Duplicate_Keys_Not_Allowed () object token1 = null, token2 = null; var callbackCount = 0; - Func callback = (loop) => { + Func callback = () => { callbackCount++; if (callbackCount == 2) ml.Stop (); return true; @@ -347,7 +347,7 @@ public void AddTimer_In_Parallel_Wont_Throw () object token1 = null, token2 = null; var callbackCount = 0; - Func callback = (loop) => { + Func callback = () => { callbackCount++; if (callbackCount == 2) ml.Stop (); return true; @@ -381,7 +381,7 @@ public void AddTimer_Run_CalledAtApproximatelyRightTime () var watch = new System.Diagnostics.Stopwatch (); var callbackCount = 0; - Func callback = (loop) => { + Func callback = () => { watch.Stop (); callbackCount++; ml.Stop (); @@ -407,7 +407,7 @@ public void AddTimer_Run_CalledTwiceApproximatelyRightTime () var watch = new System.Diagnostics.Stopwatch (); var callbackCount = 0; - Func callback = (loop) => { + Func callback = () => { callbackCount++; if (callbackCount == 2) { watch.Stop (); @@ -443,7 +443,7 @@ public void AddTimer_Remove_NotCalled () ml.AddIdle (fnStop); var callbackCount = 0; - Func callback = (loop) => { + Func callback = () => { callbackCount++; return true; }; @@ -471,7 +471,7 @@ public void AddTimer_ReturnFalse_StopsBeingCalled () ml.AddIdle (fnStop); var callbackCount = 0; - Func callback = (loop) => { + Func callback = () => { callbackCount++; return false; }; @@ -483,19 +483,6 @@ public void AddTimer_ReturnFalse_StopsBeingCalled () Assert.False (ml.RemoveTimeout (token)); } - // Invoke Tests - // TODO: Test with threading scenarios - [Fact] - public void Invoke_Adds_Idle () - { - var ml = new MainLoop (new FakeMainLoop ()); - - var actionCalled = 0; - ml.Invoke (() => { actionCalled++; }); - ml.RunIteration (); - Assert.Equal (1, actionCalled); - } - [Fact] public void CheckTimersAndIdleHandlers_NoTimers_Returns_False () { @@ -523,7 +510,7 @@ public void CheckTimersAndIdleHandlers_With1Timer_Returns_Timer () var ml = new MainLoop (new FakeMainLoop ()); var ms = TimeSpan.FromMilliseconds (50); - static bool Callback (MainLoop loop) => false; + static bool Callback () => false; _ = ml.AddTimeout (ms, Callback); var retVal = ml.CheckTimersAndIdleHandlers (out var waitTimeOut); @@ -539,7 +526,7 @@ public void CheckTimersAndIdleHandlers_With2Timers_Returns_Timer () var ml = new MainLoop (new FakeMainLoop ()); var ms = TimeSpan.FromMilliseconds (50); - static bool Callback (MainLoop loop) => false; + static bool Callback () => false; _ = ml.AddTimeout (ms, Callback); _ = ml.AddTimeout (ms, Callback); @@ -559,7 +546,7 @@ public void Internal_Tests () Assert.Empty (mainloop._idleHandlers); Assert.NotNull (new Timeout () { Span = new TimeSpan (), - Callback = (_) => true + Callback = () => true }); } @@ -604,7 +591,7 @@ private static void Launch (Random r, TextField tf, int target) { Task.Run (() => { Thread.Sleep (r.Next (2, 4)); - Application.MainLoop.Invoke (() => { + Application.Invoke (() => { tf.Text = $"index{r.Next ()}"; Interlocked.Increment (ref tbCounter); if (target == tbCounter) { @@ -627,15 +614,15 @@ private static void RunTest (Random r, TextField tf, int numPasses, int numIncre var tbNow = tbCounter; _wakeUp.Wait (pollMs); if (tbCounter == tbNow) { - // No change after wait: Idle handlers added via Application.MainLoop.Invoke have gone missing - Application.MainLoop.Invoke (() => Application.RequestStop ()); + // No change after wait: Idle handlers added via Application.Invoke have gone missing + Application.Invoke (() => Application.RequestStop ()); throw new TimeoutException ( $"Timeout: Increment lost. tbCounter ({tbCounter}) didn't " + $"change after waiting {pollMs} ms. Failed to reach {(j + 1) * numIncrements} on pass {j + 1}"); } }; } - Application.MainLoop.Invoke (() => Application.RequestStop ()); + Application.Invoke (() => Application.RequestStop ()); } [Fact] @@ -734,7 +721,7 @@ public static IEnumerable TestAddIdle { yield return new object [] { a1, "Click Me", "Cancel", "Pew Pew", 0, 1, 2, 3, 4 }; // Also goes fine - Action a2 = () => Application.MainLoop.Invoke (StartWindow); + Action a2 = () => Application.Invoke (StartWindow); yield return new object [] { a2, "Click Me", "Cancel", "Pew Pew", 0, 1, 2, 3, 4 }; } } @@ -811,7 +798,7 @@ private static void RunSql () Assert.Equal (cancel, btn.Text); Assert.Equal (one, total); - Application.MainLoop.Invoke (() => { + Application.Invoke (() => { btn.Text = "Pew Pew"; Interlocked.Increment (ref total); btn.SetNeedsDisplay (); @@ -824,7 +811,7 @@ private static void SetReadyToRun () Assert.Equal (pewPew, btn.Text); Assert.Equal (two, total); - Application.MainLoop.Invoke (() => { + Application.Invoke (() => { btn.Text = "Click Me"; Interlocked.Increment (ref total); btn.SetNeedsDisplay (); diff --git a/UnitTests/Application/SynchronizatonContextTests.cs b/UnitTests/Application/SynchronizatonContextTests.cs index c40682356c..6c6566a88b 100644 --- a/UnitTests/Application/SynchronizatonContextTests.cs +++ b/UnitTests/Application/SynchronizatonContextTests.cs @@ -31,7 +31,7 @@ public void SynchronizationContext_Post () success = true; // then tell the application to quit - Application.MainLoop.Invoke (() => Application.RequestStop ()); + Application.Invoke (() => Application.RequestStop ()); }, null); Assert.False (success); }); @@ -56,7 +56,7 @@ public void SynchronizationContext_Send () success = true; // then tell the application to quit - Application.MainLoop.Invoke (() => Application.RequestStop ()); + Application.Invoke (() => Application.RequestStop ()); }, null); Assert.True (success); }); diff --git a/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs b/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs index 405ffb4048..82d9a74765 100644 --- a/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs +++ b/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs @@ -160,7 +160,7 @@ public void FakeDriver_MockKeyPresses (Type driverType) // return false; // }; // output.WriteLine ($"Add timeout to simulate key presses after {quitTime}ms"); - // _ = Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (quitTime), closeCallback); + // _ = Application.AddTimeout (TimeSpan.FromMilliseconds (quitTime), closeCallback); // // If Top doesn't quit within abortTime * 5 (500ms), this will force it // uint abortTime = quitTime * 5; @@ -170,7 +170,7 @@ public void FakeDriver_MockKeyPresses (Type driverType) // return false; // }; // output.WriteLine ($"Add timeout to force quit after {abortTime}ms"); - // _ = Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (abortTime), forceCloseCallback); + // _ = Application.AddTimeout (TimeSpan.FromMilliseconds (abortTime), forceCloseCallback); // Key key = Key.Unknown; @@ -238,7 +238,7 @@ public void TerminalResized_Simulation (Type driverType) // System.Threading.Tasks.Task.Run (() => { // System.Threading.Tasks.Task.Delay (500).Wait (); -// Application.MainLoop.Invoke (() => { +// Application.Invoke (() => { // var lbl = new Label ("Hello World") { X = Pos.Center () }; // var dlg = new Dialog (); // dlg.Add (lbl); diff --git a/UnitTests/ConsoleDrivers/MainLoopDriverTests.cs b/UnitTests/ConsoleDrivers/MainLoopDriverTests.cs index da6ff96a86..01bea55f69 100644 --- a/UnitTests/ConsoleDrivers/MainLoopDriverTests.cs +++ b/UnitTests/ConsoleDrivers/MainLoopDriverTests.cs @@ -58,7 +58,7 @@ public void MainLoop_AddTimeout_ValidParameters_ReturnsToken (Type driverType, T var mainLoop = new MainLoop (mainLoopDriver); var callbackInvoked = false; - var token = mainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), (_) => { + var token = mainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), () => { callbackInvoked = true; return false; }); @@ -83,7 +83,7 @@ public void MainLoop_RemoveTimeout_ValidToken_ReturnsTrue (Type driverType, Type var mainLoopDriver = (IMainLoopDriver)Activator.CreateInstance (mainLoopDriverType, new object [] { driver }); var mainLoop = new MainLoop (mainLoopDriver); - var token = mainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), (_) => false); + var token = mainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), () => false); var result = mainLoop.RemoveTimeout (token); Assert.True (result); @@ -222,7 +222,7 @@ public void MainLoop_CheckTimersAndIdleHandlers_TimersActive_ReturnsTrue (Type d var mainLoopDriver = (IMainLoopDriver)Activator.CreateInstance (mainLoopDriverType, new object [] { driver }); var mainLoop = new MainLoop (mainLoopDriver); - mainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), (_) => false); + mainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), () => false); var result = mainLoop.CheckTimersAndIdleHandlers (out var waitTimeout); Assert.True (result); @@ -249,22 +249,22 @@ public void MainLoop_CheckTimersAndIdleHandlers_IdleHandlersActive_ReturnsTrue ( mainLoop.Dispose (); } - [Theory] - [InlineData (typeof (FakeDriver), typeof (FakeMainLoop))] - [InlineData (typeof (NetDriver), typeof (NetMainLoop))] - [InlineData (typeof (CursesDriver), typeof (UnixMainLoop))] - [InlineData (typeof (WindowsDriver), typeof (WindowsMainLoop))] - public void MainLoop_Invoke_ValidAction_RunsAction (Type driverType, Type mainLoopDriverType) - { - var driver = (ConsoleDriver)Activator.CreateInstance (driverType); - var mainLoopDriver = (IMainLoopDriver)Activator.CreateInstance (mainLoopDriverType, new object [] { driver }); - var mainLoop = new MainLoop (mainLoopDriver); - var actionInvoked = false; - - mainLoop.Invoke (() => { actionInvoked = true; }); - mainLoop.RunIteration (); // Run an iteration to process the action. - - Assert.True (actionInvoked); - mainLoop.Dispose (); - } + //[Theory] + //[InlineData (typeof (FakeDriver), typeof (FakeMainLoop))] + //[InlineData (typeof (NetDriver), typeof (NetMainLoop))] + //[InlineData (typeof (CursesDriver), typeof (UnixMainLoop))] + //[InlineData (typeof (WindowsDriver), typeof (WindowsMainLoop))] + //public void MainLoop_Invoke_ValidAction_RunsAction (Type driverType, Type mainLoopDriverType) + //{ + // var driver = (ConsoleDriver)Activator.CreateInstance (driverType); + // var mainLoopDriver = (IMainLoopDriver)Activator.CreateInstance (mainLoopDriverType, new object [] { driver }); + // var mainLoop = new MainLoop (mainLoopDriver); + // var actionInvoked = false; + + // mainLoop.Invoke (() => { actionInvoked = true; }); + // mainLoop.RunIteration (); // Run an iteration to process the action. + + // Assert.True (actionInvoked); + // mainLoop.Dispose (); + //} } diff --git a/UnitTests/Dialogs/DialogTests.cs b/UnitTests/Dialogs/DialogTests.cs index 7550799ea8..f8d395b507 100644 --- a/UnitTests/Dialogs/DialogTests.cs +++ b/UnitTests/Dialogs/DialogTests.cs @@ -352,7 +352,7 @@ public void ButtonAlignment_Two_Hidden () button2 = new Button (btn2Text); (runstate, dlg) = RunButtonTestDialog (title, width, Dialog.ButtonAlignments.Center, button1, button2); button1.Visible = false; - Application.RunMainLoopIteration (ref runstate, ref firstIteration); + Application.RunIteration (ref runstate, ref firstIteration); buttonRow = $@"{CM.Glyphs.VLine} {btn2} {CM.Glyphs.VLine}"; TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output); Application.End (runstate); @@ -363,7 +363,7 @@ public void ButtonAlignment_Two_Hidden () button2 = new Button (btn2Text); (runstate, dlg) = RunButtonTestDialog (title, width, Dialog.ButtonAlignments.Justify, button1, button2); button1.Visible = false; - Application.RunMainLoopIteration (ref runstate, ref firstIteration); + Application.RunIteration (ref runstate, ref firstIteration); buttonRow = $@"{CM.Glyphs.VLine} {btn2}{CM.Glyphs.VLine}"; TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output); Application.End (runstate); @@ -374,7 +374,7 @@ public void ButtonAlignment_Two_Hidden () button2 = new Button (btn2Text); (runstate, dlg) = RunButtonTestDialog (title, width, Dialog.ButtonAlignments.Right, button1, button2); button1.Visible = false; - Application.RunMainLoopIteration (ref runstate, ref firstIteration); + Application.RunIteration (ref runstate, ref firstIteration); TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output); Application.End (runstate); @@ -384,7 +384,7 @@ public void ButtonAlignment_Two_Hidden () button2 = new Button (btn2Text); (runstate, dlg) = RunButtonTestDialog (title, width, Dialog.ButtonAlignments.Left, button1, button2); button1.Visible = false; - Application.RunMainLoopIteration (ref runstate, ref firstIteration); + Application.RunIteration (ref runstate, ref firstIteration); buttonRow = $@"{CM.Glyphs.VLine} {btn2} {CM.Glyphs.VLine}"; TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output); Application.End (runstate); @@ -713,7 +713,7 @@ public void Add_Button_Works () buttonRow = $"{CM.Glyphs.VLine} {btn1} {btn2} {CM.Glyphs.VLine}"; dlg.AddButton (new Button (btn2Text)); bool first = false; - Application.RunMainLoopIteration (ref runstate, ref first); + Application.RunIteration (ref runstate, ref first); TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output); Application.End (runstate); @@ -729,7 +729,7 @@ public void Add_Button_Works () buttonRow = $"{CM.Glyphs.VLine}{btn1} {btn2}{CM.Glyphs.VLine}"; dlg.AddButton (new Button (btn2Text)); first = false; - Application.RunMainLoopIteration (ref runstate, ref first); + Application.RunIteration (ref runstate, ref first); TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output); Application.End (runstate); @@ -745,7 +745,7 @@ public void Add_Button_Works () buttonRow = $"{CM.Glyphs.VLine} {btn1} {btn2}{CM.Glyphs.VLine}"; dlg.AddButton (new Button (btn2Text)); first = false; - Application.RunMainLoopIteration (ref runstate, ref first); + Application.RunIteration (ref runstate, ref first); TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output); Application.End (runstate); @@ -761,7 +761,7 @@ public void Add_Button_Works () buttonRow = $"{CM.Glyphs.VLine}{btn1} {btn2} {CM.Glyphs.VLine}"; dlg.AddButton (new Button (btn2Text)); first = false; - Application.RunMainLoopIteration (ref runstate, ref first); + Application.RunIteration (ref runstate, ref first); TestHelpers.AssertDriverContentsWithFrameAre ($"{buttonRow}", output); Application.End (runstate); } diff --git a/UnitTests/Dialogs/WizardTests.cs b/UnitTests/Dialogs/WizardTests.cs index 978d4784bf..f5afb7d9fe 100644 --- a/UnitTests/Dialogs/WizardTests.cs +++ b/UnitTests/Dialogs/WizardTests.cs @@ -163,7 +163,7 @@ public void OneStepWizard_Shows () //wizard.LayoutSubviews (); var firstIteration = false; var runstate = Application.Begin (wizard); - Application.RunMainLoopIteration (ref runstate, ref firstIteration); + Application.RunIteration (ref runstate, ref firstIteration); TestHelpers.AssertDriverContentsWithFrameAre ($"{topRow}\n{row2}\n{row3}\n{row4}\n{separatorRow}\n{buttonRow}\n{bottomRow}", output); Application.End (runstate); @@ -530,10 +530,10 @@ public void Finish_Button_Closes () var runstate = Application.Begin (wizard); var firstIteration = true; - Application.RunMainLoopIteration (ref runstate, ref firstIteration); + Application.RunIteration (ref runstate, ref firstIteration); wizard.NextFinishButton.OnClicked (); - Application.RunMainLoopIteration (ref runstate, ref firstIteration); + Application.RunIteration (ref runstate, ref firstIteration); Application.End (runstate); Assert.True (finishedFired); Assert.True (closedFired); @@ -559,7 +559,7 @@ public void Finish_Button_Closes () }; runstate = Application.Begin (wizard); - Application.RunMainLoopIteration (ref runstate, ref firstIteration); + Application.RunIteration (ref runstate, ref firstIteration); Assert.Equal (step1.Title, wizard.CurrentStep.Title); wizard.NextFinishButton.OnClicked (); @@ -597,7 +597,7 @@ public void Finish_Button_Closes () }; runstate = Application.Begin (wizard); - Application.RunMainLoopIteration (ref runstate, ref firstIteration); + Application.RunIteration (ref runstate, ref firstIteration); Assert.Equal (step2.Title, wizard.CurrentStep.Title); Assert.Equal (wizard.GetLastStep ().Title, wizard.CurrentStep.Title); diff --git a/UnitTests/UICatalog/ScenarioTests.cs b/UnitTests/UICatalog/ScenarioTests.cs index 1edd6ece58..bacb1f1b54 100644 --- a/UnitTests/UICatalog/ScenarioTests.cs +++ b/UnitTests/UICatalog/ScenarioTests.cs @@ -79,7 +79,7 @@ public void Run_All_Scenarios () uint abortTime = 500; // If the scenario doesn't close within 500ms, this will force it to quit - Func forceCloseCallback = (MainLoop loop) => { + Func forceCloseCallback = () => { if (Application.Top.Running && FakeConsole.MockKeyPresses.Count == 0) { Application.RequestStop (); // See #2474 for why this is commented out @@ -88,7 +88,7 @@ public void Run_All_Scenarios () return false; }; //output.WriteLine ($" Add timeout to force quit after {abortTime}ms"); - _ = Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (abortTime), forceCloseCallback); + _ = Application.AddTimeout (TimeSpan.FromMilliseconds (abortTime), forceCloseCallback); Application.Iteration += () => { //output.WriteLine ($" iteration {++iterations}"); @@ -148,13 +148,13 @@ public void Run_Generic () var ms = 100; var abortCount = 0; - Func abortCallback = (MainLoop loop) => { + Func abortCallback = () => { abortCount++; output.WriteLine ($"'Generic' abortCount {abortCount}"); Application.RequestStop (); return false; }; - var token = Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (ms), abortCallback); + var token = Application.AddTimeout (TimeSpan.FromMilliseconds (ms), abortCallback); Application.Top.KeyPress += (object sender, KeyEventEventArgs args) => { // See #2474 for why this is commented out diff --git a/UnitTests/View/FrameTests.cs b/UnitTests/View/FrameTests.cs index 685380b7a4..f2497f2d60 100644 --- a/UnitTests/View/FrameTests.cs +++ b/UnitTests/View/FrameTests.cs @@ -61,7 +61,7 @@ public void Border_With_Title_Size_Height (int height) bool firstIteration = false; ((FakeDriver)Application.Driver).SetBufferSize (20, height); - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); var expected = string.Empty; switch (height) { @@ -119,7 +119,7 @@ public void Border_With_Title_Size_Width (int width) bool firstIteration = false; ((FakeDriver)Application.Driver).SetBufferSize (width, 3); - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); var expected = string.Empty; switch (width) { @@ -210,7 +210,7 @@ public void NoSuperView () bool firstIteration = false; ((FakeDriver)Application.Driver).SetBufferSize (3, 3); - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); var expected = @" ┌─┐ │ │ @@ -234,7 +234,7 @@ public void HasSuperView () bool firstIteration = false; ((FakeDriver)Application.Driver).SetBufferSize (5, 5); - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); var expected = @" ╔═══╗ ║┌─┐║ @@ -262,7 +262,7 @@ public void HasSuperView_Title () bool firstIteration = false; ((FakeDriver)Application.Driver).SetBufferSize (10, 4); - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); var expected = @" ╔════════╗ ║┌┤1234├┐║ @@ -299,7 +299,7 @@ public void Border_With_Title_Border_Double_Thickness_Top_Two_Size_Width (int wi bool firstIteration = false; ((FakeDriver)Application.Driver).SetBufferSize (width, 4); - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); var expected = string.Empty; switch (width) { @@ -411,7 +411,7 @@ public void Border_With_Title_Border_Double_Thickness_Top_Three_Size_Width (int bool firstIteration = false; ((FakeDriver)Application.Driver).SetBufferSize (width, 4); - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); var expected = string.Empty; switch (width) { @@ -523,7 +523,7 @@ public void Border_With_Title_Border_Double_Thickness_Top_Four_Size_Width (int w bool firstIteration = false; ((FakeDriver)Application.Driver).SetBufferSize (width, 5); - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); var expected = string.Empty; switch (width) { diff --git a/UnitTests/View/Layout/LayoutTests.cs b/UnitTests/View/Layout/LayoutTests.cs index 4935bcf98b..8dfd1a31be 100644 --- a/UnitTests/View/Layout/LayoutTests.cs +++ b/UnitTests/View/Layout/LayoutTests.cs @@ -1396,7 +1396,7 @@ public void Setting_Frame_Dont_Respect_AutoSize_True_On_Layout_Absolute () view1.Frame = new Rect (0, 0, 25, 4); bool firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); Assert.True (view1.AutoSize); Assert.Equal (LayoutStyle.Absolute, view1.LayoutStyle); @@ -1407,7 +1407,7 @@ public void Setting_Frame_Dont_Respect_AutoSize_True_On_Layout_Absolute () Assert.Equal ("Absolute(1)", view1.Height.ToString ()); view2.Frame = new Rect (0, 0, 1, 25); - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); Assert.True (view2.AutoSize); Assert.Equal (LayoutStyle.Absolute, view2.LayoutStyle); @@ -1598,7 +1598,7 @@ public void Dim_CenteredSubView_85_Percent_Height (int height) ((FakeDriver)Application.Driver).SetBufferSize (20, height); - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); var expected = string.Empty; switch (height) { @@ -1736,7 +1736,7 @@ public void Dim_CenteredSubView_85_Percent_Width (int width) ((FakeDriver)Application.Driver).SetBufferSize (width, 7); - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); var expected = string.Empty; switch (width) { diff --git a/UnitTests/View/ViewTests.cs b/UnitTests/View/ViewTests.cs index aea66a2c35..0e2ab587c6 100644 --- a/UnitTests/View/ViewTests.cs +++ b/UnitTests/View/ViewTests.cs @@ -846,7 +846,7 @@ public void Visible_Clear_The_View_Output () label.Visible = false; bool firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); TestHelpers.AssertDriverContentsWithFrameAre (@" ┌────────────────────────────┐ │ │ diff --git a/UnitTests/Views/ContextMenuTests.cs b/UnitTests/Views/ContextMenuTests.cs index 0623572a1d..465a64d84f 100644 --- a/UnitTests/Views/ContextMenuTests.cs +++ b/UnitTests/Views/ContextMenuTests.cs @@ -967,7 +967,7 @@ public void Draw_A_ContextMenu_Over_A_Dialog () }); var firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); TestHelpers.AssertDriverContentsWithFrameAre (@" ┌──────────────────┐ │ │ @@ -1018,7 +1018,7 @@ public void Draw_A_ContextMenu_Over_A_Top_Dialog () }); var firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); TestHelpers.AssertDriverContentsWithFrameAre (@" ┌─────────────┐ │ Test │ @@ -1062,7 +1062,7 @@ public void Draw_A_ContextMenu_Over_A_Borderless_Top () }); var firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); TestHelpers.AssertDriverContentsWithFrameAre (@" Test ┌─────────────────── @@ -1113,7 +1113,7 @@ public void UseSubMenusSingleFrame_True_By_Mouse () }); var firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); Assert.Equal (new Rect (5, 11, 10, 5), Application.Top.Subviews [0].Frame); Assert.Equal (new Rect (5, 11, 15, 6), Application.Top.Subviews [1].Frame); TestHelpers.AssertDriverContentsWithFrameAre (@" @@ -1134,7 +1134,7 @@ public void UseSubMenusSingleFrame_True_By_Mouse () }); firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); Assert.Equal (new Rect (5, 11, 10, 5), Application.Top.Subviews [0].Frame); TestHelpers.AssertDriverContentsWithFrameAre (@" ┌────────┐ diff --git a/UnitTests/Views/MenuTests.cs b/UnitTests/Views/MenuTests.cs index 7ec9209a66..b34cb908f8 100644 --- a/UnitTests/Views/MenuTests.cs +++ b/UnitTests/Views/MenuTests.cs @@ -2376,7 +2376,7 @@ void ChangeMenuTitle (string title) Assert.Equal ("File", menu.Menus [0].Title); menu.OpenMenu (); var firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); TestHelpers.AssertDriverContentsWithFrameAre (@" ┌──────────────────────────────────────┐ │ │ @@ -2404,7 +2404,7 @@ void ChangeMenuTitle (string title) }); firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); Assert.Equal (items [0], menu.Menus [0].Title); TestHelpers.AssertDriverContentsWithFrameAre (@" ┌──────────────────────────────────────┐ @@ -2436,14 +2436,14 @@ void ChangeMenuTitle (string title) }); firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); Assert.Equal (items [i], menu.Menus [0].Title); } ((FakeDriver)Application.Driver).SetBufferSize (20, 15); menu.OpenMenu (); firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); TestHelpers.AssertDriverContentsWithFrameAre (@" ┌──────────────────┐ │ │ @@ -2505,7 +2505,7 @@ void ChangeMenuTitle (string title) Assert.Equal ("File", menu.Menus [0].Title); menu.OpenMenu (); var firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); TestHelpers.AssertDriverContentsWithFrameAre (@" ┌─────────────┐ │ File │ @@ -2528,7 +2528,7 @@ void ChangeMenuTitle (string title) }); firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); Assert.Equal (items [0], menu.Menus [0].Title); TestHelpers.AssertDriverContentsWithFrameAre (@" ┌─────────────┐ @@ -2549,14 +2549,14 @@ void ChangeMenuTitle (string title) }); firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); Assert.Equal (items [i], menu.Menus [0].Title); } ((FakeDriver)Application.Driver).SetBufferSize (20, 15); menu.OpenMenu (); firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); TestHelpers.AssertDriverContentsWithFrameAre (@" ┌─────────────┐ │ Delete │ @@ -2585,7 +2585,7 @@ public void Resizing_Close_Menus () menu.OpenMenu (); var firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); TestHelpers.AssertDriverContentsWithFrameAre (@" File ┌────────────────────────────┐ @@ -2594,7 +2594,7 @@ public void Resizing_Close_Menus () ((FakeDriver)Application.Driver).SetBufferSize (20, 15); firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); TestHelpers.AssertDriverContentsWithFrameAre (@" File", output); diff --git a/UnitTests/Views/ToplevelTests.cs b/UnitTests/Views/ToplevelTests.cs index 9ea7e26136..ea3f5bb68a 100644 --- a/UnitTests/Views/ToplevelTests.cs +++ b/UnitTests/Views/ToplevelTests.cs @@ -1416,7 +1416,7 @@ public void Modal_As_Top_Will_Drag_Cleanly () }); var firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); Assert.Equal (dialog, Application.MouseGrabView); Assert.Equal (new Rect (25, 7, 30, 10), dialog.Frame); @@ -1442,7 +1442,7 @@ public void Modal_As_Top_Will_Drag_Cleanly () }); firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); Assert.Equal (dialog, Application.MouseGrabView); Assert.Equal (new Rect (20, 10, 30, 10), dialog.Frame); TestHelpers.AssertDriverContentsWithFrameAre (@" @@ -1560,7 +1560,7 @@ void Current_DrawContentComplete (object sender, DrawEventArgs e) }); var firstIteration = false; - Application.RunMainLoopIteration (ref rs, ref firstIteration); + Application.RunIteration (ref rs, ref firstIteration); TestHelpers.AssertDriverContentsWithFrameAre (@$" ┌──────────────────┐ │ │ @@ -1619,7 +1619,7 @@ public void Multi_Thread_Toplevels () bool fromTopStillKnowSecondIsRunning = false; bool fromFirstStillKnowSecondIsRunning = false; - Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), (_) => { + Application.AddTimeout (TimeSpan.FromMilliseconds (100), () => { count++; if (count1 == 5) { log1 = true; @@ -1656,7 +1656,7 @@ void FirstDialogToplevel (object sender, EventArgs args) var od = new OpenDialog (); od.Ready += SecondDialogToplevel; - Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), (_) => { + Application.AddTimeout (TimeSpan.FromMilliseconds (100), () => { count1++; if (count2 == 5) { log2 = true; @@ -1679,7 +1679,7 @@ void SecondDialogToplevel (object sender, EventArgs args) { var d = new Dialog (); - Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (100), (_) => { + Application.AddTimeout (TimeSpan.FromMilliseconds (100), () => { count2++; if (count < 30) { log = true; From 2d2345be7d38b1bac3f3ecb3c1a9ace63540aad3 Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Wed, 18 Oct 2023 23:52:44 -0500 Subject: [PATCH 006/194] Modernized Terminal resize events --- Terminal.Gui/Application.cs | 31 +++++++++++++----- Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs | 14 +++++--- .../CursesDriver/CursesDriver.cs | 6 ++-- .../ConsoleDrivers/FakeDriver/FakeDriver.cs | 6 ++-- Terminal.Gui/ConsoleDrivers/NetDriver.cs | 7 ++-- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 6 ++-- Terminal.Gui/View/Layout/ResizedEventArgs.cs | 32 ------------------- .../View/Layout/SizeChangedEventArgs.cs | 5 +++ UnitTests/Application/ApplicationTests.cs | 2 -- UnitTests/ConsoleDrivers/AddRuneTests.cs | 10 +++--- .../ConsoleDrivers/ConsoleDriverTests.cs | 10 +++--- UnitTests/ConsoleDrivers/DriverColorTests.cs | 4 +-- UnitTests/Drawing/AttributeTests.cs | 6 ++-- UnitTests/Views/GraphViewTests.cs | 4 +-- UnitTests/Views/TabViewTests.cs | 2 +- UnitTests/Views/TreeViewTests.cs | 2 +- 16 files changed, 65 insertions(+), 82 deletions(-) delete mode 100644 Terminal.Gui/View/Layout/ResizedEventArgs.cs diff --git a/Terminal.Gui/Application.cs b/Terminal.Gui/Application.cs index 0cf61c715b..a2a377b966 100644 --- a/Terminal.Gui/Application.cs +++ b/Terminal.Gui/Application.cs @@ -178,7 +178,7 @@ internal static void InternalInit (Func topLevelFactory, ConsoleDriver MainLoop = Driver.CreateMainLoop (); try { - Driver.Init (OnTerminalResized); + Driver.Init (); } catch (InvalidOperationException ex) { // This is a case where the driver is unable to initialize the console. // This can happen if the console is already in use by another process or @@ -187,6 +187,7 @@ internal static void InternalInit (Func topLevelFactory, ConsoleDriver throw new InvalidOperationException ("Unable to initialize the console. This can happen if the console is already in use by another process or in unit tests.", ex); } + Driver.SizeChanged += (s, args) => OnSizeChanging (args); Driver.PrepareToRun (ProcessKeyEvent, ProcessKeyDownEvent, ProcessKeyUpEvent, ProcessMouseEvent); SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext ()); @@ -239,7 +240,7 @@ static void ResetState () Iteration = null; RootMouseEvent = null; RootKeyEvent = null; - TerminalResized = null; + SizeChanging = null; _mainThreadId = -1; NotifyNewRunState = null; NotifyStopRunState = null; @@ -990,19 +991,33 @@ static bool MoveCurrent (Toplevel top) /// /// Invoked when the terminal was resized. The new size of the terminal is provided. /// - public static Action TerminalResized; + /// + /// Event handlers can set to + /// to prevent from changing it's size to match the new terminal size. + /// + public static event EventHandler SizeChanging; - static void OnTerminalResized () + /// + /// Called when the application's size changes. Sets the size of all s and + /// fires the event. + /// + /// The new size. + /// if the size was changed. + public static bool OnSizeChanging (SizeChangedEventArgs args) { - var full = new Rect (0, 0, Driver.Cols, Driver.Rows); - TerminalResized?.Invoke (new ResizedEventArgs () { Cols = full.Width, Rows = full.Height }); + SizeChanging?.Invoke (null, args); + if (args.Cancel) { + return false; + } + foreach (var t in _toplevels) { - t.SetRelativeLayout (full); + t.SetRelativeLayout (new Rect(0, 0, args.Size.Width, args.Size.Height)); t.LayoutSubviews (); t.PositionToplevels (); - t.OnTerminalResized (new SizeChangedEventArgs (full.Size)); + t.OnTerminalResized (new SizeChangedEventArgs (args.Size)); } Refresh (); + return true; } #endregion Toplevel handling diff --git a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs index 634a1aaeb3..d634a772e8 100644 --- a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs @@ -44,7 +44,7 @@ public abstract class ConsoleDriver { /// Initializes the driver /// /// Method to invoke when the terminal is resized. - internal abstract void Init (Action terminalResized); + internal abstract void Init (); /// /// Prepare the driver and set the key and mouse events handlers. @@ -63,9 +63,15 @@ public abstract class ConsoleDriver { #endregion /// - /// The handler fired when the terminal is resized. + /// The event fired when the terminal is resized. /// - protected Action TerminalResized; + public event EventHandler SizeChanged; + + /// + /// Called when the terminal size changes. Firest the event. + /// + /// + public void OnSizeChanged (SizeChangedEventArgs args) => SizeChanged?.Invoke (this, args); /// /// The number of columns visible in the terminal. @@ -441,7 +447,7 @@ public virtual Attribute MakeAttribute (Color fore, Color back) /// /// The current attribute. public Attribute GetAttribute () => CurrentAttribute; - + /// /// Makes an . /// diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs index 50b1f4a798..68d85ce5f9 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs @@ -63,7 +63,7 @@ private void ProcessWinChange () { if (!RunningUnitTests && Curses.CheckWinChange ()) { ClearContents (); - TerminalResized?.Invoke (); + OnSizeChanged (new SizeChangedEventArgs (new Size (Cols, Rows))); } } @@ -630,7 +630,7 @@ internal override void PrepareToRun (Action keyHandler, Action - /// Event arguments for the event. - /// - public class ResizedEventArgs : EventArgs { - /// - /// The number of rows in the resized terminal. - /// - public int Rows { get; set; } - /// - /// The number of columns in the resized terminal. - /// - public int Cols { get; set; } - } -} diff --git a/Terminal.Gui/View/Layout/SizeChangedEventArgs.cs b/Terminal.Gui/View/Layout/SizeChangedEventArgs.cs index 66c52bf3a2..adde33a158 100644 --- a/Terminal.Gui/View/Layout/SizeChangedEventArgs.cs +++ b/Terminal.Gui/View/Layout/SizeChangedEventArgs.cs @@ -22,5 +22,10 @@ public SizeChangedEventArgs (Size size) /// resolved. /// public Size Size { get; } + + /// + /// Set to to cause the resize to be cancelled, if appropriate. + /// + public bool Cancel { get; set; } } } diff --git a/UnitTests/Application/ApplicationTests.cs b/UnitTests/Application/ApplicationTests.cs index b3a2df2885..b019ab9946 100644 --- a/UnitTests/Application/ApplicationTests.cs +++ b/UnitTests/Application/ApplicationTests.cs @@ -27,7 +27,6 @@ void Pre_Init_State () Assert.Null (Application.MainLoop); Assert.Null (Application.Iteration); Assert.Null (Application.RootMouseEvent); - Assert.Null (Application.TerminalResized); } void Post_Init_State () @@ -38,7 +37,6 @@ void Post_Init_State () Assert.NotNull (Application.MainLoop); Assert.Null (Application.Iteration); Assert.Null (Application.RootMouseEvent); - Assert.Null (Application.TerminalResized); // FakeDriver is always 80x25 Assert.Equal (80, Application.Driver.Cols); Assert.Equal (25, Application.Driver.Rows); diff --git a/UnitTests/ConsoleDrivers/AddRuneTests.cs b/UnitTests/ConsoleDrivers/AddRuneTests.cs index 5d2e7c5a12..a58f0a83e4 100644 --- a/UnitTests/ConsoleDrivers/AddRuneTests.cs +++ b/UnitTests/ConsoleDrivers/AddRuneTests.cs @@ -20,7 +20,7 @@ public void AddRune () var driver = new FakeDriver (); Application.Init (driver); - driver.Init (() => { }); + driver.Init (); driver.AddRune (new Rune ('a')); Assert.Equal ((Rune)'a', driver.Contents [0, 0].Runes [0]); @@ -34,7 +34,7 @@ public void AddRune_InvalidLocation_DoesNothing () { var driver = new FakeDriver (); Application.Init (driver); - driver.Init (() => { }); + driver.Init (); driver.Move (driver.Cols, driver.Rows); driver.AddRune ('a'); @@ -54,7 +54,7 @@ public void AddRune_MovesToNextColumn () { var driver = new FakeDriver (); Application.Init (driver); - driver.Init (() => { }); + driver.Init (); driver.AddRune ('a'); Assert.Equal ((Rune)'a', driver.Contents [0, 0].Runes [0]); @@ -95,7 +95,7 @@ public void AddRune_MovesToNextColumn_Wide () { var driver = new FakeDriver (); Application.Init (driver); - driver.Init (() => { }); + driver.Init (); // 🍕 Slice of Pizza "\U0001F355" var operationStatus = Rune.DecodeFromUtf16 ("\U0001F355", out Rune rune, out int charsConsumed); @@ -143,7 +143,7 @@ public void AddRune_Accented_Letter_With_Three_Combining_Unicode_Chars () { var driver = new FakeDriver (); Application.Init (driver); - driver.Init (() => { }); + driver.Init (); var expected = new Rune ('ắ'); diff --git a/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs b/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs index 82d9a74765..255d393ca3 100644 --- a/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs +++ b/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs @@ -27,7 +27,7 @@ public void Init_Inits (Type driverType) { var driver = (ConsoleDriver)Activator.CreateInstance (driverType); Application.Init (driver); - driver.Init (() => { }); + driver.Init (); Assert.Equal (80, Console.BufferWidth); Assert.Equal (25, Console.BufferHeight); @@ -50,7 +50,7 @@ public void End_Cleans_Up (Type driverType) { var driver = (ConsoleDriver)Activator.CreateInstance (driverType); Application.Init (driver); - driver.Init (() => { }); + driver.Init (); Console.ForegroundColor = ConsoleColor.Red; Assert.Equal (ConsoleColor.Red, Console.ForegroundColor); @@ -204,10 +204,10 @@ public void TerminalResized_Simulation (Type driverType) var driver = (FakeDriver)Activator.CreateInstance (driverType); Application.Init (driver); var wasTerminalResized = false; - Application.TerminalResized = (e) => { + Application.SizeChanging += (s, e) => { wasTerminalResized = true; - Assert.Equal (120, e.Cols); - Assert.Equal (40, e.Rows); + Assert.Equal (120, e.Size.Width); + Assert.Equal (40, e.Size.Height); }; Assert.Equal (80, Console.BufferWidth); diff --git a/UnitTests/ConsoleDrivers/DriverColorTests.cs b/UnitTests/ConsoleDrivers/DriverColorTests.cs index d9de6973e7..80c5a8caa3 100644 --- a/UnitTests/ConsoleDrivers/DriverColorTests.cs +++ b/UnitTests/ConsoleDrivers/DriverColorTests.cs @@ -47,7 +47,7 @@ public void SetColors_Changes_Colors (Type driverType) public void SupportsTrueColor_Defaults (Type driverType, bool expectedSetting) { var driver = (ConsoleDriver)Activator.CreateInstance (driverType); - driver.Init (() => { }); + driver.Init (); Assert.Equal (expectedSetting, driver.SupportsTrueColor); @@ -65,7 +65,7 @@ public void SupportsTrueColor_Defaults (Type driverType, bool expectedSetting) public void Force16Colors_Sets (Type driverType) { var driver = (ConsoleDriver)Activator.CreateInstance (driverType); - driver.Init (() => { }); + driver.Init (); driver.Force16Colors = true; Assert.True (driver.Force16Colors); diff --git a/UnitTests/Drawing/AttributeTests.cs b/UnitTests/Drawing/AttributeTests.cs index 33cc15a594..f837e70c87 100644 --- a/UnitTests/Drawing/AttributeTests.cs +++ b/UnitTests/Drawing/AttributeTests.cs @@ -91,7 +91,7 @@ public void Constuctors_Constuct () { var driver = new FakeDriver (); Application.Init (driver); - driver.Init (() => { }); + driver.Init (); // Test parameterless constructor var attr = new Attribute (); @@ -197,7 +197,7 @@ public void Implicit_Assign () { var driver = new FakeDriver (); Application.Init (driver); - driver.Init (() => { }); + driver.Init (); var attr = new Attribute (); @@ -238,7 +238,7 @@ public void Make_Creates () { var driver = new FakeDriver (); Application.Init (driver); - driver.Init (() => { }); + driver.Init (); var fg = new Color (); fg = new Color (Color.Red); diff --git a/UnitTests/Views/GraphViewTests.cs b/UnitTests/Views/GraphViewTests.cs index f660ccad85..5a7d52fd20 100644 --- a/UnitTests/Views/GraphViewTests.cs +++ b/UnitTests/Views/GraphViewTests.cs @@ -69,7 +69,7 @@ public static FakeDriver InitFakeDriver () throw new Exception ("A test did not call shutdown correctly. Test stack trace was:" + LastInitFakeDriver); } - driver.Init (() => { }); + driver.Init (); LastInitFakeDriver = Environment.StackTrace; return driver; @@ -1516,7 +1516,7 @@ public void LabelChangeText_RendersCorrectly (bool useFill) { var driver = new FakeDriver (); Application.Init (driver); - driver.Init (() => { }); + driver.Init (); // create a wide window var mount = new View () { diff --git a/UnitTests/Views/TabViewTests.cs b/UnitTests/Views/TabViewTests.cs index 571a90d6ad..ea049a2997 100644 --- a/UnitTests/Views/TabViewTests.cs +++ b/UnitTests/Views/TabViewTests.cs @@ -850,7 +850,7 @@ private void InitFakeDriver () { var driver = new FakeDriver (); Application.Init (driver); - driver.Init (() => { }); + driver.Init (); } } } \ No newline at end of file diff --git a/UnitTests/Views/TreeViewTests.cs b/UnitTests/Views/TreeViewTests.cs index 991f63fe52..d6fa9ade29 100644 --- a/UnitTests/Views/TreeViewTests.cs +++ b/UnitTests/Views/TreeViewTests.cs @@ -1280,7 +1280,7 @@ private void InitFakeDriver () { var driver = new FakeDriver (); Application.Init (driver); - driver.Init (() => { }); + driver.Init (); } } } From fcea94698d4553ffbe6cc10c1a6e46427d9d0140 Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Thu, 19 Oct 2023 00:00:50 -0500 Subject: [PATCH 007/194] Modernized Terminal resize events --- Terminal.Gui/Application.cs | 4 +-- Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs | 3 +-- Terminal.Gui/View/ViewLayout.cs | 2 +- Terminal.Gui/Views/Menu.cs | 4 +-- Terminal.Gui/Views/Toplevel.cs | 28 +++++--------------- 5 files changed, 13 insertions(+), 28 deletions(-) diff --git a/Terminal.Gui/Application.cs b/Terminal.Gui/Application.cs index a2a377b966..54de7ffd83 100644 --- a/Terminal.Gui/Application.cs +++ b/Terminal.Gui/Application.cs @@ -989,7 +989,7 @@ static bool MoveCurrent (Toplevel top) } /// - /// Invoked when the terminal was resized. The new size of the terminal is provided. + /// Invoked when the terminal's size changed. The new size of the terminal is provided. /// /// /// Event handlers can set to @@ -1014,7 +1014,7 @@ public static bool OnSizeChanging (SizeChangedEventArgs args) t.SetRelativeLayout (new Rect(0, 0, args.Size.Width, args.Size.Height)); t.LayoutSubviews (); t.PositionToplevels (); - t.OnTerminalResized (new SizeChangedEventArgs (args.Size)); + t.OnSizeChanging (new SizeChangedEventArgs (args.Size)); } Refresh (); return true; diff --git a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs index d634a772e8..b91816815e 100644 --- a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs @@ -43,7 +43,6 @@ public abstract class ConsoleDriver { /// /// Initializes the driver /// - /// Method to invoke when the terminal is resized. internal abstract void Init (); /// @@ -68,7 +67,7 @@ public abstract class ConsoleDriver { public event EventHandler SizeChanged; /// - /// Called when the terminal size changes. Firest the event. + /// Called when the terminal size changes. Fires the event. /// /// public void OnSizeChanged (SizeChangedEventArgs args) => SizeChanged?.Invoke (this, args); diff --git a/Terminal.Gui/View/ViewLayout.cs b/Terminal.Gui/View/ViewLayout.cs index 3b720339c6..48b5434cdf 100644 --- a/Terminal.Gui/View/ViewLayout.cs +++ b/Terminal.Gui/View/ViewLayout.cs @@ -431,7 +431,7 @@ public bool SetMinWidthHeight () /// /// Called whenever the view needs to be resized. Sets and - /// triggers a call. /// + /// triggers a call. /// /// /// Can be overridden if the view resize behavior is different than the default. diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs index 8b24bd2aae..74f0229de4 100644 --- a/Terminal.Gui/Views/Menu.cs +++ b/Terminal.Gui/Views/Menu.cs @@ -482,7 +482,7 @@ public Menu (MenuBar host, int x, int y, MenuBarItem barItems, Menu parent = nul if (Application.Current != null) { Application.Current.DrawContentComplete += Current_DrawContentComplete; - Application.Current.TerminalResized += Current_TerminalResized; + Application.Current.SizeChanging += Current_TerminalResized; } Application.RootMouseEvent += Application_RootMouseEvent; @@ -985,7 +985,7 @@ protected override void Dispose (bool disposing) { if (Application.Current != null) { Application.Current.DrawContentComplete -= Current_DrawContentComplete; - Application.Current.TerminalResized -= Current_TerminalResized; + Application.Current.SizeChanging -= Current_TerminalResized; } Application.RootMouseEvent -= Application_RootMouseEvent; base.Dispose (disposing); diff --git a/Terminal.Gui/Views/Toplevel.cs b/Terminal.Gui/Views/Toplevel.cs index fa2d56096b..4612d84cf0 100644 --- a/Terminal.Gui/Views/Toplevel.cs +++ b/Terminal.Gui/Views/Toplevel.cs @@ -98,27 +98,16 @@ public partial class Toplevel : View { /// /// Invoked when the terminal has been resized. The new of the terminal is provided. /// - public event EventHandler TerminalResized; + public event EventHandler SizeChanging; - internal virtual void OnTerminalResized (SizeChangedEventArgs size) - { - TerminalResized?.Invoke (this, size); - } + // TODO: Make cancelable? + internal virtual void OnSizeChanging (SizeChangedEventArgs size) => SizeChanging?.Invoke (this, size); - internal virtual void OnChildUnloaded (Toplevel top) - { - ChildUnloaded?.Invoke (this, new ToplevelEventArgs (top)); - } + internal virtual void OnChildUnloaded (Toplevel top) => ChildUnloaded?.Invoke (this, new ToplevelEventArgs (top)); - internal virtual void OnChildLoaded (Toplevel top) - { - ChildLoaded?.Invoke (this, new ToplevelEventArgs (top)); - } + internal virtual void OnChildLoaded (Toplevel top) => ChildLoaded?.Invoke (this, new ToplevelEventArgs (top)); - internal virtual void OnClosed (Toplevel top) - { - Closed?.Invoke (this, new ToplevelEventArgs (top)); - } + internal virtual void OnClosed (Toplevel top) => Closed?.Invoke (this, new ToplevelEventArgs (top)); internal virtual bool OnClosing (ToplevelClosingEventArgs ev) { @@ -126,10 +115,7 @@ internal virtual bool OnClosing (ToplevelClosingEventArgs ev) return ev.Cancel; } - internal virtual void OnAllChildClosed () - { - AllChildClosed?.Invoke (this, EventArgs.Empty); - } + internal virtual void OnAllChildClosed () => AllChildClosed?.Invoke (this, EventArgs.Empty); internal virtual void OnChildClosed (Toplevel top) { From 9a8730384a93af06df11acb12b7fddf52103023a Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Thu, 19 Oct 2023 00:11:43 -0500 Subject: [PATCH 008/194] Removed un used property --- Terminal.Gui/Application.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Terminal.Gui/Application.cs b/Terminal.Gui/Application.cs index 54de7ffd83..ce898455cc 100644 --- a/Terminal.Gui/Application.cs +++ b/Terminal.Gui/Application.cs @@ -585,8 +585,6 @@ public static void Refresh () // users use async/await on their code // class MainLoopSyncContext : SynchronizationContext { - readonly MainLoop _mainLoop; - public override SynchronizationContext CreateCopy () { return new MainLoopSyncContext (); From 54f200a752ad3c73cd11508b6071367ae72da544 Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Thu, 19 Oct 2023 00:14:45 -0500 Subject: [PATCH 009/194] for _isWindowsTerminal devenv->wininit; not sure what changed --- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index a5d04690b8..97cd384bb8 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -788,7 +788,7 @@ internal class WindowsDriver : ConsoleDriver { public WindowsConsole WinConsole { get; private set; } public override bool SupportsTrueColor => RunningUnitTests || (Environment.OSVersion.Version.Build >= 14931 - && (_isWindowsTerminal || _parentProcessName == "devenv")); + && (_isWindowsTerminal || _parentProcessName == "wininit")); readonly bool _isWindowsTerminal = false; readonly string _parentProcessName = "WindowsTerminal"; @@ -813,7 +813,7 @@ public WindowsDriver () if (!RunningUnitTests) { _parentProcessName = GetParentProcessName (); _isWindowsTerminal = _parentProcessName == "WindowsTerminal"; - if (!_isWindowsTerminal && _parentProcessName != "devenv") { + if (!_isWindowsTerminal && _parentProcessName != "wininit") { Force16Colors = true; } } From e6db63eee6683b50b179e744149e786258fec639 Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Thu, 19 Oct 2023 11:50:44 -0600 Subject: [PATCH 010/194] Modernized mouse/keyboard events (Action->EventHandler) --- CONTRIBUTING.md | 6 +- Terminal.Gui/Application.cs | 275 ++- Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs | 75 +- .../CursesDriver/CursesDriver.cs | 57 +- .../ConsoleDrivers/FakeDriver/FakeDriver.cs | 20 +- Terminal.Gui/ConsoleDrivers/NetDriver.cs | 34 +- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 37 +- Terminal.Gui/Input/Event.cs | 4 +- Terminal.Gui/Input/MouseEventEventArgs.cs | 2 + Terminal.Gui/View/ViewKeyboard.cs | 12 +- Terminal.Gui/Views/Button.cs | 8 +- Terminal.Gui/Views/FileDialog.cs | 10 +- Terminal.Gui/Views/Label.cs | 2 +- Terminal.Gui/Views/Menu.cs | 20 +- .../Views/TableView/TreeTableSource.cs | 4 +- Terminal.Gui/Views/ToplevelOverlapped.cs | 40 +- UICatalog/KeyBindingsDialog.cs | 2 +- UICatalog/Scenarios/ASCIICustomButton.cs | 4 +- .../Scenarios/BackgroundWorkerCollection.cs | 4 +- UICatalog/Scenarios/BasicColors.cs | 8 +- UICatalog/Scenarios/ContextMenus.cs | 10 +- UICatalog/Scenarios/CsvEditor.cs | 2 +- UICatalog/Scenarios/Editor.cs | 2 +- UICatalog/Scenarios/InteractiveTree.cs | 2 +- UICatalog/Scenarios/Keys.cs | 37 +- UICatalog/Scenarios/LineDrawing.cs | 2 +- UICatalog/Scenarios/ListColumns.cs | 2 +- UICatalog/Scenarios/Mouse.cs | 6 +- UICatalog/Scenarios/Scrolling.cs | 4 +- UICatalog/Scenarios/SendKeys.cs | 4 +- UICatalog/Scenarios/SingleBackgroundWorker.cs | 2 +- UICatalog/Scenarios/TableEditor.cs | 2 +- UICatalog/Scenarios/TreeViewFileSystem.cs | 2 +- UICatalog/Scenarios/TrueColors.cs | 6 +- UICatalog/Scenarios/VkeyPacketSimulator.cs | 4 +- UnitTests/Application/ApplicationTests.cs | 1742 ++++++++--------- UnitTests/Application/MainLoopTests.cs | 2 +- UnitTests/Clipboard/ClipboardTests.cs | 16 +- .../Configuration/ConfigurationMangerTests.cs | 3 - .../ConsoleDrivers/ConsoleDriverTests.cs | 10 +- UnitTests/ConsoleDrivers/KeyTests.cs | 4 +- UnitTests/Dialogs/DialogTests.cs | 10 +- UnitTests/Dialogs/MessageBoxTests.cs | 28 +- UnitTests/Input/EscSeqUtilsTests.cs | 28 +- UnitTests/ReflectionTools.cs | 35 - UnitTests/UICatalog/ScenarioTests.cs | 10 +- UnitTests/View/KeyboardTests.cs | 12 +- UnitTests/View/Layout/DimTests.cs | 12 +- UnitTests/View/Layout/LayoutTests.cs | 25 +- UnitTests/View/Layout/PosTests.cs | 14 +- UnitTests/View/NavigationTests.cs | 22 +- UnitTests/View/ViewTests.cs | 6 +- UnitTests/Views/ContextMenuTests.cs | 69 +- UnitTests/Views/MenuTests.cs | 56 +- UnitTests/Views/OverlappedTests.cs | 20 +- UnitTests/Views/ScrollBarViewTests.cs | 26 +- UnitTests/Views/StatusBarTests.cs | 4 +- UnitTests/Views/TextFieldTests.cs | 30 +- UnitTests/Views/TextViewTests.cs | 18 +- UnitTests/Views/ToplevelTests.cs | 292 ++- 60 files changed, 1552 insertions(+), 1653 deletions(-) delete mode 100644 UnitTests/ReflectionTools.cs diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d837cfc822..8e622eaff6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -148,11 +148,11 @@ The [Microsoft .NET Framework Design Guidelines](https://docs.microsoft.com/en-u > ✔️ DO name event argument classes with the "EventArgs" suffix. 1. We follow the naming guidelines provided in https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/names-of-type-members?redirectedfrom=MSDN -2. We use the `event Action` idiom. +2. We use the `event EventHandler` idiom. 3. For public APIs, the class that can raise the event will implement: - A `virtual` event raising function, named as `OnEventToRaise`. Typical implementations will simply do a `EventToRaise?.Invoke(this, eventArgs)`. - - An `event` as in `public event Action EventToRaise` - - Consumers of the event can do `theobject.EventToRaise += (args) => {};` + - An `event` as in `public event EventHandler EventToRaise` + - Consumers of the event can do `theobject.EventToRaise += (sender, args) => {};` - Sub-classes of the class implementing `EventToRaise` can override `OnEventToRaise` as needed. 4. Where possible, a subclass of `EventArgs` should be provided and the old and new state should be included. By doing this, event handler methods do not have to query the sender for state. diff --git a/Terminal.Gui/Application.cs b/Terminal.Gui/Application.cs index ce898455cc..c769f72a57 100644 --- a/Terminal.Gui/Application.cs +++ b/Terminal.Gui/Application.cs @@ -188,7 +188,11 @@ internal static void InternalInit (Func topLevelFactory, ConsoleDriver } Driver.SizeChanged += (s, args) => OnSizeChanging (args); - Driver.PrepareToRun (ProcessKeyEvent, ProcessKeyDownEvent, ProcessKeyUpEvent, ProcessMouseEvent); + Driver.KeyPressed += (s, args) => OnKeyPressed (args); + Driver.KeyDown += (s, args) => OnKeyDown (args); + Driver.KeyUp += (s, args) => OnKeyUp (args); + Driver.MouseEvent += (s, args) => OnMouseEvent (args); + Driver.PrepareToRun (); SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext ()); @@ -222,11 +226,11 @@ static void ResetState () // Shutdown is the bookend for Init. As such it needs to clean up all resources // Init created. Apps that do any threading will need to code defensively for this. // e.g. see Issue #537 - foreach (var t in _toplevels) { + foreach (var t in _topLevels) { t.Running = false; t.Dispose (); } - _toplevels.Clear (); + _topLevels.Clear (); Current = null; Top?.Dispose (); Top = null; @@ -238,8 +242,10 @@ static void ResetState () Driver?.End (); Driver = null; Iteration = null; - RootMouseEvent = null; - RootKeyEvent = null; + MouseEvent = null; + KeyDown = null; + KeyUp = null; + KeyPressed = null; SizeChanging = null; _mainThreadId = -1; NotifyNewRunState = null; @@ -311,34 +317,34 @@ public static RunState Begin (Toplevel Toplevel) Toplevel.EndInit (); } - lock (_toplevels) { + lock (_topLevels) { // If Top was already initialized with Init, and Begin has never been called // Top was not added to the Toplevels Stack. It will thus never get disposed. // Clean it up here: - if (Top != null && Toplevel != Top && !_toplevels.Contains (Top)) { + if (Top != null && Toplevel != Top && !_topLevels.Contains (Top)) { Top.Dispose (); Top = null; - } else if (Top != null && Toplevel != Top && _toplevels.Contains (Top)) { + } else if (Top != null && Toplevel != Top && _topLevels.Contains (Top)) { Top.OnLeave (Toplevel); } if (string.IsNullOrEmpty (Toplevel.Id)) { var count = 1; - var id = (_toplevels.Count + count).ToString (); - while (_toplevels.Count > 0 && _toplevels.FirstOrDefault (x => x.Id == id) != null) { + var id = (_topLevels.Count + count).ToString (); + while (_topLevels.Count > 0 && _topLevels.FirstOrDefault (x => x.Id == id) != null) { count++; - id = (_toplevels.Count + count).ToString (); + id = (_topLevels.Count + count).ToString (); } - Toplevel.Id = (_toplevels.Count + count).ToString (); + Toplevel.Id = (_topLevels.Count + count).ToString (); - _toplevels.Push (Toplevel); + _topLevels.Push (Toplevel); } else { - var dup = _toplevels.FirstOrDefault (x => x.Id == Toplevel.Id); + var dup = _topLevels.FirstOrDefault (x => x.Id == Toplevel.Id); if (dup == null) { - _toplevels.Push (Toplevel); + _topLevels.Push (Toplevel); } } - if (_toplevels.FindDuplicates (new ToplevelEqualityComparer ()).Count > 0) { + if (_topLevels.FindDuplicates (new ToplevelEqualityComparer ()).Count > 0) { throw new ArgumentException ("There are duplicates Toplevels Id's"); } } @@ -356,7 +362,7 @@ public static RunState Begin (Toplevel Toplevel) } else { refreshDriver = false; } - } else if ((OverlappedTop != null && Toplevel != OverlappedTop && Current?.Modal == true && !_toplevels.Peek ().Modal) + } else if ((OverlappedTop != null && Toplevel != OverlappedTop && Current?.Modal == true && !_topLevels.Peek ().Modal) || (OverlappedTop != null && Toplevel != OverlappedTop && Current?.Running == false)) { refreshDriver = false; MoveCurrent (Toplevel); @@ -548,7 +554,7 @@ public static void Refresh () // TODO: Figure out how to remove this call to ClearContents. Refresh should just repaint damaged areas, not clear Driver.ClearContents (); View last = null; - foreach (var v in _toplevels.Reverse ()) { + foreach (var v in _topLevels.Reverse ()) { if (v.Visible) { v.SetNeedsDisplay (); v.SetSubViewNeedsDisplay (); @@ -566,7 +572,7 @@ public static void Refresh () /// /// See also /// - public static Action Iteration; + public static event EventHandler Iteration; /// /// The driver for the application @@ -616,15 +622,6 @@ public override void Send (SendOrPostCallback d, object state) } } - /// - /// Determines whether there are pending events to be processed. - /// - /// - /// Use this method to probe if events are pending. Typically used to flush the input queue while still - /// running code on the main thread. - /// - public static bool EventsPending () => MainLoop.EventsPending (); - /// /// Building block API: Runs the for the created . /// @@ -662,7 +659,7 @@ public static void RunIteration (ref RunState state, ref bool firstIteration) } MainLoop.RunIteration (); - Iteration?.Invoke (); + Iteration?.Invoke (null, new IterationEventArgs()); EnsureModalOrVisibleAlwaysOnTop (state.Toplevel); if (state.Toplevel != Current) { @@ -686,7 +683,7 @@ public static void RunIteration (ref RunState state, ref bool firstIteration) state.Toplevel.SetNeedsDisplay (state.Toplevel.Frame); Top.Clear (); Top.Draw (); - foreach (var top in _toplevels.Reverse ()) { + foreach (var top in _topLevels.Reverse ()) { if (top != Top && top != state.Toplevel) { top.SetNeedsDisplay (); top.SetSubViewNeedsDisplay (); @@ -695,7 +692,7 @@ public static void RunIteration (ref RunState state, ref bool firstIteration) } } } - if (_toplevels.Count == 1 && state.Toplevel == Top + if (_topLevels.Count == 1 && state.Toplevel == Top && (Driver.Cols != state.Toplevel.Frame.Width || Driver.Rows != state.Toplevel.Frame.Height) && (state.Toplevel.NeedsDisplay || state.Toplevel.SubViewNeedsDisplay || state.Toplevel.LayoutNeeded)) { @@ -763,7 +760,7 @@ public static void RequestStop (Toplevel top = null) } else if ((OverlappedTop != null && top != OverlappedTop && top != Current && Current?.Modal == false && Current?.Running == true && !top.Running) || (OverlappedTop != null && top != OverlappedTop && top != Current && Current?.Modal == false - && Current?.Running == false && !top.Running && _toplevels.ToArray () [1].Running)) { + && Current?.Running == false && !top.Running && _topLevels.ToArray () [1].Running)) { MoveCurrent (top); } else if (OverlappedTop != null && Current != top && Current?.Running == true && !top.Running @@ -822,13 +819,13 @@ public static void End (RunState runState) // End the RunState.Toplevel // First, take it off the Toplevel Stack - if (_toplevels.Count > 0) { - if (_toplevels.Peek () != runState.Toplevel) { + if (_topLevels.Count > 0) { + if (_topLevels.Peek () != runState.Toplevel) { // If there the top of the stack is not the RunState.Toplevel then // this call to End is not balanced with the call to Begin that started the RunState throw new ArgumentException ("End must be balanced with calls to Begin"); } - _toplevels.Pop (); + _topLevels.Pop (); } // Notify that it is closing @@ -841,11 +838,11 @@ public static void End (RunState runState) } // Set Current and Top to the next TopLevel on the stack - if (_toplevels.Count == 0) { + if (_topLevels.Count == 0) { Current = null; } else { - Current = _toplevels.Peek (); - if (_toplevels.Count == 1 && Current == OverlappedTop) { + Current = _topLevels.Peek (); + if (_topLevels.Count == 1 && Current == OverlappedTop) { OverlappedTop.OnAllChildClosed (); } else { SetCurrentOverlappedAsTop (); @@ -863,7 +860,7 @@ public static void End (RunState runState) #endregion Run (Begin, Run, End) #region Toplevel handling - static readonly Stack _toplevels = new Stack (); + static readonly Stack _topLevels = new Stack (); /// /// The object used for the application on startup () @@ -880,11 +877,11 @@ public static void End (RunState runState) static void EnsureModalOrVisibleAlwaysOnTop (Toplevel Toplevel) { - if (!Toplevel.Running || (Toplevel == Current && Toplevel.Visible) || OverlappedTop == null || _toplevels.Peek ().Modal) { + if (!Toplevel.Running || (Toplevel == Current && Toplevel.Visible) || OverlappedTop == null || _topLevels.Peek ().Modal) { return; } - foreach (var top in _toplevels.Reverse ()) { + foreach (var top in _topLevels.Reverse ()) { if (top.Modal && top != Current) { MoveCurrent (top); return; @@ -905,12 +902,12 @@ static View FindDeepestTop (Toplevel start, int x, int y, out int resx, out int return null; } - if (_toplevels != null) { - int count = _toplevels.Count; + if (_topLevels != null) { + int count = _topLevels.Count; if (count > 0) { var rx = x - startFrame.X; var ry = y - startFrame.Y; - foreach (var t in _toplevels) { + foreach (var t in _topLevels) { if (t != Current) { if (t != start && t.Visible && t.Frame.Contains (rx, ry)) { start = t; @@ -941,16 +938,16 @@ static bool MoveCurrent (Toplevel top) { // The Current is modal and the top is not modal Toplevel then // the Current must be moved above the first not modal Toplevel. - if (OverlappedTop != null && top != OverlappedTop && top != Current && Current?.Modal == true && !_toplevels.Peek ().Modal) { - lock (_toplevels) { - _toplevels.MoveTo (Current, 0, new ToplevelEqualityComparer ()); + if (OverlappedTop != null && top != OverlappedTop && top != Current && Current?.Modal == true && !_topLevels.Peek ().Modal) { + lock (_topLevels) { + _topLevels.MoveTo (Current, 0, new ToplevelEqualityComparer ()); } var index = 0; - var savedToplevels = _toplevels.ToArray (); + var savedToplevels = _topLevels.ToArray (); foreach (var t in savedToplevels) { if (!t.Modal && t != Current && t != top && t != savedToplevels [index]) { - lock (_toplevels) { - _toplevels.MoveTo (top, index, new ToplevelEqualityComparer ()); + lock (_topLevels) { + _topLevels.MoveTo (top, index, new ToplevelEqualityComparer ()); } } index++; @@ -960,26 +957,26 @@ static bool MoveCurrent (Toplevel top) // The Current and the top are both not running Toplevel then // the top must be moved above the first not running Toplevel. if (OverlappedTop != null && top != OverlappedTop && top != Current && Current?.Running == false && !top.Running) { - lock (_toplevels) { - _toplevels.MoveTo (Current, 0, new ToplevelEqualityComparer ()); + lock (_topLevels) { + _topLevels.MoveTo (Current, 0, new ToplevelEqualityComparer ()); } var index = 0; - foreach (var t in _toplevels.ToArray ()) { + foreach (var t in _topLevels.ToArray ()) { if (!t.Running && t != Current && index > 0) { - lock (_toplevels) { - _toplevels.MoveTo (top, index - 1, new ToplevelEqualityComparer ()); + lock (_topLevels) { + _topLevels.MoveTo (top, index - 1, new ToplevelEqualityComparer ()); } } index++; } return false; } - if ((OverlappedTop != null && top?.Modal == true && _toplevels.Peek () != top) + if ((OverlappedTop != null && top?.Modal == true && _topLevels.Peek () != top) || (OverlappedTop != null && Current != OverlappedTop && Current?.Modal == false && top == OverlappedTop) || (OverlappedTop != null && Current?.Modal == false && top != Current) || (OverlappedTop != null && Current?.Modal == true && top == OverlappedTop)) { - lock (_toplevels) { - _toplevels.MoveTo (top, 0, new ToplevelEqualityComparer ()); + lock (_topLevels) { + _topLevels.MoveTo (top, 0, new ToplevelEqualityComparer ()); Current = top; } } @@ -1008,8 +1005,8 @@ public static bool OnSizeChanging (SizeChangedEventArgs args) return false; } - foreach (var t in _toplevels) { - t.SetRelativeLayout (new Rect(0, 0, args.Size.Width, args.Size.Height)); + foreach (var t in _topLevels) { + t.SetRelativeLayout (new Rect (0, 0, args.Size.Width, args.Size.Height)); t.LayoutSubviews (); t.PositionToplevels (); t.OnSizeChanging (new SizeChangedEventArgs (args.Size)); @@ -1120,14 +1117,27 @@ static void OnUnGrabbedMouse (View view) UnGrabbedMouse?.Invoke (view, new ViewEventArgs (view)); } + static View _lastMouseOwnerView; + /// - /// Merely a debugging aid to see the raw mouse events + /// Event fired when a mouse move or click occurs. Coordinates are screen relative. /// - public static Action RootMouseEvent { get; set; } - - static View _lastMouseOwnerView; + /// + /// + /// Use this event to receive mouse events in screen coordinates. Use to receive + /// mouse events relative to a 's bounds. + /// + /// + /// The will contain the that contains the mouse coordinates. + /// + /// + public static event EventHandler MouseEvent; - static void ProcessMouseEvent (MouseEvent me) + /// + /// Called when a mouse event occurs. Fires the event. + /// + /// + public static void OnMouseEvent (MouseEventEventArgs a) { static bool OutsideBounds (Point p, Rect r) => p.X < 0 || p.X > r.Right || p.Y < 0 || p.Y > r.Bottom; @@ -1135,7 +1145,7 @@ static void ProcessMouseEvent (MouseEvent me) return; } - var view = View.FindDeepestView (Current, me.X, me.Y, out int rx, out int ry); + var view = View.FindDeepestView (Current, a.MouseEvent.X, a.MouseEvent.Y, out int rx, out int ry); if (view != null && view.WantContinuousButtonPressed) { WantContinuousButtonPressedView = view; @@ -1143,26 +1153,26 @@ static void ProcessMouseEvent (MouseEvent me) WantContinuousButtonPressedView = null; } if (view != null) { - me.View = view; + a.MouseEvent.View = view; } - RootMouseEvent?.Invoke (me); + MouseEvent?.Invoke (null, new MouseEventEventArgs (a.MouseEvent)); - if (me.Handled) { + if (a.MouseEvent.Handled) { return; } if (_mouseGrabView != null) { - var newxy = _mouseGrabView.ScreenToView (me.X, me.Y); + var newxy = _mouseGrabView.ScreenToView (a.MouseEvent.X, a.MouseEvent.Y); var nme = new MouseEvent () { X = newxy.X, Y = newxy.Y, - Flags = me.Flags, - OfX = me.X - newxy.X, - OfY = me.Y - newxy.Y, + Flags = a.MouseEvent.Flags, + OfX = a.MouseEvent.X - newxy.X, + OfY = a.MouseEvent.Y - newxy.Y, View = view }; if (OutsideBounds (new Point (nme.X, nme.Y), _mouseGrabView.Bounds)) { - _lastMouseOwnerView?.OnMouseLeave (me); + _lastMouseOwnerView?.OnMouseLeave (a.MouseEvent); } //System.Diagnostics.Debug.WriteLine ($"{nme.Flags};{nme.X};{nme.Y};{mouseGrabView}"); if (_mouseGrabView?.OnMouseEvent (nme) == true) { @@ -1171,10 +1181,10 @@ static void ProcessMouseEvent (MouseEvent me) } if ((view == null || view == OverlappedTop) && !Current.Modal && OverlappedTop != null - && me.Flags != MouseFlags.ReportMousePosition && me.Flags != 0) { + && a.MouseEvent.Flags != MouseFlags.ReportMousePosition && a.MouseEvent.Flags != 0) { - var top = FindDeepestTop (Top, me.X, me.Y, out _, out _); - view = View.FindDeepestView (top, me.X, me.Y, out rx, out ry); + var top = FindDeepestTop (Top, a.MouseEvent.X, a.MouseEvent.Y, out _, out _); + view = View.FindDeepestView (top, a.MouseEvent.X, a.MouseEvent.Y, out rx, out ry); if (view != null && view != OverlappedTop && top != Current) { MoveCurrent ((Toplevel)top); @@ -1185,7 +1195,7 @@ static void ProcessMouseEvent (MouseEvent me) var nme = new MouseEvent () { X = rx, Y = ry, - Flags = me.Flags, + Flags = a.MouseEvent.Flags, OfX = 0, OfY = 0, View = view @@ -1200,7 +1210,7 @@ static void ProcessMouseEvent (MouseEvent me) _lastMouseOwnerView = view; } - if (!view.WantMousePositionReports && me.Flags == MouseFlags.ReportMousePosition) + if (!view.WantMousePositionReports && a.MouseEvent.Flags == MouseFlags.ReportMousePosition) return; if (view.WantContinuousButtonPressed) @@ -1218,7 +1228,6 @@ static void ProcessMouseEvent (MouseEvent me) #region Keyboard handling - static Key _alternateForwardKey = Key.PageDown | Key.CtrlMask; /// @@ -1238,7 +1247,7 @@ public static Key AlternateForwardKey { static void OnAlternateForwardKeyChanged (KeyChangedEventArgs e) { - foreach (var top in _toplevels.ToArray ()) { + foreach (var top in _topLevels.ToArray ()) { top.OnAlternateForwardKeyChanged (e); } } @@ -1262,7 +1271,7 @@ public static Key AlternateBackwardKey { static void OnAlternateBackwardKeyChanged (KeyChangedEventArgs oldKey) { - foreach (var top in _toplevels.ToArray ()) { + foreach (var top in _topLevels.ToArray ()) { top.OnAlternateBackwardKeyChanged (oldKey); } } @@ -1286,72 +1295,122 @@ public static Key QuitKey { static void OnQuitKeyChanged (KeyChangedEventArgs e) { // Duplicate the list so if it changes during enumeration we're safe - foreach (var top in _toplevels.ToArray ()) { + foreach (var top in _topLevels.ToArray ()) { top.OnQuitKeyChanged (e); } } - static void ProcessKeyEvent (KeyEvent ke) + /// + /// Event fired after a key has been pressed and released. + /// Set to to suppress the event. + /// + /// + /// All drivers support firing the event. Some drivers (Curses) + /// do not support firing the and events. + /// + public static event EventHandler KeyPressed; + + /// + /// Called after a key has been pressed and released. Fires the event. + /// + /// Called for new KeyPressed events before any processing is performed or + /// views evaluate. Use for global key handling and/or debugging. + /// + /// + /// + /// if the key was handled. + public static bool OnKeyPressed (KeyEventEventArgs a) { - if (RootKeyEvent?.Invoke (ke) ?? false) { - return; + KeyPressed?.Invoke (null, a); + if (a.Handled) { + return true; } - var chain = _toplevels.ToList (); + var chain = _topLevels.ToList (); foreach (var topLevel in chain) { - if (topLevel.ProcessHotKey (ke)) - return; + if (topLevel.ProcessHotKey (a.KeyEvent)) { + return true; + } if (topLevel.Modal) break; } foreach (var topLevel in chain) { - if (topLevel.ProcessKey (ke)) - return; + if (topLevel.ProcessKey (a.KeyEvent)) { + return true; + } if (topLevel.Modal) break; } foreach (var topLevel in chain) { // Process the key normally - if (topLevel.ProcessColdKey (ke)) - return; + if (topLevel.ProcessColdKey (a.KeyEvent)) { + return true; + } if (topLevel.Modal) break; } + return false; } - static void ProcessKeyDownEvent (KeyEvent ke) + /// + /// Event fired when a key is pressed (and not yet released). + /// + /// + /// All drivers support firing the event. Some drivers (Curses) + /// do not support firing the and events. + /// + public static event EventHandler KeyDown; + + /// + /// Called when a key is pressed (and not yet released). Fires the event. + /// + /// + public static void OnKeyDown (KeyEventEventArgs a) { - var chain = _toplevels.ToList (); + KeyDown?.Invoke (null, a); + var chain = _topLevels.ToList (); foreach (var topLevel in chain) { - if (topLevel.OnKeyDown (ke)) + if (topLevel.OnKeyDown (a.KeyEvent)) return; if (topLevel.Modal) break; } } - static void ProcessKeyUpEvent (KeyEvent ke) + /// + /// Event fired when a key is released. + /// + /// + /// All drivers support firing the event. Some drivers (Curses) + /// do not support firing the and events. + /// + public static event EventHandler KeyUp; + + /// + /// Called when a key is released. Fires the event. + /// + /// + public static void OnKeyUp (KeyEventEventArgs a) { - var chain = _toplevels.ToList (); + KeyUp?.Invoke (null, a); + var chain = _topLevels.ToList (); foreach (var topLevel in chain) { - if (topLevel.OnKeyUp (ke)) + if (topLevel.OnKeyUp (a.KeyEvent)) return; if (topLevel.Modal) break; } - } - /// - /// - /// Called for new KeyPress events before any processing is performed or - /// views evaluate. Use for global key handling and/or debugging. - /// - /// Return true to suppress the KeyPress event - /// - public static Func RootKeyEvent { get; set; } + } #endregion Keyboard handling } + + /// + /// Event arguments for the event. + /// + public class IterationEventArgs { + } } diff --git a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs index b91816815e..0eb4c7dfd4 100644 --- a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs @@ -9,7 +9,6 @@ namespace Terminal.Gui; - /// /// Base class for Terminal.Gui ConsoleDriver implementations. /// @@ -48,11 +47,7 @@ public abstract class ConsoleDriver { /// /// Prepare the driver and set the key and mouse events handlers. /// - /// The handler for ProcessKey - /// The handler for key down events - /// The handler for key up events - /// The handler for mouse events - internal abstract void PrepareToRun (Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler); + internal abstract void PrepareToRun (); /// /// Ends the execution of the console driver. @@ -464,6 +459,64 @@ public virtual Attribute MakeColor (Color foreground, Color background) } + #endregion + + #region Mouse and Keyboard + + /// + /// Event fired after a key has been pressed and released. + /// + public event EventHandler KeyPressed; + + /// + /// Called after a key has been pressed and released. Fires the event. + /// + /// + public void OnKeyPressed (KeyEventEventArgs a) => KeyPressed?.Invoke(this, a); + + /// + /// Event fired when a key is released. + /// + public event EventHandler KeyUp; + + /// + /// Called when a key is released. Fires the event. + /// + /// + public void OnKeyUp (KeyEventEventArgs a) => KeyUp?.Invoke (this, a); + + /// + /// Event fired when a key is pressed. + /// + public event EventHandler KeyDown; + + /// + /// Called when a key is pressed. Fires the event. + /// + /// + public void OnKeyDown (KeyEventEventArgs a) => KeyDown?.Invoke (this, a); + + /// + /// Event fired when a mouse event occurs. + /// + public event EventHandler MouseEvent; + + /// + /// Called when a mouse event occurs. Fires the event. + /// + /// + public void OnMouseEvent (MouseEventEventArgs a) => MouseEvent?.Invoke (this, a); + + /// + /// Simulates a key press. + /// + /// The key character. + /// The key. + /// If simulates the Shift key being pressed. + /// If simulates the Alt key being pressed. + /// If simulates the Ctrl key being pressed. + public abstract void SendKeys (char keyChar, ConsoleKey key, bool shift, bool alt, bool ctrl); + #endregion /// @@ -498,16 +551,6 @@ public enum DiagnosticFlags : uint { /// This is only implemented in . public abstract void Suspend (); - /// - /// Simulates a key press. - /// - /// The key character. - /// The key. - /// If simulates the Shift key being pressed. - /// If simulates the Alt key being pressed. - /// If simulates the Ctrl key being pressed. - public abstract void SendKeys (char keyChar, ConsoleKey key, bool shift, bool alt, bool ctrl); - // TODO: Move FillRect to ./Drawing /// /// Fills the specified rectangle with the specified rune. diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs index 68d85ce5f9..e820763177 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs @@ -432,9 +432,9 @@ internal void ProcessInput () wch -= 60; k = Key.ShiftMask | Key.AltMask | MapCursesKey (wch); } - _keyDownHandler (new KeyEvent (k, MapKeyModifiers (k))); - _keyHandler (new KeyEvent (k, MapKeyModifiers (k))); - _keyUpHandler (new KeyEvent (k, MapKeyModifiers (k))); + OnKeyDown (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); + OnKeyUp (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); + OnKeyPressed (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); return; } @@ -485,16 +485,18 @@ internal void ProcessInput () } } key = new KeyEvent (k, MapKeyModifiers (k)); - _keyDownHandler (key); - _keyHandler (key); + OnKeyDown (new KeyEventEventArgs (key)); + OnKeyUp (new KeyEventEventArgs (key)); + OnKeyPressed (new KeyEventEventArgs (key)); } else { k = Key.Esc; - _keyHandler (new KeyEvent (k, MapKeyModifiers (k))); + OnKeyPressed (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); } } else if (wch == Curses.KeyTab) { k = MapCursesKey (wch); - _keyDownHandler (new KeyEvent (k, MapKeyModifiers (k))); - _keyHandler (new KeyEvent (k, MapKeyModifiers (k))); + OnKeyDown (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); + OnKeyUp (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); + OnKeyPressed (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); } else { // Unfortunately there are no way to differentiate Ctrl+alfa and Ctrl+Shift+alfa. k = (Key)wch; @@ -507,9 +509,9 @@ internal void ProcessInput () } else if (wch >= (uint)Key.A && wch <= (uint)Key.Z) { _keyModifiers.Shift = true; } - _keyDownHandler (new KeyEvent (k, MapKeyModifiers (k))); - _keyHandler (new KeyEvent (k, MapKeyModifiers (k))); - _keyUpHandler (new KeyEvent (k, MapKeyModifiers (k))); + OnKeyDown (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); + OnKeyUp (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); + OnKeyPressed (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); } // Cause OnKeyUp and OnKeyPressed. Note that the special handling for ESC above // will not impact KeyUp. @@ -529,7 +531,7 @@ void HandleEscSeqResponse (ref int code, ref Key k, ref int wch2, ref KeyEvent k code = Curses.get_wch (out wch2); var consoleKeyInfo = new ConsoleKeyInfo ((char)wch2, 0, false, false, false); if (wch2 == 0 || wch2 == 27 || wch2 == Curses.KeyMouse) { - EscSeqUtils.DecodeEscSeq (null, ref consoleKeyInfo, ref ck, cki, ref mod, out _, out _, out _, out _, out bool isKeyMouse, out List mouseFlags, out Point pos, out _, ProcessContinuousButtonPressed); + EscSeqUtils.DecodeEscSeq (null, ref consoleKeyInfo, ref ck, cki, ref mod, out _, out _, out _, out _, out bool isKeyMouse, out List mouseFlags, out Point pos, out _, ProcessMouseEvent); if (isKeyMouse) { foreach (var mf in mouseFlags) { ProcessMouseEvent (mf, pos); @@ -543,8 +545,8 @@ void HandleEscSeqResponse (ref int code, ref Key k, ref int wch2, ref KeyEvent k k = ConsoleKeyMapping.MapConsoleKeyToKey (consoleKeyInfo.Key, out _); k = ConsoleKeyMapping.MapKeyModifiers (consoleKeyInfo, k); key = new KeyEvent (k, MapKeyModifiers (k)); - _keyDownHandler (key); - _keyHandler (key); + OnKeyDown (new KeyEventEventArgs (key)); + OnKeyPressed (new KeyEventEventArgs (key)); } } else { cki = EscSeqUtils.ResizeArray (consoleKeyInfo, cki); @@ -596,34 +598,17 @@ bool IsButtonClickedOrDoubleClicked (MouseFlags flag) X = pos.X, Y = pos.Y }; - _mouseHandler (me); + OnMouseEvent (new MouseEventEventArgs (me)); } - - void ProcessContinuousButtonPressed (MouseFlags mouseFlag, Point pos) - { - ProcessMouseEvent (mouseFlag, pos); - } - - Action _keyHandler; - Action _keyDownHandler; - Action _keyUpHandler; - Action _mouseHandler; - object _processInputToken; - internal override void PrepareToRun (Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler) + internal override void PrepareToRun () { if (!RunningUnitTests) { Curses.timeout (0); } - _keyHandler = keyHandler; - // Note: Curses doesn't support keydown/up events and thus any passed keyDown/UpHandlers will never be called - _keyDownHandler = keyDownHandler; - _keyUpHandler = keyUpHandler; - _mouseHandler = mouseHandler; - _processInputToken = _mainLoopDriver?.AddWatch (0, UnixMainLoop.Condition.PollIn, x => { ProcessInput (); return true; @@ -817,9 +802,9 @@ public override void SendKeys (char keyChar, ConsoleKey consoleKey, bool shift, key |= Key.CtrlMask; km.Ctrl = control; } - _keyDownHandler (new KeyEvent (key, km)); - _keyHandler (new KeyEvent (key, km)); - _keyUpHandler (new KeyEvent (key, km)); + OnKeyDown (new KeyEventEventArgs (new KeyEvent (key, km))); + OnKeyPressed (new KeyEventEventArgs (new KeyEvent (key, km))); + OnKeyUp (new KeyEventEventArgs (new KeyEvent (key, km))); } diff --git a/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs b/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs index b5b43be7fb..9338d0ce92 100644 --- a/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs @@ -346,18 +346,10 @@ private Key MapKeyModifiers (ConsoleKeyInfo keyInfo, Key key) return keyMod != Key.Null ? keyMod | key : key; } - Action _keyDownHandler; - Action _keyHandler; - Action _keyUpHandler; private CursorVisibility _savedCursorVisibility; - internal override void PrepareToRun (Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler) + internal override void PrepareToRun () { - _keyHandler = keyHandler; - _keyDownHandler = keyDownHandler; - _keyUpHandler = keyUpHandler; - //_mouseHandler = mouseHandler; - // Note: Net doesn't support keydown/up events and thus any passed keyDown/UpHandlers will never be called _mainLoopDriver.KeyPressed = (consoleKey) => ProcessInput (consoleKey); } @@ -380,15 +372,15 @@ void ProcessInput (ConsoleKeyInfo consoleKey) var map = MapKey (consoleKey); if (map == (Key)0xffffffff) { if ((consoleKey.Modifiers & (ConsoleModifiers.Shift | ConsoleModifiers.Alt | ConsoleModifiers.Control)) != 0) { - _keyDownHandler (new KeyEvent (map, keyModifiers)); - _keyUpHandler (new KeyEvent (map, keyModifiers)); + OnKeyDown(new KeyEventEventArgs(new KeyEvent (map, keyModifiers))); + OnKeyUp (new KeyEventEventArgs (new KeyEvent (map, keyModifiers))); } return; } - _keyDownHandler (new KeyEvent (map, keyModifiers)); - _keyHandler (new KeyEvent (map, keyModifiers)); - _keyUpHandler (new KeyEvent (map, keyModifiers)); + OnKeyDown (new KeyEventEventArgs (new KeyEvent (map, keyModifiers))); + OnKeyUp (new KeyEventEventArgs (new KeyEvent (map, keyModifiers))); + OnKeyPressed (new KeyEventEventArgs (new KeyEvent (map, keyModifiers))); } /// diff --git a/Terminal.Gui/ConsoleDrivers/NetDriver.cs b/Terminal.Gui/ConsoleDrivers/NetDriver.cs index 01dedae075..c8f6438864 100644 --- a/Terminal.Gui/ConsoleDrivers/NetDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/NetDriver.cs @@ -640,6 +640,12 @@ internal override MainLoop CreateMainLoop () public NetWinVTConsole NetWinConsole { get; private set; } public bool IsWinPlatform { get; private set; } + internal override void PrepareToRun () + { + // Note: .Net API doesn't support keydown/up events and thus any passed keyDown/UpHandlers will be simulated to be called. + _mainLoopDriver.ProcessInput = ProcessInput; + } + internal override void End () { if (IsWinPlatform) { @@ -1110,22 +1116,6 @@ Key MapKeyModifiers (ConsoleKeyInfo keyInfo, Key key) return keyMod != Key.Null ? keyMod | key : key; } - Action _keyHandler; - Action _keyDownHandler; - Action _keyUpHandler; - Action _mouseHandler; - - internal override void PrepareToRun (Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler) - { - _keyHandler = keyHandler; - _keyDownHandler = keyDownHandler; - _keyUpHandler = keyUpHandler; - _mouseHandler = mouseHandler; - - // Note: .Net API doesn't support keydown/up events and thus any passed keyDown/UpHandlers will be simulated to be called. - _mainLoopDriver.ProcessInput = ProcessInput; - } - volatile bool _winSizeChanging; void ProcessInput (NetEvents.InputResult inputEvent) @@ -1142,16 +1132,16 @@ void ProcessInput (NetEvents.InputResult inputEvent) return; } if (map == Key.Null) { - _keyDownHandler (new KeyEvent (map, _keyModifiers)); - _keyUpHandler (new KeyEvent (map, _keyModifiers)); + OnKeyDown (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); + OnKeyUp (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); } else { - _keyDownHandler (new KeyEvent (map, _keyModifiers)); - _keyHandler (new KeyEvent (map, _keyModifiers)); - _keyUpHandler (new KeyEvent (map, _keyModifiers)); + OnKeyDown (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); + OnKeyUp (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); + OnKeyPressed (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); } break; case NetEvents.EventType.Mouse: - _mouseHandler (ToDriverMouse (inputEvent.MouseEvent)); + OnMouseEvent (new MouseEventEventArgs (ToDriverMouse (inputEvent.MouseEvent))); break; case NetEvents.EventType.WindowSize: _winSizeChanging = true; diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index 97cd384bb8..5a1e3c18c4 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -780,10 +780,6 @@ static extern Coord GetLargestConsoleWindowSize ( internal class WindowsDriver : ConsoleDriver { WindowsConsole.ExtendedCharInfo [] _outputBuffer; WindowsConsole.SmallRect _damageRegion; - Action _keyHandler; - Action _keyDownHandler; - Action _keyUpHandler; - Action _mouseHandler; public WindowsConsole WinConsole { get; private set; } @@ -858,12 +854,8 @@ private static string GetParentProcessName () #pragma warning restore CA1416 // Validate platform compatibility } - internal override void PrepareToRun (Action keyHandler, Action keyDownHandler, Action keyUpHandler, Action mouseHandler) + internal override void PrepareToRun () { - _keyHandler = keyHandler; - _keyDownHandler = keyDownHandler; - _keyUpHandler = keyUpHandler; - _mouseHandler = mouseHandler; #if HACK_CHECK_WINCHANGED _mainLoopDriver.WinChanged = ChangeWin; @@ -974,19 +966,19 @@ internal void ProcessInput (WindowsConsole.InputRecord inputEvent) } if (inputEvent.KeyEvent.bKeyDown) { - _keyDownHandler (key); + OnKeyDown(new KeyEventEventArgs(key)); } else { - _keyUpHandler (key); + OnKeyUp (new KeyEventEventArgs (key)); } } else { if (inputEvent.KeyEvent.bKeyDown) { // May occurs using SendKeys _keyModifiers ??= new KeyModifiers (); - // Key Down - Fire KeyDown Event and KeyStroke (ProcessKey) Event - _keyDownHandler (new KeyEvent (map, _keyModifiers)); - _keyHandler (new KeyEvent (map, _keyModifiers)); + // Key Down - Fire KeyDown Event and KeyPressed Event + OnKeyDown (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); } else { - _keyUpHandler (new KeyEvent (map, _keyModifiers)); + OnKeyUp (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); + OnKeyPressed (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); } } if (!inputEvent.KeyEvent.bKeyDown && inputEvent.KeyEvent.dwControlKeyState == 0) { @@ -996,14 +988,13 @@ internal void ProcessInput (WindowsConsole.InputRecord inputEvent) case WindowsConsole.EventType.Mouse: var me = ToDriverMouse (inputEvent.MouseEvent); - _mouseHandler (me); + OnMouseEvent (new MouseEventEventArgs (me)); if (_processButtonClick) { - _mouseHandler ( - new MouseEvent () { - X = me.X, - Y = me.Y, - Flags = ProcessButtonClick (inputEvent.MouseEvent) - }); + OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = me.X, + Y = me.Y, + Flags = ProcessButtonClick (inputEvent.MouseEvent) + })); } break; @@ -1261,7 +1252,7 @@ async Task ProcessContinuousButtonPressedAsync (MouseFlags mouseFlag) break; } if (_isButtonPressed && (mouseFlag & MouseFlags.ReportMousePosition) == 0) { - Application.Invoke (() => _mouseHandler (me)); + Application.Invoke (() => OnMouseEvent (new MouseEventEventArgs(me))); } } } diff --git a/Terminal.Gui/Input/Event.cs b/Terminal.Gui/Input/Event.cs index a46bbf7e53..995e463cf6 100644 --- a/Terminal.Gui/Input/Event.cs +++ b/Terminal.Gui/Input/Event.cs @@ -766,12 +766,14 @@ public enum MouseFlags { AllEvents = unchecked((int)0x7ffffff), } + // TODO: Merge MouseEvent and MouseEventEventArgs into a single class. + /// /// Low-level construct that conveys the details of mouse events, such /// as coordinates and button state, from ConsoleDrivers up to and /// Views. /// - /// The class includes the + /// The class includes the /// Action which takes a MouseEvent argument. public class MouseEvent { /// diff --git a/Terminal.Gui/Input/MouseEventEventArgs.cs b/Terminal.Gui/Input/MouseEventEventArgs.cs index 4f58274652..5df8b4b00d 100644 --- a/Terminal.Gui/Input/MouseEventEventArgs.cs +++ b/Terminal.Gui/Input/MouseEventEventArgs.cs @@ -12,6 +12,8 @@ public class MouseEventEventArgs : EventArgs { /// /// The mouse event. public MouseEventEventArgs (MouseEvent me) => MouseEvent = me; + + // TODO: Merge MouseEvent and MouseEventEventArgs into a single class. /// /// The for the event. /// diff --git a/Terminal.Gui/View/ViewKeyboard.cs b/Terminal.Gui/View/ViewKeyboard.cs index 66a2ce491f..421f941621 100644 --- a/Terminal.Gui/View/ViewKeyboard.cs +++ b/Terminal.Gui/View/ViewKeyboard.cs @@ -163,7 +163,7 @@ public bool TabStop { /// /// Invoked when a character key is pressed and occurs after the key up event. /// - public event EventHandler KeyPress; + public event EventHandler KeyPressed; /// public override bool ProcessKey (KeyEvent keyEvent) @@ -173,11 +173,11 @@ public override bool ProcessKey (KeyEvent keyEvent) } var args = new KeyEventEventArgs (keyEvent); - KeyPress?.Invoke (this, args); + KeyPressed?.Invoke (this, args); if (args.Handled) return true; if (Focused?.Enabled == true) { - Focused?.KeyPress?.Invoke (this, args); + Focused?.KeyPressed?.Invoke (this, args); if (args.Handled) return true; } @@ -348,7 +348,7 @@ public override bool ProcessHotKey (KeyEvent keyEvent) var args = new KeyEventEventArgs (keyEvent); if (MostFocused?.Enabled == true) { - MostFocused?.KeyPress?.Invoke (this, args); + MostFocused?.KeyPressed?.Invoke (this, args); if (args.Handled) return true; } @@ -371,11 +371,11 @@ public override bool ProcessColdKey (KeyEvent keyEvent) } var args = new KeyEventEventArgs (keyEvent); - KeyPress?.Invoke (this, args); + KeyPressed?.Invoke (this, args); if (args.Handled) return true; if (MostFocused?.Enabled == true) { - MostFocused?.KeyPress?.Invoke (this, args); + MostFocused?.KeyPressed?.Invoke (this, args); if (args.Handled) return true; } diff --git a/Terminal.Gui/Views/Button.cs b/Terminal.Gui/Views/Button.cs index 7af58684fe..5cd1605dd9 100644 --- a/Terminal.Gui/Views/Button.cs +++ b/Terminal.Gui/Views/Button.cs @@ -10,11 +10,11 @@ namespace Terminal.Gui { /// - /// Button is a that provides an item that invokes an when activated by the user. + /// Button is a that provides an item that invokes raises the event. /// /// /// - /// Provides a button showing text invokes an when clicked on with a mouse + /// Provides a button showing text that raises the event when clicked on with a mouse /// or when the user presses SPACE, ENTER, or hotkey. The hotkey is the first letter or digit following the first underscore ('_') /// in the button text. /// @@ -27,7 +27,7 @@ namespace Terminal.Gui { /// /// When the button is configured as the default () and the user presses /// the ENTER key, if no other processes the , the 's - /// will be invoked. + /// event will will be fired. /// /// public class Button : View { @@ -258,7 +258,7 @@ public virtual void OnClicked () } /// - /// Clicked , raised when the user clicks the primary mouse button within the Bounds of this + /// The event fired when the user clicks the primary mouse button within the Bounds of this /// or if the user presses the action key while this view is focused. (TODO: IsDefault) /// /// diff --git a/Terminal.Gui/Views/FileDialog.cs b/Terminal.Gui/Views/FileDialog.cs index c727b71a2d..725bbfa86d 100644 --- a/Terminal.Gui/Views/FileDialog.cs +++ b/Terminal.Gui/Views/FileDialog.cs @@ -145,7 +145,7 @@ public FileDialog (IFileSystem fileSystem) X = Pos.Function (CalculateOkButtonPosX) }; this.btnOk.Clicked += (s, e) => this.Accept (true); - this.btnOk.KeyPress += (s, k) => { + this.btnOk.KeyPressed += (s, k) => { this.NavigateIf (k, Key.CursorLeft, this.btnCancel); this.NavigateIf (k, Key.CursorUp, this.tableView); }; @@ -154,7 +154,7 @@ public FileDialog (IFileSystem fileSystem) Y = Pos.AnchorEnd (1), X = Pos.Right (btnOk) + 1 }; - this.btnCancel.KeyPress += (s, k) => { + this.btnCancel.KeyPressed += (s, k) => { this.NavigateIf (k, Key.CursorLeft, this.btnToggleSplitterCollapse); this.NavigateIf (k, Key.CursorUp, this.tableView); this.NavigateIf (k, Key.CursorRight, this.btnOk); @@ -179,7 +179,7 @@ public FileDialog (IFileSystem fileSystem) Width = Dim.Fill (0), CaptionColor = new Color (Color.Black) }; - this.tbPath.KeyPress += (s, k) => { + this.tbPath.KeyPressed += (s, k) => { ClearFeedback (); @@ -228,7 +228,7 @@ public FileDialog (IFileSystem fileSystem) typeStyle.MinWidth = 6; typeStyle.ColorGetter = this.ColorGetter; - this.tableView.KeyPress += (s, k) => { + this.tableView.KeyPressed += (s, k) => { if (this.tableView.SelectedRow <= 0) { this.NavigateIf (k, Key.CursorUp, this.tbPath); } @@ -285,7 +285,7 @@ public FileDialog (IFileSystem fileSystem) }; tbFind.TextChanged += (s, o) => RestartSearch (); - tbFind.KeyPress += (s, o) => { + tbFind.KeyPressed += (s, o) => { if (o.KeyEvent.Key == Key.Enter) { RestartSearch (); o.Handled = true; diff --git a/Terminal.Gui/Views/Label.cs b/Terminal.Gui/Views/Label.cs index 9ea34be11d..29b476fb77 100644 --- a/Terminal.Gui/Views/Label.cs +++ b/Terminal.Gui/Views/Label.cs @@ -65,7 +65,7 @@ void SetInitialProperties (bool autosize = true) } /// - /// Clicked , raised when the user clicks the primary mouse button within the Bounds of this + /// The event fired when the user clicks the primary mouse button within the Bounds of this /// or if the user presses the action key while this view is focused. (TODO: IsDefault) /// /// diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs index 74f0229de4..7c16edc534 100644 --- a/Terminal.Gui/Views/Menu.cs +++ b/Terminal.Gui/Views/Menu.cs @@ -484,7 +484,7 @@ public Menu (MenuBar host, int x, int y, MenuBarItem barItems, Menu parent = nul Application.Current.DrawContentComplete += Current_DrawContentComplete; Application.Current.SizeChanging += Current_TerminalResized; } - Application.RootMouseEvent += Application_RootMouseEvent; + Application.MouseEvent += Application_RootMouseEvent; // Things this view knows how to do AddCommand (Command.LineUp, () => MoveUp ()); @@ -523,15 +523,15 @@ public override void OnVisibleChanged () { base.OnVisibleChanged (); if (Visible) { - Application.RootMouseEvent += Application_RootMouseEvent; + Application.MouseEvent += Application_RootMouseEvent; } else { - Application.RootMouseEvent -= Application_RootMouseEvent; + Application.MouseEvent -= Application_RootMouseEvent; } } - private void Application_RootMouseEvent (MouseEvent me) + private void Application_RootMouseEvent (object sender, MouseEventEventArgs a) { - if (me.View is MenuBar) { + if (a.MouseEvent.View is MenuBar) { return; } var locationOffset = host.GetScreenOffsetFromCurrent (); @@ -539,7 +539,7 @@ private void Application_RootMouseEvent (MouseEvent me) locationOffset.X += SuperView.Border.Thickness.Left; locationOffset.Y += SuperView.Border.Thickness.Top; } - var view = View.FindDeepestView (this, me.X + locationOffset.X, me.Y + locationOffset.Y, out int rx, out int ry); + var view = View.FindDeepestView (this, a.MouseEvent.X + locationOffset.X, a.MouseEvent.Y + locationOffset.Y, out int rx, out int ry); if (view == this) { if (!Visible) { throw new InvalidOperationException ("This shouldn't running on a invisible menu!"); @@ -548,11 +548,11 @@ private void Application_RootMouseEvent (MouseEvent me) var nme = new MouseEvent () { X = rx, Y = ry, - Flags = me.Flags, + Flags = a.MouseEvent.Flags, View = view }; - if (MouseEvent (nme) || me.Flags == MouseFlags.Button1Pressed || me.Flags == MouseFlags.Button1Released) { - me.Handled = true; + if (MouseEvent (nme) || a.MouseEvent.Flags == MouseFlags.Button1Pressed || a.MouseEvent.Flags == MouseFlags.Button1Released) { + a.MouseEvent.Handled = true; } } } @@ -987,7 +987,7 @@ protected override void Dispose (bool disposing) Application.Current.DrawContentComplete -= Current_DrawContentComplete; Application.Current.SizeChanging -= Current_TerminalResized; } - Application.RootMouseEvent -= Application_RootMouseEvent; + Application.MouseEvent -= Application_RootMouseEvent; base.Dispose (disposing); } } diff --git a/Terminal.Gui/Views/TableView/TreeTableSource.cs b/Terminal.Gui/Views/TableView/TreeTableSource.cs index 9a8b088660..0b06691fd0 100644 --- a/Terminal.Gui/Views/TableView/TreeTableSource.cs +++ b/Terminal.Gui/Views/TableView/TreeTableSource.cs @@ -38,7 +38,7 @@ public TreeTableSource (TableView table, string firstColumnName, TreeView tre { _tableView = table; _tree = tree; - _tableView.KeyPress += Table_KeyPress; + _tableView.KeyPressed += Table_KeyPress; _tableView.MouseClick += Table_MouseClick; var colList = subsequentColumns.Keys.ToList (); @@ -68,7 +68,7 @@ public TreeTableSource (TableView table, string firstColumnName, TreeView tre /// public void Dispose () { - _tableView.KeyPress -= Table_KeyPress; + _tableView.KeyPressed -= Table_KeyPress; _tableView.MouseClick -= Table_MouseClick; _tree.Dispose (); } diff --git a/Terminal.Gui/Views/ToplevelOverlapped.cs b/Terminal.Gui/Views/ToplevelOverlapped.cs index 1c95d66477..e1e56e4de0 100644 --- a/Terminal.Gui/Views/ToplevelOverlapped.cs +++ b/Terminal.Gui/Views/ToplevelOverlapped.cs @@ -30,7 +30,7 @@ public static List OverlappedChildren { get { if (OverlappedTop != null) { List _overlappedChildren = new List (); - foreach (var top in _toplevels) { + foreach (var top in _topLevels) { if (top != OverlappedTop && !top.Modal) { _overlappedChildren.Add (top); } @@ -71,9 +71,9 @@ static View FindDeepestOverlappedView (View start, int x, int y, out int resx, o return null; } - int count = _toplevels.Count; + int count = _topLevels.Count; for (int i = count - 1; i >= 0; i--) { - foreach (var top in _toplevels) { + foreach (var top in _topLevels) { var rx = x - startFrame.X; var ry = y - startFrame.Y; if (top.Visible && top.Frame.Contains (rx, ry)) { @@ -96,7 +96,7 @@ static bool OverlappedChildNeedsDisplay () return false; } - foreach (var top in _toplevels) { + foreach (var top in _topLevels) { if (top != Current && top.Visible && (top.NeedsDisplay || top.SubViewNeedsDisplay || top.LayoutNeeded)) { OverlappedTop.SetSubViewNeedsDisplay (); return true; @@ -124,19 +124,19 @@ static bool SetCurrentOverlappedAsTop () public static void OverlappedMoveNext () { if (OverlappedTop != null && !Current.Modal) { - lock (_toplevels) { - _toplevels.MoveNext (); + lock (_topLevels) { + _topLevels.MoveNext (); var isOverlapped = false; - while (_toplevels.Peek () == OverlappedTop || !_toplevels.Peek ().Visible) { - if (!isOverlapped && _toplevels.Peek () == OverlappedTop) { + while (_topLevels.Peek () == OverlappedTop || !_topLevels.Peek ().Visible) { + if (!isOverlapped && _topLevels.Peek () == OverlappedTop) { isOverlapped = true; - } else if (isOverlapped && _toplevels.Peek () == OverlappedTop) { + } else if (isOverlapped && _topLevels.Peek () == OverlappedTop) { MoveCurrent (Top); break; } - _toplevels.MoveNext (); + _topLevels.MoveNext (); } - Current = _toplevels.Peek (); + Current = _topLevels.Peek (); } } } @@ -147,19 +147,19 @@ public static void OverlappedMoveNext () public static void OverlappedMovePrevious () { if (OverlappedTop != null && !Current.Modal) { - lock (_toplevels) { - _toplevels.MovePrevious (); + lock (_topLevels) { + _topLevels.MovePrevious (); var isOverlapped = false; - while (_toplevels.Peek () == OverlappedTop || !_toplevels.Peek ().Visible) { - if (!isOverlapped && _toplevels.Peek () == OverlappedTop) { + while (_topLevels.Peek () == OverlappedTop || !_topLevels.Peek ().Visible) { + if (!isOverlapped && _topLevels.Peek () == OverlappedTop) { isOverlapped = true; - } else if (isOverlapped && _toplevels.Peek () == OverlappedTop) { + } else if (isOverlapped && _topLevels.Peek () == OverlappedTop) { MoveCurrent (Top); break; } - _toplevels.MovePrevious (); + _topLevels.MovePrevious (); } - Current = _toplevels.Peek (); + Current = _topLevels.Peek (); } } } @@ -172,8 +172,8 @@ public static void OverlappedMovePrevious () public static bool MoveToOverlappedChild (Toplevel top) { if (top.Visible && OverlappedTop != null && Current?.Modal == false) { - lock (_toplevels) { - _toplevels.MoveTo (top, 0, new ToplevelEqualityComparer ()); + lock (_topLevels) { + _topLevels.MoveTo (top, 0, new ToplevelEqualityComparer ()); Current = top; } return true; diff --git a/UICatalog/KeyBindingsDialog.cs b/UICatalog/KeyBindingsDialog.cs index efce13b427..538320f383 100644 --- a/UICatalog/KeyBindingsDialog.cs +++ b/UICatalog/KeyBindingsDialog.cs @@ -180,7 +180,7 @@ private void RemapKey (object sender, EventArgs e) // prompt user to hit a key var dlg = new Dialog () { Title = "Enter Key" }; - dlg.KeyPress += (s, k) => { + dlg.KeyPressed += (s, k) => { key = k.KeyEvent.Key; Application.RequestStop (); }; diff --git a/UICatalog/Scenarios/ASCIICustomButton.cs b/UICatalog/Scenarios/ASCIICustomButton.cs index 066bc65d24..eabde34c57 100644 --- a/UICatalog/Scenarios/ASCIICustomButton.cs +++ b/UICatalog/Scenarios/ASCIICustomButton.cs @@ -205,7 +205,7 @@ public ScrollViewTestWindow () button.Clicked += Button_Clicked; button.PointerEnter += Button_PointerEnter; button.MouseClick += Button_MouseClick; - button.KeyPress += Button_KeyPress; + button.KeyPressed += Button_KeyPress; scrollView.Add (button); buttons.Add (button); prevButton = button; @@ -215,7 +215,7 @@ public ScrollViewTestWindow () closeButton.Clicked += Button_Clicked; closeButton.PointerEnter += Button_PointerEnter; closeButton.MouseClick += Button_MouseClick; - closeButton.KeyPress += Button_KeyPress; + closeButton.KeyPressed += Button_KeyPress; scrollView.Add (closeButton); buttons.Add (closeButton); diff --git a/UICatalog/Scenarios/BackgroundWorkerCollection.cs b/UICatalog/Scenarios/BackgroundWorkerCollection.cs index fb661153b1..22434aaedf 100644 --- a/UICatalog/Scenarios/BackgroundWorkerCollection.cs +++ b/UICatalog/Scenarios/BackgroundWorkerCollection.cs @@ -56,7 +56,7 @@ public OverlappedMain () Closed += OverlappedMain_Closed; - Application.Iteration += () => { + Application.Iteration += (s, a) => { if (canOpenWorkerApp && !workerApp.Running && Application.OverlappedTop.Running) { Application.Run (workerApp); } @@ -338,7 +338,7 @@ public StagingUIController () close.Clicked += OnReportClosed; Add (close); - KeyPress += (s, e) => { + KeyPressed += (s, e) => { if (e.KeyEvent.Key == Key.Esc) { OnReportClosed (this, EventArgs.Empty); } diff --git a/UICatalog/Scenarios/BasicColors.cs b/UICatalog/Scenarios/BasicColors.cs index 4ca1594a72..e99c88db32 100644 --- a/UICatalog/Scenarios/BasicColors.cs +++ b/UICatalog/Scenarios/BasicColors.cs @@ -86,10 +86,10 @@ public override void Setup () }; Win.Add (viewBackground); - Application.RootMouseEvent = (e) => { - if (e.View != null) { - var fore = e.View.GetNormalColor ().Foreground; - var back = e.View.GetNormalColor ().Background; + Application.MouseEvent += (s, e) => { + if (e.MouseEvent.View != null) { + var fore = e.MouseEvent.View.GetNormalColor ().Foreground; + var back = e.MouseEvent.View.GetNormalColor ().Background; lblForeground.Text = $"#{fore.R:X2}{fore.G:X2}{fore.B:X2} {fore.ColorName} "; viewForeground.ColorScheme.Normal = new Attribute (fore, fore); lblBackground.Text = $"#{back.R:X2}{back.G:X2}{back.B:X2} {back.ColorName} "; diff --git a/UICatalog/Scenarios/ContextMenus.cs b/UICatalog/Scenarios/ContextMenus.cs index b66f482a2b..c39cb248c6 100644 --- a/UICatalog/Scenarios/ContextMenus.cs +++ b/UICatalog/Scenarios/ContextMenus.cs @@ -58,7 +58,7 @@ public override void Setup () Point mousePos = default; - Win.KeyPress += (s, e) => { + Win.KeyPressed += (s, e) => { if (e.KeyEvent.Key == (Key.Space | Key.CtrlMask)) { ShowContextMenu (mousePos.X, mousePos.Y); e.Handled = true; @@ -72,18 +72,18 @@ public override void Setup () } }; - Application.RootMouseEvent += Application_RootMouseEvent; + Application.MouseEvent += ApplicationMouseEvent; - void Application_RootMouseEvent (MouseEvent me) + void ApplicationMouseEvent (object sender, MouseEventEventArgs a) { - mousePos = new Point (me.X, me.Y); + mousePos = new Point (a.MouseEvent.X, a.MouseEvent.Y); } Win.WantMousePositionReports = true; Application.Top.Closed += (s,e) => { Thread.CurrentThread.CurrentUICulture = new CultureInfo ("en-US"); - Application.RootMouseEvent -= Application_RootMouseEvent; + Application.MouseEvent -= ApplicationMouseEvent; }; } diff --git a/UICatalog/Scenarios/CsvEditor.cs b/UICatalog/Scenarios/CsvEditor.cs index 4b3825cec1..96ff667ffe 100644 --- a/UICatalog/Scenarios/CsvEditor.cs +++ b/UICatalog/Scenarios/CsvEditor.cs @@ -88,7 +88,7 @@ public override void Setup () tableView.SelectedCellChanged += OnSelectedCellChanged; tableView.CellActivated += EditCurrentCell; - tableView.KeyPress += TableViewKeyPress; + tableView.KeyPressed += TableViewKeyPress; SetupScrollBar (); } diff --git a/UICatalog/Scenarios/Editor.cs b/UICatalog/Scenarios/Editor.cs index 20552e119d..45c6f704fd 100644 --- a/UICatalog/Scenarios/Editor.cs +++ b/UICatalog/Scenarios/Editor.cs @@ -176,7 +176,7 @@ public override void Init () _scrollBar.Refresh (); }; - Win.KeyPress += (s, e) => { + Win.KeyPressed += (s, e) => { var keys = ShortcutHelper.GetModifiersKey (e.KeyEvent); if (_winDialog != null && (e.KeyEvent.Key == Key.Esc || e.KeyEvent.Key == Application.QuitKey)) { diff --git a/UICatalog/Scenarios/InteractiveTree.cs b/UICatalog/Scenarios/InteractiveTree.cs index 623946437f..26b26d1fde 100644 --- a/UICatalog/Scenarios/InteractiveTree.cs +++ b/UICatalog/Scenarios/InteractiveTree.cs @@ -30,7 +30,7 @@ public override void Setup () Width = Dim.Fill (), Height = Dim.Fill (1), }; - treeView.KeyPress += TreeView_KeyPress; + treeView.KeyPressed += TreeView_KeyPress; Win.Add (treeView); diff --git a/UICatalog/Scenarios/Keys.cs b/UICatalog/Scenarios/Keys.cs index a1bb15f2bf..6594daa07c 100644 --- a/UICatalog/Scenarios/Keys.cs +++ b/UICatalog/Scenarios/Keys.cs @@ -3,7 +3,7 @@ using Terminal.Gui; namespace UICatalog.Scenarios { - [ScenarioMetadata (Name: "Keys", Description: "Shows how to handle keyboard input")] + [ScenarioMetadata (Name: "Keys", Description: "Shows keyboard input handling.")] [ScenarioCategory ("Mouse and Keyboard")] public class Keys : Scenario { @@ -37,7 +37,7 @@ public override void Init () Application.Init (); ConfigurationManager.Themes.Theme = Theme; ConfigurationManager.Apply (); - + Win = new TestWindow () { Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}", X = 0, @@ -65,7 +65,7 @@ public override void Setup () Win.Add (edit); // Last KeyPress: ______ - var keyPressedLabel = new Label ("Last KeyPress:") { + var keyPressedLabel = new Label ("Last Application.KeyPress:") { X = Pos.Left (editLabel), Y = Pos.Top (editLabel) + 2, }; @@ -79,10 +79,10 @@ public override void Setup () }; Win.Add (labelKeypress); - Win.KeyPress += (s,e) => labelKeypress.Text = e.KeyEvent.ToString (); + Win.KeyPressed += (s, e) => labelKeypress.Text = e.KeyEvent.ToString (); // Key stroke log: - var keyLogLabel = new Label ("Key stroke log:") { + var keyLogLabel = new Label ("Key event log:") { X = Pos.Left (editLabel), Y = Pos.Top (editLabel) + 4, }; @@ -94,19 +94,19 @@ public override void Setup () }); var maxLogEntry = $"Key{"",-5}: {fakeKeyPress}".Length; var yOffset = (Application.Top == Application.Top ? 1 : 6); - var keyStrokelist = new List (); - var keyStrokeListView = new ListView (keyStrokelist) { + var keyEventlist = new List (); + var keyEventListView = new ListView (keyEventlist) { X = 0, Y = Pos.Top (keyLogLabel) + yOffset, Width = Dim.Percent (30), Height = Dim.Fill (), }; - keyStrokeListView.ColorScheme = Colors.TopLevel; - Win.Add (keyStrokeListView); + keyEventListView.ColorScheme = Colors.TopLevel; + Win.Add (keyEventListView); // ProcessKey log: var processKeyLogLabel = new Label ("ProcessKey log:") { - X = Pos.Right (keyStrokeListView) + 1, + X = Pos.Right (keyEventListView) + 1, Y = Pos.Top (editLabel) + 4, }; Win.Add (processKeyLogLabel); @@ -116,7 +116,7 @@ public override void Setup () var processKeyListView = new ListView (((TestWindow)Win)._processKeyList) { X = Pos.Left (processKeyLogLabel), Y = Pos.Top (processKeyLogLabel) + yOffset, - Width = Dim.Percent(30), + Width = Dim.Percent (30), Height = Dim.Fill (), }; processKeyListView.ColorScheme = Colors.TopLevel; @@ -156,15 +156,16 @@ public override void Setup () Height = Dim.Fill (), }; - Win.KeyDown += (s,a) => KeyDownPressUp (a.KeyEvent, "Down"); - Win.KeyPress += (s, a) => KeyDownPressUp (a.KeyEvent, "Press"); - Win.KeyUp += (s, a) => KeyDownPressUp (a.KeyEvent, "Up"); + Application.KeyDown += (s, a) => KeyDownPressUp (a, "Down"); + Application.KeyPressed += (s, a) => KeyDownPressUp (a, "Press"); + Application.KeyUp += (s, a) => KeyDownPressUp (a, "Up"); - void KeyDownPressUp (KeyEvent keyEvent, string updown) + void KeyDownPressUp (KeyEventEventArgs args, string updown) { - var msg = $"Key{updown,-5}: {keyEvent}"; - keyStrokelist.Add (msg); - keyStrokeListView.MoveDown (); + // BUGBUG: KeyEvent.ToString is badly broken + var msg = $"Key{updown,-5}: {args.KeyEvent}"; + keyEventlist.Add (msg); + keyEventListView.MoveDown (); processKeyListView.MoveDown (); processColdKeyListView.MoveDown (); processHotKeyListView.MoveDown (); diff --git a/UICatalog/Scenarios/LineDrawing.cs b/UICatalog/Scenarios/LineDrawing.cs index 295fe67a1c..45de71facb 100644 --- a/UICatalog/Scenarios/LineDrawing.cs +++ b/UICatalog/Scenarios/LineDrawing.cs @@ -32,7 +32,7 @@ public override void Setup () Win.Add (canvas); Win.Add (tools); - Win.KeyPress += (s,e) => { e.Handled = canvas.ProcessKey (e.KeyEvent); }; + Win.KeyPressed += (s,e) => { e.Handled = canvas.ProcessKey (e.KeyEvent); }; } class ToolsView : Window { diff --git a/UICatalog/Scenarios/ListColumns.cs b/UICatalog/Scenarios/ListColumns.cs index 96ebafd429..c3c38f0695 100644 --- a/UICatalog/Scenarios/ListColumns.cs +++ b/UICatalog/Scenarios/ListColumns.cs @@ -101,7 +101,7 @@ public override void Setup () Win.Add (selectedCellLabel); listColView.SelectedCellChanged += (s, e) => { selectedCellLabel.Text = $"{listColView.SelectedRow},{listColView.SelectedColumn}"; }; - listColView.KeyPress += TableViewKeyPress; + listColView.KeyPressed += TableViewKeyPress; SetupScrollBar (); diff --git a/UICatalog/Scenarios/Mouse.cs b/UICatalog/Scenarios/Mouse.cs index 52c01ae6d6..05f722c5af 100644 --- a/UICatalog/Scenarios/Mouse.cs +++ b/UICatalog/Scenarios/Mouse.cs @@ -27,9 +27,9 @@ public override void Setup () }; Win.Add (rmeList); - Application.RootMouseEvent += delegate (MouseEvent me) { - ml.Text = $"Mouse: ({me.X},{me.Y}) - {me.Flags} {count}"; - rme.Add ($"({me.X},{me.Y}) - {me.Flags} {count++}"); + Application.MouseEvent += (sender, a) => { + ml.Text = $"Mouse: ({a.MouseEvent.X},{a.MouseEvent.Y}) - {a.MouseEvent.Flags} {count}"; + rme.Add ($"({a.MouseEvent.X},{a.MouseEvent.Y}) - {a.MouseEvent.Flags} {count++}"); rmeList.MoveDown (); }; diff --git a/UICatalog/Scenarios/Scrolling.cs b/UICatalog/Scenarios/Scrolling.cs index 48b2d75fb5..e021c56764 100644 --- a/UICatalog/Scenarios/Scrolling.cs +++ b/UICatalog/Scenarios/Scrolling.cs @@ -291,8 +291,8 @@ void Top_Loaded (object sender, EventArgs args) Width = 50, }; Win.Add (mousePos); - Application.RootMouseEvent += delegate (MouseEvent me) { - mousePos.Text = $"Mouse: ({me.X},{me.Y}) - {me.Flags} {count++}"; + Application.MouseEvent += (sender, a) => { + mousePos.Text = $"Mouse: ({a.MouseEvent.X},{a.MouseEvent.Y}) - {a.MouseEvent.Flags} {count++}"; }; var progress = new ProgressBar { diff --git a/UICatalog/Scenarios/SendKeys.cs b/UICatalog/Scenarios/SendKeys.cs index 9aebec6576..dd9eef8ddd 100644 --- a/UICatalog/Scenarios/SendKeys.cs +++ b/UICatalog/Scenarios/SendKeys.cs @@ -57,7 +57,7 @@ public override void Setup () var IsAlt = false; var IsCtrl = false; - txtResult.KeyPress += (s, e) => { + txtResult.KeyPressed += (s, e) => { rKeys += (char)e.KeyEvent.Key; if (!IsShift && e.KeyEvent.IsShift) { rControlKeys += " Shift "; @@ -116,7 +116,7 @@ void ProcessInput () button.Clicked += (s,e) => ProcessInput (); - Win.KeyPress += (s, e) => { + Win.KeyPressed += (s, e) => { if (e.KeyEvent.Key == Key.Enter) { ProcessInput (); e.Handled = true; diff --git a/UICatalog/Scenarios/SingleBackgroundWorker.cs b/UICatalog/Scenarios/SingleBackgroundWorker.cs index 3318f2ea69..80b3693e65 100644 --- a/UICatalog/Scenarios/SingleBackgroundWorker.cs +++ b/UICatalog/Scenarios/SingleBackgroundWorker.cs @@ -133,7 +133,7 @@ public class StagingUIController : Window { public StagingUIController (DateTime? start, List list) { top = new Toplevel (Application.Top.Frame); - top.KeyPress += (s,e) => { + top.KeyPressed += (s,e) => { // Prevents Ctrl+Q from closing this. // Only Ctrl+C is allowed. if (e.KeyEvent.Key == Application.QuitKey) { diff --git a/UICatalog/Scenarios/TableEditor.cs b/UICatalog/Scenarios/TableEditor.cs index f710a79240..bf477e8eac 100644 --- a/UICatalog/Scenarios/TableEditor.cs +++ b/UICatalog/Scenarios/TableEditor.cs @@ -122,7 +122,7 @@ public override void Setup () tableView.SelectedCellChanged += (s, e) => { selectedCellLabel.Text = $"{tableView.SelectedRow},{tableView.SelectedColumn}"; }; tableView.CellActivated += EditCurrentCell; - tableView.KeyPress += TableViewKeyPress; + tableView.KeyPressed += TableViewKeyPress; SetupScrollBar (); diff --git a/UICatalog/Scenarios/TreeViewFileSystem.cs b/UICatalog/Scenarios/TreeViewFileSystem.cs index 87906d243d..7e4c722426 100644 --- a/UICatalog/Scenarios/TreeViewFileSystem.cs +++ b/UICatalog/Scenarios/TreeViewFileSystem.cs @@ -95,7 +95,7 @@ public override void Setup () Win.Add (_detailsFrame); treeViewFiles.MouseClick += TreeViewFiles_MouseClick; - treeViewFiles.KeyPress += TreeViewFiles_KeyPress; + treeViewFiles.KeyPressed += TreeViewFiles_KeyPress; treeViewFiles.SelectionChanged += TreeViewFiles_SelectionChanged; SetupFileTree (); diff --git a/UICatalog/Scenarios/TrueColors.cs b/UICatalog/Scenarios/TrueColors.cs index c2f15d5e9a..9cd6189619 100644 --- a/UICatalog/Scenarios/TrueColors.cs +++ b/UICatalog/Scenarios/TrueColors.cs @@ -82,9 +82,9 @@ public override void Setup () }; Win.Add (lblBlue); - Application.RootMouseEvent = (e) => { - if (e.View != null) { - var normal = e.View.GetNormalColor (); + Application.MouseEvent += (s, e) => { + if (e.MouseEvent.View != null) { + var normal = e.MouseEvent.View.GetNormalColor (); lblRed.Text = normal.Foreground.R.ToString (); lblGreen.Text = normal.Foreground.G.ToString (); lblBlue.Text = normal.Foreground.B.ToString (); diff --git a/UICatalog/Scenarios/VkeyPacketSimulator.cs b/UICatalog/Scenarios/VkeyPacketSimulator.cs index 1153887ba5..f1d940f6e6 100644 --- a/UICatalog/Scenarios/VkeyPacketSimulator.cs +++ b/UICatalog/Scenarios/VkeyPacketSimulator.cs @@ -96,7 +96,7 @@ public override void Setup () } }; - tvOutput.KeyPress += (s, e) => { + tvOutput.KeyPressed += (s, e) => { //System.Diagnostics.Debug.WriteLine ($"Output - KeyPress - _keyboardStrokes: {_keyboardStrokes.Count}"); if (_outputStarted && _keyboardStrokes.Count > 0) { var ev = ShortcutHelper.GetModifiersKey (e.KeyEvent); @@ -124,7 +124,7 @@ public override void Setup () KeyEventEventArgs unknownChar = null; - tvInput.KeyPress += (s, e) => { + tvInput.KeyPressed += (s, e) => { if (e.KeyEvent.Key == (Key.Q | Key.CtrlMask)) { Application.RequestStop (); return; diff --git a/UnitTests/Application/ApplicationTests.cs b/UnitTests/Application/ApplicationTests.cs index b019ab9946..5dca0018c8 100644 --- a/UnitTests/Application/ApplicationTests.cs +++ b/UnitTests/Application/ApplicationTests.cs @@ -9,1019 +9,1003 @@ // Alias Console to MockConsole so we don't accidentally use Console using Console = Terminal.Gui.FakeConsole; -namespace Terminal.Gui.ApplicationTests { - public class ApplicationTests { - public ApplicationTests () - { +namespace Terminal.Gui.ApplicationTests; + +public class ApplicationTests { + public ApplicationTests () + { #if DEBUG_IDISPOSABLE - Responder.Instances.Clear (); - RunState.Instances.Clear (); + Responder.Instances.Clear (); + RunState.Instances.Clear (); #endif - } + } - void Pre_Init_State () - { - Assert.Null (Application.Driver); - Assert.Null (Application.Top); - Assert.Null (Application.Current); - Assert.Null (Application.MainLoop); - Assert.Null (Application.Iteration); - Assert.Null (Application.RootMouseEvent); - } + void Pre_Init_State () + { + Assert.Null (Application.Driver); + Assert.Null (Application.Top); + Assert.Null (Application.Current); + Assert.Null (Application.MainLoop); + } - void Post_Init_State () - { - Assert.NotNull (Application.Driver); - Assert.NotNull (Application.Top); - Assert.NotNull (Application.Current); - Assert.NotNull (Application.MainLoop); - Assert.Null (Application.Iteration); - Assert.Null (Application.RootMouseEvent); - // FakeDriver is always 80x25 - Assert.Equal (80, Application.Driver.Cols); - Assert.Equal (25, Application.Driver.Rows); + void Post_Init_State () + { + Assert.NotNull (Application.Driver); + Assert.NotNull (Application.Top); + Assert.NotNull (Application.Current); + Assert.NotNull (Application.MainLoop); + // FakeDriver is always 80x25 + Assert.Equal (80, Application.Driver.Cols); + Assert.Equal (25, Application.Driver.Rows); - } + } - void Init () - { - Application.Init (new FakeDriver ()); - Assert.NotNull (Application.Driver); - Assert.NotNull (Application.MainLoop); - Assert.NotNull (SynchronizationContext.Current); - } + void Init () + { + Application.Init (new FakeDriver ()); + Assert.NotNull (Application.Driver); + Assert.NotNull (Application.MainLoop); + Assert.NotNull (SynchronizationContext.Current); + } - void Shutdown () - { - Application.Shutdown (); - } + void Shutdown () + { + Application.Shutdown (); + } - [Fact] - public void Init_Shutdown_Cleans_Up () - { - // Verify initial state is per spec - //Pre_Init_State (); + [Fact] + public void Init_Shutdown_Cleans_Up () + { + // Verify initial state is per spec + //Pre_Init_State (); - Application.Init (new FakeDriver ()); + Application.Init (new FakeDriver ()); - // Verify post-Init state is correct - //Post_Init_State (); + // Verify post-Init state is correct + //Post_Init_State (); - Application.Shutdown (); + Application.Shutdown (); - // Verify state is back to initial - //Pre_Init_State (); + // Verify state is back to initial + //Pre_Init_State (); #if DEBUG_IDISPOSABLE - // Validate there are no outstanding Responder-based instances - // after a scenario was selected to run. This proves the main UI Catalog - // 'app' closed cleanly. - //foreach (var inst in Responder.Instances) { - //Assert.True (inst.WasDisposed); - //} + // Validate there are no outstanding Responder-based instances + // after a scenario was selected to run. This proves the main UI Catalog + // 'app' closed cleanly. + //foreach (var inst in Responder.Instances) { + //Assert.True (inst.WasDisposed); + //} #endif - } + } - [Fact] - public void Init_Unbalanced_Throws () - { - Application.Init (new FakeDriver ()); + [Fact] + public void Init_Unbalanced_Throws () + { + Application.Init (new FakeDriver ()); - Toplevel topLevel = null; - Assert.Throws (() => Application.InternalInit (() => topLevel = new TestToplevel (), new FakeDriver ())); - Shutdown (); + Toplevel topLevel = null; + Assert.Throws (() => Application.InternalInit (() => topLevel = new TestToplevel (), new FakeDriver ())); + Shutdown (); - Assert.Null (Application.Top); - Assert.Null (Application.MainLoop); - Assert.Null (Application.Driver); + Assert.Null (Application.Top); + Assert.Null (Application.MainLoop); + Assert.Null (Application.Driver); - // Now try the other way - topLevel = null; - Application.InternalInit (() => topLevel = new TestToplevel (), new FakeDriver ()); + // Now try the other way + topLevel = null; + Application.InternalInit (() => topLevel = new TestToplevel (), new FakeDriver ()); - Assert.Throws (() => Application.Init (new FakeDriver ())); - Shutdown (); + Assert.Throws (() => Application.Init (new FakeDriver ())); + Shutdown (); - Assert.Null (Application.Top); - Assert.Null (Application.MainLoop); - Assert.Null (Application.Driver); - } + Assert.Null (Application.Top); + Assert.Null (Application.MainLoop); + Assert.Null (Application.Driver); + } - class TestToplevel : Toplevel { - public TestToplevel () - { - IsOverlappedContainer = false; - } + class TestToplevel : Toplevel { + public TestToplevel () + { + IsOverlappedContainer = false; } + } - [Fact] - public void Init_Null_Driver_Should_Pick_A_Driver () - { - Application.Init (null); + [Fact] + public void Init_Null_Driver_Should_Pick_A_Driver () + { + Application.Init (null); - Assert.NotNull (Application.Driver); + Assert.NotNull (Application.Driver); - Shutdown (); - } + Shutdown (); + } - [Fact] - public void Init_Begin_End_Cleans_Up () - { - Init (); + [Fact] + public void Init_Begin_End_Cleans_Up () + { + Init (); + + // Begin will cause Run() to be called, which will call Begin(). Thus will block the tests + // if we don't stop + Application.Iteration += (s, a) => { + Application.RequestStop (); + }; + + RunState runstate = null; + EventHandler NewRunStateFn = (s, e) => { + Assert.NotNull (e.State); + runstate = e.State; + }; + Application.NotifyNewRunState += NewRunStateFn; + + Toplevel topLevel = new Toplevel (); + var rs = Application.Begin (topLevel); + Assert.NotNull (rs); + Assert.NotNull (runstate); + Assert.Equal (rs, runstate); + + Assert.Equal (topLevel, Application.Top); + Assert.Equal (topLevel, Application.Current); + + Application.NotifyNewRunState -= NewRunStateFn; + Application.End (runstate); + + Assert.Null (Application.Current); + Assert.NotNull (Application.Top); + Assert.NotNull (Application.MainLoop); + Assert.NotNull (Application.Driver); + + Shutdown (); + + Assert.Null (Application.Top); + Assert.Null (Application.MainLoop); + Assert.Null (Application.Driver); + } - // Begin will cause Run() to be called, which will call Begin(). Thus will block the tests - // if we don't stop - Application.Iteration = () => { - Application.RequestStop (); - }; + [Fact] + public void InitWithTopLevelFactory_Begin_End_Cleans_Up () + { + // Begin will cause Run() to be called, which will call Begin(). Thus will block the tests + // if we don't stop + Application.Iteration += (s, a) => { + Application.RequestStop (); + }; + + // NOTE: Run, when called after Init has been called behaves differently than + // when called if Init has not been called. + Toplevel topLevel = null; + Application.InternalInit (() => topLevel = new TestToplevel (), new FakeDriver ()); + + RunState runstate = null; + EventHandler NewRunStateFn = (s, e) => { + Assert.NotNull (e.State); + runstate = e.State; + }; + Application.NotifyNewRunState += NewRunStateFn; + + var rs = Application.Begin (topLevel); + Assert.NotNull (rs); + Assert.NotNull (runstate); + Assert.Equal (rs, runstate); + + Assert.Equal (topLevel, Application.Top); + Assert.Equal (topLevel, Application.Current); + + Application.NotifyNewRunState -= NewRunStateFn; + Application.End (runstate); + + Assert.Null (Application.Current); + Assert.NotNull (Application.Top); + Assert.NotNull (Application.MainLoop); + Assert.NotNull (Application.Driver); + + Shutdown (); + + Assert.Null (Application.Top); + Assert.Null (Application.MainLoop); + Assert.Null (Application.Driver); + } - RunState runstate = null; - EventHandler NewRunStateFn = (s, e) => { - Assert.NotNull (e.State); - runstate = e.State; - }; - Application.NotifyNewRunState += NewRunStateFn; + [Fact] + public void Begin_Null_Toplevel_Throws () + { + // Setup Mock driver + Init (); - Toplevel topLevel = new Toplevel (); - var rs = Application.Begin (topLevel); - Assert.NotNull (rs); - Assert.NotNull (runstate); - Assert.Equal (rs, runstate); + // Test null Toplevel + Assert.Throws (() => Application.Begin (null)); - Assert.Equal (topLevel, Application.Top); - Assert.Equal (topLevel, Application.Current); + Shutdown (); - Application.NotifyNewRunState -= NewRunStateFn; - Application.End (runstate); + Assert.Null (Application.Top); + Assert.Null (Application.MainLoop); + Assert.Null (Application.Driver); + } - Assert.Null (Application.Current); - Assert.NotNull (Application.Top); - Assert.NotNull (Application.MainLoop); - Assert.NotNull (Application.Driver); + #region RunTests - Shutdown (); + [Fact] + public void Run_T_After_InitWithDriver_with_TopLevel_Throws () + { + // Setup Mock driver + Init (); - Assert.Null (Application.Top); - Assert.Null (Application.MainLoop); - Assert.Null (Application.Driver); - } + // Run when already initialized with a Driver will throw (because Toplevel is not dervied from TopLevel) + Assert.Throws (() => Application.Run (errorHandler: null)); - [Fact] - public void InitWithTopLevelFactory_Begin_End_Cleans_Up () - { - // Begin will cause Run() to be called, which will call Begin(). Thus will block the tests - // if we don't stop - Application.Iteration = () => { - Application.RequestStop (); - }; + Shutdown (); - // NOTE: Run, when called after Init has been called behaves differently than - // when called if Init has not been called. - Toplevel topLevel = null; - Application.InternalInit (() => topLevel = new TestToplevel (), new FakeDriver ()); + Assert.Null (Application.Top); + Assert.Null (Application.MainLoop); + Assert.Null (Application.Driver); + } - RunState runstate = null; - EventHandler NewRunStateFn = (s, e) => { - Assert.NotNull (e.State); - runstate = e.State; - }; - Application.NotifyNewRunState += NewRunStateFn; + [Fact] + public void Run_T_After_InitWithDriver_with_TopLevel_and_Driver_Throws () + { + // Setup Mock driver + Init (); - var rs = Application.Begin (topLevel); - Assert.NotNull (rs); - Assert.NotNull (runstate); - Assert.Equal (rs, runstate); + // Run when already initialized with a Driver will throw (because Toplevel is not dervied from TopLevel) + Assert.Throws (() => Application.Run (errorHandler: null, new FakeDriver ())); - Assert.Equal (topLevel, Application.Top); - Assert.Equal (topLevel, Application.Current); + Shutdown (); - Application.NotifyNewRunState -= NewRunStateFn; - Application.End (runstate); + Assert.Null (Application.Top); + Assert.Null (Application.MainLoop); + Assert.Null (Application.Driver); + } - Assert.Null (Application.Current); - Assert.NotNull (Application.Top); - Assert.NotNull (Application.MainLoop); - Assert.NotNull (Application.Driver); + [Fact] + public void Run_T_After_InitWithDriver_with_TestTopLevel_DoesNotThrow () + { + // Setup Mock driver + Init (); - Shutdown (); + Application.Iteration += (s, a) => { + Application.RequestStop (); + }; - Assert.Null (Application.Top); - Assert.Null (Application.MainLoop); - Assert.Null (Application.Driver); - } + // Init has been called and we're passing no driver to Run. This is ok. + Application.Run (); - [Fact] - public void Begin_Null_Toplevel_Throws () - { - // Setup Mock driver - Init (); + Shutdown (); - // Test null Toplevel - Assert.Throws (() => Application.Begin (null)); + Assert.Null (Application.Top); + Assert.Null (Application.MainLoop); + Assert.Null (Application.Driver); + } - Shutdown (); + [Fact] + public void Run_T_After_InitNullDriver_with_TestTopLevel_Throws () + { + Application._forceFakeConsole = true; - Assert.Null (Application.Top); - Assert.Null (Application.MainLoop); - Assert.Null (Application.Driver); - } + Application.Init (null); + Assert.Equal (typeof (FakeDriver), Application.Driver.GetType ()); - #region RunTests + Application.Iteration += (s, a) => { + Application.RequestStop (); + }; - [Fact] - public void Run_T_After_InitWithDriver_with_TopLevel_Throws () - { - // Setup Mock driver - Init (); + // Init has been called without selecting a driver and we're passing no driver to Run. Bad + Application.Run (); - // Run when already initialized with a Driver will throw (because Toplevel is not dervied from TopLevel) - Assert.Throws (() => Application.Run (errorHandler: null)); + Shutdown (); - Shutdown (); + Assert.Null (Application.Top); + Assert.Null (Application.MainLoop); + Assert.Null (Application.Driver); + } - Assert.Null (Application.Top); - Assert.Null (Application.MainLoop); - Assert.Null (Application.Driver); - } + [Fact] + public void Run_T_Init_Driver_Cleared_with_TestTopLevel_Throws () + { + Init (); - [Fact] - public void Run_T_After_InitWithDriver_with_TopLevel_and_Driver_Throws () - { - // Setup Mock driver - Init (); + Application.Driver = null; - // Run when already initialized with a Driver will throw (because Toplevel is not dervied from TopLevel) - Assert.Throws (() => Application.Run (errorHandler: null, new FakeDriver ())); + Application.Iteration += (s, a) => { + Application.RequestStop (); + }; - Shutdown (); + // Init has been called, but Driver has been set to null. Bad. + Assert.Throws (() => Application.Run ()); - Assert.Null (Application.Top); - Assert.Null (Application.MainLoop); - Assert.Null (Application.Driver); - } + Shutdown (); - [Fact] - public void Run_T_After_InitWithDriver_with_TestTopLevel_DoesNotThrow () - { - // Setup Mock driver - Init (); + Assert.Null (Application.Top); + Assert.Null (Application.MainLoop); + Assert.Null (Application.Driver); + } - Application.Iteration = () => { - Application.RequestStop (); - }; + [Fact] + public void Run_T_NoInit_DoesNotThrow () + { + Application._forceFakeConsole = true; - // Init has been called and we're passing no driver to Run. This is ok. - Application.Run (); + Application.Iteration += (s, a) => { + Application.RequestStop (); + }; - Shutdown (); + Application.Run (); + Assert.Equal (typeof (FakeDriver), Application.Driver.GetType ()); - Assert.Null (Application.Top); - Assert.Null (Application.MainLoop); - Assert.Null (Application.Driver); - } + Shutdown (); - [Fact] - public void Run_T_After_InitNullDriver_with_TestTopLevel_Throws () - { - Application._forceFakeConsole = true; + Assert.Null (Application.Top); + Assert.Null (Application.MainLoop); + Assert.Null (Application.Driver); + } - Application.Init (null); - Assert.Equal (typeof (FakeDriver), Application.Driver.GetType ()); + [Fact] + public void Run_T_NoInit_WithDriver_DoesNotThrow () + { + Application.Iteration += (s, a) => { + Application.RequestStop (); + }; - Application.Iteration = () => { - Application.RequestStop (); - }; + // Init has NOT been called and we're passing a valid driver to Run. This is ok. + Application.Run (errorHandler: null, new FakeDriver ()); - // Init has been called without selecting a driver and we're passing no driver to Run. Bad - Application.Run (); + Shutdown (); - Shutdown (); + Assert.Null (Application.Top); + Assert.Null (Application.MainLoop); + Assert.Null (Application.Driver); + } - Assert.Null (Application.Top); - Assert.Null (Application.MainLoop); - Assert.Null (Application.Driver); - } + [Fact] + public void Run_RequestStop_Stops () + { + // Setup Mock driver + Init (); - [Fact] - public void Run_T_Init_Driver_Cleared_with_TestTopLevel_Throws () - { - Init (); + var top = new Toplevel (); + var rs = Application.Begin (top); + Assert.NotNull (rs); + Assert.Equal (top, Application.Current); - Application.Driver = null; + Application.Iteration += (s, a) => { + Application.RequestStop (); + }; - Application.Iteration = () => { - Application.RequestStop (); - }; + Application.Run (top); - // Init has been called, but Driver has been set to null. Bad. - Assert.Throws (() => Application.Run ()); + Application.Shutdown (); + Assert.Null (Application.Current); + Assert.Null (Application.Top); + Assert.Null (Application.MainLoop); + Assert.Null (Application.Driver); + } - Shutdown (); + [Fact] + public void Run_RunningFalse_Stops () + { + // Setup Mock driver + Init (); - Assert.Null (Application.Top); - Assert.Null (Application.MainLoop); - Assert.Null (Application.Driver); - } + var top = new Toplevel (); + var rs = Application.Begin (top); + Assert.NotNull (rs); + Assert.Equal (top, Application.Current); - [Fact] - public void Run_T_NoInit_DoesNotThrow () - { - Application._forceFakeConsole = true; + Application.Iteration += (s, a) => { + top.Running = false; + }; - Application.Iteration = () => { - Application.RequestStop (); - }; + Application.Run (top); - Application.Run (); - Assert.Equal (typeof (FakeDriver), Application.Driver.GetType ()); + Application.Shutdown (); + Assert.Null (Application.Current); + Assert.Null (Application.Top); + Assert.Null (Application.MainLoop); + Assert.Null (Application.Driver); + } - Shutdown (); + [Fact] + public void Run_Loaded_Ready_Unlodaded_Events () + { + Init (); + var top = Application.Top; + var count = 0; + top.Loaded += (s, e) => count++; + top.Ready += (s, e) => count++; + top.Unloaded += (s, e) => count++; + Application.Iteration += (s, a) => Application.RequestStop (); + Application.Run (); + Application.Shutdown (); + Assert.Equal (3, count); + } - Assert.Null (Application.Top); - Assert.Null (Application.MainLoop); - Assert.Null (Application.Driver); - } + // TODO: Add tests for Run that test errorHandler - [Fact] - public void Run_T_NoInit_WithDriver_DoesNotThrow () + #endregion + + #region ShutdownTests + [Fact] + public void Shutdown_Allows_Async () + { + static async Task TaskWithAsyncContinuation () { - Application.Iteration = () => { - Application.RequestStop (); - }; + await Task.Yield (); + await Task.Yield (); + } + + Init (); + Application.Shutdown (); - // Init has NOT been called and we're passing a valid driver to Run. This is ok. - Application.Run (errorHandler: null, new FakeDriver ()); + var task = TaskWithAsyncContinuation (); + Thread.Sleep (20); + Assert.True (task.IsCompletedSuccessfully); + } - Shutdown (); + [Fact] + public void Shutdown_Resets_SyncContext () + { + Init (); + Application.Shutdown (); + Assert.Null (SynchronizationContext.Current); + } + #endregion + + [Fact, AutoInitShutdown] + public void Begin_Sets_Application_Top_To_Console_Size () + { + Assert.Equal (new Rect (0, 0, 80, 25), Application.Top.Frame); + + ((FakeDriver)Application.Driver).SetBufferSize (5, 5); + Application.Begin (Application.Top); + Assert.Equal (new Rect (0, 0, 80, 25), Application.Top.Frame); + ((FakeDriver)Application.Driver).SetBufferSize (5, 5); + Assert.Equal (new Rect (0, 0, 5, 5), Application.Top.Frame); + } - Assert.Null (Application.Top); - Assert.Null (Application.MainLoop); - Assert.Null (Application.Driver); - } + [Fact] + [AutoInitShutdown] + public void SetCurrentAsTop_Run_A_Not_Modal_Toplevel_Make_It_The_Current_Application_Top () + { + var t1 = new Toplevel (); + var t2 = new Toplevel (); + var t3 = new Toplevel (); + var d = new Dialog (); + var t4 = new Toplevel (); - [Fact] - public void Run_RequestStop_Stops () - { - // Setup Mock driver - Init (); + // t1, t2, t3, d, t4 + var iterations = 5; + + t1.Ready += (s, e) => { + Assert.Equal (t1, Application.Top); + Application.Run (t2); + }; + t2.Ready += (s, e) => { + Assert.Equal (t2, Application.Top); + Application.Run (t3); + }; + t3.Ready += (s, e) => { + Assert.Equal (t3, Application.Top); + Application.Run (d); + }; + d.Ready += (s, e) => { + Assert.Equal (t3, Application.Top); + Application.Run (t4); + }; + t4.Ready += (s, e) => { + Assert.Equal (t4, Application.Top); + t4.RequestStop (); + d.RequestStop (); + t3.RequestStop (); + t2.RequestStop (); + }; + // Now this will close the OverlappedContainer when all OverlappedChildren was closed + t2.Closed += (s, _) => { + t1.RequestStop (); + }; + Application.Iteration += (s, a) => { + if (iterations == 5) { + // The Current still is t4 because Current.Running is false. + Assert.Equal (t4, Application.Current); + Assert.False (Application.Current.Running); + Assert.Equal (t4, Application.Top); + } else if (iterations == 4) { + // The Current is d and Current.Running is false. + Assert.Equal (d, Application.Current); + Assert.False (Application.Current.Running); + Assert.Equal (t4, Application.Top); + } else if (iterations == 3) { + // The Current is t3 and Current.Running is false. + Assert.Equal (t3, Application.Current); + Assert.False (Application.Current.Running); + Assert.Equal (t3, Application.Top); + } else if (iterations == 2) { + // The Current is t2 and Current.Running is false. + Assert.Equal (t2, Application.Current); + Assert.False (Application.Current.Running); + Assert.Equal (t2, Application.Top); + } else { + // The Current is t1. + Assert.Equal (t1, Application.Current); + Assert.False (Application.Current.Running); + Assert.Equal (t1, Application.Top); + } + iterations--; + }; - var top = new Toplevel (); - var rs = Application.Begin (top); - Assert.NotNull (rs); - Assert.Equal (top, Application.Current); + Application.Run (t1); - Application.Iteration = () => { - Application.RequestStop (); - }; + Assert.Equal (t1, Application.Top); + } - Application.Run (top); + [Fact] + [AutoInitShutdown] + public void Internal_Properties_Correct () + { + Assert.True (Application._initialized); + Assert.NotNull (Application.Top); + var rs = Application.Begin (Application.Top); + Assert.Equal (Application.Top, rs.Toplevel); + Assert.Null (Application.MouseGrabView); // public + Assert.Null (Application.WantContinuousButtonPressedView); // public + Assert.False (Application.MoveToOverlappedChild (Application.Top)); + } - Application.Shutdown (); - Assert.Null (Application.Current); - Assert.Null (Application.Top); - Assert.Null (Application.MainLoop); - Assert.Null (Application.Driver); + #region KeyboardTests + [Fact] + public void KeyUp_Event () + { + // Setup Mock driver + Init (); + + // Setup some fake keypresses (This) + var input = "Tests"; + + // Put a control-q in at the end + FakeConsole.MockKeyPresses.Push (new ConsoleKeyInfo ('q', ConsoleKey.Q, shift: false, alt: false, control: true)); + foreach (var c in input.Reverse ()) { + if (char.IsLetter (c)) { + FakeConsole.MockKeyPresses.Push (new ConsoleKeyInfo (c, (ConsoleKey)char.ToUpper (c), shift: char.IsUpper (c), alt: false, control: false)); + } else { + FakeConsole.MockKeyPresses.Push (new ConsoleKeyInfo (c, (ConsoleKey)c, shift: false, alt: false, control: false)); + } } - [Fact] - public void Run_RunningFalse_Stops () - { - // Setup Mock driver - Init (); + int stackSize = FakeConsole.MockKeyPresses.Count; - var top = new Toplevel (); - var rs = Application.Begin (top); - Assert.NotNull (rs); - Assert.Equal (top, Application.Current); + int iterations = 0; + Application.Iteration += (s, a) => { + iterations++; + // Stop if we run out of control... + if (iterations > 10) { + Application.RequestStop (); + } + }; - Application.Iteration = () => { - top.Running = false; - }; + int keyUps = 0; + var output = string.Empty; + Application.Top.KeyUp += (object sender, KeyEventEventArgs args) => { + if (args.KeyEvent.Key != (Key.CtrlMask | Key.Q)) { + output += (char)args.KeyEvent.KeyValue; + } + keyUps++; + }; - Application.Run (top); + Application.Run (Application.Top); - Application.Shutdown (); - Assert.Null (Application.Current); - Assert.Null (Application.Top); - Assert.Null (Application.MainLoop); - Assert.Null (Application.Driver); - } + // Input string should match output + Assert.Equal (input, output); - [Fact] - public void Run_Loaded_Ready_Unlodaded_Events () - { - Init (); - var top = Application.Top; - var count = 0; - top.Loaded += (s, e) => count++; - top.Ready += (s, e) => count++; - top.Unloaded += (s, e) => count++; - Application.Iteration = () => Application.RequestStop (); - Application.Run (); - Application.Shutdown (); - Assert.Equal (3, count); - } + // # of key up events should match stack size + //Assert.Equal (stackSize, keyUps); + // We can't use numbers variables on the left side of an Assert.Equal/NotEqual, + // it must be literal (Linux only). + Assert.Equal (6, keyUps); - // TODO: Add tests for Run that test errorHandler + // # of key up events should match # of iterations + Assert.Equal (stackSize, iterations); - #endregion + Application.Shutdown (); + Assert.Null (Application.Current); + Assert.Null (Application.Top); + Assert.Null (Application.MainLoop); + Assert.Null (Application.Driver); + } - #region ShutdownTests - [Fact] - public void Shutdown_Allows_Async () - { - static async Task TaskWithAsyncContinuation () - { - await Task.Yield (); - await Task.Yield (); - } + [Fact] + public void AlternateForwardKey_AlternateBackwardKey_Tests () + { + Init (); + + var top = Application.Top; + var w1 = new Window (); + var v1 = new TextField (); + var v2 = new TextView (); + w1.Add (v1, v2); + + var w2 = new Window (); + var v3 = new CheckBox (); + var v4 = new Button (); + w2.Add (v3, v4); + + top.Add (w1, w2); + + Application.Iteration += (s, a) => { + Assert.True (v1.HasFocus); + // Using default keys. + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, + new KeyModifiers () { Ctrl = true })); + Assert.True (v2.HasFocus); + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, + new KeyModifiers () { Ctrl = true })); + Assert.True (v3.HasFocus); + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, + new KeyModifiers () { Ctrl = true })); + Assert.True (v4.HasFocus); + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, + new KeyModifiers () { Ctrl = true })); + Assert.True (v1.HasFocus); + + top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, + new KeyModifiers () { Shift = true, Ctrl = true })); + Assert.True (v4.HasFocus); + top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, + new KeyModifiers () { Shift = true, Ctrl = true })); + Assert.True (v3.HasFocus); + top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, + new KeyModifiers () { Shift = true, Ctrl = true })); + Assert.True (v2.HasFocus); + top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, + new KeyModifiers () { Shift = true, Ctrl = true })); + Assert.True (v1.HasFocus); + + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown, + new KeyModifiers () { Ctrl = true })); + Assert.True (v2.HasFocus); + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown, + new KeyModifiers () { Ctrl = true })); + Assert.True (v3.HasFocus); + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown, + new KeyModifiers () { Ctrl = true })); + Assert.True (v4.HasFocus); + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown, + new KeyModifiers () { Ctrl = true })); + Assert.True (v1.HasFocus); + + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp, + new KeyModifiers () { Ctrl = true })); + Assert.True (v4.HasFocus); + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp, + new KeyModifiers () { Ctrl = true })); + Assert.True (v3.HasFocus); + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp, + new KeyModifiers () { Ctrl = true })); + Assert.True (v2.HasFocus); + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp, + new KeyModifiers () { Ctrl = true })); + Assert.True (v1.HasFocus); + + // Using another's alternate keys. + Application.AlternateForwardKey = Key.F7; + Application.AlternateBackwardKey = Key.F6; + + top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ())); + Assert.True (v2.HasFocus); + top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ())); + Assert.True (v3.HasFocus); + top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ())); + Assert.True (v4.HasFocus); + top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ())); + Assert.True (v1.HasFocus); + + top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ())); + Assert.True (v4.HasFocus); + top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ())); + Assert.True (v3.HasFocus); + top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ())); + Assert.True (v2.HasFocus); + top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ())); + Assert.True (v1.HasFocus); + + Application.RequestStop (); + }; + + Application.Run (top); + + // Replacing the defaults keys to avoid errors on others unit tests that are using it. + Application.AlternateForwardKey = Key.PageDown | Key.CtrlMask; + Application.AlternateBackwardKey = Key.PageUp | Key.CtrlMask; + Application.QuitKey = Key.Q | Key.CtrlMask; + + Assert.Equal (Key.PageDown | Key.CtrlMask, Application.AlternateForwardKey); + Assert.Equal (Key.PageUp | Key.CtrlMask, Application.AlternateBackwardKey); + Assert.Equal (Key.Q | Key.CtrlMask, Application.QuitKey); + + // Shutdown must be called to safely clean up Application if Init has been called + Application.Shutdown (); + } - Init (); - Application.Shutdown (); + [Fact] + [AutoInitShutdown] + public void QuitKey_Getter_Setter () + { + var top = Application.Top; + var isQuiting = false; - var task = TaskWithAsyncContinuation (); - Thread.Sleep (20); - Assert.True (task.IsCompletedSuccessfully); - } + top.Closing += (s, e) => { + isQuiting = true; + e.Cancel = true; + }; - [Fact] - public void Shutdown_Resets_SyncContext () - { - Init (); - Application.Shutdown (); - Assert.Null (SynchronizationContext.Current); - } - #endregion + Application.Begin (top); + top.Running = true; - [Fact, AutoInitShutdown] - public void Begin_Sets_Application_Top_To_Console_Size () - { - Assert.Equal (new Rect (0, 0, 80, 25), Application.Top.Frame); + Assert.Equal (Key.Q | Key.CtrlMask, Application.QuitKey); + Application.Driver.SendKeys ('q', ConsoleKey.Q, false, false, true); + Assert.True (isQuiting); - ((FakeDriver)Application.Driver).SetBufferSize (5, 5); - Application.Begin (Application.Top); - Assert.Equal (new Rect (0, 0, 80, 25), Application.Top.Frame); - ((FakeDriver)Application.Driver).SetBufferSize (5, 5); - Assert.Equal (new Rect (0, 0, 5, 5), Application.Top.Frame); - } + isQuiting = false; + Application.QuitKey = Key.C | Key.CtrlMask; - [Fact] - [AutoInitShutdown] - public void SetCurrentAsTop_Run_A_Not_Modal_Toplevel_Make_It_The_Current_Application_Top () - { - var t1 = new Toplevel (); - var t2 = new Toplevel (); - var t3 = new Toplevel (); - var d = new Dialog (); - var t4 = new Toplevel (); + Application.Driver.SendKeys ('q', ConsoleKey.Q, false, false, true); + Assert.False (isQuiting); + Application.Driver.SendKeys ('c', ConsoleKey.C, false, false, true); + Assert.True (isQuiting); - // t1, t2, t3, d, t4 - var iterations = 5; + // Reset the QuitKey to avoid throws errors on another tests + Application.QuitKey = Key.Q | Key.CtrlMask; + } - t1.Ready += (s, e) => { - Assert.Equal (t1, Application.Top); - Application.Run (t2); - }; - t2.Ready += (s, e) => { - Assert.Equal (t2, Application.Top); - Application.Run (t3); - }; - t3.Ready += (s, e) => { - Assert.Equal (t3, Application.Top); - Application.Run (d); - }; - d.Ready += (s, e) => { - Assert.Equal (t3, Application.Top); - Application.Run (t4); - }; - t4.Ready += (s, e) => { - Assert.Equal (t4, Application.Top); - t4.RequestStop (); - d.RequestStop (); - t3.RequestStop (); - t2.RequestStop (); - }; - // Now this will close the OverlappedContainer when all OverlappedChildren was closed - t2.Closed += (s, _) => { - t1.RequestStop (); - }; - Application.Iteration += () => { - if (iterations == 5) { - // The Current still is t4 because Current.Running is false. - Assert.Equal (t4, Application.Current); - Assert.False (Application.Current.Running); - Assert.Equal (t4, Application.Top); - } else if (iterations == 4) { - // The Current is d and Current.Running is false. - Assert.Equal (d, Application.Current); - Assert.False (Application.Current.Running); - Assert.Equal (t4, Application.Top); - } else if (iterations == 3) { - // The Current is t3 and Current.Running is false. - Assert.Equal (t3, Application.Current); - Assert.False (Application.Current.Running); - Assert.Equal (t3, Application.Top); - } else if (iterations == 2) { - // The Current is t2 and Current.Running is false. - Assert.Equal (t2, Application.Current); - Assert.False (Application.Current.Running); - Assert.Equal (t2, Application.Top); - } else { - // The Current is t1. - Assert.Equal (t1, Application.Current); - Assert.False (Application.Current.Running); - Assert.Equal (t1, Application.Top); - } - iterations--; - }; - - Application.Run (t1); + [Fact] + [AutoInitShutdown] + public void EnsuresTopOnFront_CanFocus_True_By_Keyboard_And_Mouse () + { + var top = Application.Top; + var win = new Window () { Title = "win", X = 0, Y = 0, Width = 20, Height = 10 }; + var tf = new TextField () { Width = 10 }; + win.Add (tf); + var win2 = new Window () { Title = "win2", X = 22, Y = 0, Width = 20, Height = 10 }; + var tf2 = new TextField () { Width = 10 }; + win2.Add (tf2); + top.Add (win, win2); + + Application.Begin (top); + + Assert.True (win.CanFocus); + Assert.True (win.HasFocus); + Assert.True (win2.CanFocus); + Assert.False (win2.HasFocus); + Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); + + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); + Assert.True (win.CanFocus); + Assert.False (win.HasFocus); + Assert.True (win2.CanFocus); + Assert.True (win2.HasFocus); + Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); + + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); + Assert.True (win.CanFocus); + Assert.True (win.HasFocus); + Assert.True (win2.CanFocus); + Assert.False (win2.HasFocus); + Assert.Equal ("win", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); + + win2.MouseEvent (new MouseEvent () { Flags = MouseFlags.Button1Pressed }); + Assert.True (win.CanFocus); + Assert.False (win.HasFocus); + Assert.True (win2.CanFocus); + Assert.True (win2.HasFocus); + Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); + win2.MouseEvent (new MouseEvent () { Flags = MouseFlags.Button1Released }); + Assert.Null (Toplevel._dragPosition); + } - Assert.Equal (t1, Application.Top); - } + [Fact] + [AutoInitShutdown] + public void EnsuresTopOnFront_CanFocus_False_By_Keyboard_And_Mouse () + { + var top = Application.Top; + var win = new Window () { Title = "win", X = 0, Y = 0, Width = 20, Height = 10 }; + var tf = new TextField () { Width = 10 }; + win.Add (tf); + var win2 = new Window () { Title = "win2", X = 22, Y = 0, Width = 20, Height = 10 }; + var tf2 = new TextField () { Width = 10 }; + win2.Add (tf2); + top.Add (win, win2); + + Application.Begin (top); + + Assert.True (win.CanFocus); + Assert.True (win.HasFocus); + Assert.True (win2.CanFocus); + Assert.False (win2.HasFocus); + Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); + + win.CanFocus = false; + Assert.False (win.CanFocus); + Assert.False (win.HasFocus); + Assert.True (win2.CanFocus); + Assert.True (win2.HasFocus); + Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); + + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); + Assert.True (win2.CanFocus); + Assert.False (win.HasFocus); + Assert.True (win2.CanFocus); + Assert.True (win2.HasFocus); + Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); + + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); + Assert.False (win.CanFocus); + Assert.False (win.HasFocus); + Assert.True (win2.CanFocus); + Assert.True (win2.HasFocus); + Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); + + win.MouseEvent (new MouseEvent () { Flags = MouseFlags.Button1Pressed }); + Assert.False (win.CanFocus); + Assert.False (win.HasFocus); + Assert.True (win2.CanFocus); + Assert.True (win2.HasFocus); + Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); + win2.MouseEvent (new MouseEvent () { Flags = MouseFlags.Button1Released }); + Assert.Null (Toplevel._dragPosition); + } - [Fact] - [AutoInitShutdown] - public void Internal_Properties_Correct () - { - Assert.True (Application._initialized); - Assert.NotNull (Application.Top); - var rs = Application.Begin (Application.Top); - Assert.Equal (Application.Top, rs.Toplevel); - Assert.Null (Application.MouseGrabView); // public - Assert.Null (Application.WantContinuousButtonPressedView); // public - Assert.False (Application.MoveToOverlappedChild (Application.Top)); - } + #endregion - #region KeyboardTests - [Fact] - public void KeyUp_Event () - { - // Setup Mock driver - Init (); - - // Setup some fake keypresses (This) - var input = "Tests"; - - // Put a control-q in at the end - FakeConsole.MockKeyPresses.Push (new ConsoleKeyInfo ('q', ConsoleKey.Q, shift: false, alt: false, control: true)); - foreach (var c in input.Reverse ()) { - if (char.IsLetter (c)) { - FakeConsole.MockKeyPresses.Push (new ConsoleKeyInfo (c, (ConsoleKey)char.ToUpper (c), shift: char.IsUpper (c), alt: false, control: false)); - } else { - FakeConsole.MockKeyPresses.Push (new ConsoleKeyInfo (c, (ConsoleKey)c, shift: false, alt: false, control: false)); - } - } - int stackSize = FakeConsole.MockKeyPresses.Count; - - int iterations = 0; - Application.Iteration = () => { - iterations++; - // Stop if we run out of control... - if (iterations > 10) { - Application.RequestStop (); - } - }; - - int keyUps = 0; - var output = string.Empty; - Application.Top.KeyUp += (object sender, KeyEventEventArgs args) => { - if (args.KeyEvent.Key != (Key.CtrlMask | Key.Q)) { - output += (char)args.KeyEvent.KeyValue; - } - keyUps++; - }; - - Application.Run (Application.Top); - - // Input string should match output - Assert.Equal (input, output); - - // # of key up events should match stack size - //Assert.Equal (stackSize, keyUps); - // We can't use numbers variables on the left side of an Assert.Equal/NotEqual, - // it must be literal (Linux only). - Assert.Equal (6, keyUps); - - // # of key up events should match # of iterations - Assert.Equal (stackSize, iterations); - - Application.Shutdown (); - Assert.Null (Application.Current); - Assert.Null (Application.Top); - Assert.Null (Application.MainLoop); - Assert.Null (Application.Driver); - } + // Invoke Tests + // TODO: Test with threading scenarios + [Fact] + public void Invoke_Adds_Idle () + { + Application.Init (new FakeDriver ()); + var top = new Toplevel (); + var rs = Application.Begin (top); + bool firstIteration = false; - [Fact] - public void AlternateForwardKey_AlternateBackwardKey_Tests () - { - Init (); - - var top = Application.Top; - var w1 = new Window (); - var v1 = new TextField (); - var v2 = new TextView (); - w1.Add (v1, v2); - - var w2 = new Window (); - var v3 = new CheckBox (); - var v4 = new Button (); - w2.Add (v3, v4); - - top.Add (w1, w2); - - Application.Iteration += () => { - Assert.True (v1.HasFocus); - // Using default keys. - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, - new KeyModifiers () { Ctrl = true })); - Assert.True (v2.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, - new KeyModifiers () { Ctrl = true })); - Assert.True (v3.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, - new KeyModifiers () { Ctrl = true })); - Assert.True (v4.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, - new KeyModifiers () { Ctrl = true })); - Assert.True (v1.HasFocus); - - top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, - new KeyModifiers () { Shift = true, Ctrl = true })); - Assert.True (v4.HasFocus); - top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, - new KeyModifiers () { Shift = true, Ctrl = true })); - Assert.True (v3.HasFocus); - top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, - new KeyModifiers () { Shift = true, Ctrl = true })); - Assert.True (v2.HasFocus); - top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, - new KeyModifiers () { Shift = true, Ctrl = true })); - Assert.True (v1.HasFocus); - - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown, - new KeyModifiers () { Ctrl = true })); - Assert.True (v2.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown, - new KeyModifiers () { Ctrl = true })); - Assert.True (v3.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown, - new KeyModifiers () { Ctrl = true })); - Assert.True (v4.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown, - new KeyModifiers () { Ctrl = true })); - Assert.True (v1.HasFocus); - - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp, - new KeyModifiers () { Ctrl = true })); - Assert.True (v4.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp, - new KeyModifiers () { Ctrl = true })); - Assert.True (v3.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp, - new KeyModifiers () { Ctrl = true })); - Assert.True (v2.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp, - new KeyModifiers () { Ctrl = true })); - Assert.True (v1.HasFocus); - - // Using another's alternate keys. - Application.AlternateForwardKey = Key.F7; - Application.AlternateBackwardKey = Key.F6; - - top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ())); - Assert.True (v2.HasFocus); - top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ())); - Assert.True (v3.HasFocus); - top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ())); - Assert.True (v4.HasFocus); - top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ())); - Assert.True (v1.HasFocus); - - top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ())); - Assert.True (v4.HasFocus); - top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ())); - Assert.True (v3.HasFocus); - top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ())); - Assert.True (v2.HasFocus); - top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ())); - Assert.True (v1.HasFocus); + var actionCalled = 0; + Application.Invoke (() => { actionCalled++; }); + Application.RunIteration (ref rs, ref firstIteration); + Assert.Equal (1, actionCalled); + Application.Shutdown (); + } - Application.RequestStop (); - }; - Application.Run (top); + #region mousegrabtests + [Fact, AutoInitShutdown] + public void MouseGrabView_WithNullMouseEventView () + { + var tf = new TextField () { Width = 10 }; + var sv = new ScrollView () { + Width = Dim.Fill (), + Height = Dim.Fill (), + ContentSize = new Size (100, 100) + }; - // Replacing the defaults keys to avoid errors on others unit tests that are using it. - Application.AlternateForwardKey = Key.PageDown | Key.CtrlMask; - Application.AlternateBackwardKey = Key.PageUp | Key.CtrlMask; - Application.QuitKey = Key.Q | Key.CtrlMask; + sv.Add (tf); + Application.Top.Add (sv); - Assert.Equal (Key.PageDown | Key.CtrlMask, Application.AlternateForwardKey); - Assert.Equal (Key.PageUp | Key.CtrlMask, Application.AlternateBackwardKey); - Assert.Equal (Key.Q | Key.CtrlMask, Application.QuitKey); + var iterations = -1; - // Shutdown must be called to safely clean up Application if Init has been called - Application.Shutdown (); - } + Application.Iteration += (s, a) => { + iterations++; + if (iterations == 0) { + Assert.True (tf.HasFocus); + Assert.Null (Application.MouseGrabView); - [Fact] - [AutoInitShutdown] - public void QuitKey_Getter_Setter () - { - var top = Application.Top; - var isQuiting = false; + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 5, + Y = 5, + Flags = MouseFlags.ReportMousePosition + })); - top.Closing += (s, e) => { - isQuiting = true; - e.Cancel = true; - }; + Assert.Equal (sv, Application.MouseGrabView); - Application.Begin (top); - top.Running = true; + MessageBox.Query ("Title", "Test", "Ok"); - Assert.Equal (Key.Q | Key.CtrlMask, Application.QuitKey); - Application.Driver.SendKeys ('q', ConsoleKey.Q, false, false, true); - Assert.True (isQuiting); + Assert.Null (Application.MouseGrabView); + } else if (iterations == 1) { + // Application.MouseGrabView is null because + // another toplevel (Dialog) was opened + Assert.Null (Application.MouseGrabView); - isQuiting = false; - Application.QuitKey = Key.C | Key.CtrlMask; + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 5, + Y = 5, + Flags = MouseFlags.ReportMousePosition + })); - Application.Driver.SendKeys ('q', ConsoleKey.Q, false, false, true); - Assert.False (isQuiting); - Application.Driver.SendKeys ('c', ConsoleKey.C, false, false, true); - Assert.True (isQuiting); + Assert.Null (Application.MouseGrabView); - // Reset the QuitKey to avoid throws errors on another tests - Application.QuitKey = Key.Q | Key.CtrlMask; - } + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 40, + Y = 12, + Flags = MouseFlags.ReportMousePosition + })); - [Fact] - [AutoInitShutdown] - public void EnsuresTopOnFront_CanFocus_True_By_Keyboard_And_Mouse () - { - var top = Application.Top; - var win = new Window () { Title = "win", X = 0, Y = 0, Width = 20, Height = 10 }; - var tf = new TextField () { Width = 10 }; - win.Add (tf); - var win2 = new Window () { Title = "win2", X = 22, Y = 0, Width = 20, Height = 10 }; - var tf2 = new TextField () { Width = 10 }; - win2.Add (tf2); - top.Add (win, win2); - - Application.Begin (top); - - Assert.True (win.CanFocus); - Assert.True (win.HasFocus); - Assert.True (win2.CanFocus); - Assert.False (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); - Assert.True (win.CanFocus); - Assert.False (win.HasFocus); - Assert.True (win2.CanFocus); - Assert.True (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); - Assert.True (win.CanFocus); - Assert.True (win.HasFocus); - Assert.True (win2.CanFocus); - Assert.False (win2.HasFocus); - Assert.Equal ("win", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - - win2.MouseEvent (new MouseEvent () { Flags = MouseFlags.Button1Pressed }); - Assert.True (win.CanFocus); - Assert.False (win.HasFocus); - Assert.True (win2.CanFocus); - Assert.True (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - win2.MouseEvent (new MouseEvent () { Flags = MouseFlags.Button1Released }); - Assert.Null (Toplevel._dragPosition); - } + Assert.Null (Application.MouseGrabView); - [Fact] - [AutoInitShutdown] - public void EnsuresTopOnFront_CanFocus_False_By_Keyboard_And_Mouse () - { - var top = Application.Top; - var win = new Window () { Title = "win", X = 0, Y = 0, Width = 20, Height = 10 }; - var tf = new TextField () { Width = 10 }; - win.Add (tf); - var win2 = new Window () { Title = "win2", X = 22, Y = 0, Width = 20, Height = 10 }; - var tf2 = new TextField () { Width = 10 }; - win2.Add (tf2); - top.Add (win, win2); - - Application.Begin (top); - - Assert.True (win.CanFocus); - Assert.True (win.HasFocus); - Assert.True (win2.CanFocus); - Assert.False (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - - win.CanFocus = false; - Assert.False (win.CanFocus); - Assert.False (win.HasFocus); - Assert.True (win2.CanFocus); - Assert.True (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); - Assert.True (win2.CanFocus); - Assert.False (win.HasFocus); - Assert.True (win2.CanFocus); - Assert.True (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); - Assert.False (win.CanFocus); - Assert.False (win.HasFocus); - Assert.True (win2.CanFocus); - Assert.True (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - - win.MouseEvent (new MouseEvent () { Flags = MouseFlags.Button1Pressed }); - Assert.False (win.CanFocus); - Assert.False (win.HasFocus); - Assert.True (win2.CanFocus); - Assert.True (win2.HasFocus); - Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - win2.MouseEvent (new MouseEvent () { Flags = MouseFlags.Button1Released }); - Assert.Null (Toplevel._dragPosition); - } + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 0, + Y = 0, + Flags = MouseFlags.Button1Pressed + })); - #endregion + Assert.Null (Application.MouseGrabView); + Application.RequestStop (); + } else if (iterations == 2) { + Assert.Null (Application.MouseGrabView); - // Invoke Tests - // TODO: Test with threading scenarios - [Fact] - public void Invoke_Adds_Idle () - { - Application.Init (new FakeDriver ()); - var top = new Toplevel (); - var rs = Application.Begin (top); - bool firstIteration = false; - - var actionCalled = 0; - Application.Invoke (() => { actionCalled++; }); - Application.RunIteration (ref rs, ref firstIteration); - Assert.Equal (1, actionCalled); - Application.Shutdown (); - } + Application.RequestStop (); + } + }; + + Application.Run (); + } + [Fact, AutoInitShutdown] + public void MouseGrabView_GrabbedMouse_UnGrabbedMouse () + { + View grabView = null; + var count = 0; + + var view1 = new View (); + var view2 = new View (); + + Application.GrabbedMouse += Application_GrabbedMouse; + Application.UnGrabbedMouse += Application_UnGrabbedMouse; + + Application.GrabMouse (view1); + Assert.Equal (0, count); + Assert.Equal (grabView, view1); + Assert.Equal (view1, Application.MouseGrabView); + + Application.UngrabMouse (); + Assert.Equal (1, count); + Assert.Equal (grabView, view1); + Assert.Null (Application.MouseGrabView); + + Application.GrabbedMouse += Application_GrabbedMouse; + Application.UnGrabbedMouse += Application_UnGrabbedMouse; + + Application.GrabMouse (view2); + Assert.Equal (1, count); + Assert.Equal (grabView, view2); + Assert.Equal (view2, Application.MouseGrabView); + + Application.UngrabMouse (); + Assert.Equal (2, count); + Assert.Equal (grabView, view2); + Assert.Null (Application.MouseGrabView); + + void Application_GrabbedMouse (object sender, ViewEventArgs e) + { + if (count == 0) { + Assert.Equal (view1, e.View); + grabView = view1; + } else { + Assert.Equal (view2, e.View); + grabView = view2; + } - #region mousegrabtests - [Fact, AutoInitShutdown] - public void MouseGrabView_WithNullMouseEventView () - { - var tf = new TextField () { Width = 10 }; - var sv = new ScrollView () { - Width = Dim.Fill (), - Height = Dim.Fill (), - ContentSize = new Size (100, 100) - }; - - sv.Add (tf); - Application.Top.Add (sv); - - var iterations = -1; - - Application.Iteration = () => { - iterations++; - if (iterations == 0) { - Assert.True (tf.HasFocus); - Assert.Null (Application.MouseGrabView); - - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 5, - Y = 5, - Flags = MouseFlags.ReportMousePosition - }); - - Assert.Equal (sv, Application.MouseGrabView); - - MessageBox.Query ("Title", "Test", "Ok"); - - Assert.Null (Application.MouseGrabView); - } else if (iterations == 1) { - // Application.MouseGrabView is null because - // another toplevel (Dialog) was opened - Assert.Null (Application.MouseGrabView); - - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 5, - Y = 5, - Flags = MouseFlags.ReportMousePosition - }); - - Assert.Null (Application.MouseGrabView); - - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 40, - Y = 12, - Flags = MouseFlags.ReportMousePosition - }); - - Assert.Null (Application.MouseGrabView); - - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 0, - Y = 0, - Flags = MouseFlags.Button1Pressed - }); - - Assert.Null (Application.MouseGrabView); - - Application.RequestStop (); - } else if (iterations == 2) { - Assert.Null (Application.MouseGrabView); - - Application.RequestStop (); - } - }; - - Application.Run (); + Application.GrabbedMouse -= Application_GrabbedMouse; } - [Fact, AutoInitShutdown] - public void MouseGrabView_GrabbedMouse_UnGrabbedMouse () + void Application_UnGrabbedMouse (object sender, ViewEventArgs e) { - View grabView = null; - var count = 0; - - var view1 = new View (); - var view2 = new View (); - - Application.GrabbedMouse += Application_GrabbedMouse; - Application.UnGrabbedMouse += Application_UnGrabbedMouse; - - Application.GrabMouse (view1); - Assert.Equal (0, count); - Assert.Equal (grabView, view1); - Assert.Equal (view1, Application.MouseGrabView); - - Application.UngrabMouse (); - Assert.Equal (1, count); - Assert.Equal (grabView, view1); - Assert.Null (Application.MouseGrabView); - - Application.GrabbedMouse += Application_GrabbedMouse; - Application.UnGrabbedMouse += Application_UnGrabbedMouse; - - Application.GrabMouse (view2); - Assert.Equal (1, count); - Assert.Equal (grabView, view2); - Assert.Equal (view2, Application.MouseGrabView); - - Application.UngrabMouse (); - Assert.Equal (2, count); - Assert.Equal (grabView, view2); - Assert.Null (Application.MouseGrabView); - - void Application_GrabbedMouse (object sender, ViewEventArgs e) - { - if (count == 0) { - Assert.Equal (view1, e.View); - grabView = view1; - } else { - Assert.Equal (view2, e.View); - grabView = view2; - } - - Application.GrabbedMouse -= Application_GrabbedMouse; + if (count == 0) { + Assert.Equal (view1, e.View); + Assert.Equal (grabView, e.View); + } else { + Assert.Equal (view2, e.View); + Assert.Equal (grabView, e.View); } + count++; - void Application_UnGrabbedMouse (object sender, ViewEventArgs e) - { - if (count == 0) { - Assert.Equal (view1, e.View); - Assert.Equal (grabView, e.View); - } else { - Assert.Equal (view2, e.View); - Assert.Equal (grabView, e.View); - } - count++; - - Application.UnGrabbedMouse -= Application_UnGrabbedMouse; - } + Application.UnGrabbedMouse -= Application_UnGrabbedMouse; } - #endregion } -} + #endregion +} \ No newline at end of file diff --git a/UnitTests/Application/MainLoopTests.cs b/UnitTests/Application/MainLoopTests.cs index 9bc4236a9c..a3cba7a4e7 100644 --- a/UnitTests/Application/MainLoopTests.cs +++ b/UnitTests/Application/MainLoopTests.cs @@ -683,7 +683,7 @@ public void Mainloop_Invoke_Or_AddIdle_Can_Be_Used_For_Events_Or_Actions (Action var iterations = -1; - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { Assert.Null (btn); diff --git a/UnitTests/Clipboard/ClipboardTests.cs b/UnitTests/Clipboard/ClipboardTests.cs index 7ea0543452..1440780f92 100644 --- a/UnitTests/Clipboard/ClipboardTests.cs +++ b/UnitTests/Clipboard/ClipboardTests.cs @@ -36,7 +36,7 @@ public void Contents_Fake_Gets_Sets () var clipText = "The Contents_Gets_Sets unit test pasted this to the OS clipboard."; Clipboard.Contents = clipText; - Application.Iteration += () => Application.RequestStop (); + Application.Iteration += (s, a) => Application.RequestStop (); Application.Run (); Assert.Equal (clipText, Clipboard.Contents); @@ -53,7 +53,7 @@ public void Contents_Gets_Sets () var clipText = "The Contents_Gets_Sets unit test pasted this to the OS clipboard."; Clipboard.Contents = clipText; - Application.Iteration += () => Application.RequestStop (); + Application.Iteration += (s, a) => Application.RequestStop (); Application.Run (); Assert.Equal (clipText, Clipboard.Contents); @@ -71,7 +71,7 @@ public void Contents_Gets_Sets_When_IsSupportedFalse () var clipText = "The Contents_Gets_Sets unit test pasted this to the OS clipboard."; Clipboard.Contents = clipText; - Application.Iteration += () => Application.RequestStop (); + Application.Iteration += (s, a) => Application.RequestStop (); Application.Run (); Assert.Equal (clipText, Clipboard.Contents); @@ -89,7 +89,7 @@ public void Contents_Fake_Gets_Sets_When_IsSupportedFalse () var clipText = "The Contents_Gets_Sets unit test pasted this to the OS clipboard."; Clipboard.Contents = clipText; - Application.Iteration += () => Application.RequestStop (); + Application.Iteration += (s, a) => Application.RequestStop (); Application.Run (); Assert.Equal (clipText, Clipboard.Contents); @@ -108,7 +108,7 @@ public void TryGetClipboardData_Gets_From_OS_Clipboard () var clipText = "The TryGetClipboardData_Gets_From_OS_Clipboard unit test pasted this to the OS clipboard."; Clipboard.Contents = clipText; - Application.Iteration += () => Application.RequestStop (); + Application.Iteration += (s, a) => Application.RequestStop (); Application.Run (); @@ -128,7 +128,7 @@ public void TrySetClipboardData_Sets_The_OS_Clipboard () if (Clipboard.IsSupported) Assert.True (Clipboard.TrySetClipboardData (clipText)); else Assert.False (Clipboard.TrySetClipboardData (clipText)); - Application.Iteration += () => Application.RequestStop (); + Application.Iteration += (s, a) => Application.RequestStop (); Application.Run (); @@ -150,7 +150,7 @@ public void Contents_Copies_From_OS_Clipboard () var failed = false; var getClipText = ""; - Application.Iteration += () => { + Application.Iteration += (s, a) => { int exitCode = 0; string result = ""; output.WriteLine ($"Pasting to OS clipboard: {clipText}..."); @@ -221,7 +221,7 @@ public void Contents_Pastes_To_OS_Clipboard () var clipReadText = ""; var failed = false; - Application.Iteration += () => { + Application.Iteration += (s, a) => { Clipboard.Contents = clipText; int exitCode = 0; diff --git a/UnitTests/Configuration/ConfigurationMangerTests.cs b/UnitTests/Configuration/ConfigurationMangerTests.cs index c7f6d83daa..5bd36a38cd 100644 --- a/UnitTests/Configuration/ConfigurationMangerTests.cs +++ b/UnitTests/Configuration/ConfigurationMangerTests.cs @@ -3,12 +3,9 @@ using System.IO; using System.Linq; using System.Reflection; -using System.Reflection.Metadata; using System.Text.Json; -using Terminal.Gui; using Xunit; using static Terminal.Gui.ConfigurationManager; -using Attribute = Terminal.Gui.Attribute; namespace Terminal.Gui.ConfigurationTests { public class ConfigurationManagerTests { diff --git a/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs b/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs index 255d393ca3..f36a550b13 100644 --- a/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs +++ b/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs @@ -81,12 +81,12 @@ public void FakeDriver_Only_Sends_Keystrokes_Through_MockKeyPresses (Type driver var count = 0; var wasKeyPressed = false; - view.KeyPress += (s, e) => { + view.KeyPressed += (s, e) => { wasKeyPressed = true; }; top.Add (view); - Application.Iteration += () => { + Application.Iteration += (s, a) => { count++; if (count == 10) Application.RequestStop (); }; @@ -120,7 +120,7 @@ public void FakeDriver_MockKeyPresses (Type driverType) var rText = ""; var idx = 0; - view.KeyPress += (s, e) => { + view.KeyPressed += (s, e) => { Assert.Equal (text [idx], (char)e.KeyEvent.Key); rText += (char)e.KeyEvent.Key; Assert.Equal (rText, text.Substring (0, idx + 1)); @@ -129,7 +129,7 @@ public void FakeDriver_MockKeyPresses (Type driverType) }; top.Add (view); - Application.Iteration += () => { + Application.Iteration += (s, a) => { if (mKeys.Count == 0) Application.RequestStop (); }; @@ -182,7 +182,7 @@ public void FakeDriver_MockKeyPresses (Type driverType) // }; // int iterations = 0; - // Application.Iteration += () => { + // Application.Iteration += (s, a) => { // output.WriteLine ($" iteration {++iterations}"); // if (Console.MockKeyPresses.Count == 0) { diff --git a/UnitTests/ConsoleDrivers/KeyTests.cs b/UnitTests/ConsoleDrivers/KeyTests.cs index 56e6d3c1f3..b7ad45b28c 100644 --- a/UnitTests/ConsoleDrivers/KeyTests.cs +++ b/UnitTests/ConsoleDrivers/KeyTests.cs @@ -208,7 +208,7 @@ public void TestVKPacket (uint unicodeCharacter, bool shift, bool alt, bool cont var top = Application.Top; - top.KeyPress += (s, e) => { + top.KeyPressed += (s, e) => { var after = ShortcutHelper.GetModifiersKey (e.KeyEvent); Assert.Equal (expectedRemapping, after); e.Handled = true; @@ -217,7 +217,7 @@ public void TestVKPacket (uint unicodeCharacter, bool shift, bool alt, bool cont var iterations = -1; - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) Application.Driver.SendKeys ((char)mappedConsoleKey, ConsoleKey.Packet, shift, alt, control); }; diff --git a/UnitTests/Dialogs/DialogTests.cs b/UnitTests/Dialogs/DialogTests.cs index f8d395b507..e01885ef9b 100644 --- a/UnitTests/Dialogs/DialogTests.cs +++ b/UnitTests/Dialogs/DialogTests.cs @@ -148,7 +148,7 @@ public void Location_When_Not_Application_Top_Not_Default () Application.Top.BorderStyle = LineStyle.Double; var iterations = -1; - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { @@ -796,7 +796,7 @@ public void Dialog_Opened_From_Another_Dialog () var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} Ok {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}"; var iterations = -1; - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { Assert.True (btn1.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ()))); @@ -876,7 +876,7 @@ public void Dialog_In_Window_With_Size_One_Button_Aligns () var win = new Window (); int iterations = 0; - Application.Iteration += () => { + Application.Iteration += (s, a) => { if (++iterations > 2) { Application.RequestStop (); } @@ -913,7 +913,7 @@ public void Dialog_In_Window_With_Size_One_Button_Aligns () // ((FakeDriver)Application.Driver).SetBufferSize (20, height); // var win = new Window (); - // Application.Iteration += () => { + // Application.Iteration += (s, a) => { // var dlg = new Dialog ("Test", new Button ("Ok")); // dlg.LayoutComplete += (s, a) => { @@ -946,7 +946,7 @@ public void Dialog_In_Window_With_TexxtField_And_Button_AnchorEnd () var win = new Window (); int iterations = 0; - Application.Iteration += () => { + Application.Iteration += (s, a) => { if (++iterations > 2) { Application.RequestStop (); } diff --git a/UnitTests/Dialogs/MessageBoxTests.cs b/UnitTests/Dialogs/MessageBoxTests.cs index 1a7a1afbdc..624c588058 100644 --- a/UnitTests/Dialogs/MessageBoxTests.cs +++ b/UnitTests/Dialogs/MessageBoxTests.cs @@ -23,7 +23,7 @@ public void Size_Default () Application.Begin (Application.Top); ((FakeDriver)Application.Driver).SetBufferSize (100, 100); - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { @@ -52,7 +52,7 @@ public void Location_Default () Application.Begin (Application.Top); ((FakeDriver)Application.Driver).SetBufferSize (100, 100); - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { @@ -87,7 +87,7 @@ public void Size_Not_Default_No_Message (int height, int width) Application.Begin (Application.Top); ((FakeDriver)Application.Driver).SetBufferSize (100, 100); - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { @@ -121,7 +121,7 @@ public void Size_Not_Default_Message (int height, int width, string message) Application.Begin (Application.Top); ((FakeDriver)Application.Driver).SetBufferSize (100, 100); - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { @@ -155,7 +155,7 @@ public void Size_Not_Default_Message_Button (int height, int width, string messa Application.Begin (Application.Top); ((FakeDriver)Application.Driver).SetBufferSize (100, 100); - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { @@ -179,7 +179,7 @@ public void Size_None_No_Buttons () var iterations = -1; Application.Begin (Application.Top); - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { @@ -219,7 +219,7 @@ public void Size_No_With_Button () ((FakeDriver)Application.Driver).SetBufferSize (40 + 4, 8); - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { @@ -253,7 +253,7 @@ public void Size_Tiny_Fixed_Size () var iterations = -1; Application.Begin (Application.Top); - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { @@ -287,7 +287,7 @@ public void Size_JustBigEnough_Fixed_Size () Application.Begin (Application.Top); var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} Ok {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}"; - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { @@ -320,7 +320,7 @@ public void Message_Long_Without_Spaces_WrapMessage_True () ((FakeDriver)Application.Driver).SetBufferSize (20, 10); var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} btn {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}"; - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { @@ -377,7 +377,7 @@ public void Message_With_Spaces_WrapMessage_True () var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} btn {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}"; - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { @@ -435,7 +435,7 @@ public void Message_Without_Spaces_WrapMessage_False () var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} btn {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}"; - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { @@ -490,7 +490,7 @@ public void Message_With_Spaces_WrapMessage_False () ((FakeDriver)Application.Driver).SetBufferSize (20, 10); var btn = $"{CM.Glyphs.LeftBracket}{CM.Glyphs.LeftDefaultIndicator} btn {CM.Glyphs.RightDefaultIndicator}{CM.Glyphs.RightBracket}"; - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { @@ -552,7 +552,7 @@ public void Message_Empty_Or_A_NewLline_WrapMessagge_True_Or_False (string messa var iterations = -1; Application.Begin (Application.Top); - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { diff --git a/UnitTests/Input/EscSeqUtilsTests.cs b/UnitTests/Input/EscSeqUtilsTests.cs index 9afb3d903f..a7e5c9580a 100644 --- a/UnitTests/Input/EscSeqUtilsTests.cs +++ b/UnitTests/Input/EscSeqUtilsTests.cs @@ -519,14 +519,11 @@ public void DecodeEscSeq_Tests () Application.Top.Add (view); Application.Begin (Application.Top); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 0, - Y = 0, - Flags = 0 - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 0, + Y = 0, + Flags = 0 + })); ClearAll (); cki = new ConsoleKeyInfo [] { @@ -558,18 +555,15 @@ public void DecodeEscSeq_Tests () Assert.Equal (new Point (1, 2), pos); Assert.False (isReq); - Application.Iteration += () => { + Application.Iteration += (s, a) => { if (actionStarted) { // set Application.WantContinuousButtonPressedView to null view.WantContinuousButtonPressed = false; - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 0, - Y = 0, - Flags = 0 - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 0, + Y = 0, + Flags = 0 + })); Application.RequestStop (); } diff --git a/UnitTests/ReflectionTools.cs b/UnitTests/ReflectionTools.cs deleted file mode 100644 index 3f661bc5f2..0000000000 --- a/UnitTests/ReflectionTools.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System; -using System.Reflection; - -public static class ReflectionTools { - // If the class is non-static - public static Object InvokePrivate (Object objectUnderTest, string method, params object [] args) - { - Type t = objectUnderTest.GetType (); - return t.InvokeMember (method, - BindingFlags.InvokeMethod | - BindingFlags.NonPublic | - BindingFlags.Instance | - BindingFlags.Static, - null, - objectUnderTest, - args); - } - // if the class is static - public static Object InvokePrivate (Type typeOfObjectUnderTest, string method, params object [] args) - { - MemberInfo [] members = typeOfObjectUnderTest.GetMembers (BindingFlags.NonPublic | BindingFlags.Static); - foreach (var member in members) { - if (member.Name == method) { - return typeOfObjectUnderTest.InvokeMember (method, - BindingFlags.NonPublic | - BindingFlags.Static | - BindingFlags.InvokeMethod, - null, - typeOfObjectUnderTest, - args); - } - } - return null; - } -} diff --git a/UnitTests/UICatalog/ScenarioTests.cs b/UnitTests/UICatalog/ScenarioTests.cs index bacb1f1b54..19327ece95 100644 --- a/UnitTests/UICatalog/ScenarioTests.cs +++ b/UnitTests/UICatalog/ScenarioTests.cs @@ -69,7 +69,7 @@ public void Run_All_Scenarios () FakeConsole.PushMockKeyPress (Application.QuitKey); // The only key we care about is the QuitKey - Application.Top.KeyPress += (object sender, KeyEventEventArgs args) => { + Application.Top.KeyPressed += (object sender, KeyEventEventArgs args) => { output.WriteLine ($" Keypress: {args.KeyEvent.Key}"); // BUGBUG: (#2474) For some reason ReadKey is not returning the QuitKey for some Scenarios // by adding this Space it seems to work. @@ -90,7 +90,7 @@ public void Run_All_Scenarios () //output.WriteLine ($" Add timeout to force quit after {abortTime}ms"); _ = Application.AddTimeout (TimeSpan.FromMilliseconds (abortTime), forceCloseCallback); - Application.Iteration += () => { + Application.Iteration += (s, a) => { //output.WriteLine ($" iteration {++iterations}"); if (Application.Top.Running && FakeConsole.MockKeyPresses.Count == 0) { Application.RequestStop (); @@ -136,7 +136,7 @@ public void Run_Generic () FakeConsole.PushMockKeyPress (Application.QuitKey); int iterations = 0; - Application.Iteration = () => { + Application.Iteration += (s, a) => { iterations++; output.WriteLine ($"'Generic' iteration {iterations}"); // Stop if we run out of control... @@ -156,7 +156,7 @@ public void Run_Generic () }; var token = Application.AddTimeout (TimeSpan.FromMilliseconds (ms), abortCallback); - Application.Top.KeyPress += (object sender, KeyEventEventArgs args) => { + Application.Top.KeyPressed += (object sender, KeyEventEventArgs args) => { // See #2474 for why this is commented out Assert.Equal (Key.CtrlMask | Key.Q, args.KeyEvent.Key); }; @@ -398,7 +398,7 @@ public void Run_All_Views_Tester_Scenario () int iterations = 0; - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations < _viewClasses.Count) { diff --git a/UnitTests/View/KeyboardTests.cs b/UnitTests/View/KeyboardTests.cs index 7b35d9c80a..a9557294b7 100644 --- a/UnitTests/View/KeyboardTests.cs +++ b/UnitTests/View/KeyboardTests.cs @@ -25,14 +25,14 @@ public void KeyPress_Handled_To_True_Prevents_Changes () var top = Application.Top; var text = new TextField (""); - text.KeyPress += (s, e) => { + text.KeyPressed += (s, e) => { e.Handled = true; Assert.True (e.Handled); Assert.Equal (Key.N, e.KeyEvent.Key); }; top.Add (text); - Application.Iteration += () => { + Application.Iteration += (s, a) => { Console.MockKeyPresses.Push (new ConsoleKeyInfo ('N', ConsoleKey.N, false, false, false)); Assert.Equal ("", text.Text); @@ -61,7 +61,7 @@ public void KeyDown_And_KeyUp_Events_Must_Called_Before_OnKeyDown_And_OnKeyUp () e.Handled = true; keyDown = true; }; - view.KeyPress += (s, e) => { + view.KeyPressed += (s, e) => { Assert.Equal (Key.a, e.KeyEvent.Key); Assert.False (keyPress); Assert.False (view.IsKeyPress); @@ -80,7 +80,7 @@ public void KeyDown_And_KeyUp_Events_Must_Called_Before_OnKeyDown_And_OnKeyUp () Console.MockKeyPresses.Push (new ConsoleKeyInfo ('a', ConsoleKey.A, false, false, false)); - Application.Iteration += () => Application.RequestStop (); + Application.Iteration += (s, a) => Application.RequestStop (); Assert.True (view.CanFocus); @@ -145,7 +145,7 @@ public void KeyDown_And_KeyUp_Events_With_Only_Key_Modifiers (bool shift, bool a Assert.False (view.IsKeyDown); keyDown = true; }; - view.KeyPress += (s, e) => { + view.KeyPressed += (s, e) => { keyPress = true; }; view.KeyUp += (s, e) => { @@ -162,7 +162,7 @@ public void KeyDown_And_KeyUp_Events_With_Only_Key_Modifiers (bool shift, bool a Console.MockKeyPresses.Push (new ConsoleKeyInfo ('\0', 0, shift, alt, control)); - Application.Iteration += () => Application.RequestStop (); + Application.Iteration += (s, a) => Application.RequestStop (); Assert.True (view.CanFocus); diff --git a/UnitTests/View/Layout/DimTests.cs b/UnitTests/View/Layout/DimTests.cs index 577c56a227..c70b66d458 100644 --- a/UnitTests/View/Layout/DimTests.cs +++ b/UnitTests/View/Layout/DimTests.cs @@ -298,7 +298,7 @@ public void ForceValidatePosDim_True_Dim_Validation_If_NewValue_Is_DimAbsolute_A Assert.Equal (2, v.Height); }; - Application.Iteration += () => Application.RequestStop (); + Application.Iteration += (s, a) => Application.RequestStop (); Application.Run (); } @@ -533,7 +533,7 @@ public void Only_DimAbsolute_And_DimFactor_As_A_Different_Procedure_For_Assignin Assert.Equal (38, v6.Frame.Height); // 198-7*20=18 }; - Application.Iteration += () => Application.RequestStop (); + Application.Iteration += (s, a) => Application.RequestStop (); Application.Run (); } @@ -702,7 +702,7 @@ public void Dim_Add_Operator () } }; - Application.Iteration += () => { + Application.Iteration += (s, a) => { while (count < 20) field.OnKeyDown (new KeyEvent (Key.Enter, new KeyModifiers ())); Application.RequestStop (); @@ -1075,7 +1075,7 @@ public void Dim_Add_Operator_With_Text () } }; - Application.Iteration += () => { + Application.Iteration += (s, a) => { while (count < 21) { field.OnKeyDown (new KeyEvent (Key.Enter, new KeyModifiers ())); if (count == 20) { @@ -1137,7 +1137,7 @@ public void Dim_Subtract_Operator () } }; - Application.Iteration += () => { + Application.Iteration += (s, a) => { while (count > 0) field.OnKeyDown (new KeyEvent (Key.Enter, new KeyModifiers ())); Application.RequestStop (); @@ -1214,7 +1214,7 @@ public void Dim_Subtract_Operator_With_Text () } }; - Application.Iteration += () => { + Application.Iteration += (s, a) => { while (count > -1) { field.OnKeyDown (new KeyEvent (Key.Enter, new KeyModifiers ())); if (count == 0) { diff --git a/UnitTests/View/Layout/LayoutTests.cs b/UnitTests/View/Layout/LayoutTests.cs index 8dfd1a31be..ea5887a198 100644 --- a/UnitTests/View/Layout/LayoutTests.cs +++ b/UnitTests/View/Layout/LayoutTests.cs @@ -83,7 +83,7 @@ public void LayoutSubviews_RootHas_SuperView () var second = new View () { Id = "second" }; root.Add (second); - + second.X = Pos.Right (first) + 1; root.LayoutSubviews (); @@ -586,7 +586,7 @@ string GetContents () { var text = ""; for (int i = 0; i < 4; i++) { - text += Application.Driver.Contents [0, i].Runes[0]; + text += Application.Driver.Contents [0, i].Runes [0]; } return text; } @@ -1454,7 +1454,7 @@ public void Pos_Dim_Are_Null_If_Not_Initialized_On_Constructor_IsAdded_False () Assert.Equal ("Center", view2.Y.ToString ()); Assert.Equal ("Fill(0)", view2.Width.ToString ()); Assert.Equal ("Fill(0)", view2.Height.ToString ()); - + } [Fact, TestRespondersDisposed] @@ -1861,7 +1861,7 @@ public void PosCombine_DimCombine_View_With_SubViews () var clicked = false; var top = Application.Top; var win1 = new Window () { Id = "win1", Width = 20, Height = 10 }; - var label= new Label ("[ ok ]"); + var label = new Label ("[ ok ]"); var win2 = new Window () { Id = "win2", Y = Pos.Bottom (label) + 1, Width = 10, Height = 3 }; var view1 = new View () { Id = "view1", Width = Dim.Fill (), Height = 1, CanFocus = true }; view1.MouseClick += (sender, e) => clicked = true; @@ -1893,14 +1893,11 @@ public void PosCombine_DimCombine_View_With_SubViews () Assert.Equal (new Rect (0, 0, 7, 1), view2.Frame); var foundView = View.FindDeepestView (top, 9, 4, out int rx, out int ry); Assert.Equal (foundView, view1); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 9, - Y = 4, - Flags = MouseFlags.Button1Clicked - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 9, + Y = 4, + Flags = MouseFlags.Button1Clicked + })); Assert.True (clicked); Application.End (rs); @@ -1920,7 +1917,7 @@ public void Draw_Vertical_Throws_IndexOutOfRangeException_With_Negative_Bounds ( }; top.Add (view); - Application.Iteration += () => { + Application.Iteration += (s, a) => { Assert.Equal (-2, view.Y); Application.RequestStop (); @@ -1947,7 +1944,7 @@ public void Draw_Throws_IndexOutOfRangeException_With_Negative_Bounds () var view = new View ("view") { X = -2 }; top.Add (view); - Application.Iteration += () => { + Application.Iteration += (s, a) => { Assert.Equal (-2, view.X); Application.RequestStop (); diff --git a/UnitTests/View/Layout/PosTests.cs b/UnitTests/View/Layout/PosTests.cs index 054785a9a1..1fb7febf7b 100644 --- a/UnitTests/View/Layout/PosTests.cs +++ b/UnitTests/View/Layout/PosTests.cs @@ -540,7 +540,7 @@ public void LeftTopBottomRight_Win_ShouldNotThrow () (Window win, Button button) setup () { Application.Init (new FakeDriver ()); - Application.Iteration = () => { + Application.Iteration += (s, a) => { Application.RequestStop (); }; var win = new Window () { @@ -708,7 +708,7 @@ public void ForceValidatePosDim_True_Pos_Validation_Throws_If_NewValue_Is_PosAbs Assert.Throws (() => v.Y = 2); }; - Application.Iteration += () => Application.RequestStop (); + Application.Iteration += (s, a) => Application.RequestStop (); Application.Run (); Application.Shutdown (); @@ -729,7 +729,7 @@ public void Pos_Validation_Do_Not_Throws_If_NewValue_Is_PosAbsolute_And_OldValue Assert.Equal (2, w.Y = 2); }; - Application.Iteration += () => Application.RequestStop (); + Application.Iteration += (s, a) => Application.RequestStop (); Application.Run (); Application.Shutdown (); @@ -761,7 +761,7 @@ public void Pos_Validation_Do_Not_Throws_If_NewValue_Is_PosAbsolute_And_OldValue Assert.Equal (2, v.Y = 2); }; - Application.Iteration += () => Application.RequestStop (); + Application.Iteration += (s, a) => Application.RequestStop (); Application.Run (); Application.Shutdown (); @@ -809,7 +809,7 @@ public void Pos_Validation_Do_Not_Throws_If_NewValue_Is_PosAbsolute_And_OldValue // Assert.Equal (6, v2.Frame.Y); // }; - // Application.Iteration += () => Application.RequestStop (); + // Application.Iteration += (s, a) => Application.RequestStop (); // Application.Run (); // Application.Shutdown (); @@ -875,7 +875,7 @@ public void Pos_Add_Operator () } }; - Application.Iteration += () => { + Application.Iteration += (s, a) => { while (count < 20) field.OnKeyDown (new KeyEvent (Key.Enter, new KeyModifiers ())); Application.RequestStop (); @@ -933,7 +933,7 @@ public void Pos_Subtract_Operator () } }; - Application.Iteration += () => { + Application.Iteration += (s, a) => { while (count > 0) field.OnKeyDown (new KeyEvent (Key.Enter, new KeyModifiers ())); Application.RequestStop (); diff --git a/UnitTests/View/NavigationTests.cs b/UnitTests/View/NavigationTests.cs index 6f1715e4cc..46a5e77842 100644 --- a/UnitTests/View/NavigationTests.cs +++ b/UnitTests/View/NavigationTests.cs @@ -515,7 +515,7 @@ public void CanFocus_Faced_With_Container_Before_Run () Assert.False (f.CanFocus); Assert.True (v.CanFocus); - Application.Iteration += () => Application.RequestStop (); + Application.Iteration += (s, a) => Application.RequestStop (); Application.Run (); Application.Shutdown (); @@ -558,7 +558,7 @@ public void CanFocus_Faced_With_Container_After_Run () Assert.True (v.CanFocus); }; - Application.Iteration += () => Application.RequestStop (); + Application.Iteration += (s, a) => Application.RequestStop (); Application.Run (); Application.Shutdown (); @@ -593,7 +593,7 @@ public void CanFocus_Container_ToFalse_Turns_All_Subviews_ToFalse_Too () Assert.False (v2.CanFocus); }; - Application.Iteration += () => Application.RequestStop (); + Application.Iteration += (s, a) => Application.RequestStop (); Application.Run (); Application.Shutdown (); @@ -634,7 +634,7 @@ public void CanFocus_Container_Toggling_All_Subviews_To_Old_Value_When_Is_True ( Assert.True (v2.CanFocus); }; - Application.Iteration += () => Application.RequestStop (); + Application.Iteration += (s, a) => Application.RequestStop (); Application.Run (); Application.Shutdown (); @@ -654,7 +654,7 @@ public void Navigation_With_Null_Focused_View () // Keyboard navigation with tab Console.MockKeyPresses.Push (new ConsoleKeyInfo ('\t', ConsoleKey.Tab, false, false, false)); - Application.Iteration += () => Application.RequestStop (); + Application.Iteration += (s, a) => Application.RequestStop (); Application.Run (); Application.Shutdown (); @@ -702,7 +702,7 @@ public void Enabled_Sets_Also_Sets_Subviews () var iterations = 0; - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; button.ProcessKey (new KeyEvent (Key.Enter, null)); @@ -899,7 +899,7 @@ public void ProcessHotKey_Will_Invoke_ProcessKey_Only_For_The_MostFocused_With_T new StatusItem(Key.CtrlMask | Key.Q, "~^Q~ Quit", () => sbQuiting = true ) }); var tf = new TextField (); - tf.KeyPress += Tf_KeyPress; + tf.KeyPressed += Tf_KeyPress; void Tf_KeyPress (object sender, KeyEventEventArgs obj) { @@ -911,7 +911,7 @@ void Tf_KeyPress (object sender, KeyEventEventArgs obj) var win = new Window (); win.Add (sb, tf); var top = Application.Top; - top.KeyPress += Top_KeyPress; + top.KeyPressed += Top_KeyPress; void Top_KeyPress (object sender, KeyEventEventArgs obj) { @@ -932,7 +932,7 @@ void Top_KeyPress (object sender, KeyEventEventArgs obj) Assert.True (tfQuiting); Assert.False (topQuiting); - tf.KeyPress -= Tf_KeyPress; + tf.KeyPressed -= Tf_KeyPress; tfQuiting = false; Application.Driver.SendKeys ('q', ConsoleKey.Q, false, false, true); Application.MainLoop.RunIteration (); @@ -959,7 +959,7 @@ public void ProcessHotKey_Will_Invoke_ProcessKey_Only_For_The_MostFocused_Withou new StatusItem(Key.CtrlMask | Key.Q, "~^Q~ Quit", () => sbQuiting = true ) }); var tf = new TextField (); - tf.KeyPress += Tf_KeyPress; + tf.KeyPressed += Tf_KeyPress; void Tf_KeyPress (object sender, KeyEventEventArgs obj) { @@ -981,7 +981,7 @@ void Tf_KeyPress (object sender, KeyEventEventArgs obj) Assert.False (sbQuiting); Assert.True (tfQuiting); - tf.KeyPress -= Tf_KeyPress; + tf.KeyPressed -= Tf_KeyPress; tfQuiting = false; Application.Driver.SendKeys ('q', ConsoleKey.Q, false, false, true); Application.MainLoop.RunIteration (); diff --git a/UnitTests/View/ViewTests.cs b/UnitTests/View/ViewTests.cs index 0e2ab587c6..e2d90d8825 100644 --- a/UnitTests/View/ViewTests.cs +++ b/UnitTests/View/ViewTests.cs @@ -332,7 +332,7 @@ public void Initialized_Event_Comparing_With_Added_Event () w.Add (v1, v2); t.Add (w); - Application.Iteration = () => { + Application.Iteration += (s, a) => { Application.Refresh (); t.Running = false; }; @@ -403,7 +403,7 @@ public void Initialized_Event_Will_Be_Invoked_When_Added_Dynamically () w.Add (v1, v2); t.Add (w); - Application.Iteration = () => { + Application.Iteration += (s, a) => { var sv1 = new View () { Id = "sv1", Width = Dim.Fill (), Height = Dim.Fill () }; sv1.Initialized += (s, e) => { @@ -564,7 +564,7 @@ public void Visible_Sets_Also_Sets_Subviews () var iterations = 0; - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; Assert.True (button.Visible); diff --git a/UnitTests/Views/ContextMenuTests.cs b/UnitTests/Views/ContextMenuTests.cs index 465a64d84f..96c3247603 100644 --- a/UnitTests/Views/ContextMenuTests.cs +++ b/UnitTests/Views/ContextMenuTests.cs @@ -180,7 +180,7 @@ public void Key_Changing () var cm = new ContextMenu (); - lbl.KeyPress += (s, e) => { + lbl.KeyPressed += (s, e) => { if (e.KeyEvent.Key == cm.Key) { lbl.Text = "Replaced"; e.Handled = true; @@ -957,14 +957,11 @@ public void Draw_A_ContextMenu_Over_A_Dialog () │ │ └──────────────────┘", output); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 9, - Y = 3, - Flags = MouseFlags.Button3Clicked - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 9, + Y = 3, + Flags = MouseFlags.Button3Clicked + })); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1008,14 +1005,11 @@ public void Draw_A_ContextMenu_Over_A_Top_Dialog () │ │ └─────────────┘", output); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 9, - Y = 3, - Flags = MouseFlags.Button3Clicked - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 9, + Y = 3, + Flags = MouseFlags.Button3Clicked + })); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1052,14 +1046,11 @@ public void Draw_A_ContextMenu_Over_A_Borderless_Top () TestHelpers.AssertDriverContentsWithFrameAre (@" Test", output); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 8, - Y = 2, - Flags = MouseFlags.Button3Clicked - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 8, + Y = 2, + Flags = MouseFlags.Button3Clicked + })); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1103,14 +1094,11 @@ public void UseSubMenusSingleFrame_True_By_Mouse () │ Three │ └────────┘", output); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 5, - Y = 13, - Flags = MouseFlags.Button1Clicked - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 5, + Y = 13, + Flags = MouseFlags.Button1Clicked + })); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1124,14 +1112,11 @@ public void UseSubMenusSingleFrame_True_By_Mouse () │ Sub-Menu 2 │ └─────────────┘", output); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 5, - Y = 12, - Flags = MouseFlags.Button1Clicked - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 5, + Y = 12, + Flags = MouseFlags.Button1Clicked + })); firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1154,7 +1139,7 @@ public void RequestStop_While_ContextMenu_Is_Open_Does_Not_Throws () var isMenuAllClosed = false; MenuBarItem mi = null; var iterations = -1; - Application.Iteration += () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { cm.Show (); diff --git a/UnitTests/Views/MenuTests.cs b/UnitTests/Views/MenuTests.cs index b34cb908f8..0211fe075f 100644 --- a/UnitTests/Views/MenuTests.cs +++ b/UnitTests/Views/MenuTests.cs @@ -1677,7 +1677,7 @@ public void MenuBar_In_Window_Without_Other_Views_With_Top_Init_With_Parameterle var top = Application.Top; top.Add (win); - Application.Iteration += () => { + Application.Iteration += (s, a) => { ((FakeDriver)Application.Driver).SetBufferSize (40, 8); TestHelpers.AssertDriverContentsWithFrameAre (@" @@ -1907,7 +1907,7 @@ public void MenuBar_In_Window_Without_Other_Views_Without_Top_Init_With_Run_T () { ((FakeDriver)Application.Driver).SetBufferSize (40, 8); - Application.Iteration += () => { + Application.Iteration += (s, a) => { var top = Application.Top; TestHelpers.AssertDriverContentsWithFrameAre (@" @@ -2394,14 +2394,11 @@ void ChangeMenuTitle (string title) │ │ └──────────────────────────────────────┘", output); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 20, - Y = 4, - Flags = MouseFlags.Button1Clicked - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 20, + Y = 4, + Flags = MouseFlags.Button1Clicked + })); firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -2426,14 +2423,11 @@ void ChangeMenuTitle (string title) for (int i = 1; i < items.Count; i++) { menu.OpenMenu (); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 20, - Y = 4 + i, - Flags = MouseFlags.Button1Clicked - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 20, + Y = 4 + i, + Flags = MouseFlags.Button1Clicked + })); firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -2518,14 +2512,11 @@ void ChangeMenuTitle (string title) │ Delete Delete a file Ctrl+A │ └──────────────────────────────────┘", output); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 20, - Y = 5, - Flags = MouseFlags.Button1Clicked - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 20, + Y = 5, + Flags = MouseFlags.Button1Clicked + })); firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -2539,14 +2530,11 @@ void ChangeMenuTitle (string title) for (int i = 1; i < items.Count; i++) { menu.OpenMenu (); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 20, - Y = 5 + i, - Flags = MouseFlags.Button1Clicked - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 20, + Y = 5 + i, + Flags = MouseFlags.Button1Clicked + })); firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); diff --git a/UnitTests/Views/OverlappedTests.cs b/UnitTests/Views/OverlappedTests.cs index 8c83e329f8..9d505f6cf0 100644 --- a/UnitTests/Views/OverlappedTests.cs +++ b/UnitTests/Views/OverlappedTests.cs @@ -84,7 +84,7 @@ public void Application_RequestStop_With_Params_On_A_Not_OverlappedContainer_Alw d.Closed += (s, e) => Application.RequestStop (top1); - Application.Iteration += () => { + Application.Iteration += (s, a) => { Assert.Null (Application.OverlappedChildren); if (iterations == 4) Assert.True (Application.Current == d); else if (iterations == 3) Assert.True (Application.Current == top4); @@ -150,7 +150,7 @@ public void OverlappedContainer_With_Toplevel_RequestStop_Balanced () overlapped.RequestStop (); }; - Application.Iteration += () => { + Application.Iteration += (s, a) => { if (iterations == 4) { // The Dialog was not closed before and will be closed now. Assert.True (Application.Current == d); @@ -208,7 +208,7 @@ public void OverlappedContainer_With_Application_RequestStop_OverlappedTop_With_ // Now this will close the OverlappedContainer propagating through the OverlappedChildren. d.Closed += (s, e) => Application.RequestStop (overlapped); - Application.Iteration += () => { + Application.Iteration += (s, a) => { if (iterations == 4) { // The Dialog was not closed before and will be closed now. Assert.True (Application.Current == d); @@ -266,7 +266,7 @@ public void OverlappedContainer_With_Application_RequestStop_OverlappedTop_Witho // Now this will close the OverlappedContainer propagating through the OverlappedChildren. d.Closed += (s, e) => Application.RequestStop (overlapped); - Application.Iteration += () => { + Application.Iteration += (s, a) => { if (iterations == 4) { // The Dialog still is the current top and we can't request stop to OverlappedContainer // because we are not using parameter calls. @@ -294,7 +294,7 @@ public void IsOverlappedChild_Testing () var c3 = new Window (); var d = new Dialog (); - Application.Iteration += () => { + Application.Iteration += (s, a) => { Assert.False (overlapped.IsOverlapped); Assert.True (c1.IsOverlapped); Assert.True (c2.IsOverlapped); @@ -358,7 +358,7 @@ public void Modal_Toplevel_Can_Open_Another_Modal_Toplevel_But_RequestStop_To_Th overlapped.RequestStop (); }; - Application.Iteration += () => { + Application.Iteration += (s, a) => { if (iterations == 5) { // The Dialog2 still is the current top and we can't request stop to OverlappedContainer // because Dialog2 and Dialog1 must be closed first. @@ -429,7 +429,7 @@ public void Modal_Toplevel_Can_Open_Another_Not_Modal_Toplevel_But_RequestStop_T overlapped.RequestStop (); }; - Application.Iteration += () => { + Application.Iteration += (s, a) => { if (iterations == 5) { // The Dialog2 still is the current top and we can't request stop to OverlappedContainer // because Dialog2 and Dialog1 must be closed first. @@ -483,7 +483,7 @@ public void MoveCurrent_Returns_False_If_The_Current_And_Top_Parameter_Are_Both_ c1.Closed += (s, e) => { overlapped.RequestStop (); }; - Application.Iteration += () => { + Application.Iteration += (s, a) => { if (iterations == 3) { // The Current still is c3 because Current.Running is false. Assert.True (Application.Current == c3); @@ -551,7 +551,7 @@ public void OverlappedContainer_Open_And_Close_Modal_And_Open_Not_Modal_Toplevel logger.Ready += (s, e) => Assert.Single (Application.OverlappedChildren); - Application.Iteration += () => { + Application.Iteration += (s, a) => { if (stageCompleted && running) { stageCompleted = false; var stage = new Window () { Modal = true }; @@ -631,7 +631,7 @@ public void AllChildClosed_Event_Test () overlapped.AllChildClosed += (s, e) => { overlapped.RequestStop (); }; - Application.Iteration += () => { + Application.Iteration += (s, a) => { if (iterations == 3) { // The Current still is c3 because Current.Running is false. Assert.True (Application.Current == c3); diff --git a/UnitTests/Views/ScrollBarViewTests.cs b/UnitTests/Views/ScrollBarViewTests.cs index 08cec5c4f4..79dbb9b2c1 100644 --- a/UnitTests/Views/ScrollBarViewTests.cs +++ b/UnitTests/Views/ScrollBarViewTests.cs @@ -1111,14 +1111,11 @@ This is a test This is a test This is a test ", output); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 15, - Y = 0, - Flags = MouseFlags.Button1Clicked - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 15, + Y = 0, + Flags = MouseFlags.Button1Clicked + })); Assert.Null (Application.MouseGrabView); Assert.True (clicked); @@ -1138,14 +1135,11 @@ This is a test This is a test This is a test ", output); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 15, - Y = 0, - Flags = MouseFlags.Button1Clicked - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 15, + Y = 0, + Flags = MouseFlags.Button1Clicked + })); Assert.Null (Application.MouseGrabView); Assert.True (clicked); diff --git a/UnitTests/Views/StatusBarTests.cs b/UnitTests/Views/StatusBarTests.cs index d2e81ead19..76b6aa395a 100644 --- a/UnitTests/Views/StatusBarTests.cs +++ b/UnitTests/Views/StatusBarTests.cs @@ -45,7 +45,7 @@ public void StatusBar_Constructor_Default () Assert.Equal (CursorVisibility.Default, cv); Assert.True (FakeConsole.CursorVisible); - Application.Iteration += () => { + Application.Iteration += (s, a) => { Assert.Equal (24, sb.Frame.Y); driver.SetWindowSize (driver.Cols, 15); @@ -77,7 +77,7 @@ public void Run_Action_With_Key_And_Mouse () var iteration = 0; - Application.Iteration += () => { + Application.Iteration += (s, a) => { if (iteration == 0) { Assert.Equal ("", msg); sb.ProcessHotKey (new KeyEvent (Key.CtrlMask | Key.Q, null)); diff --git a/UnitTests/Views/TextFieldTests.cs b/UnitTests/Views/TextFieldTests.cs index 5a4582dc1d..00e10c0740 100644 --- a/UnitTests/Views/TextFieldTests.cs +++ b/UnitTests/Views/TextFieldTests.cs @@ -1220,7 +1220,7 @@ public void DeleteSelectedText_InsertText_DeleteCharLeft_DeleteCharRight_Cut () [AutoInitShutdown] public void Test_RootKeyEvent_Cancel () { - Application.RootKeyEvent += SuppressKey; + Application.KeyPressed += SuppressKey; var tf = new TextField (); @@ -1234,7 +1234,7 @@ public void Test_RootKeyEvent_Cancel () Application.Driver.SendKeys ('j', ConsoleKey.A, false, false, false); Assert.Equal ("a", tf.Text); - Application.RootKeyEvent -= SuppressKey; + Application.KeyPressed -= SuppressKey; // Now that the delegate has been removed we can type j again Application.Driver.SendKeys ('j', ConsoleKey.A, false, false, false); @@ -1244,7 +1244,7 @@ public void Test_RootKeyEvent_Cancel () [AutoInitShutdown] public void Test_RootMouseKeyEvent_Cancel () { - Application.RootMouseEvent += SuppressRightClick; + Application.MouseEvent += SuppressRightClick; var tf = new TextField () { Width = 10 }; int clickCounter = 0; @@ -1253,15 +1253,12 @@ public void Test_RootMouseKeyEvent_Cancel () Application.Top.Add (tf); Application.Begin (Application.Top); - var processMouseEventMethod = typeof (Application).GetMethod ("ProcessMouseEvent", BindingFlags.Static | BindingFlags.NonPublic) - ?? throw new Exception ("Expected private method not found 'ProcessMouseEvent', this method was used for testing mouse behaviours"); - var mouseEvent = new MouseEvent { Flags = MouseFlags.Button1Clicked, View = tf }; - processMouseEventMethod.Invoke (null, new object [] { mouseEvent }); + Application.OnMouseEvent(new MouseEventEventArgs(mouseEvent)); Assert.Equal (1, clickCounter); // Get a fresh instance that represents a right click. @@ -1270,10 +1267,10 @@ public void Test_RootMouseKeyEvent_Cancel () Flags = MouseFlags.Button3Clicked, View = tf }; - processMouseEventMethod.Invoke (null, new object [] { mouseEvent }); + Application.OnMouseEvent (new MouseEventEventArgs (mouseEvent)); Assert.Equal (1, clickCounter); - Application.RootMouseEvent -= SuppressRightClick; + Application.MouseEvent -= SuppressRightClick; // Get a fresh instance that represents a right click. // Should no longer be ignored as the callback was removed @@ -1282,21 +1279,20 @@ public void Test_RootMouseKeyEvent_Cancel () View = tf }; - processMouseEventMethod.Invoke (null, new object [] { mouseEvent }); + Application.OnMouseEvent (new MouseEventEventArgs (mouseEvent)); Assert.Equal (2, clickCounter); } - private bool SuppressKey (KeyEvent arg) + private void SuppressKey (object s, KeyEventEventArgs arg) { - if (arg.KeyValue == 'j') - return true; - - return false; + if (arg.KeyEvent.KeyValue == 'j') { + arg.Handled = true; + } } - private void SuppressRightClick (MouseEvent arg) + private void SuppressRightClick (object sender, MouseEventEventArgs arg) { - if (arg.Flags.HasFlag (MouseFlags.Button3Clicked)) + if (arg.MouseEvent.Flags.HasFlag (MouseFlags.Button3Clicked)) arg.Handled = true; } diff --git a/UnitTests/Views/TextViewTests.cs b/UnitTests/Views/TextViewTests.cs index a62c4af741..7485da2523 100644 --- a/UnitTests/Views/TextViewTests.cs +++ b/UnitTests/Views/TextViewTests.cs @@ -1604,7 +1604,7 @@ public void Tab_Test_Follow_By_BackTab () { Application.Top.Add (_textView); - Application.Iteration += () => { + Application.Iteration += (s, a) => { var width = _textView.Bounds.Width - 1; Assert.Equal (30, width + 1); Assert.Equal (10, _textView.Height); @@ -1640,7 +1640,7 @@ public void BackTab_Test_Follow_By_Tab () { Application.Top.Add (_textView); - Application.Iteration += () => { + Application.Iteration += (s, a) => { var width = _textView.Bounds.Width - 1; Assert.Equal (30, width + 1); Assert.Equal (10, _textView.Height); @@ -1683,7 +1683,7 @@ public void Tab_Test_Follow_By_CursorLeft_And_Then_Follow_By_CursorRight () { Application.Top.Add (_textView); - Application.Iteration += () => { + Application.Iteration += (s, a) => { var width = _textView.Bounds.Width - 1; Assert.Equal (30, width + 1); Assert.Equal (10, _textView.Height); @@ -1726,7 +1726,7 @@ public void Tab_Test_Follow_By_BackTab_With_Text () { Application.Top.Add (_textView); - Application.Iteration += () => { + Application.Iteration += (s, a) => { var width = _textView.Bounds.Width - 1; Assert.Equal (30, width + 1); Assert.Equal (10, _textView.Height); @@ -1762,7 +1762,7 @@ public void Tab_Test_Follow_By_Home_And_Then_Follow_By_End_And_Then_Follow_By_Ba { Application.Top.Add (_textView); - Application.Iteration += () => { + Application.Iteration += (s, a) => { var width = _textView.Bounds.Width - 1; Assert.Equal (30, width + 1); Assert.Equal (10, _textView.Height); @@ -1820,7 +1820,7 @@ public void Tab_Test_Follow_By_CursorLeft_And_Then_Follow_By_CursorRight_With_Te { Application.Top.Add (_textView); - Application.Iteration += () => { + Application.Iteration += (s, a) => { var width = _textView.Bounds.Width - 1; Assert.Equal (30, width + 1); Assert.Equal (10, _textView.Height); @@ -6618,7 +6618,7 @@ public void ContentsChanged_Event_Fires_On_InsertText () [Fact, AutoInitShutdown] public void ContentsChanged_Event_Fires_On_Init () { - Application.Iteration += () => { + Application.Iteration += (s, a) => { Application.RequestStop (); }; @@ -6644,7 +6644,7 @@ public void ContentsChanged_Event_Fires_On_Init () [Fact, AutoInitShutdown] public void ContentsChanged_Event_Fires_On_Set_Text () { - Application.Iteration += () => { + Application.Iteration += (s, a) => { Application.RequestStop (); }; var eventcount = 0; @@ -6679,7 +6679,7 @@ public void ContentsChanged_Event_Fires_On_Set_Text () [Fact, AutoInitShutdown] public void ContentsChanged_Event_Fires_On_Typing () { - Application.Iteration += () => { + Application.Iteration += (s, a) => { Application.RequestStop (); }; var eventcount = 0; diff --git a/UnitTests/Views/ToplevelTests.cs b/UnitTests/Views/ToplevelTests.cs index ea3f5bb68a..42e6df504c 100644 --- a/UnitTests/Views/ToplevelTests.cs +++ b/UnitTests/Views/ToplevelTests.cs @@ -45,7 +45,7 @@ public void Application_Top_GetLocationThatFits_To_Driver_Rows_And_Cols () { var iterations = 0; - Application.Iteration += () => { + Application.Iteration += (s, a) => { if (iterations == 0) { Assert.False (Application.Top.AutoSize); Assert.Equal ("Top1", Application.Top.Text); @@ -674,7 +674,7 @@ public void Mouse_Drag_On_Top_With_Superview_Null () top.Add (win); var iterations = -1; - Application.Iteration = () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { ((FakeDriver)Application.Driver).SetBufferSize (40, 15); @@ -701,14 +701,11 @@ public void Mouse_Drag_On_Top_With_Superview_Null () } else if (iterations == 2) { Assert.Null (Application.MouseGrabView); // Grab the mouse - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 8, - Y = 5, - Flags = MouseFlags.Button1Pressed - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 8, + Y = 5, + Flags = MouseFlags.Button1Pressed + })); Assert.Equal (Application.Current, Application.MouseGrabView); Assert.Equal (new Rect (8, 5, 24, 5), Application.MouseGrabView.Frame); @@ -716,14 +713,11 @@ public void Mouse_Drag_On_Top_With_Superview_Null () } else if (iterations == 3) { Assert.Equal (Application.Current, Application.MouseGrabView); // Drag to left - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 7, - Y = 5, - Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 7, + Y = 5, + Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition + })); Assert.Equal (Application.Current, Application.MouseGrabView); Assert.Equal (new Rect (7, 5, 24, 5), Application.MouseGrabView.Frame); @@ -752,14 +746,11 @@ public void Mouse_Drag_On_Top_With_Superview_Null () } else if (iterations == 5) { Assert.Equal (Application.Current, Application.MouseGrabView); // Drag up - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 7, - Y = 4, - Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 7, + Y = 4, + Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition + })); Assert.Equal (Application.Current, Application.MouseGrabView); Assert.Equal (new Rect (7, 4, 24, 5), Application.MouseGrabView.Frame); @@ -790,14 +781,11 @@ public void Mouse_Drag_On_Top_With_Superview_Null () } else if (iterations == 7) { Assert.Equal (Application.Current, Application.MouseGrabView); // Ungrab the mouse - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 7, - Y = 4, - Flags = MouseFlags.Button1Released - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 7, + Y = 4, + Flags = MouseFlags.Button1Released + })); Assert.Null (Application.MouseGrabView); @@ -827,7 +815,7 @@ public void Mouse_Drag_On_Top_With_Superview_Not_Null () var location = new Rect (win.Frame.X, win.Frame.Y, 7, 3); - Application.Iteration = () => { + Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { ((FakeDriver)Application.Driver).SetBufferSize (30, 10); @@ -836,14 +824,11 @@ public void Mouse_Drag_On_Top_With_Superview_Not_Null () Assert.Null (Application.MouseGrabView); // Grab the mouse - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = win.Frame.X, - Y = win.Frame.Y, - Flags = MouseFlags.Button1Pressed - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = win.Frame.X, + Y = win.Frame.Y, + Flags = MouseFlags.Button1Pressed + })); Assert.Equal (win, Application.MouseGrabView); Assert.Equal (location, Application.MouseGrabView.Frame); @@ -852,14 +837,11 @@ public void Mouse_Drag_On_Top_With_Superview_Not_Null () // Drag to left movex = 1; movey = 0; - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = win.Frame.X + movex, - Y = win.Frame.Y + movey, - Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = win.Frame.X + movex, + Y = win.Frame.Y + movey, + Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition + })); Assert.Equal (win, Application.MouseGrabView); @@ -875,14 +857,11 @@ public void Mouse_Drag_On_Top_With_Superview_Not_Null () // Drag up movex = 0; movey = -1; - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = win.Frame.X + movex, - Y = win.Frame.Y + movey, - Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = win.Frame.X + movex, + Y = win.Frame.Y + movey, + Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition + })); Assert.Equal (win, Application.MouseGrabView); @@ -897,14 +876,11 @@ public void Mouse_Drag_On_Top_With_Superview_Not_Null () // Ungrab the mouse movex = 0; movey = 0; - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = win.Frame.X + movex, - Y = win.Frame.Y + movey, - Flags = MouseFlags.Button1Released - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = win.Frame.X + movex, + Y = win.Frame.Y + movey, + Flags = MouseFlags.Button1Released + })); Assert.Null (Application.MouseGrabView); } else if (iterations == 7) { @@ -1162,25 +1138,19 @@ public void Toplevel_Inside_ScrollView_MouseGrabView () │ ▼ ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ", output); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 6, - Y = 6, - Flags = MouseFlags.Button1Pressed - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 6, + Y = 6, + Flags = MouseFlags.Button1Pressed + })); Assert.Equal (win, Application.MouseGrabView); Assert.Equal (new Rect (3, 3, 194, 94), win.Frame); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 9, - Y = 9, - Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 9, + Y = 9, + Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition + })); Assert.Equal (win, Application.MouseGrabView); top.SetNeedsLayout (); top.LayoutSubviews (); @@ -1204,14 +1174,11 @@ public void Toplevel_Inside_ScrollView_MouseGrabView () │ ▼ ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ", output); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 5, - Y = 5, - Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 5, + Y = 5, + Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition + })); Assert.Equal (win, Application.MouseGrabView); top.SetNeedsLayout (); top.LayoutSubviews (); @@ -1235,24 +1202,18 @@ public void Toplevel_Inside_ScrollView_MouseGrabView () │ ▼ ◄├──────┤░░░░░░░░░░░░░░░░░░░░░░░░░░░░░► ", output); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 5, - Y = 5, - Flags = MouseFlags.Button1Released - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 5, + Y = 5, + Flags = MouseFlags.Button1Released + })); Assert.Null (Application.MouseGrabView); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 4, - Y = 4, - Flags = MouseFlags.ReportMousePosition - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 4, + Y = 4, + Flags = MouseFlags.ReportMousePosition + })); Assert.Equal (scrollView, Application.MouseGrabView); } @@ -1275,25 +1236,19 @@ public void Dialog_Bounds_Bigger_Than_Driver_Cols_And_Rows_Allow_Drag_Beyond_Lef Assert.Null (Application.MouseGrabView); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 10, - Y = 3, - Flags = MouseFlags.Button1Pressed - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 10, + Y = 3, + Flags = MouseFlags.Button1Pressed + })); Assert.Equal (dialog, Application.MouseGrabView); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = -11, - Y = -4, - Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = -11, + Y = -4, + Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition + })); Application.Refresh (); Assert.Equal (new Rect (0, 0, 40, 10), top.Frame); @@ -1306,14 +1261,11 @@ public void Dialog_Bounds_Bigger_Than_Driver_Cols_And_Rows_Allow_Drag_Beyond_Lef // Changes Top size to same size as Dialog more menu and scroll bar ((FakeDriver)Application.Driver).SetBufferSize (20, 3); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = -1, - Y = -1, - Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = -1, + Y = -1, + Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition + })); Application.Refresh (); Assert.Equal (new Rect (0, 0, 20, 3), top.Frame); @@ -1326,14 +1278,11 @@ public void Dialog_Bounds_Bigger_Than_Driver_Cols_And_Rows_Allow_Drag_Beyond_Lef // Changes Top size smaller than Dialog size ((FakeDriver)Application.Driver).SetBufferSize (19, 2); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = -1, - Y = -1, - Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = -1, + Y = -1, + Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition + })); Application.Refresh (); Assert.Equal (new Rect (0, 0, 19, 2), top.Frame); @@ -1343,14 +1292,11 @@ public void Dialog_Bounds_Bigger_Than_Driver_Cols_And_Rows_Allow_Drag_Beyond_Lef {CM.Glyphs.LeftBracket} Ok {CM.Glyphs.RightBracket} │ ", output); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 18, - Y = 1, - Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 18, + Y = 1, + Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition + })); Application.Refresh (); Assert.Equal (new Rect (0, 0, 19, 2), top.Frame); @@ -1359,14 +1305,11 @@ public void Dialog_Bounds_Bigger_Than_Driver_Cols_And_Rows_Allow_Drag_Beyond_Lef ┌", output); // On a real app we can't go beyond the SuperView bounds - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 19, - Y = 2, - Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 19, + Y = 2, + Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition + })); Application.Refresh (); Assert.Equal (new Rect (0, 0, 19, 2), top.Frame); @@ -1406,14 +1349,11 @@ public void Modal_As_Top_Will_Drag_Cleanly () │ │ └────────────────────────────┘", output); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 25, - Y = 7, - Flags = MouseFlags.Button1Pressed - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 25, + Y = 7, + Flags = MouseFlags.Button1Pressed + })); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1432,14 +1372,11 @@ public void Modal_As_Top_Will_Drag_Cleanly () │ │ └────────────────────────────┘", output); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 20, - Y = 10, - Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 20, + Y = 10, + Flags = MouseFlags.Button1Pressed | MouseFlags.ReportMousePosition + })); firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); @@ -1550,14 +1487,11 @@ void Current_DrawContentComplete (object sender, DrawEventArgs e) │ │ └──────────────────┘", output); - ReflectionTools.InvokePrivate ( - typeof (Application), - "ProcessMouseEvent", - new MouseEvent () { - X = 9, - Y = 13, - Flags = MouseFlags.Button1Clicked - }); + Application.OnMouseEvent (new MouseEventEventArgs (new MouseEvent () { + X = 9, + Y = 13, + Flags = MouseFlags.Button1Clicked + })); var firstIteration = false; Application.RunIteration (ref rs, ref firstIteration); From 101677764445971a5d394c2b0bc2a4d33e996956 Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Thu, 19 Oct 2023 13:07:17 -0600 Subject: [PATCH 011/194] Updated OnMouseEvent API docs --- Terminal.Gui/Application.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Terminal.Gui/Application.cs b/Terminal.Gui/Application.cs index c769f72a57..7c33a721c9 100644 --- a/Terminal.Gui/Application.cs +++ b/Terminal.Gui/Application.cs @@ -1136,6 +1136,9 @@ static void OnUnGrabbedMouse (View view) /// /// Called when a mouse event occurs. Fires the event. /// + /// + /// This method can be used to simulate a mouse event, e.g. in unit tests. + /// /// public static void OnMouseEvent (MouseEventEventArgs a) { From 916f3356c930693794977da1e7a7d2210d4792be Mon Sep 17 00:00:00 2001 From: Tigger Kindel Date: Fri, 20 Oct 2023 05:33:09 -0600 Subject: [PATCH 012/194] Using WT_SESSION to detect WT --- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 11 +++++++---- UICatalog/Properties/launchSettings.json | 5 +---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index 5a1e3c18c4..ba4d7cc8fc 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -807,10 +807,13 @@ public WindowsDriver () } if (!RunningUnitTests) { - _parentProcessName = GetParentProcessName (); - _isWindowsTerminal = _parentProcessName == "WindowsTerminal"; - if (!_isWindowsTerminal && _parentProcessName != "wininit") { - Force16Colors = true; + _isWindowsTerminal = Environment.GetEnvironmentVariable ("WT_SESSION") != null; + if (!_isWindowsTerminal) { + _parentProcessName = GetParentProcessName (); + _isWindowsTerminal = _parentProcessName == "WindowsTerminal"; + if (!_isWindowsTerminal && _parentProcessName != "devenv") { + Force16Colors = true; + } } } } diff --git a/UICatalog/Properties/launchSettings.json b/UICatalog/Properties/launchSettings.json index 6bc8e31502..c99be34687 100644 --- a/UICatalog/Properties/launchSettings.json +++ b/UICatalog/Properties/launchSettings.json @@ -1,10 +1,7 @@ { "profiles": { "UICatalog": { - "commandName": "Project", - "environmentVariables": { - "WT_SESSION": "1" - } + "commandName": "Project" }, "WSL : UICatalog": { "commandName": "Executable", From f7ad241d1cf1cb0a0b3e9e389ec044f3326fac43 Mon Sep 17 00:00:00 2001 From: Tigger Kindel Date: Fri, 20 Oct 2023 06:42:40 -0600 Subject: [PATCH 013/194] removes hacky GetParentProcess --- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 96 ++++++++++---------- Terminal.sln | 1 + 2 files changed, 50 insertions(+), 47 deletions(-) diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index ba4d7cc8fc..e49af73072 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -783,8 +783,7 @@ internal class WindowsDriver : ConsoleDriver { public WindowsConsole WinConsole { get; private set; } - public override bool SupportsTrueColor => RunningUnitTests || (Environment.OSVersion.Version.Build >= 14931 - && (_isWindowsTerminal || _parentProcessName == "wininit")); + public override bool SupportsTrueColor => RunningUnitTests || (Environment.OSVersion.Version.Build >= 14931 && _isWindowsTerminal); readonly bool _isWindowsTerminal = false; readonly string _parentProcessName = "WindowsTerminal"; @@ -809,53 +808,56 @@ public WindowsDriver () if (!RunningUnitTests) { _isWindowsTerminal = Environment.GetEnvironmentVariable ("WT_SESSION") != null; if (!_isWindowsTerminal) { - _parentProcessName = GetParentProcessName (); - _isWindowsTerminal = _parentProcessName == "WindowsTerminal"; - if (!_isWindowsTerminal && _parentProcessName != "devenv") { - Force16Colors = true; - } + //_parentProcessName = GetParentProcessName (); + //_isWindowsTerminal = _parentProcessName == "WindowsTerminal"; + //if (!_isWindowsTerminal && _parentProcessName != "devenv") { + Force16Colors = true; + //} } } } - private static string GetParentProcessName () - { -#pragma warning disable CA1416 // Validate platform compatibility - var myId = Process.GetCurrentProcess ().Id; - var query = string.Format ($"SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {myId}"); - var search = new ManagementObjectSearcher ("root\\CIMV2", query); - var queryObj = search.Get ().OfType ().FirstOrDefault (); - if (queryObj == null) { - return null; - } - var parentId = (uint)queryObj ["ParentProcessId"]; - var parent = Process.GetProcessById ((int)parentId); - var prevParent = parent; - - // Check if the parent is from other parent - while (queryObj != null) { - query = string.Format ($"SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {parentId}"); - search = new ManagementObjectSearcher ("root\\CIMV2", query); - queryObj = search.Get ().OfType ().FirstOrDefault (); - if (queryObj == null) { - return parent.ProcessName; - } - parentId = (uint)queryObj ["ParentProcessId"]; - try { - parent = Process.GetProcessById ((int)parentId); - if (string.Equals (parent.ProcessName, "explorer", StringComparison.InvariantCultureIgnoreCase)) { - return prevParent.ProcessName; - } - prevParent = parent; - } catch (ArgumentException) { - - return prevParent.ProcessName; - } - } - - return parent.ProcessName; -#pragma warning restore CA1416 // Validate platform compatibility - } + // BUGBUG: This code is a hack and has an infinite loop if WT is started from a non-WT terminal (start.run "pwsh"). + // commenting out for now. A better workaround for running in the VS debugger is to set the environment variable + // in the `launchSettings.json` file. + // private static string GetParentProcessName () + // { + //#pragma warning disable CA1416 // Validate platform compatibility + // var myId = Process.GetCurrentProcess ().Id; + // var query = string.Format ($"SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {myId}"); + // var search = new ManagementObjectSearcher ("root\\CIMV2", query); + // var queryObj = search.Get ().OfType ().FirstOrDefault (); + // if (queryObj == null) { + // return null; + // } + // var parentId = (uint)queryObj ["ParentProcessId"]; + // var parent = Process.GetProcessById ((int)parentId); + // var prevParent = parent; + + // // Check if the parent is from other parent + // while (queryObj != null) { + // query = string.Format ($"SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {parentId}"); + // search = new ManagementObjectSearcher ("root\\CIMV2", query); + // queryObj = search.Get ().OfType ().FirstOrDefault (); + // if (queryObj == null) { + // return parent.ProcessName; + // } + // parentId = (uint)queryObj ["ParentProcessId"]; + // try { + // parent = Process.GetProcessById ((int)parentId); + // if (string.Equals (parent.ProcessName, "explorer", StringComparison.InvariantCultureIgnoreCase)) { + // return prevParent.ProcessName; + // } + // prevParent = parent; + // } catch (ArgumentException) { + + // return prevParent.ProcessName; + // } + // } + + // return parent.ProcessName; + //#pragma warning restore CA1416 // Validate platform compatibility + // } internal override void PrepareToRun () { @@ -969,7 +971,7 @@ internal void ProcessInput (WindowsConsole.InputRecord inputEvent) } if (inputEvent.KeyEvent.bKeyDown) { - OnKeyDown(new KeyEventEventArgs(key)); + OnKeyDown (new KeyEventEventArgs (key)); } else { OnKeyUp (new KeyEventEventArgs (key)); } @@ -1255,7 +1257,7 @@ async Task ProcessContinuousButtonPressedAsync (MouseFlags mouseFlag) break; } if (_isButtonPressed && (mouseFlag & MouseFlags.ReportMousePosition) == 0) { - Application.Invoke (() => OnMouseEvent (new MouseEventEventArgs(me))); + Application.Invoke (() => OnMouseEvent (new MouseEventEventArgs (me))); } } } diff --git a/Terminal.sln b/Terminal.sln index 9906265804..58a9ace1a8 100644 --- a/Terminal.sln +++ b/Terminal.sln @@ -24,6 +24,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution nuget.config = nuget.config .github\workflows\publish.yml = .github\workflows\publish.yml README.md = README.md + Terminal.Gui\.vscode\settings.json = Terminal.Gui\.vscode\settings.json Terminal.sln.DotSettings = Terminal.sln.DotSettings testenvironments.json = testenvironments.json EndProjectSection From 934ce0ee9b4335c9d5c1b0911b24062993ec11cd Mon Sep 17 00:00:00 2001 From: Tigger Kindel Date: Fri, 20 Oct 2023 06:51:44 -0600 Subject: [PATCH 014/194] Updates to fix #2634 (clear last line) --- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index e49af73072..01de5e59fb 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -1520,17 +1520,8 @@ internal override void Init () } WindowsConsole.SmallRect.MakeEmpty (ref _damageRegion); - // Needed for Windows Terminal - // ESC [ ? 1047 h Save cursor position and activate xterm alternative buffer (no backscroll) - // ESC [ ? 1047 l Restore cursor position and restore xterm working buffer (with backscroll) - // ESC [ ? 1048 h Save cursor position - // ESC [ ? 1048 l Restore cursor position - // ESC [ ? 1049 h Activate xterm alternative buffer (no backscroll) - // ESC [ ? 1049 l Restore xterm working buffer (with backscroll) - // Per Issue #2264 using the alternative screen buffer is required for Windows Terminal to not - // wipe out the backscroll buffer when the application exits. if (_isWindowsTerminal) { - Console.Out.Write (EscSeqUtils.CSI_SaveCursorAndActivateAltBufferNoBackscroll); + Console.Out.Write (EscSeqUtils.CSI_ActivateAltBufferNoBackscroll); } } catch (Win32Exception e) { // We are being run in an environment that does not support a console @@ -1570,7 +1561,7 @@ void ResizeScreen () public override void UpdateScreen () { - var windowSize = WinConsole?.GetConsoleBufferWindow (out _) ?? new Size (Cols, Rows); + var windowSize = WinConsole?.GetConsoleBufferWindow (out var _) ?? new Size (Cols, Rows); if (!windowSize.IsEmpty && (windowSize.Width != Cols || windowSize.Height != Rows)) { return; } @@ -1760,9 +1751,9 @@ internal override void End () WinConsole?.Cleanup (); WinConsole = null; - if (!RunningUnitTests && (_isWindowsTerminal || _parentProcessName == "devenv")) { + if (!RunningUnitTests && _isWindowsTerminal) { // Disable alternative screen buffer. - Console.Out.Write (EscSeqUtils.CSI_RestoreCursorAndActivateAltBufferWithBackscroll); + Console.Out.Write (EscSeqUtils.CSI_RestoreAltBufferWithBackscroll); } } From 6c13cc7d8bbd9824c5de2a7f0f55bdc8e8ee9858 Mon Sep 17 00:00:00 2001 From: Tigger Kindel Date: Fri, 20 Oct 2023 06:56:30 -0600 Subject: [PATCH 015/194] removes hacky GetParentProcess2 --- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index 01de5e59fb..d5fe29c384 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -786,7 +786,7 @@ internal class WindowsDriver : ConsoleDriver { public override bool SupportsTrueColor => RunningUnitTests || (Environment.OSVersion.Version.Build >= 14931 && _isWindowsTerminal); readonly bool _isWindowsTerminal = false; - readonly string _parentProcessName = "WindowsTerminal"; + //readonly string _parentProcessName = "WindowsTerminal"; WindowsMainLoop _mainLoopDriver = null; internal override MainLoop CreateMainLoop () From 624230667552eafcb504ecfdc1cebea9cd68bfe0 Mon Sep 17 00:00:00 2001 From: Tigger Kindel Date: Fri, 20 Oct 2023 07:03:01 -0600 Subject: [PATCH 016/194] Addressed mac resize issue --- Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs index 8904b2a731..0044cf414e 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/UnixMainLoop.cs @@ -188,7 +188,8 @@ void IMainLoopDriver.Iteration () if (_winChanged) { _winChanged = false; _cursesDriver.ProcessInput (); - //WinChanged?.Invoke (); + // This is needed on the mac. See https://github.com/gui-cs/Terminal.Gui/pull/2922#discussion_r1365992426 + _cursesDriver.ProcessWinChange (); } if (_pollMap == null) return; foreach (var p in _pollMap) { From aa4e568c1c6a816c60bf8397edebf3a75f5555a0 Mon Sep 17 00:00:00 2001 From: Tigger Kindel Date: Fri, 20 Oct 2023 07:49:34 -0600 Subject: [PATCH 017/194] Addressed mac resize issue --- Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs index e820763177..7c1fc64bea 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs @@ -59,7 +59,7 @@ public override void Refresh () UpdateCursor (); } - private void ProcessWinChange () + internal void ProcessWinChange () { if (!RunningUnitTests && Curses.CheckWinChange ()) { ClearContents (); From 237c4074e44540d61a06416af08f50298fe57c9d Mon Sep 17 00:00:00 2001 From: Tigger Kindel Date: Fri, 20 Oct 2023 08:55:13 -0600 Subject: [PATCH 018/194] Removes ConsoleDriver.PrepareToRun, has Init return MainLoop --- Terminal.Gui/Application.cs | 5 +- Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs | 14 +- .../CursesDriver/CursesDriver.cs | 165 +++++++++--------- .../ConsoleDrivers/FakeDriver/FakeDriver.cs | 16 +- Terminal.Gui/ConsoleDrivers/NetDriver.cs | 57 +++--- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 87 +++++---- UICatalog/Properties/launchSettings.json | 5 +- 7 files changed, 158 insertions(+), 191 deletions(-) diff --git a/Terminal.Gui/Application.cs b/Terminal.Gui/Application.cs index 7c33a721c9..b1bcc63fda 100644 --- a/Terminal.Gui/Application.cs +++ b/Terminal.Gui/Application.cs @@ -175,10 +175,8 @@ internal static void InternalInit (Func topLevelFactory, ConsoleDriver } } - MainLoop = Driver.CreateMainLoop (); - try { - Driver.Init (); + MainLoop = Driver.Init (); } catch (InvalidOperationException ex) { // This is a case where the driver is unable to initialize the console. // This can happen if the console is already in use by another process or @@ -192,7 +190,6 @@ internal static void InternalInit (Func topLevelFactory, ConsoleDriver Driver.KeyDown += (s, args) => OnKeyDown (args); Driver.KeyUp += (s, args) => OnKeyUp (args); Driver.MouseEvent += (s, args) => OnMouseEvent (args); - Driver.PrepareToRun (); SynchronizationContext.SetSynchronizationContext (new MainLoopSyncContext ()); diff --git a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs index 0eb4c7dfd4..7c0a25fcbd 100644 --- a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs @@ -33,21 +33,11 @@ public abstract class ConsoleDriver { #region Setup & Teardown - /// - /// Returns an instance of using the for the driver. - /// - /// - internal abstract MainLoop CreateMainLoop (); - /// /// Initializes the driver /// - internal abstract void Init (); - - /// - /// Prepare the driver and set the key and mouse events handlers. - /// - internal abstract void PrepareToRun (); + /// Returns an instance of using the for the driver. + internal abstract MainLoop Init (); /// /// Ends the execution of the console driver. diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs index 7c1fc64bea..012e9473cf 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs @@ -23,12 +23,90 @@ internal class CursesDriver : ConsoleDriver { public override string GetVersionInfo () => $"{Curses.curses_version ()}"; UnixMainLoop _mainLoopDriver = null; - internal override MainLoop CreateMainLoop () + public override bool SupportsTrueColor => false; + + object _processInputToken; + + internal override MainLoop Init () { _mainLoopDriver = new UnixMainLoop (this); + if (!RunningUnitTests) { + + _window = Curses.initscr (); + Curses.set_escdelay (10); + + // Ensures that all procedures are performed at some previous closing. + Curses.doupdate (); + + // + // We are setting Invisible as default so we could ignore XTerm DECSUSR setting + // + switch (Curses.curs_set (0)) { + case 0: + _currentCursorVisibility = _initialCursorVisibility = CursorVisibility.Invisible; + break; + + case 1: + _currentCursorVisibility = _initialCursorVisibility = CursorVisibility.Underline; + Curses.curs_set (1); + break; + + case 2: + _currentCursorVisibility = _initialCursorVisibility = CursorVisibility.Box; + Curses.curs_set (2); + break; + + default: + _currentCursorVisibility = _initialCursorVisibility = null; + break; + } + if (!Curses.HasColors) { + throw new InvalidOperationException ("V2 - This should never happen. File an Issue if it does."); + } + + Curses.raw (); + Curses.noecho (); + + Curses.Window.Standard.keypad (true); + + Curses.StartColor (); + Curses.UseDefaultColors (); + + if (!RunningUnitTests) { + Curses.timeout (0); + } + + _processInputToken = _mainLoopDriver?.AddWatch (0, UnixMainLoop.Condition.PollIn, x => { + ProcessInput (); + return true; + }); + } + + CurrentAttribute = MakeColor (ColorName.White, ColorName.Black); + + if (Environment.OSVersion.Platform == PlatformID.Win32NT) { + Clipboard = new FakeDriver.FakeClipboard (); + } else { + if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) { + Clipboard = new MacOSXClipboard (); + } else { + if (Is_WSL_Platform ()) { + Clipboard = new WSLClipboard (); + } else { + Clipboard = new CursesClipboard (); + } + } + } + + ClearContents (); + StartReportingMouseMoves (); + + if (!RunningUnitTests) { + Curses.CheckWinChange (); + Curses.refresh (); + } return new MainLoop (_mainLoopDriver); } - public override bool SupportsTrueColor => false; public override void Move (int col, int row) { @@ -601,89 +679,6 @@ bool IsButtonClickedOrDoubleClicked (MouseFlags flag) OnMouseEvent (new MouseEventEventArgs (me)); } - object _processInputToken; - - internal override void PrepareToRun () - { - if (!RunningUnitTests) { - Curses.timeout (0); - } - - _processInputToken = _mainLoopDriver?.AddWatch (0, UnixMainLoop.Condition.PollIn, x => { - ProcessInput (); - return true; - }); - } - - internal override void Init () - { - if (!RunningUnitTests) { - - _window = Curses.initscr (); - Curses.set_escdelay (10); - - // Ensures that all procedures are performed at some previous closing. - Curses.doupdate (); - - // - // We are setting Invisible as default so we could ignore XTerm DECSUSR setting - // - switch (Curses.curs_set (0)) { - case 0: - _currentCursorVisibility = _initialCursorVisibility = CursorVisibility.Invisible; - break; - - case 1: - _currentCursorVisibility = _initialCursorVisibility = CursorVisibility.Underline; - Curses.curs_set (1); - break; - - case 2: - _currentCursorVisibility = _initialCursorVisibility = CursorVisibility.Box; - Curses.curs_set (2); - break; - - default: - _currentCursorVisibility = _initialCursorVisibility = null; - break; - } - if (!Curses.HasColors) { - throw new InvalidOperationException ("V2 - This should never happen. File an Issue if it does."); - } - - Curses.raw (); - Curses.noecho (); - - Curses.Window.Standard.keypad (true); - - Curses.StartColor (); - Curses.UseDefaultColors (); - } - - CurrentAttribute = MakeColor (ColorName.White, ColorName.Black); - - if (Environment.OSVersion.Platform == PlatformID.Win32NT) { - Clipboard = new FakeDriver.FakeClipboard (); - } else { - if (RuntimeInformation.IsOSPlatform (OSPlatform.OSX)) { - Clipboard = new MacOSXClipboard (); - } else { - if (Is_WSL_Platform ()) { - Clipboard = new WSLClipboard (); - } else { - Clipboard = new CursesClipboard (); - } - } - } - - ClearContents (); - StartReportingMouseMoves (); - - if (!RunningUnitTests) { - Curses.CheckWinChange (); - Curses.refresh (); - } - } public static bool Is_WSL_Platform () { diff --git a/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs b/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs index 9338d0ce92..af9df98c18 100644 --- a/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs @@ -64,13 +64,8 @@ internal override void End () } FakeMainLoop _mainLoopDriver = null; - internal override MainLoop CreateMainLoop () - { - _mainLoopDriver = new FakeMainLoop (this); - return new MainLoop (_mainLoopDriver); - } - internal override void Init () + internal override MainLoop Init () { FakeConsole.MockKeyPresses.Clear (); @@ -80,6 +75,10 @@ internal override void Init () ResizeScreen (); CurrentAttribute = new Attribute (Color.White, Color.Black); ClearContents (); + + _mainLoopDriver = new FakeMainLoop (this); + _mainLoopDriver.KeyPressed = ProcessInput; + return new MainLoop (_mainLoopDriver); } @@ -348,11 +347,6 @@ private Key MapKeyModifiers (ConsoleKeyInfo keyInfo, Key key) private CursorVisibility _savedCursorVisibility; - internal override void PrepareToRun () - { - // Note: Net doesn't support keydown/up events and thus any passed keyDown/UpHandlers will never be called - _mainLoopDriver.KeyPressed = (consoleKey) => ProcessInput (consoleKey); - } void ProcessInput (ConsoleKeyInfo consoleKey) { diff --git a/Terminal.Gui/ConsoleDrivers/NetDriver.cs b/Terminal.Gui/ConsoleDrivers/NetDriver.cs index c8f6438864..bd313ac5fc 100644 --- a/Terminal.Gui/ConsoleDrivers/NetDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/NetDriver.cs @@ -629,44 +629,13 @@ internal class NetDriver : ConsoleDriver { const int COLOR_BRIGHT_WHITE = 97; NetMainLoop _mainLoopDriver = null; - internal override MainLoop CreateMainLoop () - { - _mainLoopDriver = new NetMainLoop (this); - return new MainLoop (_mainLoopDriver); - } public override bool SupportsTrueColor => Environment.OSVersion.Platform == PlatformID.Unix || (IsWinPlatform && Environment.OSVersion.Version.Build >= 14931); public NetWinVTConsole NetWinConsole { get; private set; } public bool IsWinPlatform { get; private set; } - internal override void PrepareToRun () - { - // Note: .Net API doesn't support keydown/up events and thus any passed keyDown/UpHandlers will be simulated to be called. - _mainLoopDriver.ProcessInput = ProcessInput; - } - - internal override void End () - { - if (IsWinPlatform) { - NetWinConsole?.Cleanup (); - } - - StopReportingMouseMoves (); - - if (!RunningUnitTests) { - Console.ResetColor (); - - //Disable alternative screen buffer. - Console.Out.Write (EscSeqUtils.CSI_RestoreCursorAndActivateAltBufferWithBackscroll); - - //Set cursor key to cursor. - Console.Out.Write (EscSeqUtils.CSI_ShowCursor); - Console.Out.Close (); - } - } - - internal override void Init () + internal override MainLoop Init () { var p = Environment.OSVersion.Platform; if (p == PlatformID.Win32NT || p == PlatformID.Win32S || p == PlatformID.Win32Windows) { @@ -713,6 +682,30 @@ internal override void Init () CurrentAttribute = new Attribute (Color.White, Color.Black); StartReportingMouseMoves (); + + _mainLoopDriver = new NetMainLoop (this); + _mainLoopDriver.ProcessInput = ProcessInput; + return new MainLoop (_mainLoopDriver); + } + + internal override void End () + { + if (IsWinPlatform) { + NetWinConsole?.Cleanup (); + } + + StopReportingMouseMoves (); + + if (!RunningUnitTests) { + Console.ResetColor (); + + //Disable alternative screen buffer. + Console.Out.Write (EscSeqUtils.CSI_RestoreCursorAndActivateAltBufferWithBackscroll); + + //Set cursor key to cursor. + Console.Out.Write (EscSeqUtils.CSI_ShowCursor); + Console.Out.Close (); + } } public virtual void ResizeScreen () diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index d5fe29c384..3f1969cc3b 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -789,11 +789,6 @@ internal class WindowsDriver : ConsoleDriver { //readonly string _parentProcessName = "WindowsTerminal"; WindowsMainLoop _mainLoopDriver = null; - internal override MainLoop CreateMainLoop () - { - _mainLoopDriver = new WindowsMainLoop (this); - return new MainLoop (_mainLoopDriver); - } public WindowsDriver () { @@ -859,12 +854,52 @@ public WindowsDriver () //#pragma warning restore CA1416 // Validate platform compatibility // } - internal override void PrepareToRun () + + internal override MainLoop Init () { + _mainLoopDriver = new WindowsMainLoop (this); + if (RunningUnitTests) { + return new MainLoop (_mainLoopDriver); + } + + try { + if (WinConsole != null) { + // BUGBUG: The results from GetConsoleOutputWindow are incorrect when called from Init. + // Our thread in WindowsMainLoop.CheckWin will get the correct results. See #if HACK_CHECK_WINCHANGED + var winSize = WinConsole.GetConsoleOutputWindow (out Point pos); + Cols = winSize.Width; + Rows = winSize.Height; + } + WindowsConsole.SmallRect.MakeEmpty (ref _damageRegion); + + if (_isWindowsTerminal) { + Console.Out.Write (EscSeqUtils.CSI_ActivateAltBufferNoBackscroll); + } + } catch (Win32Exception e) { + // We are being run in an environment that does not support a console + // such as a unit test, or a pipe. + Debug.WriteLine ($"Likely running unit tests. Setting WinConsole to null so we can test it elsewhere. Exception: {e}"); + WinConsole = null; + } + + CurrentAttribute = new Attribute (Color.White, Color.Black); + + _outputBuffer = new WindowsConsole.ExtendedCharInfo [Rows * Cols]; + Clip = new Rect (0, 0, Cols, Rows); + _damageRegion = new WindowsConsole.SmallRect () { + Top = 0, + Left = 0, + Bottom = (short)Rows, + Right = (short)Cols + }; + + ClearContents (); #if HACK_CHECK_WINCHANGED _mainLoopDriver.WinChanged = ChangeWin; #endif + return new MainLoop (_mainLoopDriver); + } #if HACK_CHECK_WINCHANGED @@ -1504,46 +1539,6 @@ public override bool IsRuneSupported (Rune rune) return base.IsRuneSupported (rune) && rune.IsBmp; } - internal override void Init () - { - if (RunningUnitTests) { - return; - } - - try { - if (WinConsole != null) { - // BUGBUG: The results from GetConsoleOutputWindow are incorrect when called from Init. - // Our thread in WindowsMainLoop.CheckWin will get the correct results. See #if HACK_CHECK_WINCHANGED - var winSize = WinConsole.GetConsoleOutputWindow (out Point pos); - Cols = winSize.Width; - Rows = winSize.Height; - } - WindowsConsole.SmallRect.MakeEmpty (ref _damageRegion); - - if (_isWindowsTerminal) { - Console.Out.Write (EscSeqUtils.CSI_ActivateAltBufferNoBackscroll); - } - } catch (Win32Exception e) { - // We are being run in an environment that does not support a console - // such as a unit test, or a pipe. - Debug.WriteLine ($"Likely running unit tests. Setting WinConsole to null so we can test it elsewhere. Exception: {e}"); - WinConsole = null; - } - - CurrentAttribute = new Attribute (Color.White, Color.Black); - - _outputBuffer = new WindowsConsole.ExtendedCharInfo [Rows * Cols]; - Clip = new Rect (0, 0, Cols, Rows); - _damageRegion = new WindowsConsole.SmallRect () { - Top = 0, - Left = 0, - Bottom = (short)Rows, - Right = (short)Cols - }; - - ClearContents (); - } - void ResizeScreen () { _outputBuffer = new WindowsConsole.ExtendedCharInfo [Rows * Cols]; diff --git a/UICatalog/Properties/launchSettings.json b/UICatalog/Properties/launchSettings.json index c99be34687..b06e2ce0bc 100644 --- a/UICatalog/Properties/launchSettings.json +++ b/UICatalog/Properties/launchSettings.json @@ -1,7 +1,10 @@ { "profiles": { "UICatalog": { - "commandName": "Project" + "commandName": "Project", + "environmentVariables": { + "WT_SESSION": "yes" + } }, "WSL : UICatalog": { "commandName": "Executable", From d52a147fbf6c65d44b764aad6e3a4dab1c111716 Mon Sep 17 00:00:00 2001 From: Tigger Kindel Date: Fri, 20 Oct 2023 09:11:40 -0600 Subject: [PATCH 019/194] Removes unneeded Attribute methods --- Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs | 13 ++--------- .../CursesDriver/CursesDriver.cs | 23 ++----------------- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 23 +------------------ Terminal.Gui/Drawing/Color.cs | 3 ++- 4 files changed, 7 insertions(+), 55 deletions(-) diff --git a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs index 7c0a25fcbd..042a10bb24 100644 --- a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs @@ -415,23 +415,14 @@ public Attribute SetAttribute (Attribute c) return prevAttribute; } - /// - /// Make the attribute for the foreground and background colors. - /// - /// Foreground. - /// Background. - /// - public virtual Attribute MakeAttribute (Color fore, Color back) - { - return MakeColor (fore, back); - } - /// /// Gets the current . /// /// The current attribute. public Attribute GetAttribute () => CurrentAttribute; + // TODO: This is only overridden by CursesDriver. Once CursesDriver supports 24-bit color, this virtual method can be + // removed (and Attribute can lose the platformColor property). /// /// Makes an . /// diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs index 012e9473cf..036c201783 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs @@ -82,7 +82,7 @@ internal override MainLoop Init () }); } - CurrentAttribute = MakeColor (ColorName.White, ColorName.Black); + CurrentAttribute = new Attribute (ColorName.White, ColorName.Black); if (Environment.OSVersion.Platform == PlatformID.Win32NT) { Clipboard = new FakeDriver.FakeClipboard (); @@ -165,25 +165,6 @@ static Attribute MakeColor (short foreground, short background) background: CursesColorNumberToColorName (background)); } - /// - /// In the CursesDriver, colors are encoded as an int. - /// The foreground color is stored in the most significant 4 bits, - /// and the background color is stored in the least significant 4 bits. - /// The Terminal.GUi Color values are converted to curses color encoding before being encoded. - /// - private Attribute MakeColor (ColorName foregroundName, ColorName backgroundName) - { - if (!RunningUnitTests) { - return MakeColor (ColorNameToCursesColorNumber (foregroundName), ColorNameToCursesColorNumber (backgroundName)); - } else { - return new Attribute ( - platformColor: 0, - foreground: ColorNameToCursesColorNumber (foregroundName), - background: ColorNameToCursesColorNumber (backgroundName)); - } - } - - /// /// In the CursesDriver, colors are encoded as an int. /// The foreground color is stored in the most significant 4 bits, @@ -193,7 +174,7 @@ private Attribute MakeColor (ColorName foregroundName, ColorName backgroundName) public override Attribute MakeColor (Color foreground, Color background) { if (!RunningUnitTests) { - return MakeColor (foreground.ColorName, background.ColorName); + return MakeColor (ColorNameToCursesColorNumber (foreground.ColorName), ColorNameToCursesColorNumber (background.ColorName)); } else { return new Attribute ( platformColor: 0, diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index 3f1969cc3b..5c14f0688a 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -18,12 +18,10 @@ using System; using System.Collections.Generic; using System.ComponentModel; -using System.Linq; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using System.Diagnostics; -using System.Management; namespace Terminal.Gui; @@ -1619,26 +1617,7 @@ public override void Refresh () WinConsole?.SetInitialCursorVisibility (); UpdateCursor (); } - - #region Color Handling - - /// - /// In the WindowsDriver, colors are encoded as an int. - /// The background color is stored in the least significant 4 bits, - /// and the foreground color is stored in the next 4 bits. - /// - public override Attribute MakeColor (Color foreground, Color background) - { - // Encode the colors into the int value. - return new Attribute ( - platformColor: 0, // Not used anymore! (((int)foreground.ColorName) | ((int)background.ColorName << 4)), - foreground: foreground, - background: background - ); - } - - #endregion - + CursorVisibility _cachedCursorVisibility; public override void UpdateCursor () diff --git a/Terminal.Gui/Drawing/Color.cs b/Terminal.Gui/Drawing/Color.cs index e2f40d2183..a1ce645cbb 100644 --- a/Terminal.Gui/Drawing/Color.cs +++ b/Terminal.Gui/Drawing/Color.cs @@ -706,12 +706,13 @@ public Attribute (Color foreground, Color background) Foreground = foreground; Background = background; + // TODO: Once CursesDriver supports truecolor all the PlatformColor stuff goes away if (Application.Driver == null) { PlatformColor = -1; return; } - var make = Application.Driver.MakeAttribute (foreground, background); + var make = Application.Driver.MakeColor (foreground, background); PlatformColor = make.PlatformColor; } From dcb972d1082b75b82ad8214ca6024639704a03a5 Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Fri, 20 Oct 2023 13:15:16 -0600 Subject: [PATCH 020/194] Removed GetProcesssName --- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 62 +++----------------- 1 file changed, 7 insertions(+), 55 deletions(-) diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index 5c14f0688a..61553a5e09 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -784,8 +784,6 @@ internal class WindowsDriver : ConsoleDriver { public override bool SupportsTrueColor => RunningUnitTests || (Environment.OSVersion.Version.Build >= 14931 && _isWindowsTerminal); readonly bool _isWindowsTerminal = false; - //readonly string _parentProcessName = "WindowsTerminal"; - WindowsMainLoop _mainLoopDriver = null; public WindowsDriver () @@ -798,60 +796,14 @@ public WindowsDriver () Clipboard = new FakeDriver.FakeClipboard (); } - if (!RunningUnitTests) { - _isWindowsTerminal = Environment.GetEnvironmentVariable ("WT_SESSION") != null; - if (!_isWindowsTerminal) { - //_parentProcessName = GetParentProcessName (); - //_isWindowsTerminal = _parentProcessName == "WindowsTerminal"; - //if (!_isWindowsTerminal && _parentProcessName != "devenv") { - Force16Colors = true; - //} - } + // TODO: if some other Windows-based terminal supports true color, update this logic to not + // force 16color mode (.e.g ConEmu which really doesn't work well at all). + _isWindowsTerminal = Environment.GetEnvironmentVariable ("WT_SESSION") != null; + if (!_isWindowsTerminal) { + Force16Colors = true; } - } - - // BUGBUG: This code is a hack and has an infinite loop if WT is started from a non-WT terminal (start.run "pwsh"). - // commenting out for now. A better workaround for running in the VS debugger is to set the environment variable - // in the `launchSettings.json` file. - // private static string GetParentProcessName () - // { - //#pragma warning disable CA1416 // Validate platform compatibility - // var myId = Process.GetCurrentProcess ().Id; - // var query = string.Format ($"SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {myId}"); - // var search = new ManagementObjectSearcher ("root\\CIMV2", query); - // var queryObj = search.Get ().OfType ().FirstOrDefault (); - // if (queryObj == null) { - // return null; - // } - // var parentId = (uint)queryObj ["ParentProcessId"]; - // var parent = Process.GetProcessById ((int)parentId); - // var prevParent = parent; - - // // Check if the parent is from other parent - // while (queryObj != null) { - // query = string.Format ($"SELECT ParentProcessId FROM Win32_Process WHERE ProcessId = {parentId}"); - // search = new ManagementObjectSearcher ("root\\CIMV2", query); - // queryObj = search.Get ().OfType ().FirstOrDefault (); - // if (queryObj == null) { - // return parent.ProcessName; - // } - // parentId = (uint)queryObj ["ParentProcessId"]; - // try { - // parent = Process.GetProcessById ((int)parentId); - // if (string.Equals (parent.ProcessName, "explorer", StringComparison.InvariantCultureIgnoreCase)) { - // return prevParent.ProcessName; - // } - // prevParent = parent; - // } catch (ArgumentException) { - - // return prevParent.ProcessName; - // } - // } - - // return parent.ProcessName; - //#pragma warning restore CA1416 // Validate platform compatibility - // } + } internal override MainLoop Init () { @@ -1617,7 +1569,7 @@ public override void Refresh () WinConsole?.SetInitialCursorVisibility (); UpdateCursor (); } - + CursorVisibility _cachedCursorVisibility; public override void UpdateCursor () From f3ee2900a12231e3a5815ac44a84771ae81c0e6f Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Fri, 20 Oct 2023 13:15:27 -0600 Subject: [PATCH 021/194] Removed GetProcesssName --- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index 61553a5e09..ac442720b8 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -802,7 +802,6 @@ public WindowsDriver () if (!_isWindowsTerminal) { Force16Colors = true; } - } internal override MainLoop Init () From 88a00658dbcb53306d56af1b766594c0eea10b2c Mon Sep 17 00:00:00 2001 From: Tig Kindel Date: Fri, 20 Oct 2023 14:55:24 -0600 Subject: [PATCH 022/194] Refactored KeyEvent and KeyEventEventArgs into a single class --- Terminal.Gui/Application.cs | 37 +- Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs | 12 +- .../CursesDriver/CursesDriver.cs | 50 +- .../ConsoleDrivers/FakeDriver/FakeDriver.cs | 10 +- Terminal.Gui/ConsoleDrivers/NetDriver.cs | 10 +- Terminal.Gui/ConsoleDrivers/WindowsDriver.cs | 28 +- Terminal.Gui/Input/KeyEventEventArgs.cs | 24 - Terminal.Gui/Input/{Event.cs => Keyboard.cs} | 249 +--- Terminal.Gui/Input/Mouse.cs | 186 +++ Terminal.Gui/Input/Responder.cs | 77 +- Terminal.Gui/Input/ShortcutHelper.cs | 4 +- .../Text/Autocomplete/AppendAutocomplete.cs | 2 +- .../Text/Autocomplete/AutocompleteBase.cs | 2 +- .../Text/Autocomplete/IAutocomplete.cs | 2 +- .../Text/Autocomplete/PopupAutocomplete.cs | 4 +- Terminal.Gui/Text/CollectionNavigatorBase.cs | 2 +- Terminal.Gui/View/ViewKeyboard.cs | 91 +- Terminal.Gui/Views/Button.cs | 14 +- Terminal.Gui/Views/CheckBox.cs | 8 +- Terminal.Gui/Views/ColorPicker.cs | 4 +- Terminal.Gui/Views/ComboBox.cs | 6 +- Terminal.Gui/Views/DateField.cs | 8 +- Terminal.Gui/Views/Dialog.cs | 6 +- Terminal.Gui/Views/FileDialog.cs | 34 +- Terminal.Gui/Views/GraphView/GraphView.cs | 4 +- Terminal.Gui/Views/HexView.cs | 2 +- Terminal.Gui/Views/Label.cs | 2 +- Terminal.Gui/Views/ListView.cs | 4 +- Terminal.Gui/Views/Menu.cs | 22 +- Terminal.Gui/Views/RadioGroup.cs | 6 +- Terminal.Gui/Views/ScrollView.cs | 6 +- Terminal.Gui/Views/Slider.cs | 6 +- Terminal.Gui/Views/StatusBar.cs | 2 +- Terminal.Gui/Views/TabView.cs | 6 +- Terminal.Gui/Views/TableView/TableView.cs | 16 +- .../Views/TableView/TreeTableSource.cs | 6 +- Terminal.Gui/Views/TextField.cs | 16 +- Terminal.Gui/Views/TextValidateField.cs | 2 +- Terminal.Gui/Views/TextView.cs | 12 +- Terminal.Gui/Views/TileView.cs | 8 +- Terminal.Gui/Views/TimeField.cs | 2 +- Terminal.Gui/Views/Toplevel.cs | 16 +- Terminal.Gui/Views/TreeView/TreeView.cs | 10 +- Terminal.Gui/Views/Wizard/Wizard.cs | 10 +- UICatalog/KeyBindingsDialog.cs | 2 +- UICatalog/Scenarios/ASCIICustomButton.cs | 12 +- .../Scenarios/BackgroundWorkerCollection.cs | 2 +- UICatalog/Scenarios/ContextMenus.cs | 2 +- UICatalog/Scenarios/CsvEditor.cs | 4 +- UICatalog/Scenarios/DynamicMenuBar.cs | 8 +- UICatalog/Scenarios/DynamicStatusBar.cs | 8 +- UICatalog/Scenarios/Editor.cs | 8 +- UICatalog/Scenarios/InteractiveTree.cs | 4 +- UICatalog/Scenarios/Keys.cs | 53 +- UICatalog/Scenarios/LineDrawing.cs | 6 +- UICatalog/Scenarios/ListColumns.cs | 4 +- UICatalog/Scenarios/SendKeys.cs | 10 +- UICatalog/Scenarios/SingleBackgroundWorker.cs | 2 +- UICatalog/Scenarios/Snake.cs | 2 +- UICatalog/Scenarios/TableEditor.cs | 4 +- UICatalog/Scenarios/TreeViewFileSystem.cs | 4 +- UICatalog/Scenarios/VkeyPacketSimulator.cs | 39 +- UICatalog/UICatalog.cs | 12 +- UnitTests/Application/ApplicationTests.cs | 62 +- UnitTests/Application/MainLoopTests.cs | 4 +- .../ConsoleDrivers/ConsoleDriverTests.cs | 8 +- UnitTests/ConsoleDrivers/KeyTests.cs | 2 +- UnitTests/Dialogs/DialogTests.cs | 8 +- UnitTests/Input/ResponderTests.cs | 12 +- UnitTests/Text/AutocompleteTests.cs | 34 +- UnitTests/Text/CollectionNavigatorTests.cs | 4 +- UnitTests/UICatalog/ScenarioTests.cs | 10 +- UnitTests/View/KeyboardTests.cs | 30 +- UnitTests/View/Layout/DimTests.cs | 20 +- UnitTests/View/Layout/PosTests.cs | 8 +- UnitTests/View/NavigationTests.cs | 48 +- UnitTests/View/ViewTests.cs | 16 +- UnitTests/Views/AllViewsTests.cs | 6 +- UnitTests/Views/AppendAutocompleteTests.cs | 10 +- UnitTests/Views/ButtonTests.cs | 26 +- UnitTests/Views/CheckBoxTests.cs | 14 +- UnitTests/Views/ColorPickerTests.cs | 12 +- UnitTests/Views/ComboBoxTests.cs | 126 +- UnitTests/Views/ContextMenuTests.cs | 16 +- UnitTests/Views/DateFieldTests.cs | 26 +- UnitTests/Views/HexViewTests.cs | 114 +- UnitTests/Views/ListViewTests.cs | 36 +- UnitTests/Views/MenuTests.cs | 210 ++-- UnitTests/Views/RadioGroupTests.cs | 20 +- UnitTests/Views/ScrollViewTests.cs | 130 +-- UnitTests/Views/StatusBarTests.cs | 4 +- UnitTests/Views/TableViewTests.cs | 186 +-- UnitTests/Views/TextFieldTests.cs | 200 ++-- UnitTests/Views/TextValidateFieldTests.cs | 110 +- UnitTests/Views/TextViewTests.cs | 1036 ++++++++--------- UnitTests/Views/TileViewTests.cs | 70 +- UnitTests/Views/TimeFieldTests.cs | 26 +- UnitTests/Views/ToplevelTests.cs | 110 +- UnitTests/Views/TreeTableSourceTests.cs | 32 +- UnitTests/Views/TreeViewTests.cs | 14 +- UnitTests/Views/WindowTests.cs | 2 +- 101 files changed, 1998 insertions(+), 2018 deletions(-) delete mode 100644 Terminal.Gui/Input/KeyEventEventArgs.cs rename Terminal.Gui/Input/{Event.cs => Keyboard.cs} (65%) create mode 100644 Terminal.Gui/Input/Mouse.cs diff --git a/Terminal.Gui/Application.cs b/Terminal.Gui/Application.cs index b1bcc63fda..57d9f50225 100644 --- a/Terminal.Gui/Application.cs +++ b/Terminal.Gui/Application.cs @@ -94,7 +94,7 @@ private static List GetSupportedCultures () #region Initialization (Init/Shutdown) /// - /// Initializes a new instance of Application. + /// Initializes a new instance of a Application. /// /// /// Call this method once per instance (or after has been called). @@ -1064,7 +1064,6 @@ public static void GrabMouse (View view) if (!OnGrabbingMouse (view)) { OnGrabbedMouse (view); _mouseGrabView = view; - //Driver.UncookMouse (); } } @@ -1121,8 +1120,8 @@ static void OnUnGrabbedMouse (View view) /// /// /// - /// Use this event to receive mouse events in screen coordinates. Use to receive - /// mouse events relative to a 's bounds. + /// Use this event to receive all mouse events in screen coordinates. Use to receive + /// mouse events specific to a 's bounds. /// /// /// The will contain the that contains the mouse coordinates. @@ -1279,7 +1278,7 @@ static void OnAlternateBackwardKeyChanged (KeyChangedEventArgs oldKey) static Key _quitKey = Key.Q | Key.CtrlMask; /// - /// Gets or sets the key to quit the application. + /// Gets or sets the key to quit the application. The default is Ctrl-Q. /// [SerializableConfigurationProperty (Scope = typeof (SettingsScope)), JsonConverter (typeof (KeyJsonConverter))] public static Key QuitKey { @@ -1302,13 +1301,17 @@ static void OnQuitKeyChanged (KeyChangedEventArgs e) /// /// Event fired after a key has been pressed and released. - /// Set to to suppress the event. + /// Set to to suppress the event. /// + /// . /// + /// + /// + /// /// All drivers support firing the event. Some drivers (Curses) /// do not support firing the and events. /// - public static event EventHandler KeyPressed; + public static event EventHandler KeyPressed; /// /// Called after a key has been pressed and released. Fires the event. @@ -1319,7 +1322,7 @@ static void OnQuitKeyChanged (KeyChangedEventArgs e) /// /// /// if the key was handled. - public static bool OnKeyPressed (KeyEventEventArgs a) + public static bool OnKeyPressed (KeyEventArgs a) { KeyPressed?.Invoke (null, a); if (a.Handled) { @@ -1328,7 +1331,7 @@ public static bool OnKeyPressed (KeyEventEventArgs a) var chain = _topLevels.ToList (); foreach (var topLevel in chain) { - if (topLevel.ProcessHotKey (a.KeyEvent)) { + if (topLevel.ProcessHotKey (a)) { return true; } if (topLevel.Modal) @@ -1336,7 +1339,7 @@ public static bool OnKeyPressed (KeyEventEventArgs a) } foreach (var topLevel in chain) { - if (topLevel.ProcessKey (a.KeyEvent)) { + if (topLevel.OnKeyPressed (a)) { return true; } if (topLevel.Modal) @@ -1345,7 +1348,7 @@ public static bool OnKeyPressed (KeyEventEventArgs a) foreach (var topLevel in chain) { // Process the key normally - if (topLevel.ProcessColdKey (a.KeyEvent)) { + if (topLevel.ProcessColdKey (a)) { return true; } if (topLevel.Modal) @@ -1361,18 +1364,18 @@ public static bool OnKeyPressed (KeyEventEventArgs a) /// All drivers support firing the event. Some drivers (Curses) /// do not support firing the and events. /// - public static event EventHandler KeyDown; + public static event EventHandler KeyDown; /// /// Called when a key is pressed (and not yet released). Fires the event. /// /// - public static void OnKeyDown (KeyEventEventArgs a) + public static void OnKeyDown (KeyEventArgs a) { KeyDown?.Invoke (null, a); var chain = _topLevels.ToList (); foreach (var topLevel in chain) { - if (topLevel.OnKeyDown (a.KeyEvent)) + if (topLevel.OnKeyDown (a)) return; if (topLevel.Modal) break; @@ -1386,18 +1389,18 @@ public static void OnKeyDown (KeyEventEventArgs a) /// All drivers support firing the event. Some drivers (Curses) /// do not support firing the and events. /// - public static event EventHandler KeyUp; + public static event EventHandler KeyUp; /// /// Called when a key is released. Fires the event. /// /// - public static void OnKeyUp (KeyEventEventArgs a) + public static void OnKeyUp (KeyEventArgs a) { KeyUp?.Invoke (null, a); var chain = _topLevels.ToList (); foreach (var topLevel in chain) { - if (topLevel.OnKeyUp (a.KeyEvent)) + if (topLevel.OnKeyUp (a)) return; if (topLevel.Modal) break; diff --git a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs index 042a10bb24..d3150d0f7e 100644 --- a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs @@ -447,35 +447,35 @@ public virtual Attribute MakeColor (Color foreground, Color background) /// /// Event fired after a key has been pressed and released. /// - public event EventHandler KeyPressed; + public event EventHandler KeyPressed; /// /// Called after a key has been pressed and released. Fires the event. /// /// - public void OnKeyPressed (KeyEventEventArgs a) => KeyPressed?.Invoke(this, a); + public void OnKeyPressed (KeyEventArgs a) => KeyPressed?.Invoke(this, a); /// /// Event fired when a key is released. /// - public event EventHandler KeyUp; + public event EventHandler KeyUp; /// /// Called when a key is released. Fires the event. /// /// - public void OnKeyUp (KeyEventEventArgs a) => KeyUp?.Invoke (this, a); + public void OnKeyUp (KeyEventArgs a) => KeyUp?.Invoke (this, a); /// /// Event fired when a key is pressed. /// - public event EventHandler KeyDown; + public event EventHandler KeyDown; /// /// Called when a key is pressed. Fires the event. /// /// - public void OnKeyDown (KeyEventEventArgs a) => KeyDown?.Invoke (this, a); + public void OnKeyDown (KeyEventArgs a) => KeyDown?.Invoke (this, a); /// /// Event fired when a mouse event occurs. diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs index 036c201783..8cc537b351 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs @@ -458,7 +458,7 @@ internal void ProcessInput () int wch2 = wch; while (wch2 == Curses.KeyMouse) { - KeyEvent key = null; + KeyEventArgs key = null; ConsoleKeyInfo [] cki = new ConsoleKeyInfo [] { new ConsoleKeyInfo ((char)Key.Esc, 0, false, false, false), new ConsoleKeyInfo ('[', 0, false, false, false), @@ -491,9 +491,9 @@ internal void ProcessInput () wch -= 60; k = Key.ShiftMask | Key.AltMask | MapCursesKey (wch); } - OnKeyDown (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); - OnKeyUp (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); - OnKeyPressed (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); + OnKeyDown (new KeyEventArgs (k, MapKeyModifiers (k))); + OnKeyUp (new KeyEventArgs (k, MapKeyModifiers (k))); + OnKeyPressed (new KeyEventArgs (k, MapKeyModifiers (k))); return; } @@ -507,7 +507,7 @@ internal void ProcessInput () k = Key.AltMask | MapCursesKey (wch); } if (code == 0) { - KeyEvent key = null; + KeyEventArgs key = null; // The ESC-number handling, debatable. // Simulates the AltMask itself by pressing Alt + Space. @@ -543,19 +543,19 @@ internal void ProcessInput () k = (Key)((uint)(Key.AltMask | Key.CtrlMask) + wch2); } } - key = new KeyEvent (k, MapKeyModifiers (k)); - OnKeyDown (new KeyEventEventArgs (key)); - OnKeyUp (new KeyEventEventArgs (key)); - OnKeyPressed (new KeyEventEventArgs (key)); + key = new KeyEventArgs (k, MapKeyModifiers (k)); + OnKeyDown (key); + OnKeyUp (key); + OnKeyPressed (key); } else { k = Key.Esc; - OnKeyPressed (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); + OnKeyPressed (new KeyEventArgs (k, MapKeyModifiers (k))); } } else if (wch == Curses.KeyTab) { k = MapCursesKey (wch); - OnKeyDown (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); - OnKeyUp (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); - OnKeyPressed (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); + OnKeyDown (new KeyEventArgs (k, MapKeyModifiers (k))); + OnKeyUp (new KeyEventArgs (k, MapKeyModifiers (k))); + OnKeyPressed (new KeyEventArgs (k, MapKeyModifiers (k))); } else { // Unfortunately there are no way to differentiate Ctrl+alfa and Ctrl+Shift+alfa. k = (Key)wch; @@ -568,21 +568,21 @@ internal void ProcessInput () } else if (wch >= (uint)Key.A && wch <= (uint)Key.Z) { _keyModifiers.Shift = true; } - OnKeyDown (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); - OnKeyUp (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); - OnKeyPressed (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); + OnKeyDown (new KeyEventArgs (k, MapKeyModifiers (k))); + OnKeyUp (new KeyEventArgs (k, MapKeyModifiers (k))); + OnKeyPressed (new KeyEventArgs (k, MapKeyModifiers (k))); } // Cause OnKeyUp and OnKeyPressed. Note that the special handling for ESC above // will not impact KeyUp. // This is causing ESC firing even if another keystroke was handled. //if (wch == Curses.KeyTab) { - // keyUpHandler (new KeyEvent (MapCursesKey (wch), keyModifiers)); + // keyUpHandler (new KeyEventArgs (MapCursesKey (wch), keyModifiers)); //} else { - // keyUpHandler (new KeyEvent ((Key)wch, keyModifiers)); + // keyUpHandler (new KeyEventArgs ((Key)wch, keyModifiers)); //} } - void HandleEscSeqResponse (ref int code, ref Key k, ref int wch2, ref KeyEvent key, ref ConsoleKeyInfo [] cki) + void HandleEscSeqResponse (ref int code, ref Key k, ref int wch2, ref KeyEventArgs key, ref ConsoleKeyInfo [] cki) { ConsoleKey ck = 0; ConsoleModifiers mod = 0; @@ -603,9 +603,9 @@ void HandleEscSeqResponse (ref int code, ref Key k, ref int wch2, ref KeyEvent k } else { k = ConsoleKeyMapping.MapConsoleKeyToKey (consoleKeyInfo.Key, out _); k = ConsoleKeyMapping.MapKeyModifiers (consoleKeyInfo, k); - key = new KeyEvent (k, MapKeyModifiers (k)); - OnKeyDown (new KeyEventEventArgs (key)); - OnKeyPressed (new KeyEventEventArgs (key)); + key = new KeyEventArgs (k, MapKeyModifiers (k)); + OnKeyDown (key); + OnKeyPressed (key); } } else { cki = EscSeqUtils.ResizeArray (consoleKeyInfo, cki); @@ -778,9 +778,9 @@ public override void SendKeys (char keyChar, ConsoleKey consoleKey, bool shift, key |= Key.CtrlMask; km.Ctrl = control; } - OnKeyDown (new KeyEventEventArgs (new KeyEvent (key, km))); - OnKeyPressed (new KeyEventEventArgs (new KeyEvent (key, km))); - OnKeyUp (new KeyEventEventArgs (new KeyEvent (key, km))); + OnKeyDown (new KeyEventArgs (key, km)); + OnKeyPressed (new KeyEventArgs (key, km)); + OnKeyUp (new KeyEventArgs (key, km)); } diff --git a/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs b/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs index af9df98c18..9208202367 100644 --- a/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs @@ -366,15 +366,15 @@ void ProcessInput (ConsoleKeyInfo consoleKey) var map = MapKey (consoleKey); if (map == (Key)0xffffffff) { if ((consoleKey.Modifiers & (ConsoleModifiers.Shift | ConsoleModifiers.Alt | ConsoleModifiers.Control)) != 0) { - OnKeyDown(new KeyEventEventArgs(new KeyEvent (map, keyModifiers))); - OnKeyUp (new KeyEventEventArgs (new KeyEvent (map, keyModifiers))); + OnKeyDown(new KeyEventArgs (map, keyModifiers)); + OnKeyUp (new KeyEventArgs (map, keyModifiers)); } return; } - OnKeyDown (new KeyEventEventArgs (new KeyEvent (map, keyModifiers))); - OnKeyUp (new KeyEventEventArgs (new KeyEvent (map, keyModifiers))); - OnKeyPressed (new KeyEventEventArgs (new KeyEvent (map, keyModifiers))); + OnKeyDown (new KeyEventArgs (map, keyModifiers)); + OnKeyUp (new KeyEventArgs (map, keyModifiers)); + OnKeyPressed (new KeyEventArgs (map, keyModifiers)); } /// diff --git a/Terminal.Gui/ConsoleDrivers/NetDriver.cs b/Terminal.Gui/ConsoleDrivers/NetDriver.cs index bd313ac5fc..1136aa294b 100644 --- a/Terminal.Gui/ConsoleDrivers/NetDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/NetDriver.cs @@ -1125,12 +1125,12 @@ void ProcessInput (NetEvents.InputResult inputEvent) return; } if (map == Key.Null) { - OnKeyDown (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); - OnKeyUp (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); + OnKeyDown (new KeyEventArgs (map, _keyModifiers)); + OnKeyUp (new KeyEventArgs (map, _keyModifiers)); } else { - OnKeyDown (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); - OnKeyUp (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); - OnKeyPressed (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); + OnKeyDown (new KeyEventArgs (map, _keyModifiers)); + OnKeyUp (new KeyEventArgs (map, _keyModifiers)); + OnKeyPressed (new KeyEventArgs (map, _keyModifiers)); } break; case NetEvents.EventType.Mouse: diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index ac442720b8..64c383fbd2 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -902,7 +902,7 @@ internal void ProcessInput (WindowsConsole.InputRecord inputEvent) //System.Diagnostics.Debug.WriteLine ($"wVirtualScanCode: {ke.wVirtualScanCode}"); if (map == (Key)0xffffffff) { - KeyEvent key = new KeyEvent (); + KeyEventArgs key = new KeyEventArgs (); // Shift = VK_SHIFT = 0x10 // Ctrl = VK_CONTROL = 0x11 @@ -926,17 +926,17 @@ internal void ProcessInput (WindowsConsole.InputRecord inputEvent) WindowsConsole.ControlKeyState.LeftControlPressed | WindowsConsole.ControlKeyState.EnhancedKey: case WindowsConsole.ControlKeyState.EnhancedKey: - key = new KeyEvent (Key.CtrlMask | Key.AltMask, _keyModifiers); + key = new KeyEventArgs (Key.CtrlMask | Key.AltMask, _keyModifiers); break; case WindowsConsole.ControlKeyState.LeftAltPressed: - key = new KeyEvent (Key.AltMask, _keyModifiers); + key = new KeyEventArgs (Key.AltMask, _keyModifiers); break; case WindowsConsole.ControlKeyState.RightControlPressed: case WindowsConsole.ControlKeyState.LeftControlPressed: - key = new KeyEvent (Key.CtrlMask, _keyModifiers); + key = new KeyEventArgs (Key.CtrlMask, _keyModifiers); break; case WindowsConsole.ControlKeyState.ShiftPressed: - key = new KeyEvent (Key.ShiftMask, _keyModifiers); + key = new KeyEventArgs (Key.ShiftMask, _keyModifiers); break; case WindowsConsole.ControlKeyState.NumlockOn: break; @@ -946,28 +946,28 @@ internal void ProcessInput (WindowsConsole.InputRecord inputEvent) break; default: key = inputEvent.KeyEvent.wVirtualKeyCode switch { - 0x10 => new KeyEvent (Key.ShiftMask, _keyModifiers), - 0x11 => new KeyEvent (Key.CtrlMask, _keyModifiers), - 0x12 => new KeyEvent (Key.AltMask, _keyModifiers), - _ => new KeyEvent (Key.Unknown, _keyModifiers) + 0x10 => new KeyEventArgs (Key.ShiftMask, _keyModifiers), + 0x11 => new KeyEventArgs (Key.CtrlMask, _keyModifiers), + 0x12 => new KeyEventArgs (Key.AltMask, _keyModifiers), + _ => new KeyEventArgs (Key.Unknown, _keyModifiers) }; break; } if (inputEvent.KeyEvent.bKeyDown) { - OnKeyDown (new KeyEventEventArgs (key)); + OnKeyDown (key); } else { - OnKeyUp (new KeyEventEventArgs (key)); + OnKeyUp (key); } } else { if (inputEvent.KeyEvent.bKeyDown) { // May occurs using SendKeys _keyModifiers ??= new KeyModifiers (); // Key Down - Fire KeyDown Event and KeyPressed Event - OnKeyDown (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); + OnKeyDown (new KeyEventArgs (map, _keyModifiers)); } else { - OnKeyUp (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); - OnKeyPressed (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); + OnKeyUp (new KeyEventArgs (map, _keyModifiers)); + OnKeyPressed (new KeyEventArgs (map, _keyModifiers)); } } if (!inputEvent.KeyEvent.bKeyDown && inputEvent.KeyEvent.dwControlKeyState == 0) { diff --git a/Terminal.Gui/Input/KeyEventEventArgs.cs b/Terminal.Gui/Input/KeyEventEventArgs.cs deleted file mode 100644 index c7ab9e39a2..0000000000 --- a/Terminal.Gui/Input/KeyEventEventArgs.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; - -namespace Terminal.Gui { - - /// - /// Defines the event arguments for - /// - public class KeyEventEventArgs : EventArgs { - /// - /// Constructs. - /// - /// - public KeyEventEventArgs (KeyEvent ke) => KeyEvent = ke; - /// - /// The for the event. - /// - public KeyEvent KeyEvent { get; set; } - /// - /// Indicates if the current Key event has already been processed and the driver should stop notifying any other event subscriber. - /// Its important to set this value to true specially when updating any View's layout from inside the subscriber method. - /// - public bool Handled { get; set; } = false; - } -} diff --git a/Terminal.Gui/Input/Event.cs b/Terminal.Gui/Input/Keyboard.cs similarity index 65% rename from Terminal.Gui/Input/Event.cs rename to Terminal.Gui/Input/Keyboard.cs index 995e463cf6..706d3c0458 100644 --- a/Terminal.Gui/Input/Event.cs +++ b/Terminal.Gui/Input/Keyboard.cs @@ -1,10 +1,4 @@ -// -// Evemts.cs: Events, Key mappings -// -// Authors: -// Miguel de Icaza (miguel@gnome.org) -// -using System; +using System; namespace Terminal.Gui { @@ -535,10 +529,22 @@ public enum Key : uint { } /// - /// Describes a keyboard event. + /// Defines the event arguments for keyboard input. /// - public class KeyEvent { - KeyModifiers keyModifiers; + public class KeyEventArgs : EventArgs { + /// + /// Constructs. + /// + /// + public KeyEventArgs (Key key) => Key = key; + + /// + /// Indicates if the current event has already been processed and the driver should stop notifying any other event subscriber. + /// Its important to set this value to true specially when updating any View's layout from inside the subscriber method. + /// + public bool Handled { get; set; } = false; + + KeyModifiers _keyModifiers; /// /// Symbolic definition for the key. @@ -556,269 +562,86 @@ public class KeyEvent { /// Gets a value indicating whether the Shift key was pressed. /// /// true if is shift; otherwise, false. - public bool IsShift => keyModifiers.Shift || Key == Key.BackTab; + public bool IsShift => _keyModifiers.Shift || Key == Key.BackTab; /// /// Gets a value indicating whether the Alt key was pressed (real or synthesized) /// /// true if is alternate; otherwise, false. - public bool IsAlt => keyModifiers.Alt; + public bool IsAlt => _keyModifiers.Alt; /// /// Determines whether the value is a control key (and NOT just the ctrl key) /// /// true if is ctrl; otherwise, false. //public bool IsCtrl => ((uint)Key >= 1) && ((uint)Key <= 26); - public bool IsCtrl => keyModifiers.Ctrl; + public bool IsCtrl => _keyModifiers.Ctrl; /// /// Gets a value indicating whether the Caps lock key was pressed (real or synthesized) /// /// true if is alternate; otherwise, false. - public bool IsCapslock => keyModifiers.Capslock; + public bool IsCapslock => _keyModifiers.Capslock; /// /// Gets a value indicating whether the Num lock key was pressed (real or synthesized) /// /// true if is alternate; otherwise, false. - public bool IsNumlock => keyModifiers.Numlock; + public bool IsNumlock => _keyModifiers.Numlock; /// /// Gets a value indicating whether the Scroll lock key was pressed (real or synthesized) /// /// true if is alternate; otherwise, false. - public bool IsScrolllock => keyModifiers.Scrolllock; + public bool IsScrolllock => _keyModifiers.Scrolllock; /// - /// Constructs a new + /// Constructs a new /// - public KeyEvent () + public KeyEventArgs () { Key = Key.Unknown; - keyModifiers = new KeyModifiers (); + _keyModifiers = new KeyModifiers (); } /// - /// Constructs a new from the provided Key value - can be a rune cast into a Key value + /// Constructs a new from the provided Key value - can be a rune cast into a Key value /// - public KeyEvent (Key k, KeyModifiers km) + public KeyEventArgs (Key k, KeyModifiers km) { Key = k; - keyModifiers = km; + _keyModifiers = km; } /// - /// Pretty prints the KeyEvent + /// Pretty prints the KeyEventArgs /// /// public override string ToString () { string msg = ""; - var key = this.Key; - if (keyModifiers.Shift) { + if (_keyModifiers.Shift) { msg += "Shift-"; } - if (keyModifiers.Alt) { + if (_keyModifiers.Alt) { msg += "Alt-"; } - if (keyModifiers.Ctrl) { + if (_keyModifiers.Ctrl) { msg += "Ctrl-"; } - if (keyModifiers.Capslock) { + if (_keyModifiers.Capslock) { msg += "Capslock-"; } - if (keyModifiers.Numlock) { + if (_keyModifiers.Numlock) { msg += "Numlock-"; } - if (keyModifiers.Scrolllock) { + if (_keyModifiers.Scrolllock) { msg += "Scrolllock-"; } - msg += $"{((Key)KeyValue != Key.Unknown && ((uint)this.KeyValue & (uint)Key.CharMask) > 27 ? $"{(char)this.KeyValue}" : $"{key}")}"; + msg += $"{((Key)KeyValue != Key.Unknown && ((uint)this.KeyValue & (uint)Key.CharMask) > 27 ? $"{(char)KeyValue}" : $"{Key}")}"; return msg; } } - - /// - /// Mouse flags reported in . - /// - /// - /// They just happen to map to the ncurses ones. - /// - [Flags] - public enum MouseFlags { - /// - /// The first mouse button was pressed. - /// - Button1Pressed = unchecked((int)0x2), - /// - /// The first mouse button was released. - /// - Button1Released = unchecked((int)0x1), - /// - /// The first mouse button was clicked (press+release). - /// - Button1Clicked = unchecked((int)0x4), - /// - /// The first mouse button was double-clicked. - /// - Button1DoubleClicked = unchecked((int)0x8), - /// - /// The first mouse button was triple-clicked. - /// - Button1TripleClicked = unchecked((int)0x10), - /// - /// The second mouse button was pressed. - /// - Button2Pressed = unchecked((int)0x80), - /// - /// The second mouse button was released. - /// - Button2Released = unchecked((int)0x40), - /// - /// The second mouse button was clicked (press+release). - /// - Button2Clicked = unchecked((int)0x100), - /// - /// The second mouse button was double-clicked. - /// - Button2DoubleClicked = unchecked((int)0x200), - /// - /// The second mouse button was triple-clicked. - /// - Button2TripleClicked = unchecked((int)0x400), - /// - /// The third mouse button was pressed. - /// - Button3Pressed = unchecked((int)0x2000), - /// - /// The third mouse button was released. - /// - Button3Released = unchecked((int)0x1000), - /// - /// The third mouse button was clicked (press+release). - /// - Button3Clicked = unchecked((int)0x4000), - /// - /// The third mouse button was double-clicked. - /// - Button3DoubleClicked = unchecked((int)0x8000), - /// - /// The third mouse button was triple-clicked. - /// - Button3TripleClicked = unchecked((int)0x10000), - /// - /// The fourth mouse button was pressed. - /// - Button4Pressed = unchecked((int)0x80000), - /// - /// The fourth mouse button was released. - /// - Button4Released = unchecked((int)0x40000), - /// - /// The fourth button was clicked (press+release). - /// - Button4Clicked = unchecked((int)0x100000), - /// - /// The fourth button was double-clicked. - /// - Button4DoubleClicked = unchecked((int)0x200000), - /// - /// The fourth button was triple-clicked. - /// - Button4TripleClicked = unchecked((int)0x400000), - /// - /// Flag: the shift key was pressed when the mouse button took place. - /// - ButtonShift = unchecked((int)0x2000000), - /// - /// Flag: the ctrl key was pressed when the mouse button took place. - /// - ButtonCtrl = unchecked((int)0x1000000), - /// - /// Flag: the alt key was pressed when the mouse button took place. - /// - ButtonAlt = unchecked((int)0x4000000), - /// - /// The mouse position is being reported in this event. - /// - ReportMousePosition = unchecked((int)0x8000000), - /// - /// Vertical button wheeled up. - /// - WheeledUp = unchecked((int)0x10000000), - /// - /// Vertical button wheeled down. - /// - WheeledDown = unchecked((int)0x20000000), - /// - /// Vertical button wheeled up while pressing ButtonShift. - /// - WheeledLeft = ButtonShift | WheeledUp, - /// - /// Vertical button wheeled down while pressing ButtonShift. - /// - WheeledRight = ButtonShift | WheeledDown, - /// - /// Mask that captures all the events. - /// - AllEvents = unchecked((int)0x7ffffff), - } - - // TODO: Merge MouseEvent and MouseEventEventArgs into a single class. - - /// - /// Low-level construct that conveys the details of mouse events, such - /// as coordinates and button state, from ConsoleDrivers up to and - /// Views. - /// - /// The class includes the - /// Action which takes a MouseEvent argument. - public class MouseEvent { - /// - /// The X (column) location for the mouse event. - /// - public int X { get; set; } - - /// - /// The Y (column) location for the mouse event. - /// - public int Y { get; set; } - - /// - /// Flags indicating the kind of mouse event that is being posted. - /// - public MouseFlags Flags { get; set; } - - /// - /// The offset X (column) location for the mouse event. - /// - public int OfX { get; set; } - - /// - /// The offset Y (column) location for the mouse event. - /// - public int OfY { get; set; } - - /// - /// The current view at the location for the mouse event. - /// - public View View { get; set; } - - /// - /// Indicates if the current mouse event has already been processed and the driver should stop notifying any other event subscriber. - /// Its important to set this value to true specially when updating any View's layout from inside the subscriber method. - /// - public bool Handled { get; set; } - - /// - /// Returns a that represents the current . - /// - /// A that represents the current . - public override string ToString () - { - return $"({X},{Y}:{Flags}"; - } - } } diff --git a/Terminal.Gui/Input/Mouse.cs b/Terminal.Gui/Input/Mouse.cs new file mode 100644 index 0000000000..15b7951195 --- /dev/null +++ b/Terminal.Gui/Input/Mouse.cs @@ -0,0 +1,186 @@ +using System; + +namespace Terminal.Gui { + + /// + /// Mouse flags reported in . + /// + /// + /// They just happen to map to the ncurses ones. + /// + [Flags] + public enum MouseFlags { + /// + /// The first mouse button was pressed. + /// + Button1Pressed = unchecked((int)0x2), + /// + /// The first mouse button was released. + /// + Button1Released = unchecked((int)0x1), + /// + /// The first mouse button was clicked (press+release). + /// + Button1Clicked = unchecked((int)0x4), + /// + /// The first mouse button was double-clicked. + /// + Button1DoubleClicked = unchecked((int)0x8), + /// + /// The first mouse button was triple-clicked. + /// + Button1TripleClicked = unchecked((int)0x10), + /// + /// The second mouse button was pressed. + /// + Button2Pressed = unchecked((int)0x80), + /// + /// The second mouse button was released. + /// + Button2Released = unchecked((int)0x40), + /// + /// The second mouse button was clicked (press+release). + /// + Button2Clicked = unchecked((int)0x100), + /// + /// The second mouse button was double-clicked. + /// + Button2DoubleClicked = unchecked((int)0x200), + /// + /// The second mouse button was triple-clicked. + /// + Button2TripleClicked = unchecked((int)0x400), + /// + /// The third mouse button was pressed. + /// + Button3Pressed = unchecked((int)0x2000), + /// + /// The third mouse button was released. + /// + Button3Released = unchecked((int)0x1000), + /// + /// The third mouse button was clicked (press+release). + /// + Button3Clicked = unchecked((int)0x4000), + /// + /// The third mouse button was double-clicked. + /// + Button3DoubleClicked = unchecked((int)0x8000), + /// + /// The third mouse button was triple-clicked. + /// + Button3TripleClicked = unchecked((int)0x10000), + /// + /// The fourth mouse button was pressed. + /// + Button4Pressed = unchecked((int)0x80000), + /// + /// The fourth mouse button was released. + /// + Button4Released = unchecked((int)0x40000), + /// + /// The fourth button was clicked (press+release). + /// + Button4Clicked = unchecked((int)0x100000), + /// + /// The fourth button was double-clicked. + /// + Button4DoubleClicked = unchecked((int)0x200000), + /// + /// The fourth button was triple-clicked. + /// + Button4TripleClicked = unchecked((int)0x400000), + /// + /// Flag: the shift key was pressed when the mouse button took place. + /// + ButtonShift = unchecked((int)0x2000000), + /// + /// Flag: the ctrl key was pressed when the mouse button took place. + /// + ButtonCtrl = unchecked((int)0x1000000), + /// + /// Flag: the alt key was pressed when the mouse button took place. + /// + ButtonAlt = unchecked((int)0x4000000), + /// + /// The mouse position is being reported in this event. + /// + ReportMousePosition = unchecked((int)0x8000000), + /// + /// Vertical button wheeled up. + /// + WheeledUp = unchecked((int)0x10000000), + /// + /// Vertical button wheeled down. + /// + WheeledDown = unchecked((int)0x20000000), + /// + /// Vertical button wheeled up while pressing ButtonShift. + /// + WheeledLeft = ButtonShift | WheeledUp, + /// + /// Vertical button wheeled down while pressing ButtonShift. + /// + WheeledRight = ButtonShift | WheeledDown, + /// + /// Mask that captures all the events. + /// + AllEvents = unchecked((int)0x7ffffff), + } + + // TODO: Merge MouseEvent and MouseEventEventArgs into a single class. + + /// + /// Low-level construct that conveys the details of mouse events, such + /// as coordinates and button state, from ConsoleDrivers up to and + /// Views. + /// + /// The class includes the + /// Action which takes a MouseEvent argument. + public class MouseEvent { + /// + /// The X (column) location for the mouse event. + /// + public int X { get; set; } + + /// + /// The Y (column) location for the mouse event. + /// + public int Y { get; set; } + + /// + /// Flags indicating the kind of mouse event that is being posted. + /// + public MouseFlags Flags { get; set; } + + /// + /// The offset X (column) location for the mouse event. + /// + public int OfX { get; set; } + + /// + /// The offset Y (column) location for the mouse event. + /// + public int OfY { get; set; } + + /// + /// The current view at the location for the mouse event. + /// + public View View { get; set; } + + /// + /// Indicates if the current mouse event has already been processed and the driver should stop notifying any other event subscriber. + /// Its important to set this value to true specially when updating any View's layout from inside the subscriber method. + /// + public bool Handled { get; set; } + + /// + /// Returns a that represents the current . + /// + /// A that represents the current . + public override string ToString () + { + return $"({X},{Y}:{Flags}"; + } + } +} diff --git a/Terminal.Gui/Input/Responder.cs b/Terminal.Gui/Input/Responder.cs index c043a40948..1ec2f7176d 100644 --- a/Terminal.Gui/Input/Responder.cs +++ b/Terminal.Gui/Input/Responder.cs @@ -20,7 +20,7 @@ namespace Terminal.Gui { /// - /// Responder base class implemented by objects that want to participate on keyboard and mouse input. + /// Base class for classes that want to participate on keyboard and mouse input (e.g. ). /// public class Responder : IDisposable { bool disposedValue; @@ -71,20 +71,24 @@ public Responder () // Key handling /// - /// This method can be overwritten by view that + /// This method can be overwritten views that /// want to provide accelerator functionality /// (Alt-key for example). /// /// + /// + /// This is a low-level API; see for the preferred way to define what keys + /// a View should respond to. + /// /// - /// Before keys are sent to the subview on the - /// current view, all the views are - /// processed and the key is passed to the widgets - /// to allow some of them to process the keystroke + /// Before keys are sent to a subview of the + /// current view, all subviews are + /// processed and the key is passed to them + /// to allow them to process the keystroke /// as a hot-key. /// - /// For example, if you implement a button that - /// has a hotkey ok "o", you would catch the + /// For example, for a button that + /// has a hotkey Alt-o, catch the /// combination Alt-o here. If the event is /// caught, you must return true to stop the /// keystroke from being dispatched to other @@ -92,39 +96,32 @@ public Responder () /// /// - public virtual bool ProcessHotKey (KeyEvent kb) + public virtual bool ProcessHotKey (KeyEventArgs kb) { return false; } /// - /// If the view is focused, gives the view a - /// chance to process the keystroke. + /// Called after a key has been pressed and released. Fires the event. + /// + /// Called for new KeyPressed events before any processing is performed or + /// views evaluate. Use for global key handling and/or debugging. + /// /// - /// - /// - /// Views can override this method if they are - /// interested in processing the given keystroke. - /// If they consume the keystroke, they must - /// return true to stop the keystroke from being - /// processed by other widgets or consumed by the - /// widget engine. If they return false, the - /// keystroke will be passed using the ProcessColdKey - /// method to other views to process. - /// - /// - /// The View implementation does nothing but return false, - /// so it is not necessary to call base.ProcessKey if you - /// derive directly from View, but you should if you derive - /// other View subclasses. - /// - /// - /// Contains the details about the key that produced the event. - public virtual bool ProcessKey (KeyEvent keyEvent) + /// + /// if the key was handled. + public virtual bool OnKeyPressed (KeyEventArgs arg) { - return false; + KeyPressed?.Invoke (this, arg); + return arg.Handled; } + /// + /// Event fired after a key has been pressed and released. + /// Set to to suppress the event. + /// + public event EventHandler KeyPressed; + /// /// This method can be overwritten by views that /// want to provide accelerator functionality @@ -132,6 +129,10 @@ public virtual bool ProcessKey (KeyEvent keyEvent) /// interefering with normal ProcessKey behavior. /// /// + /// + /// This is a low-level API; see for the preferred way to define what keys + /// a View should respond to. + /// /// /// After keys are sent to the subviews on the /// current view, all the view are @@ -147,7 +148,7 @@ public virtual bool ProcessKey (KeyEvent keyEvent) /// /// /// Contains the details about the key that produced the event. - public virtual bool ProcessColdKey (KeyEvent keyEvent) + public virtual bool ProcessColdKey (KeyEventArgs keyEvent) { return false; } @@ -157,7 +158,7 @@ public virtual bool ProcessColdKey (KeyEvent keyEvent) /// /// Contains the details about the key that produced the event. /// true if the event was handled - public virtual bool OnKeyDown (KeyEvent keyEvent) + public virtual bool OnKeyDown (KeyEventArgs keyEvent) { return false; } @@ -167,7 +168,7 @@ public virtual bool OnKeyDown (KeyEvent keyEvent) /// /// Contains the details about the key that produced the event. /// true if the event was handled - public virtual bool OnKeyUp (KeyEvent keyEvent) + public virtual bool OnKeyUp (KeyEventArgs keyEvent) { return false; } @@ -256,7 +257,7 @@ internal static bool IsOverridden (Responder subclass, string method) } return m.GetBaseDefinition ().DeclaringType != m.DeclaringType; } - + /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// @@ -278,11 +279,11 @@ protected virtual void Dispose (bool disposing) #if DEBUG_IDISPOSABLE Instances.Remove (this); -#endif +#endif disposedValue = true; } } - + /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resource. /// diff --git a/Terminal.Gui/Input/ShortcutHelper.cs b/Terminal.Gui/Input/ShortcutHelper.cs index e1b1a3bdbb..02efc2fb60 100644 --- a/Terminal.Gui/Input/ShortcutHelper.cs +++ b/Terminal.Gui/Input/ShortcutHelper.cs @@ -38,7 +38,7 @@ public virtual Key Shortcut { /// /// The to check. /// The with all the keys modifiers. - public static Key GetModifiersKey (KeyEvent kb) + public static Key GetModifiersKey (KeyEventArgs kb) { var key = kb.Key; if (kb.IsAlt && (key & Key.AltMask) == 0) { @@ -240,7 +240,7 @@ public static bool PostShortcutValidation (Key key) /// The /// The /// true if defined falseotherwise. - public static bool FindAndOpenByShortcut (KeyEvent kb, View view = null) + public static bool FindAndOpenByShortcut (KeyEventArgs kb, View view = null) { if (view == null) { return false; } diff --git a/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs index 9aba845ede..a1c91c387a 100644 --- a/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs @@ -54,7 +54,7 @@ public override bool MouseEvent (MouseEvent me, bool fromHost = false) } /// - public override bool ProcessKey (KeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { var key = kb.Key; if (key == SelectionKey) { diff --git a/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs b/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs index 6be3e8da00..4f2db0036e 100644 --- a/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs +++ b/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs @@ -55,7 +55,7 @@ public abstract class AutocompleteBase : IAutocomplete { public abstract bool MouseEvent (MouseEvent me, bool fromHost = false); /// - public abstract bool ProcessKey (KeyEvent kb); + public abstract bool ProcessKey (KeyEventArgs kb); /// public abstract void RenderOverlay (Point renderAt); diff --git a/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs index ac31d3f9c7..d60ca09da4 100644 --- a/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs @@ -87,7 +87,7 @@ public interface IAutocomplete { /// /// The key event. /// trueif the key can be handled falseotherwise. - bool ProcessKey (KeyEvent kb); + bool ProcessKey (KeyEventArgs kb); /// /// Handle mouse events before e.g. to make mouse events like diff --git a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs index 925f5bc53b..c4b7bcdbbf 100644 --- a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs @@ -152,7 +152,7 @@ public override ColorScheme ColorScheme { public override void RenderOverlay (Point renderAt) { if (!Context.Canceled && Suggestions.Count > 0 && !Visible && HostControl?.HasFocus == true) { - ProcessKey (new KeyEvent ((Key)(Suggestions [0].Title [0]), new KeyModifiers ())); + ProcessKey (new KeyEventArgs ((Key)(Suggestions [0].Title [0]), new KeyModifiers ())); } else if (!Visible || HostControl?.HasFocus == false || Suggestions.Count == 0) { LastPopupPos = null; Visible = false; @@ -278,7 +278,7 @@ public override void EnsureSelectedIdxIsValid () /// /// The key event. /// trueif the key can be handled falseotherwise. - public override bool ProcessKey (KeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { if (SuggestionGenerator.IsWordChar ((Rune)(char)kb.Key)) { Visible = true; diff --git a/Terminal.Gui/Text/CollectionNavigatorBase.cs b/Terminal.Gui/Text/CollectionNavigatorBase.cs index 1d65116dc6..75b012f57b 100644 --- a/Terminal.Gui/Text/CollectionNavigatorBase.cs +++ b/Terminal.Gui/Text/CollectionNavigatorBase.cs @@ -209,7 +209,7 @@ private void ClearSearchString () /// /// /// - public static bool IsCompatibleKey (KeyEvent kb) + public static bool IsCompatibleKey (KeyEventArgs kb) { return !kb.IsAlt && !kb.IsCtrl; } diff --git a/Terminal.Gui/View/ViewKeyboard.cs b/Terminal.Gui/View/ViewKeyboard.cs index 421f941621..d69cb13861 100644 --- a/Terminal.Gui/View/ViewKeyboard.cs +++ b/Terminal.Gui/View/ViewKeyboard.cs @@ -163,43 +163,44 @@ public bool TabStop { /// /// Invoked when a character key is pressed and occurs after the key up event. /// - public event EventHandler KeyPressed; + public event EventHandler KeyPressed; /// - public override bool ProcessKey (KeyEvent keyEvent) + public override bool OnKeyPressed (KeyEventArgs arg) { if (!Enabled) { return false; } - var args = new KeyEventEventArgs (keyEvent); - KeyPressed?.Invoke (this, args); - if (args.Handled) + KeyPressed?.Invoke (this, arg); + if (arg.Handled) { return true; + } if (Focused?.Enabled == true) { - Focused?.KeyPressed?.Invoke (this, args); - if (args.Handled) + Focused?.KeyPressed?.Invoke (this, arg); + if (arg.Handled) { return true; + } } - return Focused?.Enabled == true && Focused?.ProcessKey (keyEvent) == true; + return Focused?.Enabled == true && Focused?.OnKeyPressed (arg) == true; } /// /// Invokes any binding that is registered on this - /// and matches the + /// and matches the /// - /// The key event passed. - protected bool? InvokeKeybindings (KeyEvent keyEvent) + /// The key event passed. + protected bool? InvokeKeybindings (KeyEventArgs KeyEventArgs) { bool? toReturn = null; - if (KeyBindings.ContainsKey (keyEvent.Key)) { + if (KeyBindings.ContainsKey (KeyEventArgs.Key)) { - foreach (var command in KeyBindings [keyEvent.Key]) { + foreach (var command in KeyBindings [KeyEventArgs.Key]) { if (!CommandImplementations.ContainsKey (command)) { - throw new NotSupportedException ($"A KeyBinding was set up for the command {command} ({keyEvent.Key}) but that command is not supported by this View ({GetType ().Name})"); + throw new NotSupportedException ($"A KeyBinding was set up for the command {command} ({KeyEventArgs.Key}) but that command is not supported by this View ({GetType ().Name})"); } // each command has its own return value @@ -340,52 +341,54 @@ public Key GetKeyFromCommand (params Command [] command) } /// - public override bool ProcessHotKey (KeyEvent keyEvent) + public override bool ProcessHotKey (KeyEventArgs arg) { if (!Enabled) { return false; } - var args = new KeyEventEventArgs (keyEvent); if (MostFocused?.Enabled == true) { - MostFocused?.KeyPressed?.Invoke (this, args); - if (args.Handled) + MostFocused?.KeyPressed?.Invoke (this, arg); + if (arg.Handled) { return true; + } } - if (MostFocused?.Enabled == true && MostFocused?.ProcessKey (keyEvent) == true) + if (MostFocused?.Enabled == true && MostFocused?.OnKeyPressed (arg) == true) { return true; - if (_subviews == null || _subviews.Count == 0) + } + if (_subviews == null || _subviews.Count == 0) { return false; + } foreach (var view in _subviews) - if (view.Enabled && view.ProcessHotKey (keyEvent)) + if (view.Enabled && view.ProcessHotKey (arg)) { return true; + } return false; } /// - public override bool ProcessColdKey (KeyEvent keyEvent) + public override bool ProcessColdKey (KeyEventArgs arg) { if (!Enabled) { return false; } - var args = new KeyEventEventArgs (keyEvent); - KeyPressed?.Invoke (this, args); - if (args.Handled) + KeyPressed?.Invoke (this, arg); + if (arg.Handled) return true; if (MostFocused?.Enabled == true) { - MostFocused?.KeyPressed?.Invoke (this, args); - if (args.Handled) + MostFocused?.KeyPressed?.Invoke (this, arg); + if (arg.Handled) return true; } - if (MostFocused?.Enabled == true && MostFocused?.ProcessKey (keyEvent) == true) + if (MostFocused?.Enabled == true && MostFocused?.OnKeyPressed (arg) == true) return true; if (_subviews == null || _subviews.Count == 0) return false; foreach (var view in _subviews) - if (view.Enabled && view.ProcessColdKey (keyEvent)) + if (view.Enabled && view.ProcessColdKey (arg)) return true; return false; } @@ -393,26 +396,25 @@ public override bool ProcessColdKey (KeyEvent keyEvent) /// /// Invoked when a key is pressed. /// - public event EventHandler KeyDown; + public event EventHandler KeyDown; /// - public override bool OnKeyDown (KeyEvent keyEvent) + public override bool OnKeyDown (KeyEventArgs arg) { if (!Enabled) { return false; } - var args = new KeyEventEventArgs (keyEvent); - KeyDown?.Invoke (this, args); - if (args.Handled) { + KeyDown?.Invoke (this, arg); + if (arg.Handled) { return true; } if (Focused?.Enabled == true) { - Focused.KeyDown?.Invoke (this, args); - if (args.Handled) { + Focused.KeyDown?.Invoke (this, arg); + if (arg.Handled) { return true; } - if (Focused?.OnKeyDown (keyEvent) == true) { + if (Focused?.OnKeyDown (arg) == true) { return true; } } @@ -423,26 +425,25 @@ public override bool OnKeyDown (KeyEvent keyEvent) /// /// Invoked when a key is released. /// - public event EventHandler KeyUp; + public event EventHandler KeyUp; /// - public override bool OnKeyUp (KeyEvent keyEvent) + public override bool OnKeyUp (KeyEventArgs arg) { if (!Enabled) { return false; } - var args = new KeyEventEventArgs (keyEvent); - KeyUp?.Invoke (this, args); - if (args.Handled) { + KeyUp?.Invoke (this, arg); + if (arg.Handled) { return true; } if (Focused?.Enabled == true) { - Focused.KeyUp?.Invoke (this, args); - if (args.Handled) { + Focused.KeyUp?.Invoke (this, arg); + if (arg.Handled) { return true; } - if (Focused?.OnKeyUp (keyEvent) == true) { + if (Focused?.OnKeyUp (arg) == true) { return true; } } diff --git a/Terminal.Gui/Views/Button.cs b/Terminal.Gui/Views/Button.cs index 5cd1605dd9..6d647455d7 100644 --- a/Terminal.Gui/Views/Button.cs +++ b/Terminal.Gui/Views/Button.cs @@ -191,7 +191,7 @@ protected override void UpdateTextFormatterText () } /// - public override bool ProcessHotKey (KeyEvent kb) + public override bool ProcessHotKey (KeyEventArgs kb) { if (!Enabled) { return false; @@ -201,7 +201,7 @@ public override bool ProcessHotKey (KeyEvent kb) } /// - public override bool ProcessColdKey (KeyEvent kb) + public override bool ProcessColdKey (KeyEventArgs kb) { if (!Enabled) { return false; @@ -211,20 +211,20 @@ public override bool ProcessColdKey (KeyEvent kb) } /// - public override bool ProcessKey (KeyEvent kb) + public override bool OnKeyPressed (KeyEventArgs arg) { if (!Enabled) { return false; } - var result = InvokeKeybindings (kb); + var result = InvokeKeybindings (arg); if (result != null) return (bool)result; - return base.ProcessKey (kb); + return base.OnKeyPressed (arg); } - bool ExecuteHotKey (KeyEvent ke) + bool ExecuteHotKey (KeyEventArgs ke) { if (ke.Key == (Key.AltMask | HotKey)) { return AcceptKey (); @@ -232,7 +232,7 @@ bool ExecuteHotKey (KeyEvent ke) return false; } - bool ExecuteColdKey (KeyEvent ke) + bool ExecuteColdKey (KeyEventArgs ke) { if (IsDefault && ke.KeyValue == '\n') { return AcceptKey (); diff --git a/Terminal.Gui/Views/CheckBox.cs b/Terminal.Gui/Views/CheckBox.cs index e8eaf8088f..4a21a8c016 100644 --- a/Terminal.Gui/Views/CheckBox.cs +++ b/Terminal.Gui/Views/CheckBox.cs @@ -168,17 +168,17 @@ public override void PositionCursor () } /// - public override bool ProcessKey (KeyEvent kb) + public override bool OnKeyPressed (KeyEventArgs arg) { - var result = InvokeKeybindings (kb); + var result = InvokeKeybindings (arg); if (result != null) return (bool)result; - return base.ProcessKey (kb); + return base.OnKeyPressed (arg); } /// - public override bool ProcessHotKey (KeyEvent kb) + public override bool ProcessHotKey (KeyEventArgs kb) { if (kb.Key == (Key.AltMask | HotKey)) return ToggleChecked (); diff --git a/Terminal.Gui/Views/ColorPicker.cs b/Terminal.Gui/Views/ColorPicker.cs index f41aa5b68d..7bf28a2a00 100644 --- a/Terminal.Gui/Views/ColorPicker.cs +++ b/Terminal.Gui/Views/ColorPicker.cs @@ -251,9 +251,9 @@ public virtual bool MoveDown () } /// - public override bool ProcessKey (KeyEvent kb) + public override bool OnKeyPressed (KeyEventArgs arg) { - var result = InvokeKeybindings (kb); + var result = InvokeKeybindings (arg); if (result != null) return (bool)result; diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index 211a11d529..d1f79075e3 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -545,13 +545,13 @@ public override void OnDrawContent (Rect contentArea) } /// - public override bool ProcessKey (KeyEvent e) + public override bool OnKeyPressed (KeyEventArgs arg) { - var result = InvokeKeybindings (e); + var result = InvokeKeybindings (arg); if (result != null) return (bool)result; - return base.ProcessKey (e); + return base.OnKeyPressed (arg); } bool UnixEmulation () diff --git a/Terminal.Gui/Views/DateField.cs b/Terminal.Gui/Views/DateField.cs index 2da853331f..2b063e1c13 100644 --- a/Terminal.Gui/Views/DateField.cs +++ b/Terminal.Gui/Views/DateField.cs @@ -328,14 +328,14 @@ void AdjCursorPosition () } /// - public override bool ProcessKey (KeyEvent kb) + public override bool OnKeyPressed (KeyEventArgs arg) { - var result = InvokeKeybindings (kb); + var result = InvokeKeybindings (arg); if (result != null) { return (bool)result; } // Ignore non-numeric characters. - if (kb.Key < (Key)((int)'0') || kb.Key > (Key)((int)'9')) { + if (arg.Key < (Key)((int)'0') || arg.Key > (Key)((int)'9')) { return false; } @@ -344,7 +344,7 @@ public override bool ProcessKey (KeyEvent kb) } // BUGBUG: This is a hack, we should be able to just use ((Rune)(uint)kb.Key) directly. - if (SetText (((Rune)(uint)kb.Key).ToString ().EnumerateRunes ().First ())) { + if (SetText (((Rune)(uint)arg.Key).ToString ().EnumerateRunes ().First ())) { IncCursorPosition (); } diff --git a/Terminal.Gui/Views/Dialog.cs b/Terminal.Gui/Views/Dialog.cs index db7016394b..67326aa282 100644 --- a/Terminal.Gui/Views/Dialog.cs +++ b/Terminal.Gui/Views/Dialog.cs @@ -229,14 +229,14 @@ void LayoutButtons () } /// - public override bool ProcessKey (KeyEvent kb) + public override bool OnKeyPressed (KeyEventArgs arg) { - switch (kb.Key) { + switch (arg.Key) { case Key.Esc: Application.RequestStop (this); return true; } - return base.ProcessKey (kb); + return base.OnKeyPressed (arg); } } } diff --git a/Terminal.Gui/Views/FileDialog.cs b/Terminal.Gui/Views/FileDialog.cs index 725bbfa86d..5138a06849 100644 --- a/Terminal.Gui/Views/FileDialog.cs +++ b/Terminal.Gui/Views/FileDialog.cs @@ -286,12 +286,12 @@ public FileDialog (IFileSystem fileSystem) tbFind.TextChanged += (s, o) => RestartSearch (); tbFind.KeyPressed += (s, o) => { - if (o.KeyEvent.Key == Key.Enter) { + if (o.Key == Key.Enter) { RestartSearch (); o.Handled = true; } - if (o.KeyEvent.Key == Key.Esc) { + if (o.Key == Key.Esc) { if (CancelSearch ()) { o.Handled = true; } @@ -316,7 +316,7 @@ public FileDialog (IFileSystem fileSystem) this.tbPath.TextChanged += (s, e) => this.PathChanged (); this.tableView.CellActivated += this.CellActivate; - this.tableView.KeyUp += (s, k) => k.Handled = this.TableView_KeyUp (k.KeyEvent); + this.tableView.KeyUp += (s, k) => k.Handled = this.TableView_KeyUp (k); this.tableView.SelectedCellChanged += this.TableView_SelectedCellChanged; this.tableView.AddKeyBinding (Key.Home, Command.TopHome); @@ -340,7 +340,7 @@ public FileDialog (IFileSystem fileSystem) return; } - k.Handled = this.TreeView_KeyDown (k.KeyEvent); + k.Handled = this.TreeView_KeyDown (k); }; @@ -485,7 +485,7 @@ private IFileSystemInfo [] GetFocusedFiles () /// - public override bool ProcessHotKey (KeyEvent keyEvent) + public override bool ProcessHotKey (KeyEventArgs keyEvent) { if (this.NavigateIf (keyEvent, Key.CtrlMask | Key.F, this.tbFind)) { return true; @@ -772,17 +772,17 @@ private void AllowedTypeMenuClicked (int idx) } } - private void SuppressIfBadChar (KeyEventEventArgs k) + private void SuppressIfBadChar (KeyEventArgs k) { // don't let user type bad letters - var ch = (char)k.KeyEvent.KeyValue; + var ch = (char)k.KeyValue; if (badChars.Contains (ch)) { k.Handled = true; } } - private bool TreeView_KeyDown (KeyEvent keyEvent) + private bool TreeView_KeyDown (KeyEventArgs keyEvent) { if (this.treeView.HasFocus && Separators.Contains ((char)keyEvent.KeyValue)) { this.tbPath.FocusFirst (); @@ -794,9 +794,9 @@ private bool TreeView_KeyDown (KeyEvent keyEvent) return false; } - private void AcceptIf (KeyEventEventArgs keyEvent, Key isKey) + private void AcceptIf (KeyEventArgs keyEvent, Key isKey) { - if (!keyEvent.Handled && keyEvent.KeyEvent.Key == isKey) { + if (!keyEvent.Handled && keyEvent.Key == isKey) { keyEvent.Handled = true; // User hit Enter in text box so probably wants the @@ -880,17 +880,7 @@ private void FinishAccept () Application.RequestStop (); } - private void NavigateIf (KeyEventEventArgs keyEvent, Key isKey, View to) - { - if (!keyEvent.Handled) { - - if (NavigateIf (keyEvent.KeyEvent, isKey, to)) { - keyEvent.Handled = true; - } - } - } - - private bool NavigateIf (KeyEvent keyEvent, Key isKey, View to) + private bool NavigateIf (KeyEventArgs keyEvent, Key isKey, View to) { if (keyEvent.Key == isKey) { @@ -956,7 +946,7 @@ private void TableView_SelectedCellChanged (object sender, SelectedCellChangedEv } } - private bool TableView_KeyUp (KeyEvent keyEvent) + private bool TableView_KeyUp (KeyEventArgs keyEvent) { if (keyEvent.Key == Key.Backspace) { return this.history.Back (); diff --git a/Terminal.Gui/Views/GraphView/GraphView.cs b/Terminal.Gui/Views/GraphView/GraphView.cs index 2d2310b1b2..bdf6d9f00d 100644 --- a/Terminal.Gui/Views/GraphView/GraphView.cs +++ b/Terminal.Gui/Views/GraphView/GraphView.cs @@ -244,7 +244,7 @@ public override bool OnEnter (View view) } /// - public override bool ProcessKey (KeyEvent keyEvent) + public override bool OnKeyPressed (KeyEventArgs keyEvent) { if (HasFocus && CanFocus) { var result = InvokeKeybindings (keyEvent); @@ -252,7 +252,7 @@ public override bool ProcessKey (KeyEvent keyEvent) return (bool)result; } - return base.ProcessKey (keyEvent); + return base.OnKeyPressed (keyEvent); } /// diff --git a/Terminal.Gui/Views/HexView.cs b/Terminal.Gui/Views/HexView.cs index b425e5f073..e5d520f331 100644 --- a/Terminal.Gui/Views/HexView.cs +++ b/Terminal.Gui/Views/HexView.cs @@ -424,7 +424,7 @@ bool MoveDown (int bytes) } /// - public override bool ProcessKey (KeyEvent keyEvent) + public override bool OnKeyPressed (KeyEventArgs keyEvent) { var result = InvokeKeybindings (keyEvent); if (result != null) diff --git a/Terminal.Gui/Views/Label.cs b/Terminal.Gui/Views/Label.cs index 29b476fb77..bd8aa813ba 100644 --- a/Terminal.Gui/Views/Label.cs +++ b/Terminal.Gui/Views/Label.cs @@ -112,7 +112,7 @@ public override bool OnEnter (View view) } /// - public override bool ProcessHotKey (KeyEvent ke) + public override bool ProcessHotKey (KeyEventArgs ke) { if (ke.Key == (Key.AltMask | HotKey)) { if (!HasFocus) { diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index 59f0e9a718..6967783bef 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -416,10 +416,10 @@ public override void OnDrawContent (Rect contentArea) public CollectionNavigator KeystrokeNavigator { get; private set; } = new CollectionNavigator (); /// - public override bool ProcessKey (KeyEvent kb) + public override bool OnKeyPressed (KeyEventArgs kb) { if (source == null) { - return base.ProcessKey (kb); + return base.OnKeyPressed (kb); } var result = InvokeKeybindings (kb); diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs index 7c16edc534..46f906892a 100644 --- a/Terminal.Gui/Views/Menu.cs +++ b/Terminal.Gui/Views/Menu.cs @@ -721,7 +721,7 @@ public override bool OnLeave (View view) return host.OnLeave (view); } - public override bool OnKeyDown (KeyEvent keyEvent) + public override bool OnKeyDown (KeyEventArgs keyEvent) { if (keyEvent.IsAlt) { host.CloseAllMenus (); @@ -731,7 +731,7 @@ public override bool OnKeyDown (KeyEvent keyEvent) return false; } - public override bool ProcessHotKey (KeyEvent keyEvent) + public override bool ProcessHotKey (KeyEventArgs keyEvent) { // To ncurses simulate a AltMask key pressing Alt+Space because // it can't detect an alone special key down was pressed. @@ -743,7 +743,7 @@ public override bool ProcessHotKey (KeyEvent keyEvent) return false; } - public override bool ProcessKey (KeyEvent kb) + public override bool OnKeyPressed (KeyEventArgs kb) { var result = InvokeKeybindings (kb); if (result != null) @@ -1165,7 +1165,7 @@ public override bool OnLeave (View view) } /// - public override bool OnKeyDown (KeyEvent keyEvent) + public override bool OnKeyDown (KeyEventArgs keyEvent) { if (keyEvent.IsAlt || (keyEvent.IsCtrl && keyEvent.Key == (Key.CtrlMask | Key.Space))) { openedByAltKey = true; @@ -1176,7 +1176,7 @@ public override bool OnKeyDown (KeyEvent keyEvent) } /// - public override bool OnKeyUp (KeyEvent keyEvent) + public override bool OnKeyUp (KeyEventArgs keyEvent) { if (keyEvent.IsAlt || keyEvent.Key == Key.AltMask || (keyEvent.IsCtrl && keyEvent.Key == (Key.CtrlMask | Key.Space))) { // User pressed Alt - this may be a precursor to a menu accelerator (e.g. Alt-F) @@ -1812,7 +1812,7 @@ internal void NextMenu (bool isSubMenu = false, bool ignoreUseSubMenusSingleFram } bool openedByHotKey; - internal bool FindAndOpenMenuByHotkey (KeyEvent kb) + internal bool FindAndOpenMenuByHotkey (KeyEventArgs kb) { //int pos = 0; var c = ((uint)kb.Key & (uint)Key.CharMask); @@ -1839,7 +1839,7 @@ internal bool FindAndOpenMenuByHotkey (KeyEvent kb) return false; } - bool FindAndOpenChildrenMenuByHotkey (KeyEvent kb, MenuItem [] children) + bool FindAndOpenChildrenMenuByHotkey (KeyEventArgs kb, MenuItem [] children) { var c = ((uint)kb.Key & (uint)Key.CharMask); for (int i = 0; i < children.Length; i++) { @@ -1873,7 +1873,7 @@ bool FindAndOpenChildrenMenuByHotkey (KeyEvent kb, MenuItem [] children) return false; } - internal bool FindAndOpenMenuByShortcut (KeyEvent kb, MenuItem [] children = null) + internal bool FindAndOpenMenuByShortcut (KeyEventArgs kb, MenuItem [] children = null) { if (children == null) { children = Menus; @@ -1931,7 +1931,7 @@ private void ProcessMenu (int i, MenuBarItem mi) } /// - public override bool ProcessHotKey (KeyEvent kb) + public override bool ProcessHotKey (KeyEventArgs kb) { if (kb.Key == Key) { if (Visible && !IsMenuOpen) { @@ -1957,7 +1957,7 @@ public override bool ProcessHotKey (KeyEvent kb) } /// - public override bool ProcessKey (KeyEvent kb) + public override bool OnKeyPressed (KeyEventArgs kb) { if (InvokeKeybindings (kb) == true) return true; @@ -2013,7 +2013,7 @@ void MoveLeft () } /// - public override bool ProcessColdKey (KeyEvent kb) + public override bool ProcessColdKey (KeyEventArgs kb) { return FindAndOpenMenuByShortcut (kb); } diff --git a/Terminal.Gui/Views/RadioGroup.cs b/Terminal.Gui/Views/RadioGroup.cs index db4656f4f3..2920a1d1c7 100644 --- a/Terminal.Gui/Views/RadioGroup.cs +++ b/Terminal.Gui/Views/RadioGroup.cs @@ -288,7 +288,7 @@ public virtual void OnSelectedItemChanged (int selectedItem, int previousSelecte } /// - public override bool ProcessColdKey (KeyEvent kb) + public override bool ProcessColdKey (KeyEventArgs kb) { var key = kb.KeyValue; if (key < Char.MaxValue && Char.IsLetterOrDigit ((char)key)) { @@ -318,13 +318,13 @@ public override bool ProcessColdKey (KeyEvent kb) } /// - public override bool ProcessKey (KeyEvent kb) + public override bool OnKeyPressed (KeyEventArgs kb) { var result = InvokeKeybindings (kb); if (result != null) return (bool)result; - return base.ProcessKey (kb); + return base.OnKeyPressed (kb); } void SelectItem () diff --git a/Terminal.Gui/Views/ScrollView.cs b/Terminal.Gui/Views/ScrollView.cs index bb83466360..b9aeb9a4b1 100644 --- a/Terminal.Gui/Views/ScrollView.cs +++ b/Terminal.Gui/Views/ScrollView.cs @@ -542,12 +542,12 @@ public bool ScrollRight (int cols) } /// - public override bool ProcessKey (KeyEvent kb) + public override bool OnKeyPressed (KeyEventArgs arg) { - if (base.ProcessKey (kb)) + if (base.OnKeyPressed (arg)) return true; - var result = InvokeKeybindings (kb); + var result = InvokeKeybindings (arg); if (result != null) return (bool)result; diff --git a/Terminal.Gui/Views/Slider.cs b/Terminal.Gui/Views/Slider.cs index a490516c5f..f5c311ebe7 100644 --- a/Terminal.Gui/Views/Slider.cs +++ b/Terminal.Gui/Views/Slider.cs @@ -1432,17 +1432,17 @@ void SetKeyBindings () } /// - public override bool ProcessKey (KeyEvent keyEvent) + public override bool OnKeyPressed (KeyEventArgs keyEvent) { if (!CanFocus || !HasFocus) { - return base.ProcessKey (keyEvent); + return base.OnKeyPressed (keyEvent); } var result = InvokeKeybindings (keyEvent); if (result != null) { return (bool)result; } - return base.ProcessKey (keyEvent); + return base.OnKeyPressed (keyEvent); } Dictionary> GetSetOptionDictionary () => _setOptions.ToDictionary (e => e, e => _options [e]); diff --git a/Terminal.Gui/Views/StatusBar.cs b/Terminal.Gui/Views/StatusBar.cs index 1d66b853dd..f6bb3fdbda 100644 --- a/Terminal.Gui/Views/StatusBar.cs +++ b/Terminal.Gui/Views/StatusBar.cs @@ -177,7 +177,7 @@ public override void OnDrawContent (Rect contentArea) } /// - public override bool ProcessHotKey (KeyEvent kb) + public override bool ProcessHotKey (KeyEventArgs kb) { foreach (var item in Items) { if (kb.Key == item.Shortcut) { diff --git a/Terminal.Gui/Views/TabView.cs b/Terminal.Gui/Views/TabView.cs index 86a558b82d..da11b6b6af 100644 --- a/Terminal.Gui/Views/TabView.cs +++ b/Terminal.Gui/Views/TabView.cs @@ -230,15 +230,15 @@ protected virtual void OnSelectedTabChanged (Tab oldTab, Tab newTab) } /// - public override bool ProcessKey (KeyEvent keyEvent) + public override bool OnKeyPressed (KeyEventArgs arg) { if (HasFocus && CanFocus && Focused == tabsBar) { - var result = InvokeKeybindings (keyEvent); + var result = InvokeKeybindings (arg); if (result != null) return (bool)result; } - return base.ProcessKey (keyEvent); + return base.OnKeyPressed (arg); } /// diff --git a/Terminal.Gui/Views/TableView/TableView.cs b/Terminal.Gui/Views/TableView/TableView.cs index a5c25f3d43..7c414b0ef3 100644 --- a/Terminal.Gui/Views/TableView/TableView.cs +++ b/Terminal.Gui/Views/TableView/TableView.cs @@ -761,14 +761,14 @@ private string TruncateOrPad (object originalCellValue, string representation, i /// - public override bool ProcessKey (KeyEvent keyEvent) + public override bool OnKeyPressed (KeyEventArgs args) { if (TableIsNullOrInvisible ()) { PositionCursor (); return false; } - var result = InvokeKeybindings (keyEvent); + var result = InvokeKeybindings (args); if (result != null) { PositionCursor (); return true; @@ -777,17 +777,17 @@ public override bool ProcessKey (KeyEvent keyEvent) if (CollectionNavigator != null && this.HasFocus && Table.Rows != 0 && - Terminal.Gui.CollectionNavigator.IsCompatibleKey (keyEvent) && - !keyEvent.Key.HasFlag (Key.CtrlMask) && - !keyEvent.Key.HasFlag (Key.AltMask) && - char.IsLetterOrDigit ((char)keyEvent.KeyValue)) { - return CycleToNextTableEntryBeginningWith (keyEvent); + Terminal.Gui.CollectionNavigator.IsCompatibleKey (args) && + !args.Key.HasFlag (Key.CtrlMask) && + !args.Key.HasFlag (Key.AltMask) && + char.IsLetterOrDigit ((char)args.KeyValue)) { + return CycleToNextTableEntryBeginningWith (args); } return false; } - private bool CycleToNextTableEntryBeginningWith (KeyEvent keyEvent) + private bool CycleToNextTableEntryBeginningWith (KeyEventArgs keyEvent) { var row = SelectedRow; diff --git a/Terminal.Gui/Views/TableView/TreeTableSource.cs b/Terminal.Gui/Views/TableView/TreeTableSource.cs index 0b06691fd0..52c695085b 100644 --- a/Terminal.Gui/Views/TableView/TreeTableSource.cs +++ b/Terminal.Gui/Views/TableView/TreeTableSource.cs @@ -106,7 +106,7 @@ private string GetColumnZeroRepresentationFromTree (int row) return sb.ToString (); } - private void Table_KeyPress (object sender, KeyEventEventArgs e) + private void Table_KeyPress (object sender, KeyEventArgs e) { if (!IsInTreeColumn (_tableView.SelectedColumn, true)) { return; @@ -118,13 +118,13 @@ private void Table_KeyPress (object sender, KeyEventEventArgs e) return; } - if (e.KeyEvent.Key == Key.CursorLeft) { + if (e.Key == Key.CursorLeft) { if (_tree.IsExpanded (obj)) { _tree.Collapse (obj); e.Handled = true; } } - if (e.KeyEvent.Key == Key.CursorRight) { + if (e.Key == Key.CursorRight) { if (_tree.CanExpand (obj) && !_tree.IsExpanded (obj)) { _tree.Expand (obj); e.Handled = true; diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs index 6ad4798d78..01bcb6b46c 100644 --- a/Terminal.Gui/Views/TextField.cs +++ b/Terminal.Gui/Views/TextField.cs @@ -637,7 +637,7 @@ void SetClipboard (IEnumerable text) /// /// /// - public override bool ProcessKey (KeyEvent kb) + public override bool OnKeyPressed (KeyEventArgs arg) { // remember current cursor position // because the new calculated cursor position is needed to be set BEFORE the change event is triggest @@ -645,28 +645,28 @@ public override bool ProcessKey (KeyEvent kb) _oldCursorPos = _point; // Give autocomplete first opportunity to respond to key presses - if (SelectedLength == 0 && Autocomplete.Suggestions.Count > 0 && Autocomplete.ProcessKey (kb)) { + if (SelectedLength == 0 && Autocomplete.Suggestions.Count > 0 && Autocomplete.ProcessKey (arg)) { return true; } - var result = InvokeKeybindings (new KeyEvent (ShortcutHelper.GetModifiersKey (kb), - new KeyModifiers () { Alt = kb.IsAlt, Ctrl = kb.IsCtrl, Shift = kb.IsShift })); + var result = InvokeKeybindings (new KeyEventArgs (ShortcutHelper.GetModifiersKey (arg), + new KeyModifiers () { Alt = arg.IsAlt, Ctrl = arg.IsCtrl, Shift = arg.IsShift })); if (result != null) return (bool)result; // Ignore other control characters. - if (kb.Key < Key.Space || kb.Key > Key.CharMask) + if (arg.Key < Key.Space || arg.Key > Key.CharMask) return false; if (ReadOnly) return true; - InsertText (kb); + InsertText (arg); return true; } - void InsertText (KeyEvent kb, bool useOldCursorPos = true) + void InsertText (KeyEventArgs kb, bool useOldCursorPos = true) { _historyText.Add (new List> () { TextModel.ToRuneCells (_text) }, new Point (_point, 0)); @@ -1312,7 +1312,7 @@ public void InsertText (string toAdd, bool useOldCursorPos = true) throw new ArgumentException ($"Cannot insert character '{ch}' because it does not map to a Key"); } - InsertText (new KeyEvent () { Key = key }, useOldCursorPos); + InsertText (new KeyEventArgs () { Key = key }, useOldCursorPos); } } diff --git a/Terminal.Gui/Views/TextValidateField.cs b/Terminal.Gui/Views/TextValidateField.cs index f687a82a5d..1107873505 100644 --- a/Terminal.Gui/Views/TextValidateField.cs +++ b/Terminal.Gui/Views/TextValidateField.cs @@ -612,7 +612,7 @@ bool EndKeyHandler () } /// - public override bool ProcessKey (KeyEvent kb) + public override bool OnKeyPressed (KeyEventArgs kb) { if (provider == null) { return false; diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs index 3a746880bf..1e0ea2cde4 100644 --- a/Terminal.Gui/Views/TextView.cs +++ b/Terminal.Gui/Views/TextView.cs @@ -3065,7 +3065,7 @@ public void InsertText (string toAdd) throw new ArgumentException ($"Cannot insert character '{ch}' because it does not map to a Key"); } - InsertText (new KeyEvent () { Key = key }); + InsertText (new KeyEventArgs () { Key = key }); } if (NeedsDisplay) { @@ -3401,7 +3401,7 @@ public void ScrollTo (int idx, bool isRow = true) bool _shiftSelecting; /// - public override bool ProcessKey (KeyEvent kb) + public override bool OnKeyPressed (KeyEventArgs kb) { if (!CanFocus) { return true; @@ -3412,7 +3412,7 @@ public override bool ProcessKey (KeyEvent kb) return true; } - var result = InvokeKeybindings (new KeyEvent (ShortcutHelper.GetModifiersKey (kb), + var result = InvokeKeybindings (new KeyEventArgs (ShortcutHelper.GetModifiersKey (kb), new KeyModifiers () { Alt = kb.IsAlt, Ctrl = kb.IsCtrl, Shift = kb.IsShift })); if (result != null) return (bool)result; @@ -3791,7 +3791,7 @@ bool ProcessTab () if (!AllowsTab || _isReadOnly) { return ProcessMoveNextView (); } - InsertText (new KeyEvent ((Key)'\t', null)); + InsertText (new KeyEventArgs ((Key)'\t', null)); DoNeededAction (); return true; } @@ -4318,7 +4318,7 @@ void ResetAllTrack () _continuousFind = false; } - bool InsertText (KeyEvent kb, ColorScheme? colorScheme = null) + bool InsertText (KeyEventArgs kb, ColorScheme? colorScheme = null) { //So that special keys like tab can be processed if (_isReadOnly) @@ -4388,7 +4388,7 @@ public void DeleteAll () } /// - public override bool OnKeyUp (KeyEvent kb) + public override bool OnKeyUp (KeyEventArgs kb) { switch (kb.Key) { case Key.Space | Key.CtrlMask: diff --git a/Terminal.Gui/Views/TileView.cs b/Terminal.Gui/Views/TileView.cs index aa660203bc..a3b0f2dcc9 100644 --- a/Terminal.Gui/Views/TileView.cs +++ b/Terminal.Gui/Views/TileView.cs @@ -443,7 +443,7 @@ public bool TrySplitTile (int idx, int numberOfPanels, out TileView result) } /// - public override bool ProcessHotKey (KeyEvent keyEvent) + public override bool ProcessHotKey (KeyEventArgs keyEvent) { bool focusMoved = false; @@ -805,17 +805,17 @@ public TileViewLineView (TileView parent, int idx) AddKeyBinding (Key.CursorDown, Command.LineDown); } - public override bool ProcessKey (KeyEvent kb) + public override bool OnKeyPressed (KeyEventArgs kb) { if (!CanFocus || !HasFocus) { - return base.ProcessKey (kb); + return base.OnKeyPressed (kb); } var result = InvokeKeybindings (kb); if (result != null) return (bool)result; - return base.ProcessKey (kb); + return base.OnKeyPressed (kb); } public override void PositionCursor () diff --git a/Terminal.Gui/Views/TimeField.cs b/Terminal.Gui/Views/TimeField.cs index ff0b7198b8..e5944f1fc0 100644 --- a/Terminal.Gui/Views/TimeField.cs +++ b/Terminal.Gui/Views/TimeField.cs @@ -247,7 +247,7 @@ void AdjCursorPosition () } /// - public override bool ProcessKey (KeyEvent kb) + public override bool OnKeyPressed (KeyEventArgs kb) { var result = InvokeKeybindings (kb); if (result != null) diff --git a/Terminal.Gui/Views/Toplevel.cs b/Terminal.Gui/Views/Toplevel.cs index 4612d84cf0..a44b296c59 100644 --- a/Terminal.Gui/Views/Toplevel.cs +++ b/Terminal.Gui/Views/Toplevel.cs @@ -318,7 +318,7 @@ public override bool CanFocus { /// /// /// - /// events will propagate keys upwards. + /// events will propagate keys upwards. /// /// /// The Toplevel will act as an embedded view (not a modal/pop-up). @@ -329,7 +329,7 @@ public override bool CanFocus { /// /// /// - /// events will NOT propogate keys upwards. + /// events will NOT propogate keys upwards. /// /// /// The Toplevel will and look like a modal (pop-up) (e.g. see . @@ -355,7 +355,7 @@ public override bool CanFocus { public bool IsLoaded { get; private set; } /// - public override bool OnKeyDown (KeyEvent keyEvent) + public override bool OnKeyDown (KeyEventArgs keyEvent) { if (base.OnKeyDown (keyEvent)) { return true; @@ -373,7 +373,7 @@ public override bool OnKeyDown (KeyEvent keyEvent) } /// - public override bool OnKeyUp (KeyEvent keyEvent) + public override bool OnKeyUp (KeyEventArgs keyEvent) { if (base.OnKeyUp (keyEvent)) { return true; @@ -393,12 +393,12 @@ public override bool OnKeyUp (KeyEvent keyEvent) } /// - public override bool ProcessKey (KeyEvent keyEvent) + public override bool OnKeyPressed (KeyEventArgs keyEvent) { - if (base.ProcessKey (keyEvent)) + if (base.OnKeyPressed (keyEvent)) return true; - var result = InvokeKeybindings (new KeyEvent (ShortcutHelper.GetModifiersKey (keyEvent), + var result = InvokeKeybindings (new KeyEventArgs (ShortcutHelper.GetModifiersKey (keyEvent), new KeyModifiers () { Alt = keyEvent.IsAlt, Ctrl = keyEvent.IsCtrl, Shift = keyEvent.IsShift })); if (result != null) return (bool)result; @@ -479,7 +479,7 @@ private void QuitToplevel () } /// - public override bool ProcessColdKey (KeyEvent keyEvent) + public override bool ProcessColdKey (KeyEventArgs keyEvent) { if (base.ProcessColdKey (keyEvent)) { return true; diff --git a/Terminal.Gui/Views/TreeView/TreeView.cs b/Terminal.Gui/Views/TreeView/TreeView.cs index ba63944118..2180cad223 100644 --- a/Terminal.Gui/Views/TreeView/TreeView.cs +++ b/Terminal.Gui/Views/TreeView/TreeView.cs @@ -621,7 +621,7 @@ private IEnumerable> AddToLineMap (Branch currentBranch, bool paren public CollectionNavigator KeystrokeNavigator { get; private set; } = new CollectionNavigator (); /// - public override bool ProcessKey (KeyEvent keyEvent) + public override bool OnKeyPressed (KeyEventArgs arg) { if (!Enabled) { return false; @@ -629,13 +629,13 @@ public override bool ProcessKey (KeyEvent keyEvent) try { // First of all deal with any registered keybindings - var result = InvokeKeybindings (keyEvent); + var result = InvokeKeybindings (arg); if (result != null) { return (bool)result; } // If not a keybinding, is the key a searchable key press? - if (CollectionNavigator.IsCompatibleKey (keyEvent) && AllowLetterBasedNavigation) { + if (CollectionNavigator.IsCompatibleKey (arg) && AllowLetterBasedNavigation) { IReadOnlyCollection> map; // If there has been a call to InvalidateMap since the last time @@ -644,7 +644,7 @@ public override bool ProcessKey (KeyEvent keyEvent) // Find the current selected object within the tree var current = map.IndexOf (b => b.Model == SelectedObject); - var newIndex = KeystrokeNavigator?.GetNextMatchingItem (current, (char)keyEvent.KeyValue); + var newIndex = KeystrokeNavigator?.GetNextMatchingItem (current, (char)arg.KeyValue); if (newIndex is int && newIndex != -1) { SelectedObject = map.ElementAt ((int)newIndex).Model; @@ -657,7 +657,7 @@ public override bool ProcessKey (KeyEvent keyEvent) PositionCursor (); } - return base.ProcessKey (keyEvent); + return base.OnKeyPressed (arg); } /// diff --git a/Terminal.Gui/Views/Wizard/Wizard.cs b/Terminal.Gui/Views/Wizard/Wizard.cs index 8b8d0c89bd..b5b2627fa1 100644 --- a/Terminal.Gui/Views/Wizard/Wizard.cs +++ b/Terminal.Gui/Views/Wizard/Wizard.cs @@ -147,23 +147,23 @@ private void NextfinishBtn_Clicked (object sender, EventArgs e) /// /// is derived from and Dialog causes Esc to call - /// , closing the Dialog. Wizard overrides + /// , closing the Dialog. Wizard overrides /// to instead fire the event when Wizard is being used as a non-modal (see . - /// See for more. + /// See for more. /// /// /// - public override bool ProcessKey (KeyEvent kb) + public override bool OnKeyPressed (KeyEventArgs arg) { if (!Modal) { - switch (kb.Key) { + switch (arg.Key) { case Key.Esc: var args = new WizardButtonEventArgs (); Cancelled?.Invoke (this, args); return false; } } - return base.ProcessKey (kb); + return base.OnKeyPressed (arg); } /// diff --git a/UICatalog/KeyBindingsDialog.cs b/UICatalog/KeyBindingsDialog.cs index 538320f383..c4d65783ed 100644 --- a/UICatalog/KeyBindingsDialog.cs +++ b/UICatalog/KeyBindingsDialog.cs @@ -181,7 +181,7 @@ private void RemapKey (object sender, EventArgs e) // prompt user to hit a key var dlg = new Dialog () { Title = "Enter Key" }; dlg.KeyPressed += (s, k) => { - key = k.KeyEvent.Key; + key = k.Key; Application.RequestStop (); }; Application.Run (dlg); diff --git a/UICatalog/Scenarios/ASCIICustomButton.cs b/UICatalog/Scenarios/ASCIICustomButton.cs index eabde34c57..d57482a019 100644 --- a/UICatalog/Scenarios/ASCIICustomButton.cs +++ b/UICatalog/Scenarios/ASCIICustomButton.cs @@ -231,30 +231,30 @@ public ScrollViewTestWindow () } } - private void Button_KeyPress (object sender, KeyEventEventArgs obj) + private void Button_KeyPress (object sender, KeyEventArgs arg) { - switch (obj.KeyEvent.Key) { + switch (arg.Key) { case Key.End: scrollView.ContentOffset = new Point (scrollView.ContentOffset.X, -(scrollView.ContentSize.Height - scrollView.Frame.Height + (scrollView.ShowHorizontalScrollIndicator ? 1 : 0))); - obj.Handled = true; + arg.Handled = true; return; case Key.Home: scrollView.ContentOffset = new Point (scrollView.ContentOffset.X, 0); - obj.Handled = true; + arg.Handled = true; return; case Key.PageDown: scrollView.ContentOffset = new Point (scrollView.ContentOffset.X, Math.Max (scrollView.ContentOffset.Y - scrollView.Frame.Height, -(scrollView.ContentSize.Height - scrollView.Frame.Height + (scrollView.ShowHorizontalScrollIndicator ? 1 : 0)))); - obj.Handled = true; + arg.Handled = true; return; case Key.PageUp: scrollView.ContentOffset = new Point (scrollView.ContentOffset.X, Math.Min (scrollView.ContentOffset.Y + scrollView.Frame.Height, 0)); - obj.Handled = true; + arg.Handled = true; return; } } diff --git a/UICatalog/Scenarios/BackgroundWorkerCollection.cs b/UICatalog/Scenarios/BackgroundWorkerCollection.cs index 22434aaedf..7eb9dca533 100644 --- a/UICatalog/Scenarios/BackgroundWorkerCollection.cs +++ b/UICatalog/Scenarios/BackgroundWorkerCollection.cs @@ -339,7 +339,7 @@ public StagingUIController () Add (close); KeyPressed += (s, e) => { - if (e.KeyEvent.Key == Key.Esc) { + if (e.Key == Key.Esc) { OnReportClosed (this, EventArgs.Empty); } }; diff --git a/UICatalog/Scenarios/ContextMenus.cs b/UICatalog/Scenarios/ContextMenus.cs index c39cb248c6..2e0eaad8f3 100644 --- a/UICatalog/Scenarios/ContextMenus.cs +++ b/UICatalog/Scenarios/ContextMenus.cs @@ -59,7 +59,7 @@ public override void Setup () Point mousePos = default; Win.KeyPressed += (s, e) => { - if (e.KeyEvent.Key == (Key.Space | Key.CtrlMask)) { + if (e.Key == (Key.Space | Key.CtrlMask)) { ShowContextMenu (mousePos.X, mousePos.Y); e.Handled = true; } diff --git a/UICatalog/Scenarios/CsvEditor.cs b/UICatalog/Scenarios/CsvEditor.cs index 96ff667ffe..7c6b1deee1 100644 --- a/UICatalog/Scenarios/CsvEditor.cs +++ b/UICatalog/Scenarios/CsvEditor.cs @@ -465,9 +465,9 @@ private void SetupScrollBar () } - private void TableViewKeyPress (object sender, KeyEventEventArgs e) + private void TableViewKeyPress (object sender, KeyEventArgs e) { - if (e.KeyEvent.Key == Key.DeleteChar) { + if (e.Key == Key.DeleteChar) { if (tableView.FullRowSelect) { // Delete button deletes all rows when in full row mode diff --git a/UICatalog/Scenarios/DynamicMenuBar.cs b/UICatalog/Scenarios/DynamicMenuBar.cs index 62a8fcb80d..bb38a2d12c 100644 --- a/UICatalog/Scenarios/DynamicMenuBar.cs +++ b/UICatalog/Scenarios/DynamicMenuBar.cs @@ -723,17 +723,17 @@ public DynamicMenuBarDetails (string title) : base (title) ReadOnly = true }; _txtShortcut.KeyDown += (s, e) => { - if (!ProcessKey (e.KeyEvent)) { + if (!ProcessKey (e)) { return; } - var k = ShortcutHelper.GetModifiersKey (e.KeyEvent); + var k = ShortcutHelper.GetModifiersKey (e); if (CheckShortcut (k, true)) { e.Handled = true; } }; - bool ProcessKey (KeyEvent ev) + bool ProcessKey (KeyEventArgs ev) { switch (ev.Key) { case Key.CursorUp: @@ -766,7 +766,7 @@ bool CheckShortcut (Key k, bool pre) } _txtShortcut.KeyUp += (s, e) => { - var k = ShortcutHelper.GetModifiersKey (e.KeyEvent); + var k = ShortcutHelper.GetModifiersKey (e); if (CheckShortcut (k, false)) { e.Handled = true; } diff --git a/UICatalog/Scenarios/DynamicStatusBar.cs b/UICatalog/Scenarios/DynamicStatusBar.cs index e28092117a..1adf3bf1b9 100644 --- a/UICatalog/Scenarios/DynamicStatusBar.cs +++ b/UICatalog/Scenarios/DynamicStatusBar.cs @@ -396,17 +396,17 @@ public DynamicStatusBarDetails (string title) : base (title) ReadOnly = true }; _txtShortcut.KeyDown += (s, e) => { - if (!ProcessKey (e.KeyEvent)) { + if (!OnKeyPressed (e)) { return; } - var k = ShortcutHelper.GetModifiersKey (e.KeyEvent); + var k = ShortcutHelper.GetModifiersKey (e); if (CheckShortcut (k, true)) { e.Handled = true; } }; - bool ProcessKey (KeyEvent ev) + bool OnKeyPressed (KeyEventArgs ev) { switch (ev.Key) { case Key.CursorUp: @@ -440,7 +440,7 @@ bool CheckShortcut (Key k, bool pre) } _txtShortcut.KeyUp += (s, e) => { - var k = ShortcutHelper.GetModifiersKey (e.KeyEvent); + var k = ShortcutHelper.GetModifiersKey (e); if (CheckShortcut (k, false)) { e.Handled = true; } diff --git a/UICatalog/Scenarios/Editor.cs b/UICatalog/Scenarios/Editor.cs index 45c6f704fd..6b945f8bbc 100644 --- a/UICatalog/Scenarios/Editor.cs +++ b/UICatalog/Scenarios/Editor.cs @@ -177,11 +177,11 @@ public override void Init () }; Win.KeyPressed += (s, e) => { - var keys = ShortcutHelper.GetModifiersKey (e.KeyEvent); - if (_winDialog != null && (e.KeyEvent.Key == Key.Esc - || e.KeyEvent.Key == Application.QuitKey)) { + var keys = ShortcutHelper.GetModifiersKey (e); + if (_winDialog != null && (e.Key == Key.Esc + || e.Key == Application.QuitKey)) { DisposeWinDialog (); - } else if (e.KeyEvent.Key == Application.QuitKey) { + } else if (e.Key == Application.QuitKey) { Quit (); e.Handled = true; } else if (_winDialog != null && keys == (Key.Tab | Key.CtrlMask)) { diff --git a/UICatalog/Scenarios/InteractiveTree.cs b/UICatalog/Scenarios/InteractiveTree.cs index 26b26d1fde..6b2ba38812 100644 --- a/UICatalog/Scenarios/InteractiveTree.cs +++ b/UICatalog/Scenarios/InteractiveTree.cs @@ -44,9 +44,9 @@ public override void Setup () } - private void TreeView_KeyPress (object sender, KeyEventEventArgs obj) + private void TreeView_KeyPress (object sender, KeyEventArgs obj) { - if (obj.KeyEvent.Key == Key.DeleteChar) { + if (obj.Key == Key.DeleteChar) { var toDelete = treeView.SelectedObject; diff --git a/UICatalog/Scenarios/Keys.cs b/UICatalog/Scenarios/Keys.cs index 6594daa07c..e6373e625c 100644 --- a/UICatalog/Scenarios/Keys.cs +++ b/UICatalog/Scenarios/Keys.cs @@ -8,23 +8,23 @@ namespace UICatalog.Scenarios { public class Keys : Scenario { class TestWindow : Window { - public List _processKeyList = new List (); + public List _onKeyPressedList = new List (); public List _processHotKeyList = new List (); public List _processColdKeyList = new List (); - public override bool ProcessKey (KeyEvent keyEvent) + public override bool OnKeyPressed (KeyEventArgs arg) { - _processKeyList.Add (keyEvent.ToString ()); - return base.ProcessKey (keyEvent); + _onKeyPressedList.Add (arg.ToString ()); + return base.OnKeyPressed (arg); } - public override bool ProcessHotKey (KeyEvent keyEvent) + public override bool ProcessHotKey (KeyEventArgs keyEvent) { _processHotKeyList.Add (keyEvent.ToString ()); return base.ProcessHotKey (keyEvent); } - public override bool ProcessColdKey (KeyEvent keyEvent) + public override bool ProcessColdKey (KeyEventArgs keyEvent) { _processColdKeyList.Add (keyEvent.ToString ()); @@ -65,29 +65,30 @@ public override void Setup () Win.Add (edit); // Last KeyPress: ______ - var keyPressedLabel = new Label ("Last Application.KeyPress:") { + var appKeyPressedLabel = new Label ("Last Application.KeyPress:") { X = Pos.Left (editLabel), Y = Pos.Top (editLabel) + 2, }; - Win.Add (keyPressedLabel); - var labelKeypress = new Label ("") { - X = Pos.Left (edit), - Y = Pos.Top (keyPressedLabel), + Win.Add (appKeyPressedLabel); + var labelAppKeyPressed = new Label ("") { + X = Pos.Right (appKeyPressedLabel) + 1, + Y = Pos.Top (appKeyPressedLabel), TextAlignment = Terminal.Gui.TextAlignment.Centered, ColorScheme = Colors.Error, AutoSize = true }; - Win.Add (labelKeypress); + Win.Add (labelAppKeyPressed); - Win.KeyPressed += (s, e) => labelKeypress.Text = e.KeyEvent.ToString (); + Application.KeyPressed += (s, e) => labelAppKeyPressed.Text = e.ToString (); - // Key stroke log: - var keyLogLabel = new Label ("Key event log:") { + // Key event log (for Application): + + var keyLogLabel = new Label ("All events:") { X = Pos.Left (editLabel), Y = Pos.Top (editLabel) + 4, }; Win.Add (keyLogLabel); - var fakeKeyPress = new KeyEvent (Key.CtrlMask | Key.A, new KeyModifiers () { + var fakeKeyPress = new KeyEventArgs (Key.CtrlMask | Key.A, new KeyModifiers () { Alt = true, Ctrl = true, Shift = true @@ -105,7 +106,7 @@ public override void Setup () Win.Add (keyEventListView); // ProcessKey log: - var processKeyLogLabel = new Label ("ProcessKey log:") { + var processKeyLogLabel = new Label ("Win.OnKeyPressed:") { X = Pos.Right (keyEventListView) + 1, Y = Pos.Top (editLabel) + 4, }; @@ -113,7 +114,7 @@ public override void Setup () maxLogEntry = $"{fakeKeyPress}".Length; yOffset = (Application.Top == Application.Top ? 1 : 6); - var processKeyListView = new ListView (((TestWindow)Win)._processKeyList) { + var processKeyListView = new ListView (((TestWindow)Win)._onKeyPressedList) { X = Pos.Left (processKeyLogLabel), Y = Pos.Top (processKeyLogLabel) + yOffset, Width = Dim.Percent (30), @@ -124,7 +125,7 @@ public override void Setup () // ProcessHotKey log: // BUGBUG: Label is not positioning right with Pos, so using TextField instead - var processHotKeyLogLabel = new Label ("ProcessHotKey log:") { + var processHotKeyLogLabel = new Label ("Win.ProcessHotKey:") { X = Pos.Right (processKeyListView) + 1, Y = Pos.Top (editLabel) + 4, }; @@ -142,7 +143,7 @@ public override void Setup () // ProcessColdKey log: // BUGBUG: Label is not positioning right with Pos, so using TextField instead - var processColdKeyLogLabel = new Label ("ProcessColdKey log:") { + var processColdKeyLogLabel = new Label ("Win.ProcessColdKey:") { X = Pos.Right (processHotKeyListView) + 1, Y = Pos.Top (editLabel) + 4, }; @@ -156,14 +157,10 @@ public override void Setup () Height = Dim.Fill (), }; - Application.KeyDown += (s, a) => KeyDownPressUp (a, "Down"); - Application.KeyPressed += (s, a) => KeyDownPressUp (a, "Press"); - Application.KeyUp += (s, a) => KeyDownPressUp (a, "Up"); - - void KeyDownPressUp (KeyEventEventArgs args, string updown) + void KeyDownPressUp (KeyEventArgs args, string updown) { // BUGBUG: KeyEvent.ToString is badly broken - var msg = $"Key{updown,-5}: {args.KeyEvent}"; + var msg = $"Key{updown,-5}: {args}"; keyEventlist.Add (msg); keyEventListView.MoveDown (); processKeyListView.MoveDown (); @@ -171,6 +168,10 @@ void KeyDownPressUp (KeyEventEventArgs args, string updown) processHotKeyListView.MoveDown (); } + Application.KeyDown += (s, a) => KeyDownPressUp (a, "Down"); + Application.KeyPressed += (s, a) => KeyDownPressUp (a, "Press"); + Application.KeyUp += (s, a) => KeyDownPressUp (a, "Up"); + processColdKeyListView.ColorScheme = Colors.TopLevel; Win.Add (processColdKeyListView); } diff --git a/UICatalog/Scenarios/LineDrawing.cs b/UICatalog/Scenarios/LineDrawing.cs index 45de71facb..89a1812a1c 100644 --- a/UICatalog/Scenarios/LineDrawing.cs +++ b/UICatalog/Scenarios/LineDrawing.cs @@ -32,7 +32,7 @@ public override void Setup () Win.Add (canvas); Win.Add (tools); - Win.KeyPressed += (s,e) => { e.Handled = canvas.ProcessKey (e.KeyEvent); }; + Win.KeyPressed += (s,e) => { e.Handled = canvas.OnKeyPressed (e); }; } class ToolsView : Window { @@ -107,7 +107,7 @@ public DrawingArea () Stack undoHistory = new (); - public override bool ProcessKey (KeyEvent e) + public override bool OnKeyPressed (KeyEventArgs e) { if (e.Key == (Key.Z | Key.CtrlMask)) { var pop = _currentLayer.RemoveLastLine (); @@ -127,7 +127,7 @@ public override bool ProcessKey (KeyEvent e) } } - return base.ProcessKey (e); + return base.OnKeyPressed (e); } internal void AddLayer () { diff --git a/UICatalog/Scenarios/ListColumns.cs b/UICatalog/Scenarios/ListColumns.cs index c3c38f0695..bb5484d07f 100644 --- a/UICatalog/Scenarios/ListColumns.cs +++ b/UICatalog/Scenarios/ListColumns.cs @@ -153,9 +153,9 @@ private void SetupScrollBar () } - private void TableViewKeyPress (object sender, KeyEventEventArgs e) + private void TableViewKeyPress (object sender, KeyEventArgs e) { - if (e.KeyEvent.Key == Key.DeleteChar) { + if (e.Key == Key.DeleteChar) { // set all selected cells to null foreach (var pt in listColView.GetAllSelectedCells ()) { diff --git a/UICatalog/Scenarios/SendKeys.cs b/UICatalog/Scenarios/SendKeys.cs index dd9eef8ddd..965fb30c80 100644 --- a/UICatalog/Scenarios/SendKeys.cs +++ b/UICatalog/Scenarios/SendKeys.cs @@ -58,16 +58,16 @@ public override void Setup () var IsCtrl = false; txtResult.KeyPressed += (s, e) => { - rKeys += (char)e.KeyEvent.Key; - if (!IsShift && e.KeyEvent.IsShift) { + rKeys += (char)e.Key; + if (!IsShift && e.IsShift) { rControlKeys += " Shift "; IsShift = true; } - if (!IsAlt && e.KeyEvent.IsAlt) { + if (!IsAlt && e.IsAlt) { rControlKeys += " Alt "; IsAlt = true; } - if (!IsCtrl && e.KeyEvent.IsCtrl) { + if (!IsCtrl && e.IsCtrl) { rControlKeys += " Ctrl "; IsCtrl = true; } @@ -117,7 +117,7 @@ void ProcessInput () button.Clicked += (s,e) => ProcessInput (); Win.KeyPressed += (s, e) => { - if (e.KeyEvent.Key == Key.Enter) { + if (e.Key == Key.Enter) { ProcessInput (); e.Handled = true; } diff --git a/UICatalog/Scenarios/SingleBackgroundWorker.cs b/UICatalog/Scenarios/SingleBackgroundWorker.cs index 80b3693e65..d979f34b4a 100644 --- a/UICatalog/Scenarios/SingleBackgroundWorker.cs +++ b/UICatalog/Scenarios/SingleBackgroundWorker.cs @@ -136,7 +136,7 @@ public StagingUIController (DateTime? start, List list) top.KeyPressed += (s,e) => { // Prevents Ctrl+Q from closing this. // Only Ctrl+C is allowed. - if (e.KeyEvent.Key == Application.QuitKey) { + if (e.Key == Application.QuitKey) { e.Handled = true; } }; diff --git a/UICatalog/Scenarios/Snake.cs b/UICatalog/Scenarios/Snake.cs index 327480ba8c..1c9d786c7e 100644 --- a/UICatalog/Scenarios/Snake.cs +++ b/UICatalog/Scenarios/Snake.cs @@ -124,7 +124,7 @@ public override void OnDrawContent (Rect contentArea) AddRune (State.Apple.X, State.Apple.Y, _appleRune); Driver.SetAttribute (white); } - public override bool OnKeyDown (KeyEvent keyEvent) + public override bool OnKeyDown (KeyEventArgs keyEvent) { if (keyEvent.Key == Key.CursorUp) { State.PlannedDirection = Direction.Up; diff --git a/UICatalog/Scenarios/TableEditor.cs b/UICatalog/Scenarios/TableEditor.cs index bf477e8eac..4de2a7ce41 100644 --- a/UICatalog/Scenarios/TableEditor.cs +++ b/UICatalog/Scenarios/TableEditor.cs @@ -386,13 +386,13 @@ private void SetupScrollBar () } - private void TableViewKeyPress (object sender, KeyEventEventArgs e) + private void TableViewKeyPress (object sender, KeyEventArgs e) { if(currentTable == null) { return; } - if (e.KeyEvent.Key == Key.DeleteChar) { + if (e.Key == Key.DeleteChar) { if (tableView.FullRowSelect) { // Delete button deletes all rows when in full row mode diff --git a/UICatalog/Scenarios/TreeViewFileSystem.cs b/UICatalog/Scenarios/TreeViewFileSystem.cs index 7e4c722426..a9517ca915 100644 --- a/UICatalog/Scenarios/TreeViewFileSystem.cs +++ b/UICatalog/Scenarios/TreeViewFileSystem.cs @@ -158,9 +158,9 @@ private void TreeViewFiles_DrawLine (object sender, DrawTreeViewLineEventArgs { - //System.Diagnostics.Debug.WriteLine ($"Output - KeyDown: {e.KeyEvent.Key}"); + //System.Diagnostics.Debug.WriteLine ($"Output - KeyDown: {e.Key}"); e.Handled = true; - if (e.KeyEvent.Key == Key.Unknown) { + if (e.Key == Key.Unknown) { _wasUnknown = true; } }; @@ -99,9 +99,9 @@ public override void Setup () tvOutput.KeyPressed += (s, e) => { //System.Diagnostics.Debug.WriteLine ($"Output - KeyPress - _keyboardStrokes: {_keyboardStrokes.Count}"); if (_outputStarted && _keyboardStrokes.Count > 0) { - var ev = ShortcutHelper.GetModifiersKey (e.KeyEvent); + var ev = ShortcutHelper.GetModifiersKey (e); //System.Diagnostics.Debug.WriteLine ($"Output - KeyPress: {ev}"); - if (!tvOutput.ProcessKey (e.KeyEvent)) { + if (!tvOutput.OnKeyPressed (e)) { Application.Invoke (() => { MessageBox.Query ("Keys", $"'{ShortcutHelper.GetShortcutTag (ev)}' pressed!", "Ok"); }); @@ -115,28 +115,28 @@ public override void Setup () Win.Add (tvOutput); tvInput.KeyDown += (s, e) => { - //System.Diagnostics.Debug.WriteLine ($"Input - KeyDown: {e.KeyEvent.Key}"); + //System.Diagnostics.Debug.WriteLine ($"Input - KeyDown: {e.Key}"); e.Handled = true; - if (e.KeyEvent.Key == Key.Unknown) { + if (e.Key == Key.Unknown) { _wasUnknown = true; } }; - KeyEventEventArgs unknownChar = null; + KeyEventArgs unknownChar = null; tvInput.KeyPressed += (s, e) => { - if (e.KeyEvent.Key == (Key.Q | Key.CtrlMask)) { + if (e.Key == (Key.Q | Key.CtrlMask)) { Application.RequestStop (); return; } - if (e.KeyEvent.Key == Key.Unknown) { + if (e.Key == Key.Unknown) { _wasUnknown = true; e.Handled = true; return; } if (_wasUnknown && _keyboardStrokes.Count == 1) { _wasUnknown = false; - } else if (_wasUnknown && char.IsLetter ((char)e.KeyEvent.Key)) { + } else if (_wasUnknown && char.IsLetter ((char)e.Key)) { _wasUnknown = false; } else if (!_wasUnknown && _keyboardStrokes.Count > 0) { e.Handled = true; @@ -147,15 +147,15 @@ public override void Setup () } else { _keyboardStrokes.Insert (0, 0); } - var ev = ShortcutHelper.GetModifiersKey (e.KeyEvent); + var ev = ShortcutHelper.GetModifiersKey (e); //System.Diagnostics.Debug.WriteLine ($"Input - KeyPress: {ev}"); //System.Diagnostics.Debug.WriteLine ($"Input - KeyPress - _keyboardStrokes: {_keyboardStrokes.Count}"); }; tvInput.KeyUp += (s, e) => { - //System.Diagnostics.Debug.WriteLine ($"Input - KeyUp: {e.KeyEvent.Key}"); + //System.Diagnostics.Debug.WriteLine ($"Input - KeyUp: {e.Key}"); //var ke = e.KeyEvent; - var ke = ShortcutHelper.GetModifiersKey (e.KeyEvent); + var ke = ShortcutHelper.GetModifiersKey (e); if (_wasUnknown && (int)ke - (int)(ke & (Key.AltMask | Key.CtrlMask | Key.ShiftMask)) != 0) { unknownChar = e; } @@ -232,21 +232,20 @@ void Win_LayoutComplete (object sender, LayoutEventArgs obj) Win.LayoutComplete += Win_LayoutComplete; } - private void AddKeyboardStrokes (KeyEventEventArgs e) + private void AddKeyboardStrokes (KeyEventArgs e) { - var ke = e.KeyEvent; var km = new KeyModifiers (); - if (ke.IsShift) { + if (e.IsShift) { km.Shift = true; } - if (ke.IsAlt) { + if (e.IsAlt) { km.Alt = true; } - if (ke.IsCtrl) { + if (e.IsCtrl) { km.Ctrl = true; } - var keyChar = ke.KeyValue; - var mK = (int)((Key)ke.KeyValue & (Key.AltMask | Key.CtrlMask | Key.ShiftMask)); + var keyChar = e.KeyValue; + var mK = (int)((Key)e.KeyValue & (Key.AltMask | Key.CtrlMask | Key.ShiftMask)); keyChar &= ~mK; _keyboardStrokes.Add (keyChar); } diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs index 73df8a21b8..3d8bfe0d04 100644 --- a/UICatalog/UICatalog.cs +++ b/UICatalog/UICatalog.cs @@ -373,8 +373,8 @@ public UICatalogTopLevel () // 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 (CollectionNavigator.IsCompatibleKey (a.KeyEvent)) { - var newItem = _scenarioCollectionNav?.GetNextMatchingItem (ScenarioList.SelectedRow, (char)a.KeyEvent.KeyValue); + if (CollectionNavigator.IsCompatibleKey (a)) { + var newItem = _scenarioCollectionNav?.GetNextMatchingItem (ScenarioList.SelectedRow, (char)a.KeyValue); if (newItem is int v && newItem != -1) { ScenarioList.SelectedRow = v; ScenarioList.EnsureSelectedCellIsVisible (); @@ -768,9 +768,9 @@ public void ConfigChanged () Application.Top.SetNeedsDisplay (); } - void KeyDownHandler (object? sender, KeyEventEventArgs? a) + void KeyDownHandler (object? sender, KeyEventArgs? a) { - if (a!.KeyEvent.IsCapslock) { + if (a!.IsCapslock) { Capslock.Title = "Caps: On"; StatusBar.SetNeedsDisplay (); } else { @@ -778,7 +778,7 @@ void KeyDownHandler (object? sender, KeyEventEventArgs? a) StatusBar.SetNeedsDisplay (); } - if (a!.KeyEvent.IsNumlock) { + if (a!.IsNumlock) { Numlock.Title = "Num: On"; StatusBar.SetNeedsDisplay (); } else { @@ -786,7 +786,7 @@ void KeyDownHandler (object? sender, KeyEventEventArgs? a) StatusBar.SetNeedsDisplay (); } - if (a!.KeyEvent.IsScrolllock) { + if (a!.IsScrolllock) { Scrolllock.Title = "Scroll: On"; StatusBar.SetNeedsDisplay (); } else { diff --git a/UnitTests/Application/ApplicationTests.cs b/UnitTests/Application/ApplicationTests.cs index 5dca0018c8..80d6eb6635 100644 --- a/UnitTests/Application/ApplicationTests.cs +++ b/UnitTests/Application/ApplicationTests.cs @@ -582,9 +582,9 @@ public void KeyUp_Event () int keyUps = 0; var output = string.Empty; - Application.Top.KeyUp += (object sender, KeyEventEventArgs args) => { - if (args.KeyEvent.Key != (Key.CtrlMask | Key.Q)) { - output += (char)args.KeyEvent.KeyValue; + Application.Top.KeyUp += (object sender, KeyEventArgs args) => { + if (args.Key != (Key.CtrlMask | Key.Q)) { + output += (char)args.KeyValue; } keyUps++; }; @@ -631,55 +631,55 @@ public void AlternateForwardKey_AlternateBackwardKey_Tests () Application.Iteration += (s, a) => { Assert.True (v1.HasFocus); // Using default keys. - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, + top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.Tab, new KeyModifiers () { Ctrl = true })); Assert.True (v2.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, + top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.Tab, new KeyModifiers () { Ctrl = true })); Assert.True (v3.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, + top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.Tab, new KeyModifiers () { Ctrl = true })); Assert.True (v4.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, + top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.Tab, new KeyModifiers () { Ctrl = true })); Assert.True (v1.HasFocus); - top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, + top.OnKeyPressed (new KeyEventArgs (Key.ShiftMask | Key.CtrlMask | Key.Tab, new KeyModifiers () { Shift = true, Ctrl = true })); Assert.True (v4.HasFocus); - top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, + top.OnKeyPressed (new KeyEventArgs (Key.ShiftMask | Key.CtrlMask | Key.Tab, new KeyModifiers () { Shift = true, Ctrl = true })); Assert.True (v3.HasFocus); - top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, + top.OnKeyPressed (new KeyEventArgs (Key.ShiftMask | Key.CtrlMask | Key.Tab, new KeyModifiers () { Shift = true, Ctrl = true })); Assert.True (v2.HasFocus); - top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, + top.OnKeyPressed (new KeyEventArgs (Key.ShiftMask | Key.CtrlMask | Key.Tab, new KeyModifiers () { Shift = true, Ctrl = true })); Assert.True (v1.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown, + top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.PageDown, new KeyModifiers () { Ctrl = true })); Assert.True (v2.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown, + top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.PageDown, new KeyModifiers () { Ctrl = true })); Assert.True (v3.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown, + top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.PageDown, new KeyModifiers () { Ctrl = true })); Assert.True (v4.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown, + top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.PageDown, new KeyModifiers () { Ctrl = true })); Assert.True (v1.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp, + top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.PageUp, new KeyModifiers () { Ctrl = true })); Assert.True (v4.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp, + top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.PageUp, new KeyModifiers () { Ctrl = true })); Assert.True (v3.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp, + top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.PageUp, new KeyModifiers () { Ctrl = true })); Assert.True (v2.HasFocus); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp, + top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.PageUp, new KeyModifiers () { Ctrl = true })); Assert.True (v1.HasFocus); @@ -687,22 +687,22 @@ public void AlternateForwardKey_AlternateBackwardKey_Tests () Application.AlternateForwardKey = Key.F7; Application.AlternateBackwardKey = Key.F6; - top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ())); + top.OnKeyPressed (new KeyEventArgs (Key.F7, new KeyModifiers ())); Assert.True (v2.HasFocus); - top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ())); + top.OnKeyPressed (new KeyEventArgs (Key.F7, new KeyModifiers ())); Assert.True (v3.HasFocus); - top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ())); + top.OnKeyPressed (new KeyEventArgs (Key.F7, new KeyModifiers ())); Assert.True (v4.HasFocus); - top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ())); + top.OnKeyPressed (new KeyEventArgs (Key.F7, new KeyModifiers ())); Assert.True (v1.HasFocus); - top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ())); + top.OnKeyPressed (new KeyEventArgs (Key.F6, new KeyModifiers ())); Assert.True (v4.HasFocus); - top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ())); + top.OnKeyPressed (new KeyEventArgs (Key.F6, new KeyModifiers ())); Assert.True (v3.HasFocus); - top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ())); + top.OnKeyPressed (new KeyEventArgs (Key.F6, new KeyModifiers ())); Assert.True (v2.HasFocus); - top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ())); + top.OnKeyPressed (new KeyEventArgs (Key.F6, new KeyModifiers ())); Assert.True (v1.HasFocus); Application.RequestStop (); @@ -775,14 +775,14 @@ public void EnsuresTopOnFront_CanFocus_True_By_Keyboard_And_Mouse () Assert.False (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); + top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.Tab, new KeyModifiers ())); Assert.True (win.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); Assert.True (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); + top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.Tab, new KeyModifiers ())); Assert.True (win.CanFocus); Assert.True (win.HasFocus); Assert.True (win2.CanFocus); @@ -827,14 +827,14 @@ public void EnsuresTopOnFront_CanFocus_False_By_Keyboard_And_Mouse () Assert.True (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); + top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.Tab, new KeyModifiers ())); Assert.True (win2.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); Assert.True (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); + top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.Tab, new KeyModifiers ())); Assert.False (win.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); diff --git a/UnitTests/Application/MainLoopTests.cs b/UnitTests/Application/MainLoopTests.cs index a3cba7a4e7..1dd7c6ff46 100644 --- a/UnitTests/Application/MainLoopTests.cs +++ b/UnitTests/Application/MainLoopTests.cs @@ -688,7 +688,7 @@ public void Mainloop_Invoke_Or_AddIdle_Can_Be_Used_For_Events_Or_Actions (Action if (iterations == 0) { Assert.Null (btn); Assert.Equal (zero, total); - Assert.True (btnLaunch.ProcessKey (new KeyEvent (Key.Enter, null))); + Assert.True (btnLaunch.OnKeyPressed (new KeyEventArgs (Key.Enter, null))); if (btn == null) { Assert.Null (btn); Assert.Equal (zero, total); @@ -699,7 +699,7 @@ public void Mainloop_Invoke_Or_AddIdle_Can_Be_Used_For_Events_Or_Actions (Action } else if (iterations == 1) { Assert.Equal (clickMe, btn.Text); Assert.Equal (zero, total); - Assert.True (btn.ProcessKey (new KeyEvent (Key.Enter, null))); + Assert.True (btn.OnKeyPressed (new KeyEventArgs (Key.Enter, null))); Assert.Equal (cancel, btn.Text); Assert.Equal (one, total); } else if (taskCompleted) { diff --git a/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs b/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs index f36a550b13..8675953355 100644 --- a/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs +++ b/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs @@ -121,8 +121,8 @@ public void FakeDriver_MockKeyPresses (Type driverType) var idx = 0; view.KeyPressed += (s, e) => { - Assert.Equal (text [idx], (char)e.KeyEvent.Key); - rText += (char)e.KeyEvent.Key; + Assert.Equal (text [idx], (char)e.Key); + rText += (char)e.Key; Assert.Equal (rText, text.Substring (0, idx + 1)); e.Handled = true; idx++; @@ -175,7 +175,7 @@ public void FakeDriver_MockKeyPresses (Type driverType) // Key key = Key.Unknown; // Application.Top.KeyPress += (e) => { - // key = e.KeyEvent.Key; + // key = e.Key; // output.WriteLine ($" Application.Top.KeyPress: {key}"); // e.Handled = true; @@ -258,7 +258,7 @@ public void TerminalResized_Simulation (Type driverType) // var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); // Assert.Equal (new Rect (0, 0, 20, 8), pos); -// Assert.True (dlg.ProcessKey (new KeyEvent (Key.Tab, new KeyModifiers ()))); +// Assert.True (dlg.ProcessKey (new KeyEventArgs (Key.Tab, new KeyModifiers ()))); // dlg.Draw (); // expected = @" diff --git a/UnitTests/ConsoleDrivers/KeyTests.cs b/UnitTests/ConsoleDrivers/KeyTests.cs index b7ad45b28c..54d0964665 100644 --- a/UnitTests/ConsoleDrivers/KeyTests.cs +++ b/UnitTests/ConsoleDrivers/KeyTests.cs @@ -209,7 +209,7 @@ public void TestVKPacket (uint unicodeCharacter, bool shift, bool alt, bool cont var top = Application.Top; top.KeyPressed += (s, e) => { - var after = ShortcutHelper.GetModifiersKey (e.KeyEvent); + var after = ShortcutHelper.GetModifiersKey (e); Assert.Equal (expectedRemapping, after); e.Handled = true; Application.RequestStop (); diff --git a/UnitTests/Dialogs/DialogTests.cs b/UnitTests/Dialogs/DialogTests.cs index e01885ef9b..3c1695a5f4 100644 --- a/UnitTests/Dialogs/DialogTests.cs +++ b/UnitTests/Dialogs/DialogTests.cs @@ -799,7 +799,7 @@ public void Dialog_Opened_From_Another_Dialog () Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { - Assert.True (btn1.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ()))); + Assert.True (btn1.OnKeyPressed (new KeyEventArgs (Key.Enter, new KeyModifiers ()))); } else if (iterations == 1) { expected = @$" ┌──────────────────────────────────────────────────────────────────┐ @@ -825,7 +825,7 @@ public void Dialog_Opened_From_Another_Dialog () └──────────────────────────────────────────────────────────────────┘"; TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.True (btn2.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ()))); + Assert.True (btn2.OnKeyPressed (new KeyEventArgs (Key.Enter, new KeyModifiers ()))); } else if (iterations == 2) { TestHelpers.AssertDriverContentsWithFrameAre (@$" ┌──────────────────────────────────────────────────────────────────┐ @@ -850,11 +850,11 @@ public void Dialog_Opened_From_Another_Dialog () │ {CM.Glyphs.LeftBracket} Show Sub {CM.Glyphs.RightBracket} {CM.Glyphs.LeftBracket} Close {CM.Glyphs.RightBracket} │ └──────────────────────────────────────────────────────────────────┘", output); - Assert.True (Application.Current.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ()))); + Assert.True (Application.Current.OnKeyPressed (new KeyEventArgs (Key.Enter, new KeyModifiers ()))); } else if (iterations == 3) { TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.True (btn3.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ()))); + Assert.True (btn3.OnKeyPressed (new KeyEventArgs (Key.Enter, new KeyModifiers ()))); } else if (iterations == 4) { TestHelpers.AssertDriverContentsWithFrameAre ("", output); diff --git a/UnitTests/Input/ResponderTests.cs b/UnitTests/Input/ResponderTests.cs index d060db42f5..72407386d5 100644 --- a/UnitTests/Input/ResponderTests.cs +++ b/UnitTests/Input/ResponderTests.cs @@ -23,11 +23,11 @@ public void New_Methods_Return_False () { var r = new Responder (); - Assert.False (r.ProcessKey (new KeyEvent () { Key = Key.Unknown })); - Assert.False (r.ProcessHotKey (new KeyEvent () { Key = Key.Unknown })); - Assert.False (r.ProcessColdKey (new KeyEvent () { Key = Key.Unknown })); - Assert.False (r.OnKeyDown (new KeyEvent () { Key = Key.Unknown })); - Assert.False (r.OnKeyUp (new KeyEvent () { Key = Key.Unknown })); + Assert.False (r.OnKeyPressed (new KeyEventArgs () { Key = Key.Unknown })); + Assert.False (r.ProcessHotKey (new KeyEventArgs () { Key = Key.Unknown })); + Assert.False (r.ProcessColdKey (new KeyEventArgs () { Key = Key.Unknown })); + Assert.False (r.OnKeyDown (new KeyEventArgs () { Key = Key.Unknown })); + Assert.False (r.OnKeyUp (new KeyEventArgs () { Key = Key.Unknown })); Assert.False (r.MouseEvent (new MouseEvent () { Flags = MouseFlags.AllEvents })); Assert.False (r.OnMouseEnter (new MouseEvent () { Flags = MouseFlags.AllEvents })); Assert.False (r.OnMouseLeave (new MouseEvent () { Flags = MouseFlags.AllEvents })); @@ -62,7 +62,7 @@ public DerivedView () { } - public override bool OnKeyDown (KeyEvent keyEvent) + public override bool OnKeyDown (KeyEventArgs keyEvent) { return true; } diff --git a/UnitTests/Text/AutocompleteTests.cs b/UnitTests/Text/AutocompleteTests.cs index dcf909fc8f..bd4233ad86 100644 --- a/UnitTests/Text/AutocompleteTests.cs +++ b/UnitTests/Text/AutocompleteTests.cs @@ -92,7 +92,7 @@ public void KeyBindings_Command () Assert.Equal ("feature", g.AllSuggestions [^1]); Assert.Equal (0, tv.Autocomplete.SelectedIdx); Assert.Empty (tv.Autocomplete.Suggestions); - Assert.True (tv.ProcessKey (new KeyEvent (Key.F, new KeyModifiers ()))); + Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.F, new KeyModifiers ()))); top.Draw (); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); @@ -101,7 +101,7 @@ public void KeyBindings_Command () Assert.Equal ("feature", tv.Autocomplete.Suggestions [^1].Replacement); Assert.Equal (0, tv.Autocomplete.SelectedIdx); Assert.Equal ("Fortunately", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); - Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ()))); + Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorDown, new KeyModifiers ()))); top.Draw (); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); @@ -110,7 +110,7 @@ public void KeyBindings_Command () Assert.Equal ("feature", tv.Autocomplete.Suggestions [^1].Replacement); Assert.Equal (1, tv.Autocomplete.SelectedIdx); Assert.Equal ("feature", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); - Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ()))); + Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorDown, new KeyModifiers ()))); top.Draw (); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); @@ -119,7 +119,7 @@ public void KeyBindings_Command () Assert.Equal ("feature", tv.Autocomplete.Suggestions [^1].Replacement); Assert.Equal (0, tv.Autocomplete.SelectedIdx); Assert.Equal ("Fortunately", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); - Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()))); + Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorUp, new KeyModifiers ()))); top.Draw (); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); @@ -128,7 +128,7 @@ public void KeyBindings_Command () Assert.Equal ("feature", tv.Autocomplete.Suggestions [^1].Replacement); Assert.Equal (1, tv.Autocomplete.SelectedIdx); Assert.Equal ("feature", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); - Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()))); + Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorUp, new KeyModifiers ()))); top.Draw (); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); @@ -139,19 +139,19 @@ public void KeyBindings_Command () Assert.Equal ("Fortunately", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); Assert.True (tv.Autocomplete.Visible); top.Draw (); - Assert.True (tv.ProcessKey (new KeyEvent (tv.Autocomplete.CloseKey, new KeyModifiers ()))); + Assert.True (tv.OnKeyPressed (new KeyEventArgs (tv.Autocomplete.CloseKey, new KeyModifiers ()))); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); Assert.Empty (tv.Autocomplete.Suggestions); Assert.Equal (3, g.AllSuggestions.Count); Assert.False (tv.Autocomplete.Visible); tv.PositionCursor (); - Assert.True (tv.ProcessKey (new KeyEvent (tv.Autocomplete.Reopen, new KeyModifiers ()))); + Assert.True (tv.OnKeyPressed (new KeyEventArgs (tv.Autocomplete.Reopen, new KeyModifiers ()))); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); Assert.Equal (2, tv.Autocomplete.Suggestions.Count); Assert.Equal (3, g.AllSuggestions.Count); - Assert.True (tv.ProcessKey (new KeyEvent (tv.Autocomplete.SelectionKey, new KeyModifiers ()))); + Assert.True (tv.OnKeyPressed (new KeyEventArgs (tv.Autocomplete.SelectionKey, new KeyModifiers ()))); tv.PositionCursor (); Assert.Equal ($"Fortunately Fortunately super feature.", tv.Text); Assert.Equal (new Point (11, 0), tv.CursorPosition); @@ -178,7 +178,7 @@ public void CursorLeft_CursorRight_Mouse_Button_Pressed_Does_Not_Show_Popup () Application.Begin (top); for (int i = 0; i < 7; i++) { - Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()))); + Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorRight, new KeyModifiers ()))); Application.Refresh (); if (i < 4 || i > 5) { TestHelpers.AssertDriverContentsWithFrameAre (@" @@ -202,51 +202,51 @@ This a long line and against TextView. and against ", output); - Assert.True (tv.ProcessKey (new KeyEvent (Key.g, new KeyModifiers ()))); + Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.g, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This ag long line and against TextView. against ", output); - Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()))); + Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorLeft, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This ag long line and against TextView. against ", output); - Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()))); + Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorLeft, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This ag long line and against TextView. against ", output); - Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()))); + Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorLeft, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This ag long line and against TextView.", output); for (int i = 0; i < 3; i++) { - Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()))); + Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorRight, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This ag long line and against TextView. against ", output); } - Assert.True (tv.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ()))); + Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.Backspace, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This a long line and against TextView. and against ", output); - Assert.True (tv.ProcessKey (new KeyEvent (Key.n, new KeyModifiers ()))); + Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.n, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This an long line and against TextView. and ", output); - Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()))); + Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorRight, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This an long line and against TextView.", output); diff --git a/UnitTests/Text/CollectionNavigatorTests.cs b/UnitTests/Text/CollectionNavigatorTests.cs index 9031b157a9..70067fec9a 100644 --- a/UnitTests/Text/CollectionNavigatorTests.cs +++ b/UnitTests/Text/CollectionNavigatorTests.cs @@ -382,7 +382,7 @@ public void IsCompatibleKey_Does_Not_Allow_Alt_And_Ctrl_Keys () { // test all Keys foreach (Key key in Enum.GetValues (typeof (Key))) { - var ke = new KeyEvent (key, new KeyModifiers () { + var ke = new KeyEventArgs (key, new KeyModifiers () { Alt = key == Key.AltMask, Ctrl = key == Key.CtrlMask, Shift = key == Key.ShiftMask @@ -395,7 +395,7 @@ public void IsCompatibleKey_Does_Not_Allow_Alt_And_Ctrl_Keys () } // test Capslock, Numlock and Scrolllock - Assert.True (CollectionNavigator.IsCompatibleKey (new KeyEvent (Key.Null, new KeyModifiers () { + Assert.True (CollectionNavigator.IsCompatibleKey (new KeyEventArgs (Key.Null, new KeyModifiers () { Alt = false, Ctrl = false, Shift = false, diff --git a/UnitTests/UICatalog/ScenarioTests.cs b/UnitTests/UICatalog/ScenarioTests.cs index 19327ece95..c53742098e 100644 --- a/UnitTests/UICatalog/ScenarioTests.cs +++ b/UnitTests/UICatalog/ScenarioTests.cs @@ -69,12 +69,12 @@ public void Run_All_Scenarios () FakeConsole.PushMockKeyPress (Application.QuitKey); // The only key we care about is the QuitKey - Application.Top.KeyPressed += (object sender, KeyEventEventArgs args) => { - output.WriteLine ($" Keypress: {args.KeyEvent.Key}"); + Application.Top.KeyPressed += (object sender, KeyEventArgs args) => { + output.WriteLine ($" Keypress: {args.Key}"); // BUGBUG: (#2474) For some reason ReadKey is not returning the QuitKey for some Scenarios // by adding this Space it seems to work. // See #2474 for why this is commented out - Assert.Equal (Application.QuitKey, args.KeyEvent.Key); + Assert.Equal (Application.QuitKey, args.Key); }; uint abortTime = 500; @@ -156,9 +156,9 @@ public void Run_Generic () }; var token = Application.AddTimeout (TimeSpan.FromMilliseconds (ms), abortCallback); - Application.Top.KeyPressed += (object sender, KeyEventEventArgs args) => { + Application.Top.KeyPressed += (object sender, KeyEventArgs args) => { // See #2474 for why this is commented out - Assert.Equal (Key.CtrlMask | Key.Q, args.KeyEvent.Key); + Assert.Equal (Key.CtrlMask | Key.Q, args.Key); }; generic.Init (); diff --git a/UnitTests/View/KeyboardTests.cs b/UnitTests/View/KeyboardTests.cs index a9557294b7..d273726a88 100644 --- a/UnitTests/View/KeyboardTests.cs +++ b/UnitTests/View/KeyboardTests.cs @@ -28,7 +28,7 @@ public void KeyPress_Handled_To_True_Prevents_Changes () text.KeyPressed += (s, e) => { e.Handled = true; Assert.True (e.Handled); - Assert.Equal (Key.N, e.KeyEvent.Key); + Assert.Equal (Key.N, e.Key); }; top.Add (text); @@ -55,21 +55,21 @@ public void KeyDown_And_KeyUp_Events_Must_Called_Before_OnKeyDown_And_OnKeyUp () var view = new DerivedView (); view.KeyDown += (s, e) => { - Assert.Equal (Key.a, e.KeyEvent.Key); + Assert.Equal (Key.a, e.Key); Assert.False (keyDown); Assert.False (view.IsKeyDown); e.Handled = true; keyDown = true; }; view.KeyPressed += (s, e) => { - Assert.Equal (Key.a, e.KeyEvent.Key); + Assert.Equal (Key.a, e.Key); Assert.False (keyPress); Assert.False (view.IsKeyPress); e.Handled = true; keyPress = true; }; view.KeyUp += (s, e) => { - Assert.Equal (Key.a, e.KeyEvent.Key); + Assert.Equal (Key.a, e.Key); Assert.False (keyUp); Assert.False (view.IsKeyUp); e.Handled = true; @@ -106,19 +106,19 @@ public DerivedView () public bool IsKeyUp { get; set; } public override string Text { get; set; } - public override bool OnKeyDown (KeyEvent keyEvent) + public override bool OnKeyDown (KeyEventArgs keyEvent) { IsKeyDown = true; return true; } - public override bool ProcessKey (KeyEvent keyEvent) + public override bool OnKeyPressed (KeyEventArgs args) { IsKeyPress = true; return true; } - public override bool OnKeyUp (KeyEvent keyEvent) + public override bool OnKeyUp (KeyEventArgs keyEvent) { IsKeyUp = true; return true; @@ -137,10 +137,10 @@ public void KeyDown_And_KeyUp_Events_With_Only_Key_Modifiers (bool shift, bool a var view = new DerivedView (); view.KeyDown += (s, e) => { - Assert.Equal (-1, e.KeyEvent.KeyValue); - Assert.Equal (shift, e.KeyEvent.IsShift); - Assert.Equal (alt, e.KeyEvent.IsAlt); - Assert.Equal (control, e.KeyEvent.IsCtrl); + Assert.Equal (-1, e.KeyValue); + Assert.Equal (shift, e.IsShift); + Assert.Equal (alt, e.IsAlt); + Assert.Equal (control, e.IsCtrl); Assert.False (keyDown); Assert.False (view.IsKeyDown); keyDown = true; @@ -149,10 +149,10 @@ public void KeyDown_And_KeyUp_Events_With_Only_Key_Modifiers (bool shift, bool a keyPress = true; }; view.KeyUp += (s, e) => { - Assert.Equal (-1, e.KeyEvent.KeyValue); - Assert.Equal (shift, e.KeyEvent.IsShift); - Assert.Equal (alt, e.KeyEvent.IsAlt); - Assert.Equal (control, e.KeyEvent.IsCtrl); + Assert.Equal (-1, e.KeyValue); + Assert.Equal (shift, e.IsShift); + Assert.Equal (alt, e.IsAlt); + Assert.Equal (control, e.IsCtrl); Assert.False (keyUp); Assert.False (view.IsKeyUp); keyUp = true; diff --git a/UnitTests/View/Layout/DimTests.cs b/UnitTests/View/Layout/DimTests.cs index c70b66d458..94219071f4 100644 --- a/UnitTests/View/Layout/DimTests.cs +++ b/UnitTests/View/Layout/DimTests.cs @@ -688,7 +688,7 @@ public void Dim_Add_Operator () var count = 0; field.KeyDown += (s, k) => { - if (k.KeyEvent.Key == Key.Enter) { + if (k.Key == Key.Enter) { field.Text = $"Label {count}"; var label = new Label (field.Text) { X = 0, Y = view.Bounds.Height, Width = 20 }; view.Add (label); @@ -703,7 +703,7 @@ public void Dim_Add_Operator () }; Application.Iteration += (s, a) => { - while (count < 20) field.OnKeyDown (new KeyEvent (Key.Enter, new KeyModifiers ())); + while (count < 20) field.OnKeyDown (new KeyEventArgs (Key.Enter, new KeyModifiers ())); Application.RequestStop (); }; @@ -1050,7 +1050,7 @@ public void Dim_Add_Operator_With_Text () var listLabels = new List /// /// - /// Use this event to receive all mouse events in screen coordinates. Use to receive - /// mouse events specific to a 's bounds. + /// Use this event to receive mouse events in screen coordinates. Use to receive + /// mouse events relative to a 's bounds. /// /// /// The will contain the that contains the mouse coordinates. @@ -1278,7 +1279,7 @@ static void OnAlternateBackwardKeyChanged (KeyChangedEventArgs oldKey) static Key _quitKey = Key.Q | Key.CtrlMask; /// - /// Gets or sets the key to quit the application. The default is Ctrl-Q. + /// Gets or sets the key to quit the application. /// [SerializableConfigurationProperty (Scope = typeof (SettingsScope)), JsonConverter (typeof (KeyJsonConverter))] public static Key QuitKey { @@ -1301,17 +1302,13 @@ static void OnQuitKeyChanged (KeyChangedEventArgs e) /// /// Event fired after a key has been pressed and released. - /// Set to to suppress the event. + /// Set to to suppress the event. /// - /// . /// - /// - /// - /// /// All drivers support firing the event. Some drivers (Curses) /// do not support firing the and events. /// - public static event EventHandler KeyPressed; + public static event EventHandler KeyPressed; /// /// Called after a key has been pressed and released. Fires the event. @@ -1322,7 +1319,7 @@ static void OnQuitKeyChanged (KeyChangedEventArgs e) /// /// /// if the key was handled. - public static bool OnKeyPressed (KeyEventArgs a) + public static bool OnKeyPressed (KeyEventEventArgs a) { KeyPressed?.Invoke (null, a); if (a.Handled) { @@ -1331,7 +1328,7 @@ public static bool OnKeyPressed (KeyEventArgs a) var chain = _topLevels.ToList (); foreach (var topLevel in chain) { - if (topLevel.ProcessHotKey (a)) { + if (topLevel.ProcessHotKey (a.KeyEvent)) { return true; } if (topLevel.Modal) @@ -1339,7 +1336,7 @@ public static bool OnKeyPressed (KeyEventArgs a) } foreach (var topLevel in chain) { - if (topLevel.OnKeyPressed (a)) { + if (topLevel.ProcessKey (a.KeyEvent)) { return true; } if (topLevel.Modal) @@ -1348,7 +1345,7 @@ public static bool OnKeyPressed (KeyEventArgs a) foreach (var topLevel in chain) { // Process the key normally - if (topLevel.ProcessColdKey (a)) { + if (topLevel.ProcessColdKey (a.KeyEvent)) { return true; } if (topLevel.Modal) @@ -1364,18 +1361,18 @@ public static bool OnKeyPressed (KeyEventArgs a) /// All drivers support firing the event. Some drivers (Curses) /// do not support firing the and events. /// - public static event EventHandler KeyDown; + public static event EventHandler KeyDown; /// /// Called when a key is pressed (and not yet released). Fires the event. /// /// - public static void OnKeyDown (KeyEventArgs a) + public static void OnKeyDown (KeyEventEventArgs a) { KeyDown?.Invoke (null, a); var chain = _topLevels.ToList (); foreach (var topLevel in chain) { - if (topLevel.OnKeyDown (a)) + if (topLevel.OnKeyDown (a.KeyEvent)) return; if (topLevel.Modal) break; @@ -1389,18 +1386,18 @@ public static void OnKeyDown (KeyEventArgs a) /// All drivers support firing the event. Some drivers (Curses) /// do not support firing the and events. /// - public static event EventHandler KeyUp; + public static event EventHandler KeyUp; /// /// Called when a key is released. Fires the event. /// /// - public static void OnKeyUp (KeyEventArgs a) + public static void OnKeyUp (KeyEventEventArgs a) { KeyUp?.Invoke (null, a); var chain = _topLevels.ToList (); foreach (var topLevel in chain) { - if (topLevel.OnKeyUp (a)) + if (topLevel.OnKeyUp (a.KeyEvent)) return; if (topLevel.Modal) break; diff --git a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs index d3150d0f7e..042a10bb24 100644 --- a/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/ConsoleDriver.cs @@ -447,35 +447,35 @@ public virtual Attribute MakeColor (Color foreground, Color background) /// /// Event fired after a key has been pressed and released. /// - public event EventHandler KeyPressed; + public event EventHandler KeyPressed; /// /// Called after a key has been pressed and released. Fires the event. /// /// - public void OnKeyPressed (KeyEventArgs a) => KeyPressed?.Invoke(this, a); + public void OnKeyPressed (KeyEventEventArgs a) => KeyPressed?.Invoke(this, a); /// /// Event fired when a key is released. /// - public event EventHandler KeyUp; + public event EventHandler KeyUp; /// /// Called when a key is released. Fires the event. /// /// - public void OnKeyUp (KeyEventArgs a) => KeyUp?.Invoke (this, a); + public void OnKeyUp (KeyEventEventArgs a) => KeyUp?.Invoke (this, a); /// /// Event fired when a key is pressed. /// - public event EventHandler KeyDown; + public event EventHandler KeyDown; /// /// Called when a key is pressed. Fires the event. /// /// - public void OnKeyDown (KeyEventArgs a) => KeyDown?.Invoke (this, a); + public void OnKeyDown (KeyEventEventArgs a) => KeyDown?.Invoke (this, a); /// /// Event fired when a mouse event occurs. diff --git a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs index 8cc537b351..036c201783 100644 --- a/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/CursesDriver/CursesDriver.cs @@ -458,7 +458,7 @@ internal void ProcessInput () int wch2 = wch; while (wch2 == Curses.KeyMouse) { - KeyEventArgs key = null; + KeyEvent key = null; ConsoleKeyInfo [] cki = new ConsoleKeyInfo [] { new ConsoleKeyInfo ((char)Key.Esc, 0, false, false, false), new ConsoleKeyInfo ('[', 0, false, false, false), @@ -491,9 +491,9 @@ internal void ProcessInput () wch -= 60; k = Key.ShiftMask | Key.AltMask | MapCursesKey (wch); } - OnKeyDown (new KeyEventArgs (k, MapKeyModifiers (k))); - OnKeyUp (new KeyEventArgs (k, MapKeyModifiers (k))); - OnKeyPressed (new KeyEventArgs (k, MapKeyModifiers (k))); + OnKeyDown (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); + OnKeyUp (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); + OnKeyPressed (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); return; } @@ -507,7 +507,7 @@ internal void ProcessInput () k = Key.AltMask | MapCursesKey (wch); } if (code == 0) { - KeyEventArgs key = null; + KeyEvent key = null; // The ESC-number handling, debatable. // Simulates the AltMask itself by pressing Alt + Space. @@ -543,19 +543,19 @@ internal void ProcessInput () k = (Key)((uint)(Key.AltMask | Key.CtrlMask) + wch2); } } - key = new KeyEventArgs (k, MapKeyModifiers (k)); - OnKeyDown (key); - OnKeyUp (key); - OnKeyPressed (key); + key = new KeyEvent (k, MapKeyModifiers (k)); + OnKeyDown (new KeyEventEventArgs (key)); + OnKeyUp (new KeyEventEventArgs (key)); + OnKeyPressed (new KeyEventEventArgs (key)); } else { k = Key.Esc; - OnKeyPressed (new KeyEventArgs (k, MapKeyModifiers (k))); + OnKeyPressed (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); } } else if (wch == Curses.KeyTab) { k = MapCursesKey (wch); - OnKeyDown (new KeyEventArgs (k, MapKeyModifiers (k))); - OnKeyUp (new KeyEventArgs (k, MapKeyModifiers (k))); - OnKeyPressed (new KeyEventArgs (k, MapKeyModifiers (k))); + OnKeyDown (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); + OnKeyUp (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); + OnKeyPressed (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); } else { // Unfortunately there are no way to differentiate Ctrl+alfa and Ctrl+Shift+alfa. k = (Key)wch; @@ -568,21 +568,21 @@ internal void ProcessInput () } else if (wch >= (uint)Key.A && wch <= (uint)Key.Z) { _keyModifiers.Shift = true; } - OnKeyDown (new KeyEventArgs (k, MapKeyModifiers (k))); - OnKeyUp (new KeyEventArgs (k, MapKeyModifiers (k))); - OnKeyPressed (new KeyEventArgs (k, MapKeyModifiers (k))); + OnKeyDown (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); + OnKeyUp (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); + OnKeyPressed (new KeyEventEventArgs (new KeyEvent (k, MapKeyModifiers (k)))); } // Cause OnKeyUp and OnKeyPressed. Note that the special handling for ESC above // will not impact KeyUp. // This is causing ESC firing even if another keystroke was handled. //if (wch == Curses.KeyTab) { - // keyUpHandler (new KeyEventArgs (MapCursesKey (wch), keyModifiers)); + // keyUpHandler (new KeyEvent (MapCursesKey (wch), keyModifiers)); //} else { - // keyUpHandler (new KeyEventArgs ((Key)wch, keyModifiers)); + // keyUpHandler (new KeyEvent ((Key)wch, keyModifiers)); //} } - void HandleEscSeqResponse (ref int code, ref Key k, ref int wch2, ref KeyEventArgs key, ref ConsoleKeyInfo [] cki) + void HandleEscSeqResponse (ref int code, ref Key k, ref int wch2, ref KeyEvent key, ref ConsoleKeyInfo [] cki) { ConsoleKey ck = 0; ConsoleModifiers mod = 0; @@ -603,9 +603,9 @@ void HandleEscSeqResponse (ref int code, ref Key k, ref int wch2, ref KeyEventAr } else { k = ConsoleKeyMapping.MapConsoleKeyToKey (consoleKeyInfo.Key, out _); k = ConsoleKeyMapping.MapKeyModifiers (consoleKeyInfo, k); - key = new KeyEventArgs (k, MapKeyModifiers (k)); - OnKeyDown (key); - OnKeyPressed (key); + key = new KeyEvent (k, MapKeyModifiers (k)); + OnKeyDown (new KeyEventEventArgs (key)); + OnKeyPressed (new KeyEventEventArgs (key)); } } else { cki = EscSeqUtils.ResizeArray (consoleKeyInfo, cki); @@ -778,9 +778,9 @@ public override void SendKeys (char keyChar, ConsoleKey consoleKey, bool shift, key |= Key.CtrlMask; km.Ctrl = control; } - OnKeyDown (new KeyEventArgs (key, km)); - OnKeyPressed (new KeyEventArgs (key, km)); - OnKeyUp (new KeyEventArgs (key, km)); + OnKeyDown (new KeyEventEventArgs (new KeyEvent (key, km))); + OnKeyPressed (new KeyEventEventArgs (new KeyEvent (key, km))); + OnKeyUp (new KeyEventEventArgs (new KeyEvent (key, km))); } diff --git a/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs b/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs index 9208202367..af9df98c18 100644 --- a/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/FakeDriver/FakeDriver.cs @@ -366,15 +366,15 @@ void ProcessInput (ConsoleKeyInfo consoleKey) var map = MapKey (consoleKey); if (map == (Key)0xffffffff) { if ((consoleKey.Modifiers & (ConsoleModifiers.Shift | ConsoleModifiers.Alt | ConsoleModifiers.Control)) != 0) { - OnKeyDown(new KeyEventArgs (map, keyModifiers)); - OnKeyUp (new KeyEventArgs (map, keyModifiers)); + OnKeyDown(new KeyEventEventArgs(new KeyEvent (map, keyModifiers))); + OnKeyUp (new KeyEventEventArgs (new KeyEvent (map, keyModifiers))); } return; } - OnKeyDown (new KeyEventArgs (map, keyModifiers)); - OnKeyUp (new KeyEventArgs (map, keyModifiers)); - OnKeyPressed (new KeyEventArgs (map, keyModifiers)); + OnKeyDown (new KeyEventEventArgs (new KeyEvent (map, keyModifiers))); + OnKeyUp (new KeyEventEventArgs (new KeyEvent (map, keyModifiers))); + OnKeyPressed (new KeyEventEventArgs (new KeyEvent (map, keyModifiers))); } /// diff --git a/Terminal.Gui/ConsoleDrivers/NetDriver.cs b/Terminal.Gui/ConsoleDrivers/NetDriver.cs index 1136aa294b..bd313ac5fc 100644 --- a/Terminal.Gui/ConsoleDrivers/NetDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/NetDriver.cs @@ -1125,12 +1125,12 @@ void ProcessInput (NetEvents.InputResult inputEvent) return; } if (map == Key.Null) { - OnKeyDown (new KeyEventArgs (map, _keyModifiers)); - OnKeyUp (new KeyEventArgs (map, _keyModifiers)); + OnKeyDown (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); + OnKeyUp (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); } else { - OnKeyDown (new KeyEventArgs (map, _keyModifiers)); - OnKeyUp (new KeyEventArgs (map, _keyModifiers)); - OnKeyPressed (new KeyEventArgs (map, _keyModifiers)); + OnKeyDown (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); + OnKeyUp (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); + OnKeyPressed (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); } break; case NetEvents.EventType.Mouse: diff --git a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs index 64c383fbd2..ac442720b8 100644 --- a/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs +++ b/Terminal.Gui/ConsoleDrivers/WindowsDriver.cs @@ -902,7 +902,7 @@ internal void ProcessInput (WindowsConsole.InputRecord inputEvent) //System.Diagnostics.Debug.WriteLine ($"wVirtualScanCode: {ke.wVirtualScanCode}"); if (map == (Key)0xffffffff) { - KeyEventArgs key = new KeyEventArgs (); + KeyEvent key = new KeyEvent (); // Shift = VK_SHIFT = 0x10 // Ctrl = VK_CONTROL = 0x11 @@ -926,17 +926,17 @@ internal void ProcessInput (WindowsConsole.InputRecord inputEvent) WindowsConsole.ControlKeyState.LeftControlPressed | WindowsConsole.ControlKeyState.EnhancedKey: case WindowsConsole.ControlKeyState.EnhancedKey: - key = new KeyEventArgs (Key.CtrlMask | Key.AltMask, _keyModifiers); + key = new KeyEvent (Key.CtrlMask | Key.AltMask, _keyModifiers); break; case WindowsConsole.ControlKeyState.LeftAltPressed: - key = new KeyEventArgs (Key.AltMask, _keyModifiers); + key = new KeyEvent (Key.AltMask, _keyModifiers); break; case WindowsConsole.ControlKeyState.RightControlPressed: case WindowsConsole.ControlKeyState.LeftControlPressed: - key = new KeyEventArgs (Key.CtrlMask, _keyModifiers); + key = new KeyEvent (Key.CtrlMask, _keyModifiers); break; case WindowsConsole.ControlKeyState.ShiftPressed: - key = new KeyEventArgs (Key.ShiftMask, _keyModifiers); + key = new KeyEvent (Key.ShiftMask, _keyModifiers); break; case WindowsConsole.ControlKeyState.NumlockOn: break; @@ -946,28 +946,28 @@ internal void ProcessInput (WindowsConsole.InputRecord inputEvent) break; default: key = inputEvent.KeyEvent.wVirtualKeyCode switch { - 0x10 => new KeyEventArgs (Key.ShiftMask, _keyModifiers), - 0x11 => new KeyEventArgs (Key.CtrlMask, _keyModifiers), - 0x12 => new KeyEventArgs (Key.AltMask, _keyModifiers), - _ => new KeyEventArgs (Key.Unknown, _keyModifiers) + 0x10 => new KeyEvent (Key.ShiftMask, _keyModifiers), + 0x11 => new KeyEvent (Key.CtrlMask, _keyModifiers), + 0x12 => new KeyEvent (Key.AltMask, _keyModifiers), + _ => new KeyEvent (Key.Unknown, _keyModifiers) }; break; } if (inputEvent.KeyEvent.bKeyDown) { - OnKeyDown (key); + OnKeyDown (new KeyEventEventArgs (key)); } else { - OnKeyUp (key); + OnKeyUp (new KeyEventEventArgs (key)); } } else { if (inputEvent.KeyEvent.bKeyDown) { // May occurs using SendKeys _keyModifiers ??= new KeyModifiers (); // Key Down - Fire KeyDown Event and KeyPressed Event - OnKeyDown (new KeyEventArgs (map, _keyModifiers)); + OnKeyDown (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); } else { - OnKeyUp (new KeyEventArgs (map, _keyModifiers)); - OnKeyPressed (new KeyEventArgs (map, _keyModifiers)); + OnKeyUp (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); + OnKeyPressed (new KeyEventEventArgs (new KeyEvent (map, _keyModifiers))); } } if (!inputEvent.KeyEvent.bKeyDown && inputEvent.KeyEvent.dwControlKeyState == 0) { diff --git a/Terminal.Gui/Input/Keyboard.cs b/Terminal.Gui/Input/Event.cs similarity index 65% rename from Terminal.Gui/Input/Keyboard.cs rename to Terminal.Gui/Input/Event.cs index 706d3c0458..995e463cf6 100644 --- a/Terminal.Gui/Input/Keyboard.cs +++ b/Terminal.Gui/Input/Event.cs @@ -1,4 +1,10 @@ -using System; +// +// Evemts.cs: Events, Key mappings +// +// Authors: +// Miguel de Icaza (miguel@gnome.org) +// +using System; namespace Terminal.Gui { @@ -529,22 +535,10 @@ public enum Key : uint { } /// - /// Defines the event arguments for keyboard input. + /// Describes a keyboard event. /// - public class KeyEventArgs : EventArgs { - /// - /// Constructs. - /// - /// - public KeyEventArgs (Key key) => Key = key; - - /// - /// Indicates if the current event has already been processed and the driver should stop notifying any other event subscriber. - /// Its important to set this value to true specially when updating any View's layout from inside the subscriber method. - /// - public bool Handled { get; set; } = false; - - KeyModifiers _keyModifiers; + public class KeyEvent { + KeyModifiers keyModifiers; /// /// Symbolic definition for the key. @@ -562,86 +556,269 @@ public class KeyEventArgs : EventArgs { /// Gets a value indicating whether the Shift key was pressed. /// /// true if is shift; otherwise, false. - public bool IsShift => _keyModifiers.Shift || Key == Key.BackTab; + public bool IsShift => keyModifiers.Shift || Key == Key.BackTab; /// /// Gets a value indicating whether the Alt key was pressed (real or synthesized) /// /// true if is alternate; otherwise, false. - public bool IsAlt => _keyModifiers.Alt; + public bool IsAlt => keyModifiers.Alt; /// /// Determines whether the value is a control key (and NOT just the ctrl key) /// /// true if is ctrl; otherwise, false. //public bool IsCtrl => ((uint)Key >= 1) && ((uint)Key <= 26); - public bool IsCtrl => _keyModifiers.Ctrl; + public bool IsCtrl => keyModifiers.Ctrl; /// /// Gets a value indicating whether the Caps lock key was pressed (real or synthesized) /// /// true if is alternate; otherwise, false. - public bool IsCapslock => _keyModifiers.Capslock; + public bool IsCapslock => keyModifiers.Capslock; /// /// Gets a value indicating whether the Num lock key was pressed (real or synthesized) /// /// true if is alternate; otherwise, false. - public bool IsNumlock => _keyModifiers.Numlock; + public bool IsNumlock => keyModifiers.Numlock; /// /// Gets a value indicating whether the Scroll lock key was pressed (real or synthesized) /// /// true if is alternate; otherwise, false. - public bool IsScrolllock => _keyModifiers.Scrolllock; + public bool IsScrolllock => keyModifiers.Scrolllock; /// - /// Constructs a new + /// Constructs a new /// - public KeyEventArgs () + public KeyEvent () { Key = Key.Unknown; - _keyModifiers = new KeyModifiers (); + keyModifiers = new KeyModifiers (); } /// - /// Constructs a new from the provided Key value - can be a rune cast into a Key value + /// Constructs a new from the provided Key value - can be a rune cast into a Key value /// - public KeyEventArgs (Key k, KeyModifiers km) + public KeyEvent (Key k, KeyModifiers km) { Key = k; - _keyModifiers = km; + keyModifiers = km; } /// - /// Pretty prints the KeyEventArgs + /// Pretty prints the KeyEvent /// /// public override string ToString () { string msg = ""; - if (_keyModifiers.Shift) { + var key = this.Key; + if (keyModifiers.Shift) { msg += "Shift-"; } - if (_keyModifiers.Alt) { + if (keyModifiers.Alt) { msg += "Alt-"; } - if (_keyModifiers.Ctrl) { + if (keyModifiers.Ctrl) { msg += "Ctrl-"; } - if (_keyModifiers.Capslock) { + if (keyModifiers.Capslock) { msg += "Capslock-"; } - if (_keyModifiers.Numlock) { + if (keyModifiers.Numlock) { msg += "Numlock-"; } - if (_keyModifiers.Scrolllock) { + if (keyModifiers.Scrolllock) { msg += "Scrolllock-"; } - msg += $"{((Key)KeyValue != Key.Unknown && ((uint)this.KeyValue & (uint)Key.CharMask) > 27 ? $"{(char)KeyValue}" : $"{Key}")}"; + msg += $"{((Key)KeyValue != Key.Unknown && ((uint)this.KeyValue & (uint)Key.CharMask) > 27 ? $"{(char)this.KeyValue}" : $"{key}")}"; return msg; } } + + /// + /// Mouse flags reported in . + /// + /// + /// They just happen to map to the ncurses ones. + /// + [Flags] + public enum MouseFlags { + /// + /// The first mouse button was pressed. + /// + Button1Pressed = unchecked((int)0x2), + /// + /// The first mouse button was released. + /// + Button1Released = unchecked((int)0x1), + /// + /// The first mouse button was clicked (press+release). + /// + Button1Clicked = unchecked((int)0x4), + /// + /// The first mouse button was double-clicked. + /// + Button1DoubleClicked = unchecked((int)0x8), + /// + /// The first mouse button was triple-clicked. + /// + Button1TripleClicked = unchecked((int)0x10), + /// + /// The second mouse button was pressed. + /// + Button2Pressed = unchecked((int)0x80), + /// + /// The second mouse button was released. + /// + Button2Released = unchecked((int)0x40), + /// + /// The second mouse button was clicked (press+release). + /// + Button2Clicked = unchecked((int)0x100), + /// + /// The second mouse button was double-clicked. + /// + Button2DoubleClicked = unchecked((int)0x200), + /// + /// The second mouse button was triple-clicked. + /// + Button2TripleClicked = unchecked((int)0x400), + /// + /// The third mouse button was pressed. + /// + Button3Pressed = unchecked((int)0x2000), + /// + /// The third mouse button was released. + /// + Button3Released = unchecked((int)0x1000), + /// + /// The third mouse button was clicked (press+release). + /// + Button3Clicked = unchecked((int)0x4000), + /// + /// The third mouse button was double-clicked. + /// + Button3DoubleClicked = unchecked((int)0x8000), + /// + /// The third mouse button was triple-clicked. + /// + Button3TripleClicked = unchecked((int)0x10000), + /// + /// The fourth mouse button was pressed. + /// + Button4Pressed = unchecked((int)0x80000), + /// + /// The fourth mouse button was released. + /// + Button4Released = unchecked((int)0x40000), + /// + /// The fourth button was clicked (press+release). + /// + Button4Clicked = unchecked((int)0x100000), + /// + /// The fourth button was double-clicked. + /// + Button4DoubleClicked = unchecked((int)0x200000), + /// + /// The fourth button was triple-clicked. + /// + Button4TripleClicked = unchecked((int)0x400000), + /// + /// Flag: the shift key was pressed when the mouse button took place. + /// + ButtonShift = unchecked((int)0x2000000), + /// + /// Flag: the ctrl key was pressed when the mouse button took place. + /// + ButtonCtrl = unchecked((int)0x1000000), + /// + /// Flag: the alt key was pressed when the mouse button took place. + /// + ButtonAlt = unchecked((int)0x4000000), + /// + /// The mouse position is being reported in this event. + /// + ReportMousePosition = unchecked((int)0x8000000), + /// + /// Vertical button wheeled up. + /// + WheeledUp = unchecked((int)0x10000000), + /// + /// Vertical button wheeled down. + /// + WheeledDown = unchecked((int)0x20000000), + /// + /// Vertical button wheeled up while pressing ButtonShift. + /// + WheeledLeft = ButtonShift | WheeledUp, + /// + /// Vertical button wheeled down while pressing ButtonShift. + /// + WheeledRight = ButtonShift | WheeledDown, + /// + /// Mask that captures all the events. + /// + AllEvents = unchecked((int)0x7ffffff), + } + + // TODO: Merge MouseEvent and MouseEventEventArgs into a single class. + + /// + /// Low-level construct that conveys the details of mouse events, such + /// as coordinates and button state, from ConsoleDrivers up to and + /// Views. + /// + /// The class includes the + /// Action which takes a MouseEvent argument. + public class MouseEvent { + /// + /// The X (column) location for the mouse event. + /// + public int X { get; set; } + + /// + /// The Y (column) location for the mouse event. + /// + public int Y { get; set; } + + /// + /// Flags indicating the kind of mouse event that is being posted. + /// + public MouseFlags Flags { get; set; } + + /// + /// The offset X (column) location for the mouse event. + /// + public int OfX { get; set; } + + /// + /// The offset Y (column) location for the mouse event. + /// + public int OfY { get; set; } + + /// + /// The current view at the location for the mouse event. + /// + public View View { get; set; } + + /// + /// Indicates if the current mouse event has already been processed and the driver should stop notifying any other event subscriber. + /// Its important to set this value to true specially when updating any View's layout from inside the subscriber method. + /// + public bool Handled { get; set; } + + /// + /// Returns a that represents the current . + /// + /// A that represents the current . + public override string ToString () + { + return $"({X},{Y}:{Flags}"; + } + } } diff --git a/Terminal.Gui/Input/KeyEventEventArgs.cs b/Terminal.Gui/Input/KeyEventEventArgs.cs new file mode 100644 index 0000000000..c7ab9e39a2 --- /dev/null +++ b/Terminal.Gui/Input/KeyEventEventArgs.cs @@ -0,0 +1,24 @@ +using System; + +namespace Terminal.Gui { + + /// + /// Defines the event arguments for + /// + public class KeyEventEventArgs : EventArgs { + /// + /// Constructs. + /// + /// + public KeyEventEventArgs (KeyEvent ke) => KeyEvent = ke; + /// + /// The for the event. + /// + public KeyEvent KeyEvent { get; set; } + /// + /// Indicates if the current Key event has already been processed and the driver should stop notifying any other event subscriber. + /// Its important to set this value to true specially when updating any View's layout from inside the subscriber method. + /// + public bool Handled { get; set; } = false; + } +} diff --git a/Terminal.Gui/Input/Mouse.cs b/Terminal.Gui/Input/Mouse.cs deleted file mode 100644 index 15b7951195..0000000000 --- a/Terminal.Gui/Input/Mouse.cs +++ /dev/null @@ -1,186 +0,0 @@ -using System; - -namespace Terminal.Gui { - - /// - /// Mouse flags reported in . - /// - /// - /// They just happen to map to the ncurses ones. - /// - [Flags] - public enum MouseFlags { - /// - /// The first mouse button was pressed. - /// - Button1Pressed = unchecked((int)0x2), - /// - /// The first mouse button was released. - /// - Button1Released = unchecked((int)0x1), - /// - /// The first mouse button was clicked (press+release). - /// - Button1Clicked = unchecked((int)0x4), - /// - /// The first mouse button was double-clicked. - /// - Button1DoubleClicked = unchecked((int)0x8), - /// - /// The first mouse button was triple-clicked. - /// - Button1TripleClicked = unchecked((int)0x10), - /// - /// The second mouse button was pressed. - /// - Button2Pressed = unchecked((int)0x80), - /// - /// The second mouse button was released. - /// - Button2Released = unchecked((int)0x40), - /// - /// The second mouse button was clicked (press+release). - /// - Button2Clicked = unchecked((int)0x100), - /// - /// The second mouse button was double-clicked. - /// - Button2DoubleClicked = unchecked((int)0x200), - /// - /// The second mouse button was triple-clicked. - /// - Button2TripleClicked = unchecked((int)0x400), - /// - /// The third mouse button was pressed. - /// - Button3Pressed = unchecked((int)0x2000), - /// - /// The third mouse button was released. - /// - Button3Released = unchecked((int)0x1000), - /// - /// The third mouse button was clicked (press+release). - /// - Button3Clicked = unchecked((int)0x4000), - /// - /// The third mouse button was double-clicked. - /// - Button3DoubleClicked = unchecked((int)0x8000), - /// - /// The third mouse button was triple-clicked. - /// - Button3TripleClicked = unchecked((int)0x10000), - /// - /// The fourth mouse button was pressed. - /// - Button4Pressed = unchecked((int)0x80000), - /// - /// The fourth mouse button was released. - /// - Button4Released = unchecked((int)0x40000), - /// - /// The fourth button was clicked (press+release). - /// - Button4Clicked = unchecked((int)0x100000), - /// - /// The fourth button was double-clicked. - /// - Button4DoubleClicked = unchecked((int)0x200000), - /// - /// The fourth button was triple-clicked. - /// - Button4TripleClicked = unchecked((int)0x400000), - /// - /// Flag: the shift key was pressed when the mouse button took place. - /// - ButtonShift = unchecked((int)0x2000000), - /// - /// Flag: the ctrl key was pressed when the mouse button took place. - /// - ButtonCtrl = unchecked((int)0x1000000), - /// - /// Flag: the alt key was pressed when the mouse button took place. - /// - ButtonAlt = unchecked((int)0x4000000), - /// - /// The mouse position is being reported in this event. - /// - ReportMousePosition = unchecked((int)0x8000000), - /// - /// Vertical button wheeled up. - /// - WheeledUp = unchecked((int)0x10000000), - /// - /// Vertical button wheeled down. - /// - WheeledDown = unchecked((int)0x20000000), - /// - /// Vertical button wheeled up while pressing ButtonShift. - /// - WheeledLeft = ButtonShift | WheeledUp, - /// - /// Vertical button wheeled down while pressing ButtonShift. - /// - WheeledRight = ButtonShift | WheeledDown, - /// - /// Mask that captures all the events. - /// - AllEvents = unchecked((int)0x7ffffff), - } - - // TODO: Merge MouseEvent and MouseEventEventArgs into a single class. - - /// - /// Low-level construct that conveys the details of mouse events, such - /// as coordinates and button state, from ConsoleDrivers up to and - /// Views. - /// - /// The class includes the - /// Action which takes a MouseEvent argument. - public class MouseEvent { - /// - /// The X (column) location for the mouse event. - /// - public int X { get; set; } - - /// - /// The Y (column) location for the mouse event. - /// - public int Y { get; set; } - - /// - /// Flags indicating the kind of mouse event that is being posted. - /// - public MouseFlags Flags { get; set; } - - /// - /// The offset X (column) location for the mouse event. - /// - public int OfX { get; set; } - - /// - /// The offset Y (column) location for the mouse event. - /// - public int OfY { get; set; } - - /// - /// The current view at the location for the mouse event. - /// - public View View { get; set; } - - /// - /// Indicates if the current mouse event has already been processed and the driver should stop notifying any other event subscriber. - /// Its important to set this value to true specially when updating any View's layout from inside the subscriber method. - /// - public bool Handled { get; set; } - - /// - /// Returns a that represents the current . - /// - /// A that represents the current . - public override string ToString () - { - return $"({X},{Y}:{Flags}"; - } - } -} diff --git a/Terminal.Gui/Input/Responder.cs b/Terminal.Gui/Input/Responder.cs index 1ec2f7176d..c043a40948 100644 --- a/Terminal.Gui/Input/Responder.cs +++ b/Terminal.Gui/Input/Responder.cs @@ -20,7 +20,7 @@ namespace Terminal.Gui { /// - /// Base class for classes that want to participate on keyboard and mouse input (e.g. ). + /// Responder base class implemented by objects that want to participate on keyboard and mouse input. /// public class Responder : IDisposable { bool disposedValue; @@ -71,24 +71,20 @@ public Responder () // Key handling /// - /// This method can be overwritten views that + /// This method can be overwritten by view that /// want to provide accelerator functionality /// (Alt-key for example). /// /// - /// - /// This is a low-level API; see for the preferred way to define what keys - /// a View should respond to. - /// /// - /// Before keys are sent to a subview of the - /// current view, all subviews are - /// processed and the key is passed to them - /// to allow them to process the keystroke + /// Before keys are sent to the subview on the + /// current view, all the views are + /// processed and the key is passed to the widgets + /// to allow some of them to process the keystroke /// as a hot-key. /// - /// For example, for a button that - /// has a hotkey Alt-o, catch the + /// For example, if you implement a button that + /// has a hotkey ok "o", you would catch the /// combination Alt-o here. If the event is /// caught, you must return true to stop the /// keystroke from being dispatched to other @@ -96,32 +92,39 @@ public Responder () /// /// - public virtual bool ProcessHotKey (KeyEventArgs kb) + public virtual bool ProcessHotKey (KeyEvent kb) { return false; } /// - /// Called after a key has been pressed and released. Fires the event. - /// - /// Called for new KeyPressed events before any processing is performed or - /// views evaluate. Use for global key handling and/or debugging. - /// + /// If the view is focused, gives the view a + /// chance to process the keystroke. /// - /// - /// if the key was handled. - public virtual bool OnKeyPressed (KeyEventArgs arg) + /// + /// + /// Views can override this method if they are + /// interested in processing the given keystroke. + /// If they consume the keystroke, they must + /// return true to stop the keystroke from being + /// processed by other widgets or consumed by the + /// widget engine. If they return false, the + /// keystroke will be passed using the ProcessColdKey + /// method to other views to process. + /// + /// + /// The View implementation does nothing but return false, + /// so it is not necessary to call base.ProcessKey if you + /// derive directly from View, but you should if you derive + /// other View subclasses. + /// + /// + /// Contains the details about the key that produced the event. + public virtual bool ProcessKey (KeyEvent keyEvent) { - KeyPressed?.Invoke (this, arg); - return arg.Handled; + return false; } - /// - /// Event fired after a key has been pressed and released. - /// Set to to suppress the event. - /// - public event EventHandler KeyPressed; - /// /// This method can be overwritten by views that /// want to provide accelerator functionality @@ -129,10 +132,6 @@ public virtual bool OnKeyPressed (KeyEventArgs arg) /// interefering with normal ProcessKey behavior. /// /// - /// - /// This is a low-level API; see for the preferred way to define what keys - /// a View should respond to. - /// /// /// After keys are sent to the subviews on the /// current view, all the view are @@ -148,7 +147,7 @@ public virtual bool OnKeyPressed (KeyEventArgs arg) /// /// /// Contains the details about the key that produced the event. - public virtual bool ProcessColdKey (KeyEventArgs keyEvent) + public virtual bool ProcessColdKey (KeyEvent keyEvent) { return false; } @@ -158,7 +157,7 @@ public virtual bool ProcessColdKey (KeyEventArgs keyEvent) /// /// Contains the details about the key that produced the event. /// true if the event was handled - public virtual bool OnKeyDown (KeyEventArgs keyEvent) + public virtual bool OnKeyDown (KeyEvent keyEvent) { return false; } @@ -168,7 +167,7 @@ public virtual bool OnKeyDown (KeyEventArgs keyEvent) /// /// Contains the details about the key that produced the event. /// true if the event was handled - public virtual bool OnKeyUp (KeyEventArgs keyEvent) + public virtual bool OnKeyUp (KeyEvent keyEvent) { return false; } @@ -257,7 +256,7 @@ internal static bool IsOverridden (Responder subclass, string method) } return m.GetBaseDefinition ().DeclaringType != m.DeclaringType; } - + /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// @@ -279,11 +278,11 @@ protected virtual void Dispose (bool disposing) #if DEBUG_IDISPOSABLE Instances.Remove (this); -#endif +#endif disposedValue = true; } } - + /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resource. /// diff --git a/Terminal.Gui/Input/ShortcutHelper.cs b/Terminal.Gui/Input/ShortcutHelper.cs index 02efc2fb60..e1b1a3bdbb 100644 --- a/Terminal.Gui/Input/ShortcutHelper.cs +++ b/Terminal.Gui/Input/ShortcutHelper.cs @@ -38,7 +38,7 @@ public virtual Key Shortcut { /// /// The to check. /// The with all the keys modifiers. - public static Key GetModifiersKey (KeyEventArgs kb) + public static Key GetModifiersKey (KeyEvent kb) { var key = kb.Key; if (kb.IsAlt && (key & Key.AltMask) == 0) { @@ -240,7 +240,7 @@ public static bool PostShortcutValidation (Key key) /// The /// The /// true if defined falseotherwise. - public static bool FindAndOpenByShortcut (KeyEventArgs kb, View view = null) + public static bool FindAndOpenByShortcut (KeyEvent kb, View view = null) { if (view == null) { return false; } diff --git a/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs index a1c91c387a..9aba845ede 100644 --- a/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs @@ -54,7 +54,7 @@ public override bool MouseEvent (MouseEvent me, bool fromHost = false) } /// - public override bool ProcessKey (KeyEventArgs kb) + public override bool ProcessKey (KeyEvent kb) { var key = kb.Key; if (key == SelectionKey) { diff --git a/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs b/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs index 4f2db0036e..6be3e8da00 100644 --- a/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs +++ b/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs @@ -55,7 +55,7 @@ public abstract class AutocompleteBase : IAutocomplete { public abstract bool MouseEvent (MouseEvent me, bool fromHost = false); /// - public abstract bool ProcessKey (KeyEventArgs kb); + public abstract bool ProcessKey (KeyEvent kb); /// public abstract void RenderOverlay (Point renderAt); diff --git a/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs index d60ca09da4..ac31d3f9c7 100644 --- a/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs @@ -87,7 +87,7 @@ public interface IAutocomplete { /// /// The key event. /// trueif the key can be handled falseotherwise. - bool ProcessKey (KeyEventArgs kb); + bool ProcessKey (KeyEvent kb); /// /// Handle mouse events before e.g. to make mouse events like diff --git a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs index c4b7bcdbbf..925f5bc53b 100644 --- a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs @@ -152,7 +152,7 @@ public override ColorScheme ColorScheme { public override void RenderOverlay (Point renderAt) { if (!Context.Canceled && Suggestions.Count > 0 && !Visible && HostControl?.HasFocus == true) { - ProcessKey (new KeyEventArgs ((Key)(Suggestions [0].Title [0]), new KeyModifiers ())); + ProcessKey (new KeyEvent ((Key)(Suggestions [0].Title [0]), new KeyModifiers ())); } else if (!Visible || HostControl?.HasFocus == false || Suggestions.Count == 0) { LastPopupPos = null; Visible = false; @@ -278,7 +278,7 @@ public override void EnsureSelectedIdxIsValid () /// /// The key event. /// trueif the key can be handled falseotherwise. - public override bool ProcessKey (KeyEventArgs kb) + public override bool ProcessKey (KeyEvent kb) { if (SuggestionGenerator.IsWordChar ((Rune)(char)kb.Key)) { Visible = true; diff --git a/Terminal.Gui/Text/CollectionNavigatorBase.cs b/Terminal.Gui/Text/CollectionNavigatorBase.cs index 75b012f57b..1d65116dc6 100644 --- a/Terminal.Gui/Text/CollectionNavigatorBase.cs +++ b/Terminal.Gui/Text/CollectionNavigatorBase.cs @@ -209,7 +209,7 @@ private void ClearSearchString () /// /// /// - public static bool IsCompatibleKey (KeyEventArgs kb) + public static bool IsCompatibleKey (KeyEvent kb) { return !kb.IsAlt && !kb.IsCtrl; } diff --git a/Terminal.Gui/View/ViewKeyboard.cs b/Terminal.Gui/View/ViewKeyboard.cs index d69cb13861..421f941621 100644 --- a/Terminal.Gui/View/ViewKeyboard.cs +++ b/Terminal.Gui/View/ViewKeyboard.cs @@ -163,44 +163,43 @@ public bool TabStop { /// /// Invoked when a character key is pressed and occurs after the key up event. /// - public event EventHandler KeyPressed; + public event EventHandler KeyPressed; /// - public override bool OnKeyPressed (KeyEventArgs arg) + public override bool ProcessKey (KeyEvent keyEvent) { if (!Enabled) { return false; } - KeyPressed?.Invoke (this, arg); - if (arg.Handled) { + var args = new KeyEventEventArgs (keyEvent); + KeyPressed?.Invoke (this, args); + if (args.Handled) return true; - } if (Focused?.Enabled == true) { - Focused?.KeyPressed?.Invoke (this, arg); - if (arg.Handled) { + Focused?.KeyPressed?.Invoke (this, args); + if (args.Handled) return true; - } } - return Focused?.Enabled == true && Focused?.OnKeyPressed (arg) == true; + return Focused?.Enabled == true && Focused?.ProcessKey (keyEvent) == true; } /// /// Invokes any binding that is registered on this - /// and matches the + /// and matches the /// - /// The key event passed. - protected bool? InvokeKeybindings (KeyEventArgs KeyEventArgs) + /// The key event passed. + protected bool? InvokeKeybindings (KeyEvent keyEvent) { bool? toReturn = null; - if (KeyBindings.ContainsKey (KeyEventArgs.Key)) { + if (KeyBindings.ContainsKey (keyEvent.Key)) { - foreach (var command in KeyBindings [KeyEventArgs.Key]) { + foreach (var command in KeyBindings [keyEvent.Key]) { if (!CommandImplementations.ContainsKey (command)) { - throw new NotSupportedException ($"A KeyBinding was set up for the command {command} ({KeyEventArgs.Key}) but that command is not supported by this View ({GetType ().Name})"); + throw new NotSupportedException ($"A KeyBinding was set up for the command {command} ({keyEvent.Key}) but that command is not supported by this View ({GetType ().Name})"); } // each command has its own return value @@ -341,54 +340,52 @@ public Key GetKeyFromCommand (params Command [] command) } /// - public override bool ProcessHotKey (KeyEventArgs arg) + public override bool ProcessHotKey (KeyEvent keyEvent) { if (!Enabled) { return false; } + var args = new KeyEventEventArgs (keyEvent); if (MostFocused?.Enabled == true) { - MostFocused?.KeyPressed?.Invoke (this, arg); - if (arg.Handled) { + MostFocused?.KeyPressed?.Invoke (this, args); + if (args.Handled) return true; - } } - if (MostFocused?.Enabled == true && MostFocused?.OnKeyPressed (arg) == true) { + if (MostFocused?.Enabled == true && MostFocused?.ProcessKey (keyEvent) == true) return true; - } - if (_subviews == null || _subviews.Count == 0) { + if (_subviews == null || _subviews.Count == 0) return false; - } foreach (var view in _subviews) - if (view.Enabled && view.ProcessHotKey (arg)) { + if (view.Enabled && view.ProcessHotKey (keyEvent)) return true; - } return false; } /// - public override bool ProcessColdKey (KeyEventArgs arg) + public override bool ProcessColdKey (KeyEvent keyEvent) { if (!Enabled) { return false; } - KeyPressed?.Invoke (this, arg); - if (arg.Handled) + var args = new KeyEventEventArgs (keyEvent); + KeyPressed?.Invoke (this, args); + if (args.Handled) return true; if (MostFocused?.Enabled == true) { - MostFocused?.KeyPressed?.Invoke (this, arg); - if (arg.Handled) + MostFocused?.KeyPressed?.Invoke (this, args); + if (args.Handled) return true; } - if (MostFocused?.Enabled == true && MostFocused?.OnKeyPressed (arg) == true) + if (MostFocused?.Enabled == true && MostFocused?.ProcessKey (keyEvent) == true) return true; if (_subviews == null || _subviews.Count == 0) return false; foreach (var view in _subviews) - if (view.Enabled && view.ProcessColdKey (arg)) + if (view.Enabled && view.ProcessColdKey (keyEvent)) return true; return false; } @@ -396,25 +393,26 @@ public override bool ProcessColdKey (KeyEventArgs arg) /// /// Invoked when a key is pressed. /// - public event EventHandler KeyDown; + public event EventHandler KeyDown; /// - public override bool OnKeyDown (KeyEventArgs arg) + public override bool OnKeyDown (KeyEvent keyEvent) { if (!Enabled) { return false; } - KeyDown?.Invoke (this, arg); - if (arg.Handled) { + var args = new KeyEventEventArgs (keyEvent); + KeyDown?.Invoke (this, args); + if (args.Handled) { return true; } if (Focused?.Enabled == true) { - Focused.KeyDown?.Invoke (this, arg); - if (arg.Handled) { + Focused.KeyDown?.Invoke (this, args); + if (args.Handled) { return true; } - if (Focused?.OnKeyDown (arg) == true) { + if (Focused?.OnKeyDown (keyEvent) == true) { return true; } } @@ -425,25 +423,26 @@ public override bool OnKeyDown (KeyEventArgs arg) /// /// Invoked when a key is released. /// - public event EventHandler KeyUp; + public event EventHandler KeyUp; /// - public override bool OnKeyUp (KeyEventArgs arg) + public override bool OnKeyUp (KeyEvent keyEvent) { if (!Enabled) { return false; } - KeyUp?.Invoke (this, arg); - if (arg.Handled) { + var args = new KeyEventEventArgs (keyEvent); + KeyUp?.Invoke (this, args); + if (args.Handled) { return true; } if (Focused?.Enabled == true) { - Focused.KeyUp?.Invoke (this, arg); - if (arg.Handled) { + Focused.KeyUp?.Invoke (this, args); + if (args.Handled) { return true; } - if (Focused?.OnKeyUp (arg) == true) { + if (Focused?.OnKeyUp (keyEvent) == true) { return true; } } diff --git a/Terminal.Gui/Views/Button.cs b/Terminal.Gui/Views/Button.cs index 6d647455d7..5cd1605dd9 100644 --- a/Terminal.Gui/Views/Button.cs +++ b/Terminal.Gui/Views/Button.cs @@ -191,7 +191,7 @@ protected override void UpdateTextFormatterText () } /// - public override bool ProcessHotKey (KeyEventArgs kb) + public override bool ProcessHotKey (KeyEvent kb) { if (!Enabled) { return false; @@ -201,7 +201,7 @@ public override bool ProcessHotKey (KeyEventArgs kb) } /// - public override bool ProcessColdKey (KeyEventArgs kb) + public override bool ProcessColdKey (KeyEvent kb) { if (!Enabled) { return false; @@ -211,20 +211,20 @@ public override bool ProcessColdKey (KeyEventArgs kb) } /// - public override bool OnKeyPressed (KeyEventArgs arg) + public override bool ProcessKey (KeyEvent kb) { if (!Enabled) { return false; } - var result = InvokeKeybindings (arg); + var result = InvokeKeybindings (kb); if (result != null) return (bool)result; - return base.OnKeyPressed (arg); + return base.ProcessKey (kb); } - bool ExecuteHotKey (KeyEventArgs ke) + bool ExecuteHotKey (KeyEvent ke) { if (ke.Key == (Key.AltMask | HotKey)) { return AcceptKey (); @@ -232,7 +232,7 @@ bool ExecuteHotKey (KeyEventArgs ke) return false; } - bool ExecuteColdKey (KeyEventArgs ke) + bool ExecuteColdKey (KeyEvent ke) { if (IsDefault && ke.KeyValue == '\n') { return AcceptKey (); diff --git a/Terminal.Gui/Views/CheckBox.cs b/Terminal.Gui/Views/CheckBox.cs index 4a21a8c016..e8eaf8088f 100644 --- a/Terminal.Gui/Views/CheckBox.cs +++ b/Terminal.Gui/Views/CheckBox.cs @@ -168,17 +168,17 @@ public override void PositionCursor () } /// - public override bool OnKeyPressed (KeyEventArgs arg) + public override bool ProcessKey (KeyEvent kb) { - var result = InvokeKeybindings (arg); + var result = InvokeKeybindings (kb); if (result != null) return (bool)result; - return base.OnKeyPressed (arg); + return base.ProcessKey (kb); } /// - public override bool ProcessHotKey (KeyEventArgs kb) + public override bool ProcessHotKey (KeyEvent kb) { if (kb.Key == (Key.AltMask | HotKey)) return ToggleChecked (); diff --git a/Terminal.Gui/Views/ColorPicker.cs b/Terminal.Gui/Views/ColorPicker.cs index 7bf28a2a00..f41aa5b68d 100644 --- a/Terminal.Gui/Views/ColorPicker.cs +++ b/Terminal.Gui/Views/ColorPicker.cs @@ -251,9 +251,9 @@ public virtual bool MoveDown () } /// - public override bool OnKeyPressed (KeyEventArgs arg) + public override bool ProcessKey (KeyEvent kb) { - var result = InvokeKeybindings (arg); + var result = InvokeKeybindings (kb); if (result != null) return (bool)result; diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index d1f79075e3..211a11d529 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -545,13 +545,13 @@ public override void OnDrawContent (Rect contentArea) } /// - public override bool OnKeyPressed (KeyEventArgs arg) + public override bool ProcessKey (KeyEvent e) { - var result = InvokeKeybindings (arg); + var result = InvokeKeybindings (e); if (result != null) return (bool)result; - return base.OnKeyPressed (arg); + return base.ProcessKey (e); } bool UnixEmulation () diff --git a/Terminal.Gui/Views/DateField.cs b/Terminal.Gui/Views/DateField.cs index 2b063e1c13..2da853331f 100644 --- a/Terminal.Gui/Views/DateField.cs +++ b/Terminal.Gui/Views/DateField.cs @@ -328,14 +328,14 @@ void AdjCursorPosition () } /// - public override bool OnKeyPressed (KeyEventArgs arg) + public override bool ProcessKey (KeyEvent kb) { - var result = InvokeKeybindings (arg); + var result = InvokeKeybindings (kb); if (result != null) { return (bool)result; } // Ignore non-numeric characters. - if (arg.Key < (Key)((int)'0') || arg.Key > (Key)((int)'9')) { + if (kb.Key < (Key)((int)'0') || kb.Key > (Key)((int)'9')) { return false; } @@ -344,7 +344,7 @@ public override bool OnKeyPressed (KeyEventArgs arg) } // BUGBUG: This is a hack, we should be able to just use ((Rune)(uint)kb.Key) directly. - if (SetText (((Rune)(uint)arg.Key).ToString ().EnumerateRunes ().First ())) { + if (SetText (((Rune)(uint)kb.Key).ToString ().EnumerateRunes ().First ())) { IncCursorPosition (); } diff --git a/Terminal.Gui/Views/Dialog.cs b/Terminal.Gui/Views/Dialog.cs index 67326aa282..db7016394b 100644 --- a/Terminal.Gui/Views/Dialog.cs +++ b/Terminal.Gui/Views/Dialog.cs @@ -229,14 +229,14 @@ void LayoutButtons () } /// - public override bool OnKeyPressed (KeyEventArgs arg) + public override bool ProcessKey (KeyEvent kb) { - switch (arg.Key) { + switch (kb.Key) { case Key.Esc: Application.RequestStop (this); return true; } - return base.OnKeyPressed (arg); + return base.ProcessKey (kb); } } } diff --git a/Terminal.Gui/Views/FileDialog.cs b/Terminal.Gui/Views/FileDialog.cs index 5138a06849..725bbfa86d 100644 --- a/Terminal.Gui/Views/FileDialog.cs +++ b/Terminal.Gui/Views/FileDialog.cs @@ -286,12 +286,12 @@ public FileDialog (IFileSystem fileSystem) tbFind.TextChanged += (s, o) => RestartSearch (); tbFind.KeyPressed += (s, o) => { - if (o.Key == Key.Enter) { + if (o.KeyEvent.Key == Key.Enter) { RestartSearch (); o.Handled = true; } - if (o.Key == Key.Esc) { + if (o.KeyEvent.Key == Key.Esc) { if (CancelSearch ()) { o.Handled = true; } @@ -316,7 +316,7 @@ public FileDialog (IFileSystem fileSystem) this.tbPath.TextChanged += (s, e) => this.PathChanged (); this.tableView.CellActivated += this.CellActivate; - this.tableView.KeyUp += (s, k) => k.Handled = this.TableView_KeyUp (k); + this.tableView.KeyUp += (s, k) => k.Handled = this.TableView_KeyUp (k.KeyEvent); this.tableView.SelectedCellChanged += this.TableView_SelectedCellChanged; this.tableView.AddKeyBinding (Key.Home, Command.TopHome); @@ -340,7 +340,7 @@ public FileDialog (IFileSystem fileSystem) return; } - k.Handled = this.TreeView_KeyDown (k); + k.Handled = this.TreeView_KeyDown (k.KeyEvent); }; @@ -485,7 +485,7 @@ private IFileSystemInfo [] GetFocusedFiles () /// - public override bool ProcessHotKey (KeyEventArgs keyEvent) + public override bool ProcessHotKey (KeyEvent keyEvent) { if (this.NavigateIf (keyEvent, Key.CtrlMask | Key.F, this.tbFind)) { return true; @@ -772,17 +772,17 @@ private void AllowedTypeMenuClicked (int idx) } } - private void SuppressIfBadChar (KeyEventArgs k) + private void SuppressIfBadChar (KeyEventEventArgs k) { // don't let user type bad letters - var ch = (char)k.KeyValue; + var ch = (char)k.KeyEvent.KeyValue; if (badChars.Contains (ch)) { k.Handled = true; } } - private bool TreeView_KeyDown (KeyEventArgs keyEvent) + private bool TreeView_KeyDown (KeyEvent keyEvent) { if (this.treeView.HasFocus && Separators.Contains ((char)keyEvent.KeyValue)) { this.tbPath.FocusFirst (); @@ -794,9 +794,9 @@ private bool TreeView_KeyDown (KeyEventArgs keyEvent) return false; } - private void AcceptIf (KeyEventArgs keyEvent, Key isKey) + private void AcceptIf (KeyEventEventArgs keyEvent, Key isKey) { - if (!keyEvent.Handled && keyEvent.Key == isKey) { + if (!keyEvent.Handled && keyEvent.KeyEvent.Key == isKey) { keyEvent.Handled = true; // User hit Enter in text box so probably wants the @@ -880,7 +880,17 @@ private void FinishAccept () Application.RequestStop (); } - private bool NavigateIf (KeyEventArgs keyEvent, Key isKey, View to) + private void NavigateIf (KeyEventEventArgs keyEvent, Key isKey, View to) + { + if (!keyEvent.Handled) { + + if (NavigateIf (keyEvent.KeyEvent, isKey, to)) { + keyEvent.Handled = true; + } + } + } + + private bool NavigateIf (KeyEvent keyEvent, Key isKey, View to) { if (keyEvent.Key == isKey) { @@ -946,7 +956,7 @@ private void TableView_SelectedCellChanged (object sender, SelectedCellChangedEv } } - private bool TableView_KeyUp (KeyEventArgs keyEvent) + private bool TableView_KeyUp (KeyEvent keyEvent) { if (keyEvent.Key == Key.Backspace) { return this.history.Back (); diff --git a/Terminal.Gui/Views/GraphView/GraphView.cs b/Terminal.Gui/Views/GraphView/GraphView.cs index bdf6d9f00d..2d2310b1b2 100644 --- a/Terminal.Gui/Views/GraphView/GraphView.cs +++ b/Terminal.Gui/Views/GraphView/GraphView.cs @@ -244,7 +244,7 @@ public override bool OnEnter (View view) } /// - public override bool OnKeyPressed (KeyEventArgs keyEvent) + public override bool ProcessKey (KeyEvent keyEvent) { if (HasFocus && CanFocus) { var result = InvokeKeybindings (keyEvent); @@ -252,7 +252,7 @@ public override bool OnKeyPressed (KeyEventArgs keyEvent) return (bool)result; } - return base.OnKeyPressed (keyEvent); + return base.ProcessKey (keyEvent); } /// diff --git a/Terminal.Gui/Views/HexView.cs b/Terminal.Gui/Views/HexView.cs index e5d520f331..b425e5f073 100644 --- a/Terminal.Gui/Views/HexView.cs +++ b/Terminal.Gui/Views/HexView.cs @@ -424,7 +424,7 @@ bool MoveDown (int bytes) } /// - public override bool OnKeyPressed (KeyEventArgs keyEvent) + public override bool ProcessKey (KeyEvent keyEvent) { var result = InvokeKeybindings (keyEvent); if (result != null) diff --git a/Terminal.Gui/Views/Label.cs b/Terminal.Gui/Views/Label.cs index bd8aa813ba..29b476fb77 100644 --- a/Terminal.Gui/Views/Label.cs +++ b/Terminal.Gui/Views/Label.cs @@ -112,7 +112,7 @@ public override bool OnEnter (View view) } /// - public override bool ProcessHotKey (KeyEventArgs ke) + public override bool ProcessHotKey (KeyEvent ke) { if (ke.Key == (Key.AltMask | HotKey)) { if (!HasFocus) { diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index 6967783bef..59f0e9a718 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -416,10 +416,10 @@ public override void OnDrawContent (Rect contentArea) public CollectionNavigator KeystrokeNavigator { get; private set; } = new CollectionNavigator (); /// - public override bool OnKeyPressed (KeyEventArgs kb) + public override bool ProcessKey (KeyEvent kb) { if (source == null) { - return base.OnKeyPressed (kb); + return base.ProcessKey (kb); } var result = InvokeKeybindings (kb); diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs index 46f906892a..7c16edc534 100644 --- a/Terminal.Gui/Views/Menu.cs +++ b/Terminal.Gui/Views/Menu.cs @@ -721,7 +721,7 @@ public override bool OnLeave (View view) return host.OnLeave (view); } - public override bool OnKeyDown (KeyEventArgs keyEvent) + public override bool OnKeyDown (KeyEvent keyEvent) { if (keyEvent.IsAlt) { host.CloseAllMenus (); @@ -731,7 +731,7 @@ public override bool OnKeyDown (KeyEventArgs keyEvent) return false; } - public override bool ProcessHotKey (KeyEventArgs keyEvent) + public override bool ProcessHotKey (KeyEvent keyEvent) { // To ncurses simulate a AltMask key pressing Alt+Space because // it can't detect an alone special key down was pressed. @@ -743,7 +743,7 @@ public override bool ProcessHotKey (KeyEventArgs keyEvent) return false; } - public override bool OnKeyPressed (KeyEventArgs kb) + public override bool ProcessKey (KeyEvent kb) { var result = InvokeKeybindings (kb); if (result != null) @@ -1165,7 +1165,7 @@ public override bool OnLeave (View view) } /// - public override bool OnKeyDown (KeyEventArgs keyEvent) + public override bool OnKeyDown (KeyEvent keyEvent) { if (keyEvent.IsAlt || (keyEvent.IsCtrl && keyEvent.Key == (Key.CtrlMask | Key.Space))) { openedByAltKey = true; @@ -1176,7 +1176,7 @@ public override bool OnKeyDown (KeyEventArgs keyEvent) } /// - public override bool OnKeyUp (KeyEventArgs keyEvent) + public override bool OnKeyUp (KeyEvent keyEvent) { if (keyEvent.IsAlt || keyEvent.Key == Key.AltMask || (keyEvent.IsCtrl && keyEvent.Key == (Key.CtrlMask | Key.Space))) { // User pressed Alt - this may be a precursor to a menu accelerator (e.g. Alt-F) @@ -1812,7 +1812,7 @@ internal void NextMenu (bool isSubMenu = false, bool ignoreUseSubMenusSingleFram } bool openedByHotKey; - internal bool FindAndOpenMenuByHotkey (KeyEventArgs kb) + internal bool FindAndOpenMenuByHotkey (KeyEvent kb) { //int pos = 0; var c = ((uint)kb.Key & (uint)Key.CharMask); @@ -1839,7 +1839,7 @@ internal bool FindAndOpenMenuByHotkey (KeyEventArgs kb) return false; } - bool FindAndOpenChildrenMenuByHotkey (KeyEventArgs kb, MenuItem [] children) + bool FindAndOpenChildrenMenuByHotkey (KeyEvent kb, MenuItem [] children) { var c = ((uint)kb.Key & (uint)Key.CharMask); for (int i = 0; i < children.Length; i++) { @@ -1873,7 +1873,7 @@ bool FindAndOpenChildrenMenuByHotkey (KeyEventArgs kb, MenuItem [] children) return false; } - internal bool FindAndOpenMenuByShortcut (KeyEventArgs kb, MenuItem [] children = null) + internal bool FindAndOpenMenuByShortcut (KeyEvent kb, MenuItem [] children = null) { if (children == null) { children = Menus; @@ -1931,7 +1931,7 @@ private void ProcessMenu (int i, MenuBarItem mi) } /// - public override bool ProcessHotKey (KeyEventArgs kb) + public override bool ProcessHotKey (KeyEvent kb) { if (kb.Key == Key) { if (Visible && !IsMenuOpen) { @@ -1957,7 +1957,7 @@ public override bool ProcessHotKey (KeyEventArgs kb) } /// - public override bool OnKeyPressed (KeyEventArgs kb) + public override bool ProcessKey (KeyEvent kb) { if (InvokeKeybindings (kb) == true) return true; @@ -2013,7 +2013,7 @@ void MoveLeft () } /// - public override bool ProcessColdKey (KeyEventArgs kb) + public override bool ProcessColdKey (KeyEvent kb) { return FindAndOpenMenuByShortcut (kb); } diff --git a/Terminal.Gui/Views/RadioGroup.cs b/Terminal.Gui/Views/RadioGroup.cs index 2920a1d1c7..db4656f4f3 100644 --- a/Terminal.Gui/Views/RadioGroup.cs +++ b/Terminal.Gui/Views/RadioGroup.cs @@ -288,7 +288,7 @@ public virtual void OnSelectedItemChanged (int selectedItem, int previousSelecte } /// - public override bool ProcessColdKey (KeyEventArgs kb) + public override bool ProcessColdKey (KeyEvent kb) { var key = kb.KeyValue; if (key < Char.MaxValue && Char.IsLetterOrDigit ((char)key)) { @@ -318,13 +318,13 @@ public override bool ProcessColdKey (KeyEventArgs kb) } /// - public override bool OnKeyPressed (KeyEventArgs kb) + public override bool ProcessKey (KeyEvent kb) { var result = InvokeKeybindings (kb); if (result != null) return (bool)result; - return base.OnKeyPressed (kb); + return base.ProcessKey (kb); } void SelectItem () diff --git a/Terminal.Gui/Views/ScrollView.cs b/Terminal.Gui/Views/ScrollView.cs index b9aeb9a4b1..bb83466360 100644 --- a/Terminal.Gui/Views/ScrollView.cs +++ b/Terminal.Gui/Views/ScrollView.cs @@ -542,12 +542,12 @@ public bool ScrollRight (int cols) } /// - public override bool OnKeyPressed (KeyEventArgs arg) + public override bool ProcessKey (KeyEvent kb) { - if (base.OnKeyPressed (arg)) + if (base.ProcessKey (kb)) return true; - var result = InvokeKeybindings (arg); + var result = InvokeKeybindings (kb); if (result != null) return (bool)result; diff --git a/Terminal.Gui/Views/Slider.cs b/Terminal.Gui/Views/Slider.cs index f5c311ebe7..a490516c5f 100644 --- a/Terminal.Gui/Views/Slider.cs +++ b/Terminal.Gui/Views/Slider.cs @@ -1432,17 +1432,17 @@ void SetKeyBindings () } /// - public override bool OnKeyPressed (KeyEventArgs keyEvent) + public override bool ProcessKey (KeyEvent keyEvent) { if (!CanFocus || !HasFocus) { - return base.OnKeyPressed (keyEvent); + return base.ProcessKey (keyEvent); } var result = InvokeKeybindings (keyEvent); if (result != null) { return (bool)result; } - return base.OnKeyPressed (keyEvent); + return base.ProcessKey (keyEvent); } Dictionary> GetSetOptionDictionary () => _setOptions.ToDictionary (e => e, e => _options [e]); diff --git a/Terminal.Gui/Views/StatusBar.cs b/Terminal.Gui/Views/StatusBar.cs index f6bb3fdbda..1d66b853dd 100644 --- a/Terminal.Gui/Views/StatusBar.cs +++ b/Terminal.Gui/Views/StatusBar.cs @@ -177,7 +177,7 @@ public override void OnDrawContent (Rect contentArea) } /// - public override bool ProcessHotKey (KeyEventArgs kb) + public override bool ProcessHotKey (KeyEvent kb) { foreach (var item in Items) { if (kb.Key == item.Shortcut) { diff --git a/Terminal.Gui/Views/TabView.cs b/Terminal.Gui/Views/TabView.cs index da11b6b6af..86a558b82d 100644 --- a/Terminal.Gui/Views/TabView.cs +++ b/Terminal.Gui/Views/TabView.cs @@ -230,15 +230,15 @@ protected virtual void OnSelectedTabChanged (Tab oldTab, Tab newTab) } /// - public override bool OnKeyPressed (KeyEventArgs arg) + public override bool ProcessKey (KeyEvent keyEvent) { if (HasFocus && CanFocus && Focused == tabsBar) { - var result = InvokeKeybindings (arg); + var result = InvokeKeybindings (keyEvent); if (result != null) return (bool)result; } - return base.OnKeyPressed (arg); + return base.ProcessKey (keyEvent); } /// diff --git a/Terminal.Gui/Views/TableView/TableView.cs b/Terminal.Gui/Views/TableView/TableView.cs index 7c414b0ef3..a5c25f3d43 100644 --- a/Terminal.Gui/Views/TableView/TableView.cs +++ b/Terminal.Gui/Views/TableView/TableView.cs @@ -761,14 +761,14 @@ private string TruncateOrPad (object originalCellValue, string representation, i /// - public override bool OnKeyPressed (KeyEventArgs args) + public override bool ProcessKey (KeyEvent keyEvent) { if (TableIsNullOrInvisible ()) { PositionCursor (); return false; } - var result = InvokeKeybindings (args); + var result = InvokeKeybindings (keyEvent); if (result != null) { PositionCursor (); return true; @@ -777,17 +777,17 @@ public override bool OnKeyPressed (KeyEventArgs args) if (CollectionNavigator != null && this.HasFocus && Table.Rows != 0 && - Terminal.Gui.CollectionNavigator.IsCompatibleKey (args) && - !args.Key.HasFlag (Key.CtrlMask) && - !args.Key.HasFlag (Key.AltMask) && - char.IsLetterOrDigit ((char)args.KeyValue)) { - return CycleToNextTableEntryBeginningWith (args); + Terminal.Gui.CollectionNavigator.IsCompatibleKey (keyEvent) && + !keyEvent.Key.HasFlag (Key.CtrlMask) && + !keyEvent.Key.HasFlag (Key.AltMask) && + char.IsLetterOrDigit ((char)keyEvent.KeyValue)) { + return CycleToNextTableEntryBeginningWith (keyEvent); } return false; } - private bool CycleToNextTableEntryBeginningWith (KeyEventArgs keyEvent) + private bool CycleToNextTableEntryBeginningWith (KeyEvent keyEvent) { var row = SelectedRow; diff --git a/Terminal.Gui/Views/TableView/TreeTableSource.cs b/Terminal.Gui/Views/TableView/TreeTableSource.cs index 52c695085b..0b06691fd0 100644 --- a/Terminal.Gui/Views/TableView/TreeTableSource.cs +++ b/Terminal.Gui/Views/TableView/TreeTableSource.cs @@ -106,7 +106,7 @@ private string GetColumnZeroRepresentationFromTree (int row) return sb.ToString (); } - private void Table_KeyPress (object sender, KeyEventArgs e) + private void Table_KeyPress (object sender, KeyEventEventArgs e) { if (!IsInTreeColumn (_tableView.SelectedColumn, true)) { return; @@ -118,13 +118,13 @@ private void Table_KeyPress (object sender, KeyEventArgs e) return; } - if (e.Key == Key.CursorLeft) { + if (e.KeyEvent.Key == Key.CursorLeft) { if (_tree.IsExpanded (obj)) { _tree.Collapse (obj); e.Handled = true; } } - if (e.Key == Key.CursorRight) { + if (e.KeyEvent.Key == Key.CursorRight) { if (_tree.CanExpand (obj) && !_tree.IsExpanded (obj)) { _tree.Expand (obj); e.Handled = true; diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs index 01bcb6b46c..6ad4798d78 100644 --- a/Terminal.Gui/Views/TextField.cs +++ b/Terminal.Gui/Views/TextField.cs @@ -637,7 +637,7 @@ void SetClipboard (IEnumerable text) /// /// /// - public override bool OnKeyPressed (KeyEventArgs arg) + public override bool ProcessKey (KeyEvent kb) { // remember current cursor position // because the new calculated cursor position is needed to be set BEFORE the change event is triggest @@ -645,28 +645,28 @@ public override bool OnKeyPressed (KeyEventArgs arg) _oldCursorPos = _point; // Give autocomplete first opportunity to respond to key presses - if (SelectedLength == 0 && Autocomplete.Suggestions.Count > 0 && Autocomplete.ProcessKey (arg)) { + if (SelectedLength == 0 && Autocomplete.Suggestions.Count > 0 && Autocomplete.ProcessKey (kb)) { return true; } - var result = InvokeKeybindings (new KeyEventArgs (ShortcutHelper.GetModifiersKey (arg), - new KeyModifiers () { Alt = arg.IsAlt, Ctrl = arg.IsCtrl, Shift = arg.IsShift })); + var result = InvokeKeybindings (new KeyEvent (ShortcutHelper.GetModifiersKey (kb), + new KeyModifiers () { Alt = kb.IsAlt, Ctrl = kb.IsCtrl, Shift = kb.IsShift })); if (result != null) return (bool)result; // Ignore other control characters. - if (arg.Key < Key.Space || arg.Key > Key.CharMask) + if (kb.Key < Key.Space || kb.Key > Key.CharMask) return false; if (ReadOnly) return true; - InsertText (arg); + InsertText (kb); return true; } - void InsertText (KeyEventArgs kb, bool useOldCursorPos = true) + void InsertText (KeyEvent kb, bool useOldCursorPos = true) { _historyText.Add (new List> () { TextModel.ToRuneCells (_text) }, new Point (_point, 0)); @@ -1312,7 +1312,7 @@ public void InsertText (string toAdd, bool useOldCursorPos = true) throw new ArgumentException ($"Cannot insert character '{ch}' because it does not map to a Key"); } - InsertText (new KeyEventArgs () { Key = key }, useOldCursorPos); + InsertText (new KeyEvent () { Key = key }, useOldCursorPos); } } diff --git a/Terminal.Gui/Views/TextValidateField.cs b/Terminal.Gui/Views/TextValidateField.cs index 1107873505..f687a82a5d 100644 --- a/Terminal.Gui/Views/TextValidateField.cs +++ b/Terminal.Gui/Views/TextValidateField.cs @@ -612,7 +612,7 @@ bool EndKeyHandler () } /// - public override bool OnKeyPressed (KeyEventArgs kb) + public override bool ProcessKey (KeyEvent kb) { if (provider == null) { return false; diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs index 1e0ea2cde4..3a746880bf 100644 --- a/Terminal.Gui/Views/TextView.cs +++ b/Terminal.Gui/Views/TextView.cs @@ -3065,7 +3065,7 @@ public void InsertText (string toAdd) throw new ArgumentException ($"Cannot insert character '{ch}' because it does not map to a Key"); } - InsertText (new KeyEventArgs () { Key = key }); + InsertText (new KeyEvent () { Key = key }); } if (NeedsDisplay) { @@ -3401,7 +3401,7 @@ public void ScrollTo (int idx, bool isRow = true) bool _shiftSelecting; /// - public override bool OnKeyPressed (KeyEventArgs kb) + public override bool ProcessKey (KeyEvent kb) { if (!CanFocus) { return true; @@ -3412,7 +3412,7 @@ public override bool OnKeyPressed (KeyEventArgs kb) return true; } - var result = InvokeKeybindings (new KeyEventArgs (ShortcutHelper.GetModifiersKey (kb), + var result = InvokeKeybindings (new KeyEvent (ShortcutHelper.GetModifiersKey (kb), new KeyModifiers () { Alt = kb.IsAlt, Ctrl = kb.IsCtrl, Shift = kb.IsShift })); if (result != null) return (bool)result; @@ -3791,7 +3791,7 @@ bool ProcessTab () if (!AllowsTab || _isReadOnly) { return ProcessMoveNextView (); } - InsertText (new KeyEventArgs ((Key)'\t', null)); + InsertText (new KeyEvent ((Key)'\t', null)); DoNeededAction (); return true; } @@ -4318,7 +4318,7 @@ void ResetAllTrack () _continuousFind = false; } - bool InsertText (KeyEventArgs kb, ColorScheme? colorScheme = null) + bool InsertText (KeyEvent kb, ColorScheme? colorScheme = null) { //So that special keys like tab can be processed if (_isReadOnly) @@ -4388,7 +4388,7 @@ public void DeleteAll () } /// - public override bool OnKeyUp (KeyEventArgs kb) + public override bool OnKeyUp (KeyEvent kb) { switch (kb.Key) { case Key.Space | Key.CtrlMask: diff --git a/Terminal.Gui/Views/TileView.cs b/Terminal.Gui/Views/TileView.cs index a3b0f2dcc9..aa660203bc 100644 --- a/Terminal.Gui/Views/TileView.cs +++ b/Terminal.Gui/Views/TileView.cs @@ -443,7 +443,7 @@ public bool TrySplitTile (int idx, int numberOfPanels, out TileView result) } /// - public override bool ProcessHotKey (KeyEventArgs keyEvent) + public override bool ProcessHotKey (KeyEvent keyEvent) { bool focusMoved = false; @@ -805,17 +805,17 @@ public TileViewLineView (TileView parent, int idx) AddKeyBinding (Key.CursorDown, Command.LineDown); } - public override bool OnKeyPressed (KeyEventArgs kb) + public override bool ProcessKey (KeyEvent kb) { if (!CanFocus || !HasFocus) { - return base.OnKeyPressed (kb); + return base.ProcessKey (kb); } var result = InvokeKeybindings (kb); if (result != null) return (bool)result; - return base.OnKeyPressed (kb); + return base.ProcessKey (kb); } public override void PositionCursor () diff --git a/Terminal.Gui/Views/TimeField.cs b/Terminal.Gui/Views/TimeField.cs index e5944f1fc0..ff0b7198b8 100644 --- a/Terminal.Gui/Views/TimeField.cs +++ b/Terminal.Gui/Views/TimeField.cs @@ -247,7 +247,7 @@ void AdjCursorPosition () } /// - public override bool OnKeyPressed (KeyEventArgs kb) + public override bool ProcessKey (KeyEvent kb) { var result = InvokeKeybindings (kb); if (result != null) diff --git a/Terminal.Gui/Views/Toplevel.cs b/Terminal.Gui/Views/Toplevel.cs index a44b296c59..4612d84cf0 100644 --- a/Terminal.Gui/Views/Toplevel.cs +++ b/Terminal.Gui/Views/Toplevel.cs @@ -318,7 +318,7 @@ public override bool CanFocus { /// /// /// - /// events will propagate keys upwards. + /// events will propagate keys upwards. /// /// /// The Toplevel will act as an embedded view (not a modal/pop-up). @@ -329,7 +329,7 @@ public override bool CanFocus { /// /// /// - /// events will NOT propogate keys upwards. + /// events will NOT propogate keys upwards. /// /// /// The Toplevel will and look like a modal (pop-up) (e.g. see . @@ -355,7 +355,7 @@ public override bool CanFocus { public bool IsLoaded { get; private set; } /// - public override bool OnKeyDown (KeyEventArgs keyEvent) + public override bool OnKeyDown (KeyEvent keyEvent) { if (base.OnKeyDown (keyEvent)) { return true; @@ -373,7 +373,7 @@ public override bool OnKeyDown (KeyEventArgs keyEvent) } /// - public override bool OnKeyUp (KeyEventArgs keyEvent) + public override bool OnKeyUp (KeyEvent keyEvent) { if (base.OnKeyUp (keyEvent)) { return true; @@ -393,12 +393,12 @@ public override bool OnKeyUp (KeyEventArgs keyEvent) } /// - public override bool OnKeyPressed (KeyEventArgs keyEvent) + public override bool ProcessKey (KeyEvent keyEvent) { - if (base.OnKeyPressed (keyEvent)) + if (base.ProcessKey (keyEvent)) return true; - var result = InvokeKeybindings (new KeyEventArgs (ShortcutHelper.GetModifiersKey (keyEvent), + var result = InvokeKeybindings (new KeyEvent (ShortcutHelper.GetModifiersKey (keyEvent), new KeyModifiers () { Alt = keyEvent.IsAlt, Ctrl = keyEvent.IsCtrl, Shift = keyEvent.IsShift })); if (result != null) return (bool)result; @@ -479,7 +479,7 @@ private void QuitToplevel () } /// - public override bool ProcessColdKey (KeyEventArgs keyEvent) + public override bool ProcessColdKey (KeyEvent keyEvent) { if (base.ProcessColdKey (keyEvent)) { return true; diff --git a/Terminal.Gui/Views/TreeView/TreeView.cs b/Terminal.Gui/Views/TreeView/TreeView.cs index 2180cad223..ba63944118 100644 --- a/Terminal.Gui/Views/TreeView/TreeView.cs +++ b/Terminal.Gui/Views/TreeView/TreeView.cs @@ -621,7 +621,7 @@ private IEnumerable> AddToLineMap (Branch currentBranch, bool paren public CollectionNavigator KeystrokeNavigator { get; private set; } = new CollectionNavigator (); /// - public override bool OnKeyPressed (KeyEventArgs arg) + public override bool ProcessKey (KeyEvent keyEvent) { if (!Enabled) { return false; @@ -629,13 +629,13 @@ public override bool OnKeyPressed (KeyEventArgs arg) try { // First of all deal with any registered keybindings - var result = InvokeKeybindings (arg); + var result = InvokeKeybindings (keyEvent); if (result != null) { return (bool)result; } // If not a keybinding, is the key a searchable key press? - if (CollectionNavigator.IsCompatibleKey (arg) && AllowLetterBasedNavigation) { + if (CollectionNavigator.IsCompatibleKey (keyEvent) && AllowLetterBasedNavigation) { IReadOnlyCollection> map; // If there has been a call to InvalidateMap since the last time @@ -644,7 +644,7 @@ public override bool OnKeyPressed (KeyEventArgs arg) // Find the current selected object within the tree var current = map.IndexOf (b => b.Model == SelectedObject); - var newIndex = KeystrokeNavigator?.GetNextMatchingItem (current, (char)arg.KeyValue); + var newIndex = KeystrokeNavigator?.GetNextMatchingItem (current, (char)keyEvent.KeyValue); if (newIndex is int && newIndex != -1) { SelectedObject = map.ElementAt ((int)newIndex).Model; @@ -657,7 +657,7 @@ public override bool OnKeyPressed (KeyEventArgs arg) PositionCursor (); } - return base.OnKeyPressed (arg); + return base.ProcessKey (keyEvent); } /// diff --git a/Terminal.Gui/Views/Wizard/Wizard.cs b/Terminal.Gui/Views/Wizard/Wizard.cs index b5b2627fa1..8b8d0c89bd 100644 --- a/Terminal.Gui/Views/Wizard/Wizard.cs +++ b/Terminal.Gui/Views/Wizard/Wizard.cs @@ -147,23 +147,23 @@ private void NextfinishBtn_Clicked (object sender, EventArgs e) /// /// is derived from and Dialog causes Esc to call - /// , closing the Dialog. Wizard overrides + /// , closing the Dialog. Wizard overrides /// to instead fire the event when Wizard is being used as a non-modal (see . - /// See for more. + /// See for more. /// /// /// - public override bool OnKeyPressed (KeyEventArgs arg) + public override bool ProcessKey (KeyEvent kb) { if (!Modal) { - switch (arg.Key) { + switch (kb.Key) { case Key.Esc: var args = new WizardButtonEventArgs (); Cancelled?.Invoke (this, args); return false; } } - return base.OnKeyPressed (arg); + return base.ProcessKey (kb); } /// diff --git a/UICatalog/KeyBindingsDialog.cs b/UICatalog/KeyBindingsDialog.cs index c4d65783ed..538320f383 100644 --- a/UICatalog/KeyBindingsDialog.cs +++ b/UICatalog/KeyBindingsDialog.cs @@ -181,7 +181,7 @@ private void RemapKey (object sender, EventArgs e) // prompt user to hit a key var dlg = new Dialog () { Title = "Enter Key" }; dlg.KeyPressed += (s, k) => { - key = k.Key; + key = k.KeyEvent.Key; Application.RequestStop (); }; Application.Run (dlg); diff --git a/UICatalog/Scenarios/ASCIICustomButton.cs b/UICatalog/Scenarios/ASCIICustomButton.cs index d57482a019..eabde34c57 100644 --- a/UICatalog/Scenarios/ASCIICustomButton.cs +++ b/UICatalog/Scenarios/ASCIICustomButton.cs @@ -231,30 +231,30 @@ public ScrollViewTestWindow () } } - private void Button_KeyPress (object sender, KeyEventArgs arg) + private void Button_KeyPress (object sender, KeyEventEventArgs obj) { - switch (arg.Key) { + switch (obj.KeyEvent.Key) { case Key.End: scrollView.ContentOffset = new Point (scrollView.ContentOffset.X, -(scrollView.ContentSize.Height - scrollView.Frame.Height + (scrollView.ShowHorizontalScrollIndicator ? 1 : 0))); - arg.Handled = true; + obj.Handled = true; return; case Key.Home: scrollView.ContentOffset = new Point (scrollView.ContentOffset.X, 0); - arg.Handled = true; + obj.Handled = true; return; case Key.PageDown: scrollView.ContentOffset = new Point (scrollView.ContentOffset.X, Math.Max (scrollView.ContentOffset.Y - scrollView.Frame.Height, -(scrollView.ContentSize.Height - scrollView.Frame.Height + (scrollView.ShowHorizontalScrollIndicator ? 1 : 0)))); - arg.Handled = true; + obj.Handled = true; return; case Key.PageUp: scrollView.ContentOffset = new Point (scrollView.ContentOffset.X, Math.Min (scrollView.ContentOffset.Y + scrollView.Frame.Height, 0)); - arg.Handled = true; + obj.Handled = true; return; } } diff --git a/UICatalog/Scenarios/BackgroundWorkerCollection.cs b/UICatalog/Scenarios/BackgroundWorkerCollection.cs index 7eb9dca533..22434aaedf 100644 --- a/UICatalog/Scenarios/BackgroundWorkerCollection.cs +++ b/UICatalog/Scenarios/BackgroundWorkerCollection.cs @@ -339,7 +339,7 @@ public StagingUIController () Add (close); KeyPressed += (s, e) => { - if (e.Key == Key.Esc) { + if (e.KeyEvent.Key == Key.Esc) { OnReportClosed (this, EventArgs.Empty); } }; diff --git a/UICatalog/Scenarios/ContextMenus.cs b/UICatalog/Scenarios/ContextMenus.cs index 2e0eaad8f3..c39cb248c6 100644 --- a/UICatalog/Scenarios/ContextMenus.cs +++ b/UICatalog/Scenarios/ContextMenus.cs @@ -59,7 +59,7 @@ public override void Setup () Point mousePos = default; Win.KeyPressed += (s, e) => { - if (e.Key == (Key.Space | Key.CtrlMask)) { + if (e.KeyEvent.Key == (Key.Space | Key.CtrlMask)) { ShowContextMenu (mousePos.X, mousePos.Y); e.Handled = true; } diff --git a/UICatalog/Scenarios/CsvEditor.cs b/UICatalog/Scenarios/CsvEditor.cs index 7c6b1deee1..96ff667ffe 100644 --- a/UICatalog/Scenarios/CsvEditor.cs +++ b/UICatalog/Scenarios/CsvEditor.cs @@ -465,9 +465,9 @@ private void SetupScrollBar () } - private void TableViewKeyPress (object sender, KeyEventArgs e) + private void TableViewKeyPress (object sender, KeyEventEventArgs e) { - if (e.Key == Key.DeleteChar) { + if (e.KeyEvent.Key == Key.DeleteChar) { if (tableView.FullRowSelect) { // Delete button deletes all rows when in full row mode diff --git a/UICatalog/Scenarios/DynamicMenuBar.cs b/UICatalog/Scenarios/DynamicMenuBar.cs index bb38a2d12c..62a8fcb80d 100644 --- a/UICatalog/Scenarios/DynamicMenuBar.cs +++ b/UICatalog/Scenarios/DynamicMenuBar.cs @@ -723,17 +723,17 @@ public DynamicMenuBarDetails (string title) : base (title) ReadOnly = true }; _txtShortcut.KeyDown += (s, e) => { - if (!ProcessKey (e)) { + if (!ProcessKey (e.KeyEvent)) { return; } - var k = ShortcutHelper.GetModifiersKey (e); + var k = ShortcutHelper.GetModifiersKey (e.KeyEvent); if (CheckShortcut (k, true)) { e.Handled = true; } }; - bool ProcessKey (KeyEventArgs ev) + bool ProcessKey (KeyEvent ev) { switch (ev.Key) { case Key.CursorUp: @@ -766,7 +766,7 @@ bool CheckShortcut (Key k, bool pre) } _txtShortcut.KeyUp += (s, e) => { - var k = ShortcutHelper.GetModifiersKey (e); + var k = ShortcutHelper.GetModifiersKey (e.KeyEvent); if (CheckShortcut (k, false)) { e.Handled = true; } diff --git a/UICatalog/Scenarios/DynamicStatusBar.cs b/UICatalog/Scenarios/DynamicStatusBar.cs index 1adf3bf1b9..e28092117a 100644 --- a/UICatalog/Scenarios/DynamicStatusBar.cs +++ b/UICatalog/Scenarios/DynamicStatusBar.cs @@ -396,17 +396,17 @@ public DynamicStatusBarDetails (string title) : base (title) ReadOnly = true }; _txtShortcut.KeyDown += (s, e) => { - if (!OnKeyPressed (e)) { + if (!ProcessKey (e.KeyEvent)) { return; } - var k = ShortcutHelper.GetModifiersKey (e); + var k = ShortcutHelper.GetModifiersKey (e.KeyEvent); if (CheckShortcut (k, true)) { e.Handled = true; } }; - bool OnKeyPressed (KeyEventArgs ev) + bool ProcessKey (KeyEvent ev) { switch (ev.Key) { case Key.CursorUp: @@ -440,7 +440,7 @@ bool CheckShortcut (Key k, bool pre) } _txtShortcut.KeyUp += (s, e) => { - var k = ShortcutHelper.GetModifiersKey (e); + var k = ShortcutHelper.GetModifiersKey (e.KeyEvent); if (CheckShortcut (k, false)) { e.Handled = true; } diff --git a/UICatalog/Scenarios/Editor.cs b/UICatalog/Scenarios/Editor.cs index 6b945f8bbc..45c6f704fd 100644 --- a/UICatalog/Scenarios/Editor.cs +++ b/UICatalog/Scenarios/Editor.cs @@ -177,11 +177,11 @@ public override void Init () }; Win.KeyPressed += (s, e) => { - var keys = ShortcutHelper.GetModifiersKey (e); - if (_winDialog != null && (e.Key == Key.Esc - || e.Key == Application.QuitKey)) { + var keys = ShortcutHelper.GetModifiersKey (e.KeyEvent); + if (_winDialog != null && (e.KeyEvent.Key == Key.Esc + || e.KeyEvent.Key == Application.QuitKey)) { DisposeWinDialog (); - } else if (e.Key == Application.QuitKey) { + } else if (e.KeyEvent.Key == Application.QuitKey) { Quit (); e.Handled = true; } else if (_winDialog != null && keys == (Key.Tab | Key.CtrlMask)) { diff --git a/UICatalog/Scenarios/InteractiveTree.cs b/UICatalog/Scenarios/InteractiveTree.cs index 6b2ba38812..26b26d1fde 100644 --- a/UICatalog/Scenarios/InteractiveTree.cs +++ b/UICatalog/Scenarios/InteractiveTree.cs @@ -44,9 +44,9 @@ public override void Setup () } - private void TreeView_KeyPress (object sender, KeyEventArgs obj) + private void TreeView_KeyPress (object sender, KeyEventEventArgs obj) { - if (obj.Key == Key.DeleteChar) { + if (obj.KeyEvent.Key == Key.DeleteChar) { var toDelete = treeView.SelectedObject; diff --git a/UICatalog/Scenarios/Keys.cs b/UICatalog/Scenarios/Keys.cs index e6373e625c..6594daa07c 100644 --- a/UICatalog/Scenarios/Keys.cs +++ b/UICatalog/Scenarios/Keys.cs @@ -8,23 +8,23 @@ namespace UICatalog.Scenarios { public class Keys : Scenario { class TestWindow : Window { - public List _onKeyPressedList = new List (); + public List _processKeyList = new List (); public List _processHotKeyList = new List (); public List _processColdKeyList = new List (); - public override bool OnKeyPressed (KeyEventArgs arg) + public override bool ProcessKey (KeyEvent keyEvent) { - _onKeyPressedList.Add (arg.ToString ()); - return base.OnKeyPressed (arg); + _processKeyList.Add (keyEvent.ToString ()); + return base.ProcessKey (keyEvent); } - public override bool ProcessHotKey (KeyEventArgs keyEvent) + public override bool ProcessHotKey (KeyEvent keyEvent) { _processHotKeyList.Add (keyEvent.ToString ()); return base.ProcessHotKey (keyEvent); } - public override bool ProcessColdKey (KeyEventArgs keyEvent) + public override bool ProcessColdKey (KeyEvent keyEvent) { _processColdKeyList.Add (keyEvent.ToString ()); @@ -65,30 +65,29 @@ public override void Setup () Win.Add (edit); // Last KeyPress: ______ - var appKeyPressedLabel = new Label ("Last Application.KeyPress:") { + var keyPressedLabel = new Label ("Last Application.KeyPress:") { X = Pos.Left (editLabel), Y = Pos.Top (editLabel) + 2, }; - Win.Add (appKeyPressedLabel); - var labelAppKeyPressed = new Label ("") { - X = Pos.Right (appKeyPressedLabel) + 1, - Y = Pos.Top (appKeyPressedLabel), + Win.Add (keyPressedLabel); + var labelKeypress = new Label ("") { + X = Pos.Left (edit), + Y = Pos.Top (keyPressedLabel), TextAlignment = Terminal.Gui.TextAlignment.Centered, ColorScheme = Colors.Error, AutoSize = true }; - Win.Add (labelAppKeyPressed); + Win.Add (labelKeypress); - Application.KeyPressed += (s, e) => labelAppKeyPressed.Text = e.ToString (); + Win.KeyPressed += (s, e) => labelKeypress.Text = e.KeyEvent.ToString (); - // Key event log (for Application): - - var keyLogLabel = new Label ("All events:") { + // Key stroke log: + var keyLogLabel = new Label ("Key event log:") { X = Pos.Left (editLabel), Y = Pos.Top (editLabel) + 4, }; Win.Add (keyLogLabel); - var fakeKeyPress = new KeyEventArgs (Key.CtrlMask | Key.A, new KeyModifiers () { + var fakeKeyPress = new KeyEvent (Key.CtrlMask | Key.A, new KeyModifiers () { Alt = true, Ctrl = true, Shift = true @@ -106,7 +105,7 @@ public override void Setup () Win.Add (keyEventListView); // ProcessKey log: - var processKeyLogLabel = new Label ("Win.OnKeyPressed:") { + var processKeyLogLabel = new Label ("ProcessKey log:") { X = Pos.Right (keyEventListView) + 1, Y = Pos.Top (editLabel) + 4, }; @@ -114,7 +113,7 @@ public override void Setup () maxLogEntry = $"{fakeKeyPress}".Length; yOffset = (Application.Top == Application.Top ? 1 : 6); - var processKeyListView = new ListView (((TestWindow)Win)._onKeyPressedList) { + var processKeyListView = new ListView (((TestWindow)Win)._processKeyList) { X = Pos.Left (processKeyLogLabel), Y = Pos.Top (processKeyLogLabel) + yOffset, Width = Dim.Percent (30), @@ -125,7 +124,7 @@ public override void Setup () // ProcessHotKey log: // BUGBUG: Label is not positioning right with Pos, so using TextField instead - var processHotKeyLogLabel = new Label ("Win.ProcessHotKey:") { + var processHotKeyLogLabel = new Label ("ProcessHotKey log:") { X = Pos.Right (processKeyListView) + 1, Y = Pos.Top (editLabel) + 4, }; @@ -143,7 +142,7 @@ public override void Setup () // ProcessColdKey log: // BUGBUG: Label is not positioning right with Pos, so using TextField instead - var processColdKeyLogLabel = new Label ("Win.ProcessColdKey:") { + var processColdKeyLogLabel = new Label ("ProcessColdKey log:") { X = Pos.Right (processHotKeyListView) + 1, Y = Pos.Top (editLabel) + 4, }; @@ -157,10 +156,14 @@ public override void Setup () Height = Dim.Fill (), }; - void KeyDownPressUp (KeyEventArgs args, string updown) + Application.KeyDown += (s, a) => KeyDownPressUp (a, "Down"); + Application.KeyPressed += (s, a) => KeyDownPressUp (a, "Press"); + Application.KeyUp += (s, a) => KeyDownPressUp (a, "Up"); + + void KeyDownPressUp (KeyEventEventArgs args, string updown) { // BUGBUG: KeyEvent.ToString is badly broken - var msg = $"Key{updown,-5}: {args}"; + var msg = $"Key{updown,-5}: {args.KeyEvent}"; keyEventlist.Add (msg); keyEventListView.MoveDown (); processKeyListView.MoveDown (); @@ -168,10 +171,6 @@ void KeyDownPressUp (KeyEventArgs args, string updown) processHotKeyListView.MoveDown (); } - Application.KeyDown += (s, a) => KeyDownPressUp (a, "Down"); - Application.KeyPressed += (s, a) => KeyDownPressUp (a, "Press"); - Application.KeyUp += (s, a) => KeyDownPressUp (a, "Up"); - processColdKeyListView.ColorScheme = Colors.TopLevel; Win.Add (processColdKeyListView); } diff --git a/UICatalog/Scenarios/LineDrawing.cs b/UICatalog/Scenarios/LineDrawing.cs index 89a1812a1c..45de71facb 100644 --- a/UICatalog/Scenarios/LineDrawing.cs +++ b/UICatalog/Scenarios/LineDrawing.cs @@ -32,7 +32,7 @@ public override void Setup () Win.Add (canvas); Win.Add (tools); - Win.KeyPressed += (s,e) => { e.Handled = canvas.OnKeyPressed (e); }; + Win.KeyPressed += (s,e) => { e.Handled = canvas.ProcessKey (e.KeyEvent); }; } class ToolsView : Window { @@ -107,7 +107,7 @@ public DrawingArea () Stack undoHistory = new (); - public override bool OnKeyPressed (KeyEventArgs e) + public override bool ProcessKey (KeyEvent e) { if (e.Key == (Key.Z | Key.CtrlMask)) { var pop = _currentLayer.RemoveLastLine (); @@ -127,7 +127,7 @@ public override bool OnKeyPressed (KeyEventArgs e) } } - return base.OnKeyPressed (e); + return base.ProcessKey (e); } internal void AddLayer () { diff --git a/UICatalog/Scenarios/ListColumns.cs b/UICatalog/Scenarios/ListColumns.cs index bb5484d07f..c3c38f0695 100644 --- a/UICatalog/Scenarios/ListColumns.cs +++ b/UICatalog/Scenarios/ListColumns.cs @@ -153,9 +153,9 @@ private void SetupScrollBar () } - private void TableViewKeyPress (object sender, KeyEventArgs e) + private void TableViewKeyPress (object sender, KeyEventEventArgs e) { - if (e.Key == Key.DeleteChar) { + if (e.KeyEvent.Key == Key.DeleteChar) { // set all selected cells to null foreach (var pt in listColView.GetAllSelectedCells ()) { diff --git a/UICatalog/Scenarios/SendKeys.cs b/UICatalog/Scenarios/SendKeys.cs index 965fb30c80..dd9eef8ddd 100644 --- a/UICatalog/Scenarios/SendKeys.cs +++ b/UICatalog/Scenarios/SendKeys.cs @@ -58,16 +58,16 @@ public override void Setup () var IsCtrl = false; txtResult.KeyPressed += (s, e) => { - rKeys += (char)e.Key; - if (!IsShift && e.IsShift) { + rKeys += (char)e.KeyEvent.Key; + if (!IsShift && e.KeyEvent.IsShift) { rControlKeys += " Shift "; IsShift = true; } - if (!IsAlt && e.IsAlt) { + if (!IsAlt && e.KeyEvent.IsAlt) { rControlKeys += " Alt "; IsAlt = true; } - if (!IsCtrl && e.IsCtrl) { + if (!IsCtrl && e.KeyEvent.IsCtrl) { rControlKeys += " Ctrl "; IsCtrl = true; } @@ -117,7 +117,7 @@ void ProcessInput () button.Clicked += (s,e) => ProcessInput (); Win.KeyPressed += (s, e) => { - if (e.Key == Key.Enter) { + if (e.KeyEvent.Key == Key.Enter) { ProcessInput (); e.Handled = true; } diff --git a/UICatalog/Scenarios/SingleBackgroundWorker.cs b/UICatalog/Scenarios/SingleBackgroundWorker.cs index d979f34b4a..80b3693e65 100644 --- a/UICatalog/Scenarios/SingleBackgroundWorker.cs +++ b/UICatalog/Scenarios/SingleBackgroundWorker.cs @@ -136,7 +136,7 @@ public StagingUIController (DateTime? start, List list) top.KeyPressed += (s,e) => { // Prevents Ctrl+Q from closing this. // Only Ctrl+C is allowed. - if (e.Key == Application.QuitKey) { + if (e.KeyEvent.Key == Application.QuitKey) { e.Handled = true; } }; diff --git a/UICatalog/Scenarios/Snake.cs b/UICatalog/Scenarios/Snake.cs index 1c9d786c7e..327480ba8c 100644 --- a/UICatalog/Scenarios/Snake.cs +++ b/UICatalog/Scenarios/Snake.cs @@ -124,7 +124,7 @@ public override void OnDrawContent (Rect contentArea) AddRune (State.Apple.X, State.Apple.Y, _appleRune); Driver.SetAttribute (white); } - public override bool OnKeyDown (KeyEventArgs keyEvent) + public override bool OnKeyDown (KeyEvent keyEvent) { if (keyEvent.Key == Key.CursorUp) { State.PlannedDirection = Direction.Up; diff --git a/UICatalog/Scenarios/TableEditor.cs b/UICatalog/Scenarios/TableEditor.cs index 4de2a7ce41..bf477e8eac 100644 --- a/UICatalog/Scenarios/TableEditor.cs +++ b/UICatalog/Scenarios/TableEditor.cs @@ -386,13 +386,13 @@ private void SetupScrollBar () } - private void TableViewKeyPress (object sender, KeyEventArgs e) + private void TableViewKeyPress (object sender, KeyEventEventArgs e) { if(currentTable == null) { return; } - if (e.Key == Key.DeleteChar) { + if (e.KeyEvent.Key == Key.DeleteChar) { if (tableView.FullRowSelect) { // Delete button deletes all rows when in full row mode diff --git a/UICatalog/Scenarios/TreeViewFileSystem.cs b/UICatalog/Scenarios/TreeViewFileSystem.cs index a9517ca915..7e4c722426 100644 --- a/UICatalog/Scenarios/TreeViewFileSystem.cs +++ b/UICatalog/Scenarios/TreeViewFileSystem.cs @@ -158,9 +158,9 @@ private void TreeViewFiles_DrawLine (object sender, DrawTreeViewLineEventArgs { - //System.Diagnostics.Debug.WriteLine ($"Output - KeyDown: {e.Key}"); + //System.Diagnostics.Debug.WriteLine ($"Output - KeyDown: {e.KeyEvent.Key}"); e.Handled = true; - if (e.Key == Key.Unknown) { + if (e.KeyEvent.Key == Key.Unknown) { _wasUnknown = true; } }; @@ -99,9 +99,9 @@ public override void Setup () tvOutput.KeyPressed += (s, e) => { //System.Diagnostics.Debug.WriteLine ($"Output - KeyPress - _keyboardStrokes: {_keyboardStrokes.Count}"); if (_outputStarted && _keyboardStrokes.Count > 0) { - var ev = ShortcutHelper.GetModifiersKey (e); + var ev = ShortcutHelper.GetModifiersKey (e.KeyEvent); //System.Diagnostics.Debug.WriteLine ($"Output - KeyPress: {ev}"); - if (!tvOutput.OnKeyPressed (e)) { + if (!tvOutput.ProcessKey (e.KeyEvent)) { Application.Invoke (() => { MessageBox.Query ("Keys", $"'{ShortcutHelper.GetShortcutTag (ev)}' pressed!", "Ok"); }); @@ -115,28 +115,28 @@ public override void Setup () Win.Add (tvOutput); tvInput.KeyDown += (s, e) => { - //System.Diagnostics.Debug.WriteLine ($"Input - KeyDown: {e.Key}"); + //System.Diagnostics.Debug.WriteLine ($"Input - KeyDown: {e.KeyEvent.Key}"); e.Handled = true; - if (e.Key == Key.Unknown) { + if (e.KeyEvent.Key == Key.Unknown) { _wasUnknown = true; } }; - KeyEventArgs unknownChar = null; + KeyEventEventArgs unknownChar = null; tvInput.KeyPressed += (s, e) => { - if (e.Key == (Key.Q | Key.CtrlMask)) { + if (e.KeyEvent.Key == (Key.Q | Key.CtrlMask)) { Application.RequestStop (); return; } - if (e.Key == Key.Unknown) { + if (e.KeyEvent.Key == Key.Unknown) { _wasUnknown = true; e.Handled = true; return; } if (_wasUnknown && _keyboardStrokes.Count == 1) { _wasUnknown = false; - } else if (_wasUnknown && char.IsLetter ((char)e.Key)) { + } else if (_wasUnknown && char.IsLetter ((char)e.KeyEvent.Key)) { _wasUnknown = false; } else if (!_wasUnknown && _keyboardStrokes.Count > 0) { e.Handled = true; @@ -147,15 +147,15 @@ public override void Setup () } else { _keyboardStrokes.Insert (0, 0); } - var ev = ShortcutHelper.GetModifiersKey (e); + var ev = ShortcutHelper.GetModifiersKey (e.KeyEvent); //System.Diagnostics.Debug.WriteLine ($"Input - KeyPress: {ev}"); //System.Diagnostics.Debug.WriteLine ($"Input - KeyPress - _keyboardStrokes: {_keyboardStrokes.Count}"); }; tvInput.KeyUp += (s, e) => { - //System.Diagnostics.Debug.WriteLine ($"Input - KeyUp: {e.Key}"); + //System.Diagnostics.Debug.WriteLine ($"Input - KeyUp: {e.KeyEvent.Key}"); //var ke = e.KeyEvent; - var ke = ShortcutHelper.GetModifiersKey (e); + var ke = ShortcutHelper.GetModifiersKey (e.KeyEvent); if (_wasUnknown && (int)ke - (int)(ke & (Key.AltMask | Key.CtrlMask | Key.ShiftMask)) != 0) { unknownChar = e; } @@ -232,20 +232,21 @@ void Win_LayoutComplete (object sender, LayoutEventArgs obj) Win.LayoutComplete += Win_LayoutComplete; } - private void AddKeyboardStrokes (KeyEventArgs e) + private void AddKeyboardStrokes (KeyEventEventArgs e) { + var ke = e.KeyEvent; var km = new KeyModifiers (); - if (e.IsShift) { + if (ke.IsShift) { km.Shift = true; } - if (e.IsAlt) { + if (ke.IsAlt) { km.Alt = true; } - if (e.IsCtrl) { + if (ke.IsCtrl) { km.Ctrl = true; } - var keyChar = e.KeyValue; - var mK = (int)((Key)e.KeyValue & (Key.AltMask | Key.CtrlMask | Key.ShiftMask)); + var keyChar = ke.KeyValue; + var mK = (int)((Key)ke.KeyValue & (Key.AltMask | Key.CtrlMask | Key.ShiftMask)); keyChar &= ~mK; _keyboardStrokes.Add (keyChar); } diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs index 3d8bfe0d04..73df8a21b8 100644 --- a/UICatalog/UICatalog.cs +++ b/UICatalog/UICatalog.cs @@ -373,8 +373,8 @@ public UICatalogTopLevel () // 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 (CollectionNavigator.IsCompatibleKey (a)) { - var newItem = _scenarioCollectionNav?.GetNextMatchingItem (ScenarioList.SelectedRow, (char)a.KeyValue); + if (CollectionNavigator.IsCompatibleKey (a.KeyEvent)) { + var newItem = _scenarioCollectionNav?.GetNextMatchingItem (ScenarioList.SelectedRow, (char)a.KeyEvent.KeyValue); if (newItem is int v && newItem != -1) { ScenarioList.SelectedRow = v; ScenarioList.EnsureSelectedCellIsVisible (); @@ -768,9 +768,9 @@ public void ConfigChanged () Application.Top.SetNeedsDisplay (); } - void KeyDownHandler (object? sender, KeyEventArgs? a) + void KeyDownHandler (object? sender, KeyEventEventArgs? a) { - if (a!.IsCapslock) { + if (a!.KeyEvent.IsCapslock) { Capslock.Title = "Caps: On"; StatusBar.SetNeedsDisplay (); } else { @@ -778,7 +778,7 @@ void KeyDownHandler (object? sender, KeyEventArgs? a) StatusBar.SetNeedsDisplay (); } - if (a!.IsNumlock) { + if (a!.KeyEvent.IsNumlock) { Numlock.Title = "Num: On"; StatusBar.SetNeedsDisplay (); } else { @@ -786,7 +786,7 @@ void KeyDownHandler (object? sender, KeyEventArgs? a) StatusBar.SetNeedsDisplay (); } - if (a!.IsScrolllock) { + if (a!.KeyEvent.IsScrolllock) { Scrolllock.Title = "Scroll: On"; StatusBar.SetNeedsDisplay (); } else { diff --git a/UnitTests/Application/ApplicationTests.cs b/UnitTests/Application/ApplicationTests.cs index 80d6eb6635..5dca0018c8 100644 --- a/UnitTests/Application/ApplicationTests.cs +++ b/UnitTests/Application/ApplicationTests.cs @@ -582,9 +582,9 @@ public void KeyUp_Event () int keyUps = 0; var output = string.Empty; - Application.Top.KeyUp += (object sender, KeyEventArgs args) => { - if (args.Key != (Key.CtrlMask | Key.Q)) { - output += (char)args.KeyValue; + Application.Top.KeyUp += (object sender, KeyEventEventArgs args) => { + if (args.KeyEvent.Key != (Key.CtrlMask | Key.Q)) { + output += (char)args.KeyEvent.KeyValue; } keyUps++; }; @@ -631,55 +631,55 @@ public void AlternateForwardKey_AlternateBackwardKey_Tests () Application.Iteration += (s, a) => { Assert.True (v1.HasFocus); // Using default keys. - top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.Tab, + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers () { Ctrl = true })); Assert.True (v2.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.Tab, + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers () { Ctrl = true })); Assert.True (v3.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.Tab, + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers () { Ctrl = true })); Assert.True (v4.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.Tab, + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers () { Ctrl = true })); Assert.True (v1.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.ShiftMask | Key.CtrlMask | Key.Tab, + top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, new KeyModifiers () { Shift = true, Ctrl = true })); Assert.True (v4.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.ShiftMask | Key.CtrlMask | Key.Tab, + top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, new KeyModifiers () { Shift = true, Ctrl = true })); Assert.True (v3.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.ShiftMask | Key.CtrlMask | Key.Tab, + top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, new KeyModifiers () { Shift = true, Ctrl = true })); Assert.True (v2.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.ShiftMask | Key.CtrlMask | Key.Tab, + top.ProcessKey (new KeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, new KeyModifiers () { Shift = true, Ctrl = true })); Assert.True (v1.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.PageDown, + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown, new KeyModifiers () { Ctrl = true })); Assert.True (v2.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.PageDown, + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown, new KeyModifiers () { Ctrl = true })); Assert.True (v3.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.PageDown, + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown, new KeyModifiers () { Ctrl = true })); Assert.True (v4.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.PageDown, + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageDown, new KeyModifiers () { Ctrl = true })); Assert.True (v1.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.PageUp, + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp, new KeyModifiers () { Ctrl = true })); Assert.True (v4.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.PageUp, + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp, new KeyModifiers () { Ctrl = true })); Assert.True (v3.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.PageUp, + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp, new KeyModifiers () { Ctrl = true })); Assert.True (v2.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.PageUp, + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.PageUp, new KeyModifiers () { Ctrl = true })); Assert.True (v1.HasFocus); @@ -687,22 +687,22 @@ public void AlternateForwardKey_AlternateBackwardKey_Tests () Application.AlternateForwardKey = Key.F7; Application.AlternateBackwardKey = Key.F6; - top.OnKeyPressed (new KeyEventArgs (Key.F7, new KeyModifiers ())); + top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ())); Assert.True (v2.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.F7, new KeyModifiers ())); + top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ())); Assert.True (v3.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.F7, new KeyModifiers ())); + top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ())); Assert.True (v4.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.F7, new KeyModifiers ())); + top.ProcessKey (new KeyEvent (Key.F7, new KeyModifiers ())); Assert.True (v1.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.F6, new KeyModifiers ())); + top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ())); Assert.True (v4.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.F6, new KeyModifiers ())); + top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ())); Assert.True (v3.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.F6, new KeyModifiers ())); + top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ())); Assert.True (v2.HasFocus); - top.OnKeyPressed (new KeyEventArgs (Key.F6, new KeyModifiers ())); + top.ProcessKey (new KeyEvent (Key.F6, new KeyModifiers ())); Assert.True (v1.HasFocus); Application.RequestStop (); @@ -775,14 +775,14 @@ public void EnsuresTopOnFront_CanFocus_True_By_Keyboard_And_Mouse () Assert.False (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.Tab, new KeyModifiers ())); + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); Assert.True (win.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); Assert.True (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.Tab, new KeyModifiers ())); + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); Assert.True (win.CanFocus); Assert.True (win.HasFocus); Assert.True (win2.CanFocus); @@ -827,14 +827,14 @@ public void EnsuresTopOnFront_CanFocus_False_By_Keyboard_And_Mouse () Assert.True (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.Tab, new KeyModifiers ())); + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); Assert.True (win2.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); Assert.True (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - top.OnKeyPressed (new KeyEventArgs (Key.CtrlMask | Key.Tab, new KeyModifiers ())); + top.ProcessKey (new KeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); Assert.False (win.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); diff --git a/UnitTests/Application/MainLoopTests.cs b/UnitTests/Application/MainLoopTests.cs index 1dd7c6ff46..a3cba7a4e7 100644 --- a/UnitTests/Application/MainLoopTests.cs +++ b/UnitTests/Application/MainLoopTests.cs @@ -688,7 +688,7 @@ public void Mainloop_Invoke_Or_AddIdle_Can_Be_Used_For_Events_Or_Actions (Action if (iterations == 0) { Assert.Null (btn); Assert.Equal (zero, total); - Assert.True (btnLaunch.OnKeyPressed (new KeyEventArgs (Key.Enter, null))); + Assert.True (btnLaunch.ProcessKey (new KeyEvent (Key.Enter, null))); if (btn == null) { Assert.Null (btn); Assert.Equal (zero, total); @@ -699,7 +699,7 @@ public void Mainloop_Invoke_Or_AddIdle_Can_Be_Used_For_Events_Or_Actions (Action } else if (iterations == 1) { Assert.Equal (clickMe, btn.Text); Assert.Equal (zero, total); - Assert.True (btn.OnKeyPressed (new KeyEventArgs (Key.Enter, null))); + Assert.True (btn.ProcessKey (new KeyEvent (Key.Enter, null))); Assert.Equal (cancel, btn.Text); Assert.Equal (one, total); } else if (taskCompleted) { diff --git a/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs b/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs index 8675953355..f36a550b13 100644 --- a/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs +++ b/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs @@ -121,8 +121,8 @@ public void FakeDriver_MockKeyPresses (Type driverType) var idx = 0; view.KeyPressed += (s, e) => { - Assert.Equal (text [idx], (char)e.Key); - rText += (char)e.Key; + Assert.Equal (text [idx], (char)e.KeyEvent.Key); + rText += (char)e.KeyEvent.Key; Assert.Equal (rText, text.Substring (0, idx + 1)); e.Handled = true; idx++; @@ -175,7 +175,7 @@ public void FakeDriver_MockKeyPresses (Type driverType) // Key key = Key.Unknown; // Application.Top.KeyPress += (e) => { - // key = e.Key; + // key = e.KeyEvent.Key; // output.WriteLine ($" Application.Top.KeyPress: {key}"); // e.Handled = true; @@ -258,7 +258,7 @@ public void TerminalResized_Simulation (Type driverType) // var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); // Assert.Equal (new Rect (0, 0, 20, 8), pos); -// Assert.True (dlg.ProcessKey (new KeyEventArgs (Key.Tab, new KeyModifiers ()))); +// Assert.True (dlg.ProcessKey (new KeyEvent (Key.Tab, new KeyModifiers ()))); // dlg.Draw (); // expected = @" diff --git a/UnitTests/ConsoleDrivers/KeyTests.cs b/UnitTests/ConsoleDrivers/KeyTests.cs index 54d0964665..b7ad45b28c 100644 --- a/UnitTests/ConsoleDrivers/KeyTests.cs +++ b/UnitTests/ConsoleDrivers/KeyTests.cs @@ -209,7 +209,7 @@ public void TestVKPacket (uint unicodeCharacter, bool shift, bool alt, bool cont var top = Application.Top; top.KeyPressed += (s, e) => { - var after = ShortcutHelper.GetModifiersKey (e); + var after = ShortcutHelper.GetModifiersKey (e.KeyEvent); Assert.Equal (expectedRemapping, after); e.Handled = true; Application.RequestStop (); diff --git a/UnitTests/Dialogs/DialogTests.cs b/UnitTests/Dialogs/DialogTests.cs index 3c1695a5f4..e01885ef9b 100644 --- a/UnitTests/Dialogs/DialogTests.cs +++ b/UnitTests/Dialogs/DialogTests.cs @@ -799,7 +799,7 @@ public void Dialog_Opened_From_Another_Dialog () Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { - Assert.True (btn1.OnKeyPressed (new KeyEventArgs (Key.Enter, new KeyModifiers ()))); + Assert.True (btn1.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ()))); } else if (iterations == 1) { expected = @$" ┌──────────────────────────────────────────────────────────────────┐ @@ -825,7 +825,7 @@ public void Dialog_Opened_From_Another_Dialog () └──────────────────────────────────────────────────────────────────┘"; TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.True (btn2.OnKeyPressed (new KeyEventArgs (Key.Enter, new KeyModifiers ()))); + Assert.True (btn2.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ()))); } else if (iterations == 2) { TestHelpers.AssertDriverContentsWithFrameAre (@$" ┌──────────────────────────────────────────────────────────────────┐ @@ -850,11 +850,11 @@ public void Dialog_Opened_From_Another_Dialog () │ {CM.Glyphs.LeftBracket} Show Sub {CM.Glyphs.RightBracket} {CM.Glyphs.LeftBracket} Close {CM.Glyphs.RightBracket} │ └──────────────────────────────────────────────────────────────────┘", output); - Assert.True (Application.Current.OnKeyPressed (new KeyEventArgs (Key.Enter, new KeyModifiers ()))); + Assert.True (Application.Current.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ()))); } else if (iterations == 3) { TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.True (btn3.OnKeyPressed (new KeyEventArgs (Key.Enter, new KeyModifiers ()))); + Assert.True (btn3.ProcessKey (new KeyEvent (Key.Enter, new KeyModifiers ()))); } else if (iterations == 4) { TestHelpers.AssertDriverContentsWithFrameAre ("", output); diff --git a/UnitTests/Input/ResponderTests.cs b/UnitTests/Input/ResponderTests.cs index 72407386d5..d060db42f5 100644 --- a/UnitTests/Input/ResponderTests.cs +++ b/UnitTests/Input/ResponderTests.cs @@ -23,11 +23,11 @@ public void New_Methods_Return_False () { var r = new Responder (); - Assert.False (r.OnKeyPressed (new KeyEventArgs () { Key = Key.Unknown })); - Assert.False (r.ProcessHotKey (new KeyEventArgs () { Key = Key.Unknown })); - Assert.False (r.ProcessColdKey (new KeyEventArgs () { Key = Key.Unknown })); - Assert.False (r.OnKeyDown (new KeyEventArgs () { Key = Key.Unknown })); - Assert.False (r.OnKeyUp (new KeyEventArgs () { Key = Key.Unknown })); + Assert.False (r.ProcessKey (new KeyEvent () { Key = Key.Unknown })); + Assert.False (r.ProcessHotKey (new KeyEvent () { Key = Key.Unknown })); + Assert.False (r.ProcessColdKey (new KeyEvent () { Key = Key.Unknown })); + Assert.False (r.OnKeyDown (new KeyEvent () { Key = Key.Unknown })); + Assert.False (r.OnKeyUp (new KeyEvent () { Key = Key.Unknown })); Assert.False (r.MouseEvent (new MouseEvent () { Flags = MouseFlags.AllEvents })); Assert.False (r.OnMouseEnter (new MouseEvent () { Flags = MouseFlags.AllEvents })); Assert.False (r.OnMouseLeave (new MouseEvent () { Flags = MouseFlags.AllEvents })); @@ -62,7 +62,7 @@ public DerivedView () { } - public override bool OnKeyDown (KeyEventArgs keyEvent) + public override bool OnKeyDown (KeyEvent keyEvent) { return true; } diff --git a/UnitTests/Text/AutocompleteTests.cs b/UnitTests/Text/AutocompleteTests.cs index bd4233ad86..dcf909fc8f 100644 --- a/UnitTests/Text/AutocompleteTests.cs +++ b/UnitTests/Text/AutocompleteTests.cs @@ -92,7 +92,7 @@ public void KeyBindings_Command () Assert.Equal ("feature", g.AllSuggestions [^1]); Assert.Equal (0, tv.Autocomplete.SelectedIdx); Assert.Empty (tv.Autocomplete.Suggestions); - Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.F, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new KeyEvent (Key.F, new KeyModifiers ()))); top.Draw (); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); @@ -101,7 +101,7 @@ public void KeyBindings_Command () Assert.Equal ("feature", tv.Autocomplete.Suggestions [^1].Replacement); Assert.Equal (0, tv.Autocomplete.SelectedIdx); Assert.Equal ("Fortunately", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); - Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorDown, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ()))); top.Draw (); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); @@ -110,7 +110,7 @@ public void KeyBindings_Command () Assert.Equal ("feature", tv.Autocomplete.Suggestions [^1].Replacement); Assert.Equal (1, tv.Autocomplete.SelectedIdx); Assert.Equal ("feature", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); - Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorDown, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorDown, new KeyModifiers ()))); top.Draw (); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); @@ -119,7 +119,7 @@ public void KeyBindings_Command () Assert.Equal ("feature", tv.Autocomplete.Suggestions [^1].Replacement); Assert.Equal (0, tv.Autocomplete.SelectedIdx); Assert.Equal ("Fortunately", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); - Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorUp, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()))); top.Draw (); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); @@ -128,7 +128,7 @@ public void KeyBindings_Command () Assert.Equal ("feature", tv.Autocomplete.Suggestions [^1].Replacement); Assert.Equal (1, tv.Autocomplete.SelectedIdx); Assert.Equal ("feature", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); - Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorUp, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorUp, new KeyModifiers ()))); top.Draw (); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); @@ -139,19 +139,19 @@ public void KeyBindings_Command () Assert.Equal ("Fortunately", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); Assert.True (tv.Autocomplete.Visible); top.Draw (); - Assert.True (tv.OnKeyPressed (new KeyEventArgs (tv.Autocomplete.CloseKey, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new KeyEvent (tv.Autocomplete.CloseKey, new KeyModifiers ()))); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); Assert.Empty (tv.Autocomplete.Suggestions); Assert.Equal (3, g.AllSuggestions.Count); Assert.False (tv.Autocomplete.Visible); tv.PositionCursor (); - Assert.True (tv.OnKeyPressed (new KeyEventArgs (tv.Autocomplete.Reopen, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new KeyEvent (tv.Autocomplete.Reopen, new KeyModifiers ()))); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); Assert.Equal (2, tv.Autocomplete.Suggestions.Count); Assert.Equal (3, g.AllSuggestions.Count); - Assert.True (tv.OnKeyPressed (new KeyEventArgs (tv.Autocomplete.SelectionKey, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new KeyEvent (tv.Autocomplete.SelectionKey, new KeyModifiers ()))); tv.PositionCursor (); Assert.Equal ($"Fortunately Fortunately super feature.", tv.Text); Assert.Equal (new Point (11, 0), tv.CursorPosition); @@ -178,7 +178,7 @@ public void CursorLeft_CursorRight_Mouse_Button_Pressed_Does_Not_Show_Popup () Application.Begin (top); for (int i = 0; i < 7; i++) { - Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorRight, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()))); Application.Refresh (); if (i < 4 || i > 5) { TestHelpers.AssertDriverContentsWithFrameAre (@" @@ -202,51 +202,51 @@ This a long line and against TextView. and against ", output); - Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.g, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new KeyEvent (Key.g, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This ag long line and against TextView. against ", output); - Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorLeft, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This ag long line and against TextView. against ", output); - Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorLeft, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This ag long line and against TextView. against ", output); - Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorLeft, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorLeft, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This ag long line and against TextView.", output); for (int i = 0; i < 3; i++) { - Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorRight, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This ag long line and against TextView. against ", output); } - Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.Backspace, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new KeyEvent (Key.Backspace, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This a long line and against TextView. and against ", output); - Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.n, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new KeyEvent (Key.n, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This an long line and against TextView. and ", output); - Assert.True (tv.OnKeyPressed (new KeyEventArgs (Key.CursorRight, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new KeyEvent (Key.CursorRight, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This an long line and against TextView.", output); diff --git a/UnitTests/Text/CollectionNavigatorTests.cs b/UnitTests/Text/CollectionNavigatorTests.cs index 70067fec9a..9031b157a9 100644 --- a/UnitTests/Text/CollectionNavigatorTests.cs +++ b/UnitTests/Text/CollectionNavigatorTests.cs @@ -382,7 +382,7 @@ public void IsCompatibleKey_Does_Not_Allow_Alt_And_Ctrl_Keys () { // test all Keys foreach (Key key in Enum.GetValues (typeof (Key))) { - var ke = new KeyEventArgs (key, new KeyModifiers () { + var ke = new KeyEvent (key, new KeyModifiers () { Alt = key == Key.AltMask, Ctrl = key == Key.CtrlMask, Shift = key == Key.ShiftMask @@ -395,7 +395,7 @@ public void IsCompatibleKey_Does_Not_Allow_Alt_And_Ctrl_Keys () } // test Capslock, Numlock and Scrolllock - Assert.True (CollectionNavigator.IsCompatibleKey (new KeyEventArgs (Key.Null, new KeyModifiers () { + Assert.True (CollectionNavigator.IsCompatibleKey (new KeyEvent (Key.Null, new KeyModifiers () { Alt = false, Ctrl = false, Shift = false, diff --git a/UnitTests/UICatalog/ScenarioTests.cs b/UnitTests/UICatalog/ScenarioTests.cs index c53742098e..19327ece95 100644 --- a/UnitTests/UICatalog/ScenarioTests.cs +++ b/UnitTests/UICatalog/ScenarioTests.cs @@ -69,12 +69,12 @@ public void Run_All_Scenarios () FakeConsole.PushMockKeyPress (Application.QuitKey); // The only key we care about is the QuitKey - Application.Top.KeyPressed += (object sender, KeyEventArgs args) => { - output.WriteLine ($" Keypress: {args.Key}"); + Application.Top.KeyPressed += (object sender, KeyEventEventArgs args) => { + output.WriteLine ($" Keypress: {args.KeyEvent.Key}"); // BUGBUG: (#2474) For some reason ReadKey is not returning the QuitKey for some Scenarios // by adding this Space it seems to work. // See #2474 for why this is commented out - Assert.Equal (Application.QuitKey, args.Key); + Assert.Equal (Application.QuitKey, args.KeyEvent.Key); }; uint abortTime = 500; @@ -156,9 +156,9 @@ public void Run_Generic () }; var token = Application.AddTimeout (TimeSpan.FromMilliseconds (ms), abortCallback); - Application.Top.KeyPressed += (object sender, KeyEventArgs args) => { + Application.Top.KeyPressed += (object sender, KeyEventEventArgs args) => { // See #2474 for why this is commented out - Assert.Equal (Key.CtrlMask | Key.Q, args.Key); + Assert.Equal (Key.CtrlMask | Key.Q, args.KeyEvent.Key); }; generic.Init (); diff --git a/UnitTests/View/KeyboardTests.cs b/UnitTests/View/KeyboardTests.cs index d273726a88..a9557294b7 100644 --- a/UnitTests/View/KeyboardTests.cs +++ b/UnitTests/View/KeyboardTests.cs @@ -28,7 +28,7 @@ public void KeyPress_Handled_To_True_Prevents_Changes () text.KeyPressed += (s, e) => { e.Handled = true; Assert.True (e.Handled); - Assert.Equal (Key.N, e.Key); + Assert.Equal (Key.N, e.KeyEvent.Key); }; top.Add (text); @@ -55,21 +55,21 @@ public void KeyDown_And_KeyUp_Events_Must_Called_Before_OnKeyDown_And_OnKeyUp () var view = new DerivedView (); view.KeyDown += (s, e) => { - Assert.Equal (Key.a, e.Key); + Assert.Equal (Key.a, e.KeyEvent.Key); Assert.False (keyDown); Assert.False (view.IsKeyDown); e.Handled = true; keyDown = true; }; view.KeyPressed += (s, e) => { - Assert.Equal (Key.a, e.Key); + Assert.Equal (Key.a, e.KeyEvent.Key); Assert.False (keyPress); Assert.False (view.IsKeyPress); e.Handled = true; keyPress = true; }; view.KeyUp += (s, e) => { - Assert.Equal (Key.a, e.Key); + Assert.Equal (Key.a, e.KeyEvent.Key); Assert.False (keyUp); Assert.False (view.IsKeyUp); e.Handled = true; @@ -106,19 +106,19 @@ public DerivedView () public bool IsKeyUp { get; set; } public override string Text { get; set; } - public override bool OnKeyDown (KeyEventArgs keyEvent) + public override bool OnKeyDown (KeyEvent keyEvent) { IsKeyDown = true; return true; } - public override bool OnKeyPressed (KeyEventArgs args) + public override bool ProcessKey (KeyEvent keyEvent) { IsKeyPress = true; return true; } - public override bool OnKeyUp (KeyEventArgs keyEvent) + public override bool OnKeyUp (KeyEvent keyEvent) { IsKeyUp = true; return true; @@ -137,10 +137,10 @@ public void KeyDown_And_KeyUp_Events_With_Only_Key_Modifiers (bool shift, bool a var view = new DerivedView (); view.KeyDown += (s, e) => { - Assert.Equal (-1, e.KeyValue); - Assert.Equal (shift, e.IsShift); - Assert.Equal (alt, e.IsAlt); - Assert.Equal (control, e.IsCtrl); + Assert.Equal (-1, e.KeyEvent.KeyValue); + Assert.Equal (shift, e.KeyEvent.IsShift); + Assert.Equal (alt, e.KeyEvent.IsAlt); + Assert.Equal (control, e.KeyEvent.IsCtrl); Assert.False (keyDown); Assert.False (view.IsKeyDown); keyDown = true; @@ -149,10 +149,10 @@ public void KeyDown_And_KeyUp_Events_With_Only_Key_Modifiers (bool shift, bool a keyPress = true; }; view.KeyUp += (s, e) => { - Assert.Equal (-1, e.KeyValue); - Assert.Equal (shift, e.IsShift); - Assert.Equal (alt, e.IsAlt); - Assert.Equal (control, e.IsCtrl); + Assert.Equal (-1, e.KeyEvent.KeyValue); + Assert.Equal (shift, e.KeyEvent.IsShift); + Assert.Equal (alt, e.KeyEvent.IsAlt); + Assert.Equal (control, e.KeyEvent.IsCtrl); Assert.False (keyUp); Assert.False (view.IsKeyUp); keyUp = true; diff --git a/UnitTests/View/Layout/DimTests.cs b/UnitTests/View/Layout/DimTests.cs index 94219071f4..c70b66d458 100644 --- a/UnitTests/View/Layout/DimTests.cs +++ b/UnitTests/View/Layout/DimTests.cs @@ -688,7 +688,7 @@ public void Dim_Add_Operator () var count = 0; field.KeyDown += (s, k) => { - if (k.Key == Key.Enter) { + if (k.KeyEvent.Key == Key.Enter) { field.Text = $"Label {count}"; var label = new Label (field.Text) { X = 0, Y = view.Bounds.Height, Width = 20 }; view.Add (label); @@ -703,7 +703,7 @@ public void Dim_Add_Operator () }; Application.Iteration += (s, a) => { - while (count < 20) field.OnKeyDown (new KeyEventArgs (Key.Enter, new KeyModifiers ())); + while (count < 20) field.OnKeyDown (new KeyEvent (Key.Enter, new KeyModifiers ())); Application.RequestStop (); }; @@ -1050,7 +1050,7 @@ public void Dim_Add_Operator_With_Text () var listLabels = new List /// Contains the details about the key that produced the event. /// true if the event was handled - public virtual bool OnKeyUp (OldKeyEvent keyEvent) + public virtual bool OnKeyUp (KeyEventArgs keyEvent) { return false; } diff --git a/Terminal.Gui/Input/ShortcutHelper.cs b/Terminal.Gui/Input/ShortcutHelper.cs index bb5273285c..942b8a4d95 100644 --- a/Terminal.Gui/Input/ShortcutHelper.cs +++ b/Terminal.Gui/Input/ShortcutHelper.cs @@ -36,9 +36,9 @@ public virtual Key Shortcut { /// /// Gets the key with all the keys modifiers, especially the shift key that sometimes have to be injected later. /// - /// The to check. - /// The with all the keys modifiers. - public static Key GetModifiersKey (OldKeyEvent kb) + /// The to check. + /// The with all the keys modifiers. + public static Key GetModifiersKey (KeyEventArgs kb) { var key = kb.Key; if (kb.IsAlt && (key & Key.AltMask) == 0) { @@ -237,10 +237,10 @@ public static bool PostShortcutValidation (Key key) /// /// Allows a view to run a if defined. /// - /// The + /// The /// The /// true if defined falseotherwise. - public static bool FindAndOpenByShortcut (OldKeyEvent kb, View view = null) + public static bool FindAndOpenByShortcut (KeyEventArgs kb, View view = null) { if (view == null) { return false; } diff --git a/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs index e9ddaf1b5a..a1c91c387a 100644 --- a/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/AppendAutocomplete.cs @@ -54,7 +54,7 @@ public override bool MouseEvent (MouseEvent me, bool fromHost = false) } /// - public override bool ProcessKey (OldKeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { var key = kb.Key; if (key == SelectionKey) { diff --git a/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs b/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs index fff5d469a8..4f2db0036e 100644 --- a/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs +++ b/Terminal.Gui/Text/Autocomplete/AutocompleteBase.cs @@ -55,7 +55,7 @@ public abstract class AutocompleteBase : IAutocomplete { public abstract bool MouseEvent (MouseEvent me, bool fromHost = false); /// - public abstract bool ProcessKey (OldKeyEvent kb); + public abstract bool ProcessKey (KeyEventArgs kb); /// public abstract void RenderOverlay (Point renderAt); diff --git a/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs index d5d364dc5e..d60ca09da4 100644 --- a/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/IAutocomplete.cs @@ -87,7 +87,7 @@ public interface IAutocomplete { /// /// The key event. /// trueif the key can be handled falseotherwise. - bool ProcessKey (OldKeyEvent kb); + bool ProcessKey (KeyEventArgs kb); /// /// Handle mouse events before e.g. to make mouse events like diff --git a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs index 9d0ea5a7c1..428c28538d 100644 --- a/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs +++ b/Terminal.Gui/Text/Autocomplete/PopupAutocomplete.cs @@ -152,7 +152,7 @@ public override ColorScheme ColorScheme { public override void RenderOverlay (Point renderAt) { if (!Context.Canceled && Suggestions.Count > 0 && !Visible && HostControl?.HasFocus == true) { - ProcessKey (new OldKeyEvent ((Key)(Suggestions [0].Title [0]), new KeyModifiers ())); + ProcessKey (new ((Key)(Suggestions [0].Title [0]), new KeyModifiers ())); } else if (!Visible || HostControl?.HasFocus == false || Suggestions.Count == 0) { LastPopupPos = null; Visible = false; @@ -278,7 +278,7 @@ public override void EnsureSelectedIdxIsValid () /// /// The key event. /// trueif the key can be handled falseotherwise. - public override bool ProcessKey (OldKeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { if (SuggestionGenerator.IsWordChar ((Rune)(char)kb.Key)) { Visible = true; diff --git a/Terminal.Gui/Text/CollectionNavigatorBase.cs b/Terminal.Gui/Text/CollectionNavigatorBase.cs index 1e846cb841..75b012f57b 100644 --- a/Terminal.Gui/Text/CollectionNavigatorBase.cs +++ b/Terminal.Gui/Text/CollectionNavigatorBase.cs @@ -209,7 +209,7 @@ private void ClearSearchString () /// /// /// - public static bool IsCompatibleKey (OldKeyEvent kb) + public static bool IsCompatibleKey (KeyEventArgs kb) { return !kb.IsAlt && !kb.IsCtrl; } diff --git a/Terminal.Gui/View/ViewKeyboard.cs b/Terminal.Gui/View/ViewKeyboard.cs index 96b112625b..4d152883b8 100644 --- a/Terminal.Gui/View/ViewKeyboard.cs +++ b/Terminal.Gui/View/ViewKeyboard.cs @@ -166,19 +166,18 @@ public bool TabStop { public event EventHandler KeyPressed; /// - public override bool ProcessKey (OldKeyEvent keyEvent) + public override bool ProcessKey (KeyEventArgs keyEvent) { if (!Enabled) { return false; } - var args = new KeyEventArgs (keyEvent); - KeyPressed?.Invoke (this, args); - if (args.Handled) + KeyPressed?.Invoke (this, keyEvent); + if (keyEvent.Handled) return true; if (Focused?.Enabled == true) { - Focused?.KeyPressed?.Invoke (this, args); - if (args.Handled) + Focused?.KeyPressed?.Invoke (this, keyEvent); + if (keyEvent.Handled) return true; } @@ -190,7 +189,7 @@ public override bool ProcessKey (OldKeyEvent keyEvent) /// and matches the /// /// The key event passed. - protected bool? InvokeKeybindings (OldKeyEvent keyEvent) + protected bool? InvokeKeybindings (KeyEventArgs keyEvent) { bool? toReturn = null; @@ -340,16 +339,15 @@ public Key GetKeyFromCommand (params Command [] command) } /// - public override bool ProcessHotKey (OldKeyEvent keyEvent) + public override bool ProcessHotKey (KeyEventArgs keyEvent) { if (!Enabled) { return false; } - var args = new KeyEventArgs (keyEvent); if (MostFocused?.Enabled == true) { - MostFocused?.KeyPressed?.Invoke (this, args); - if (args.Handled) + MostFocused?.KeyPressed?.Invoke (this, keyEvent); + if (keyEvent.Handled) return true; } if (MostFocused?.Enabled == true && MostFocused?.ProcessKey (keyEvent) == true) @@ -364,19 +362,18 @@ public override bool ProcessHotKey (OldKeyEvent keyEvent) } /// - public override bool ProcessColdKey (OldKeyEvent keyEvent) + public override bool ProcessColdKey (KeyEventArgs keyEvent) { if (!Enabled) { return false; } - var args = new KeyEventArgs (keyEvent); - KeyPressed?.Invoke (this, args); - if (args.Handled) + KeyPressed?.Invoke (this, keyEvent); + if (keyEvent.Handled) return true; if (MostFocused?.Enabled == true) { - MostFocused?.KeyPressed?.Invoke (this, args); - if (args.Handled) + MostFocused?.KeyPressed?.Invoke (this, keyEvent); + if (keyEvent.Handled) return true; } if (MostFocused?.Enabled == true && MostFocused?.ProcessKey (keyEvent) == true) @@ -396,20 +393,19 @@ public override bool ProcessColdKey (OldKeyEvent keyEvent) public event EventHandler KeyDown; /// - public override bool OnKeyDown (OldKeyEvent keyEvent) + public override bool OnKeyDown (KeyEventArgs keyEvent) { if (!Enabled) { return false; } - var args = new KeyEventArgs (keyEvent); - KeyDown?.Invoke (this, args); - if (args.Handled) { + KeyDown?.Invoke (this, keyEvent); + if (keyEvent.Handled) { return true; } if (Focused?.Enabled == true) { - Focused.KeyDown?.Invoke (this, args); - if (args.Handled) { + Focused.KeyDown?.Invoke (this, keyEvent); + if (keyEvent.Handled) { return true; } if (Focused?.OnKeyDown (keyEvent) == true) { @@ -426,20 +422,19 @@ public override bool OnKeyDown (OldKeyEvent keyEvent) public event EventHandler KeyUp; /// - public override bool OnKeyUp (OldKeyEvent keyEvent) + public override bool OnKeyUp (KeyEventArgs keyEvent) { if (!Enabled) { return false; } - var args = new KeyEventArgs (keyEvent); - KeyUp?.Invoke (this, args); - if (args.Handled) { + KeyUp?.Invoke (this, keyEvent); + if (keyEvent.Handled) { return true; } if (Focused?.Enabled == true) { - Focused.KeyUp?.Invoke (this, args); - if (args.Handled) { + Focused.KeyUp?.Invoke (this, keyEvent); + if (keyEvent.Handled) { return true; } if (Focused?.OnKeyUp (keyEvent) == true) { diff --git a/Terminal.Gui/Views/Button.cs b/Terminal.Gui/Views/Button.cs index a984050f76..1ef53229cb 100644 --- a/Terminal.Gui/Views/Button.cs +++ b/Terminal.Gui/Views/Button.cs @@ -26,7 +26,7 @@ namespace Terminal.Gui { /// /// /// When the button is configured as the default () and the user presses - /// the ENTER key, if no other processes the , the 's + /// the ENTER key, if no other processes the , the 's /// event will will be fired. /// /// @@ -191,7 +191,7 @@ protected override void UpdateTextFormatterText () } /// - public override bool ProcessHotKey (OldKeyEvent kb) + public override bool ProcessHotKey (KeyEventArgs kb) { if (!Enabled) { return false; @@ -201,7 +201,7 @@ public override bool ProcessHotKey (OldKeyEvent kb) } /// - public override bool ProcessColdKey (OldKeyEvent kb) + public override bool ProcessColdKey (KeyEventArgs kb) { if (!Enabled) { return false; @@ -211,7 +211,7 @@ public override bool ProcessColdKey (OldKeyEvent kb) } /// - public override bool ProcessKey (OldKeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { if (!Enabled) { return false; @@ -224,7 +224,7 @@ public override bool ProcessKey (OldKeyEvent kb) return base.ProcessKey (kb); } - bool ExecuteHotKey (OldKeyEvent ke) + bool ExecuteHotKey (KeyEventArgs ke) { if (ke.Key == (Key.AltMask | HotKey)) { return AcceptKey (); @@ -232,7 +232,7 @@ bool ExecuteHotKey (OldKeyEvent ke) return false; } - bool ExecuteColdKey (OldKeyEvent ke) + bool ExecuteColdKey (KeyEventArgs ke) { if (IsDefault && ke.KeyValue == '\n') { return AcceptKey (); diff --git a/Terminal.Gui/Views/CheckBox.cs b/Terminal.Gui/Views/CheckBox.cs index fa6fcffc3d..85e77ae115 100644 --- a/Terminal.Gui/Views/CheckBox.cs +++ b/Terminal.Gui/Views/CheckBox.cs @@ -168,7 +168,7 @@ public override void PositionCursor () } /// - public override bool ProcessKey (OldKeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { var result = InvokeKeybindings (kb); if (result != null) @@ -178,7 +178,7 @@ public override bool ProcessKey (OldKeyEvent kb) } /// - public override bool ProcessHotKey (OldKeyEvent kb) + public override bool ProcessHotKey (KeyEventArgs kb) { if (kb.Key == (Key.AltMask | HotKey)) return ToggleChecked (); diff --git a/Terminal.Gui/Views/ColorPicker.cs b/Terminal.Gui/Views/ColorPicker.cs index af382456d3..b2f214d0ea 100644 --- a/Terminal.Gui/Views/ColorPicker.cs +++ b/Terminal.Gui/Views/ColorPicker.cs @@ -251,7 +251,7 @@ public virtual bool MoveDown () } /// - public override bool ProcessKey (OldKeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { var result = InvokeKeybindings (kb); if (result != null) diff --git a/Terminal.Gui/Views/ComboBox.cs b/Terminal.Gui/Views/ComboBox.cs index cb9b83bff7..911c946b9c 100644 --- a/Terminal.Gui/Views/ComboBox.cs +++ b/Terminal.Gui/Views/ComboBox.cs @@ -545,7 +545,7 @@ public override void OnDrawContent (Rect contentArea) } /// - public override bool ProcessKey (OldKeyEvent e) + public override bool ProcessKey (KeyEventArgs e) { var result = InvokeKeybindings (e); if (result != null) diff --git a/Terminal.Gui/Views/DateField.cs b/Terminal.Gui/Views/DateField.cs index d7e3eec282..1019cadcb5 100644 --- a/Terminal.Gui/Views/DateField.cs +++ b/Terminal.Gui/Views/DateField.cs @@ -328,7 +328,7 @@ void AdjCursorPosition () } /// - public override bool ProcessKey (OldKeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { var result = InvokeKeybindings (kb); if (result != null) { diff --git a/Terminal.Gui/Views/Dialog.cs b/Terminal.Gui/Views/Dialog.cs index 31a3400c67..c3427306b1 100644 --- a/Terminal.Gui/Views/Dialog.cs +++ b/Terminal.Gui/Views/Dialog.cs @@ -229,7 +229,7 @@ void LayoutButtons () } /// - public override bool ProcessKey (OldKeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { switch (kb.Key) { case Key.Esc: diff --git a/Terminal.Gui/Views/FileDialog.cs b/Terminal.Gui/Views/FileDialog.cs index bb0bb12f61..5138a06849 100644 --- a/Terminal.Gui/Views/FileDialog.cs +++ b/Terminal.Gui/Views/FileDialog.cs @@ -286,12 +286,12 @@ public FileDialog (IFileSystem fileSystem) tbFind.TextChanged += (s, o) => RestartSearch (); tbFind.KeyPressed += (s, o) => { - if (o.KeyEvent.Key == Key.Enter) { + if (o.Key == Key.Enter) { RestartSearch (); o.Handled = true; } - if (o.KeyEvent.Key == Key.Esc) { + if (o.Key == Key.Esc) { if (CancelSearch ()) { o.Handled = true; } @@ -316,7 +316,7 @@ public FileDialog (IFileSystem fileSystem) this.tbPath.TextChanged += (s, e) => this.PathChanged (); this.tableView.CellActivated += this.CellActivate; - this.tableView.KeyUp += (s, k) => k.Handled = this.TableView_KeyUp (k.KeyEvent); + this.tableView.KeyUp += (s, k) => k.Handled = this.TableView_KeyUp (k); this.tableView.SelectedCellChanged += this.TableView_SelectedCellChanged; this.tableView.AddKeyBinding (Key.Home, Command.TopHome); @@ -340,7 +340,7 @@ public FileDialog (IFileSystem fileSystem) return; } - k.Handled = this.TreeView_KeyDown (k.KeyEvent); + k.Handled = this.TreeView_KeyDown (k); }; @@ -485,7 +485,7 @@ private IFileSystemInfo [] GetFocusedFiles () /// - public override bool ProcessHotKey (OldKeyEvent keyEvent) + public override bool ProcessHotKey (KeyEventArgs keyEvent) { if (this.NavigateIf (keyEvent, Key.CtrlMask | Key.F, this.tbFind)) { return true; @@ -775,14 +775,14 @@ private void AllowedTypeMenuClicked (int idx) private void SuppressIfBadChar (KeyEventArgs k) { // don't let user type bad letters - var ch = (char)k.KeyEvent.KeyValue; + var ch = (char)k.KeyValue; if (badChars.Contains (ch)) { k.Handled = true; } } - private bool TreeView_KeyDown (OldKeyEvent keyEvent) + private bool TreeView_KeyDown (KeyEventArgs keyEvent) { if (this.treeView.HasFocus && Separators.Contains ((char)keyEvent.KeyValue)) { this.tbPath.FocusFirst (); @@ -796,7 +796,7 @@ private bool TreeView_KeyDown (OldKeyEvent keyEvent) private void AcceptIf (KeyEventArgs keyEvent, Key isKey) { - if (!keyEvent.Handled && keyEvent.KeyEvent.Key == isKey) { + if (!keyEvent.Handled && keyEvent.Key == isKey) { keyEvent.Handled = true; // User hit Enter in text box so probably wants the @@ -880,17 +880,7 @@ private void FinishAccept () Application.RequestStop (); } - private void NavigateIf (KeyEventArgs keyEvent, Key isKey, View to) - { - if (!keyEvent.Handled) { - - if (NavigateIf (keyEvent.KeyEvent, isKey, to)) { - keyEvent.Handled = true; - } - } - } - - private bool NavigateIf (OldKeyEvent keyEvent, Key isKey, View to) + private bool NavigateIf (KeyEventArgs keyEvent, Key isKey, View to) { if (keyEvent.Key == isKey) { @@ -956,7 +946,7 @@ private void TableView_SelectedCellChanged (object sender, SelectedCellChangedEv } } - private bool TableView_KeyUp (OldKeyEvent keyEvent) + private bool TableView_KeyUp (KeyEventArgs keyEvent) { if (keyEvent.Key == Key.Backspace) { return this.history.Back (); diff --git a/Terminal.Gui/Views/GraphView/GraphView.cs b/Terminal.Gui/Views/GraphView/GraphView.cs index df4790a1ed..1ff6d069c9 100644 --- a/Terminal.Gui/Views/GraphView/GraphView.cs +++ b/Terminal.Gui/Views/GraphView/GraphView.cs @@ -244,7 +244,7 @@ public override bool OnEnter (View view) } /// - public override bool ProcessKey (OldKeyEvent keyEvent) + public override bool ProcessKey (KeyEventArgs keyEvent) { if (HasFocus && CanFocus) { var result = InvokeKeybindings (keyEvent); diff --git a/Terminal.Gui/Views/HexView.cs b/Terminal.Gui/Views/HexView.cs index f62ca663a5..1426cc6053 100644 --- a/Terminal.Gui/Views/HexView.cs +++ b/Terminal.Gui/Views/HexView.cs @@ -424,7 +424,7 @@ bool MoveDown (int bytes) } /// - public override bool ProcessKey (OldKeyEvent keyEvent) + public override bool ProcessKey (KeyEventArgs keyEvent) { var result = InvokeKeybindings (keyEvent); if (result != null) diff --git a/Terminal.Gui/Views/Label.cs b/Terminal.Gui/Views/Label.cs index 1191a2c1de..bd8aa813ba 100644 --- a/Terminal.Gui/Views/Label.cs +++ b/Terminal.Gui/Views/Label.cs @@ -112,7 +112,7 @@ public override bool OnEnter (View view) } /// - public override bool ProcessHotKey (OldKeyEvent ke) + public override bool ProcessHotKey (KeyEventArgs ke) { if (ke.Key == (Key.AltMask | HotKey)) { if (!HasFocus) { diff --git a/Terminal.Gui/Views/ListView.cs b/Terminal.Gui/Views/ListView.cs index 1007b062c5..2bde538498 100644 --- a/Terminal.Gui/Views/ListView.cs +++ b/Terminal.Gui/Views/ListView.cs @@ -416,7 +416,7 @@ public override void OnDrawContent (Rect contentArea) public CollectionNavigator KeystrokeNavigator { get; private set; } = new CollectionNavigator (); /// - public override bool ProcessKey (OldKeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { if (source == null) { return base.ProcessKey (kb); diff --git a/Terminal.Gui/Views/Menu.cs b/Terminal.Gui/Views/Menu.cs index dbe1ca445f..1eb2440b29 100644 --- a/Terminal.Gui/Views/Menu.cs +++ b/Terminal.Gui/Views/Menu.cs @@ -721,7 +721,7 @@ public override bool OnLeave (View view) return host.OnLeave (view); } - public override bool OnKeyDown (OldKeyEvent keyEvent) + public override bool OnKeyDown (KeyEventArgs keyEvent) { if (keyEvent.IsAlt) { host.CloseAllMenus (); @@ -731,7 +731,7 @@ public override bool OnKeyDown (OldKeyEvent keyEvent) return false; } - public override bool ProcessHotKey (OldKeyEvent keyEvent) + public override bool ProcessHotKey (KeyEventArgs keyEvent) { // To ncurses simulate a AltMask key pressing Alt+Space because // it can't detect an alone special key down was pressed. @@ -743,7 +743,7 @@ public override bool ProcessHotKey (OldKeyEvent keyEvent) return false; } - public override bool ProcessKey (OldKeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { var result = InvokeKeybindings (kb); if (result != null) @@ -1165,7 +1165,7 @@ public override bool OnLeave (View view) } /// - public override bool OnKeyDown (OldKeyEvent keyEvent) + public override bool OnKeyDown (KeyEventArgs keyEvent) { if (keyEvent.IsAlt || (keyEvent.IsCtrl && keyEvent.Key == (Key.CtrlMask | Key.Space))) { openedByAltKey = true; @@ -1176,7 +1176,7 @@ public override bool OnKeyDown (OldKeyEvent keyEvent) } /// - public override bool OnKeyUp (OldKeyEvent keyEvent) + public override bool OnKeyUp (KeyEventArgs keyEvent) { if (keyEvent.IsAlt || keyEvent.Key == Key.AltMask || (keyEvent.IsCtrl && keyEvent.Key == (Key.CtrlMask | Key.Space))) { // User pressed Alt - this may be a precursor to a menu accelerator (e.g. Alt-F) @@ -1812,7 +1812,7 @@ internal void NextMenu (bool isSubMenu = false, bool ignoreUseSubMenusSingleFram } bool openedByHotKey; - internal bool FindAndOpenMenuByHotkey (OldKeyEvent kb) + internal bool FindAndOpenMenuByHotkey (KeyEventArgs kb) { //int pos = 0; var c = ((uint)kb.Key & (uint)Key.CharMask); @@ -1839,7 +1839,7 @@ internal bool FindAndOpenMenuByHotkey (OldKeyEvent kb) return false; } - bool FindAndOpenChildrenMenuByHotkey (OldKeyEvent kb, MenuItem [] children) + bool FindAndOpenChildrenMenuByHotkey (KeyEventArgs kb, MenuItem [] children) { var c = ((uint)kb.Key & (uint)Key.CharMask); for (int i = 0; i < children.Length; i++) { @@ -1873,7 +1873,7 @@ bool FindAndOpenChildrenMenuByHotkey (OldKeyEvent kb, MenuItem [] children) return false; } - internal bool FindAndOpenMenuByShortcut (OldKeyEvent kb, MenuItem [] children = null) + internal bool FindAndOpenMenuByShortcut (KeyEventArgs kb, MenuItem [] children = null) { if (children == null) { children = Menus; @@ -1931,7 +1931,7 @@ private void ProcessMenu (int i, MenuBarItem mi) } /// - public override bool ProcessHotKey (OldKeyEvent kb) + public override bool ProcessHotKey (KeyEventArgs kb) { if (kb.Key == Key) { if (Visible && !IsMenuOpen) { @@ -1957,7 +1957,7 @@ public override bool ProcessHotKey (OldKeyEvent kb) } /// - public override bool ProcessKey (OldKeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { if (InvokeKeybindings (kb) == true) return true; @@ -2013,7 +2013,7 @@ void MoveLeft () } /// - public override bool ProcessColdKey (OldKeyEvent kb) + public override bool ProcessColdKey (KeyEventArgs kb) { return FindAndOpenMenuByShortcut (kb); } diff --git a/Terminal.Gui/Views/RadioGroup.cs b/Terminal.Gui/Views/RadioGroup.cs index dbd488686c..29c3d21e0b 100644 --- a/Terminal.Gui/Views/RadioGroup.cs +++ b/Terminal.Gui/Views/RadioGroup.cs @@ -288,7 +288,7 @@ public virtual void OnSelectedItemChanged (int selectedItem, int previousSelecte } /// - public override bool ProcessColdKey (OldKeyEvent kb) + public override bool ProcessColdKey (KeyEventArgs kb) { var key = kb.KeyValue; if (key < Char.MaxValue && Char.IsLetterOrDigit ((char)key)) { @@ -318,7 +318,7 @@ public override bool ProcessColdKey (OldKeyEvent kb) } /// - public override bool ProcessKey (OldKeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { var result = InvokeKeybindings (kb); if (result != null) diff --git a/Terminal.Gui/Views/ScrollView.cs b/Terminal.Gui/Views/ScrollView.cs index e1f8d79f93..43afca122e 100644 --- a/Terminal.Gui/Views/ScrollView.cs +++ b/Terminal.Gui/Views/ScrollView.cs @@ -542,7 +542,7 @@ public bool ScrollRight (int cols) } /// - public override bool ProcessKey (OldKeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { if (base.ProcessKey (kb)) return true; diff --git a/Terminal.Gui/Views/Slider.cs b/Terminal.Gui/Views/Slider.cs index 888532046f..efd1c4b216 100644 --- a/Terminal.Gui/Views/Slider.cs +++ b/Terminal.Gui/Views/Slider.cs @@ -1432,7 +1432,7 @@ void SetKeyBindings () } /// - public override bool ProcessKey (OldKeyEvent keyEvent) + public override bool ProcessKey (KeyEventArgs keyEvent) { if (!CanFocus || !HasFocus) { return base.ProcessKey (keyEvent); diff --git a/Terminal.Gui/Views/StatusBar.cs b/Terminal.Gui/Views/StatusBar.cs index 9ac061c40e..f6bb3fdbda 100644 --- a/Terminal.Gui/Views/StatusBar.cs +++ b/Terminal.Gui/Views/StatusBar.cs @@ -177,7 +177,7 @@ public override void OnDrawContent (Rect contentArea) } /// - public override bool ProcessHotKey (OldKeyEvent kb) + public override bool ProcessHotKey (KeyEventArgs kb) { foreach (var item in Items) { if (kb.Key == item.Shortcut) { diff --git a/Terminal.Gui/Views/TabView.cs b/Terminal.Gui/Views/TabView.cs index 3aa427cbf7..546d734fab 100644 --- a/Terminal.Gui/Views/TabView.cs +++ b/Terminal.Gui/Views/TabView.cs @@ -230,7 +230,7 @@ protected virtual void OnSelectedTabChanged (Tab oldTab, Tab newTab) } /// - public override bool ProcessKey (OldKeyEvent keyEvent) + public override bool ProcessKey (KeyEventArgs keyEvent) { if (HasFocus && CanFocus && Focused == tabsBar) { var result = InvokeKeybindings (keyEvent); diff --git a/Terminal.Gui/Views/TableView/TableView.cs b/Terminal.Gui/Views/TableView/TableView.cs index 9bac11d4f1..7ee8bc3dbc 100644 --- a/Terminal.Gui/Views/TableView/TableView.cs +++ b/Terminal.Gui/Views/TableView/TableView.cs @@ -761,7 +761,7 @@ private string TruncateOrPad (object originalCellValue, string representation, i /// - public override bool ProcessKey (OldKeyEvent keyEvent) + public override bool ProcessKey (KeyEventArgs keyEvent) { if (TableIsNullOrInvisible ()) { PositionCursor (); @@ -787,7 +787,7 @@ public override bool ProcessKey (OldKeyEvent keyEvent) return false; } - private bool CycleToNextTableEntryBeginningWith (OldKeyEvent keyEvent) + private bool CycleToNextTableEntryBeginningWith (KeyEventArgs keyEvent) { var row = SelectedRow; diff --git a/Terminal.Gui/Views/TableView/TreeTableSource.cs b/Terminal.Gui/Views/TableView/TreeTableSource.cs index 7248f06a52..52c695085b 100644 --- a/Terminal.Gui/Views/TableView/TreeTableSource.cs +++ b/Terminal.Gui/Views/TableView/TreeTableSource.cs @@ -118,13 +118,13 @@ private void Table_KeyPress (object sender, KeyEventArgs e) return; } - if (e.KeyEvent.Key == Key.CursorLeft) { + if (e.Key == Key.CursorLeft) { if (_tree.IsExpanded (obj)) { _tree.Collapse (obj); e.Handled = true; } } - if (e.KeyEvent.Key == Key.CursorRight) { + if (e.Key == Key.CursorRight) { if (_tree.CanExpand (obj) && !_tree.IsExpanded (obj)) { _tree.Expand (obj); e.Handled = true; diff --git a/Terminal.Gui/Views/TextField.cs b/Terminal.Gui/Views/TextField.cs index 506653f266..4a299f6e53 100644 --- a/Terminal.Gui/Views/TextField.cs +++ b/Terminal.Gui/Views/TextField.cs @@ -637,7 +637,7 @@ void SetClipboard (IEnumerable text) /// /// /// - public override bool ProcessKey (OldKeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { // remember current cursor position // because the new calculated cursor position is needed to be set BEFORE the change event is triggest @@ -649,7 +649,7 @@ public override bool ProcessKey (OldKeyEvent kb) return true; } - var result = InvokeKeybindings (new OldKeyEvent (ShortcutHelper.GetModifiersKey (kb), + var result = InvokeKeybindings (new (ShortcutHelper.GetModifiersKey (kb), new KeyModifiers () { Alt = kb.IsAlt, Ctrl = kb.IsCtrl, Shift = kb.IsShift })); if (result != null) return (bool)result; @@ -666,7 +666,7 @@ public override bool ProcessKey (OldKeyEvent kb) return true; } - void InsertText (OldKeyEvent kb, bool useOldCursorPos = true) + void InsertText (KeyEventArgs kb, bool useOldCursorPos = true) { _historyText.Add (new List> () { TextModel.ToRuneCells (_text) }, new Point (_point, 0)); @@ -1312,7 +1312,7 @@ public void InsertText (string toAdd, bool useOldCursorPos = true) throw new ArgumentException ($"Cannot insert character '{ch}' because it does not map to a Key"); } - InsertText (new OldKeyEvent () { Key = key }, useOldCursorPos); + InsertText (new KeyEventArgs () { Key = key }, useOldCursorPos); } } diff --git a/Terminal.Gui/Views/TextValidateField.cs b/Terminal.Gui/Views/TextValidateField.cs index 7566dadb8c..02ba25af8d 100644 --- a/Terminal.Gui/Views/TextValidateField.cs +++ b/Terminal.Gui/Views/TextValidateField.cs @@ -612,7 +612,7 @@ bool EndKeyHandler () } /// - public override bool ProcessKey (OldKeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { if (provider == null) { return false; diff --git a/Terminal.Gui/Views/TextView.cs b/Terminal.Gui/Views/TextView.cs index 7c6cfbc397..4c260c5d4c 100644 --- a/Terminal.Gui/Views/TextView.cs +++ b/Terminal.Gui/Views/TextView.cs @@ -3065,7 +3065,7 @@ public void InsertText (string toAdd) throw new ArgumentException ($"Cannot insert character '{ch}' because it does not map to a Key"); } - InsertText (new OldKeyEvent () { Key = key }); + InsertText (new KeyEventArgs () { Key = key }); } if (NeedsDisplay) { @@ -3401,7 +3401,7 @@ public void ScrollTo (int idx, bool isRow = true) bool _shiftSelecting; /// - public override bool ProcessKey (OldKeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { if (!CanFocus) { return true; @@ -3412,7 +3412,7 @@ public override bool ProcessKey (OldKeyEvent kb) return true; } - var result = InvokeKeybindings (new OldKeyEvent (ShortcutHelper.GetModifiersKey (kb), + var result = InvokeKeybindings (new (ShortcutHelper.GetModifiersKey (kb), new KeyModifiers () { Alt = kb.IsAlt, Ctrl = kb.IsCtrl, Shift = kb.IsShift })); if (result != null) return (bool)result; @@ -3791,7 +3791,7 @@ bool ProcessTab () if (!AllowsTab || _isReadOnly) { return ProcessMoveNextView (); } - InsertText (new OldKeyEvent ((Key)'\t', null)); + InsertText (new KeyEventArgs ((Key)'\t', null)); DoNeededAction (); return true; } @@ -4318,7 +4318,7 @@ void ResetAllTrack () _continuousFind = false; } - bool InsertText (OldKeyEvent kb, ColorScheme? colorScheme = null) + bool InsertText (KeyEventArgs kb, ColorScheme? colorScheme = null) { //So that special keys like tab can be processed if (_isReadOnly) @@ -4388,7 +4388,7 @@ public void DeleteAll () } /// - public override bool OnKeyUp (OldKeyEvent kb) + public override bool OnKeyUp (KeyEventArgs kb) { switch (kb.Key) { case Key.Space | Key.CtrlMask: diff --git a/Terminal.Gui/Views/TileView.cs b/Terminal.Gui/Views/TileView.cs index 3628c725a8..a394f85852 100644 --- a/Terminal.Gui/Views/TileView.cs +++ b/Terminal.Gui/Views/TileView.cs @@ -443,7 +443,7 @@ public bool TrySplitTile (int idx, int numberOfPanels, out TileView result) } /// - public override bool ProcessHotKey (OldKeyEvent keyEvent) + public override bool ProcessHotKey (KeyEventArgs keyEvent) { bool focusMoved = false; @@ -805,7 +805,7 @@ public TileViewLineView (TileView parent, int idx) AddKeyBinding (Key.CursorDown, Command.LineDown); } - public override bool ProcessKey (OldKeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { if (!CanFocus || !HasFocus) { return base.ProcessKey (kb); diff --git a/Terminal.Gui/Views/TimeField.cs b/Terminal.Gui/Views/TimeField.cs index a722c33683..c4997e1c43 100644 --- a/Terminal.Gui/Views/TimeField.cs +++ b/Terminal.Gui/Views/TimeField.cs @@ -247,7 +247,7 @@ void AdjCursorPosition () } /// - public override bool ProcessKey (OldKeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { var result = InvokeKeybindings (kb); if (result != null) diff --git a/Terminal.Gui/Views/Toplevel.cs b/Terminal.Gui/Views/Toplevel.cs index c8f5139ec6..2c787a041b 100644 --- a/Terminal.Gui/Views/Toplevel.cs +++ b/Terminal.Gui/Views/Toplevel.cs @@ -318,7 +318,7 @@ public override bool CanFocus { /// /// /// - /// events will propagate keys upwards. + /// events will propagate keys upwards. /// /// /// The Toplevel will act as an embedded view (not a modal/pop-up). @@ -329,7 +329,7 @@ public override bool CanFocus { /// /// /// - /// events will NOT propogate keys upwards. + /// events will NOT propogate keys upwards. /// /// /// The Toplevel will and look like a modal (pop-up) (e.g. see . @@ -355,7 +355,7 @@ public override bool CanFocus { public bool IsLoaded { get; private set; } /// - public override bool OnKeyDown (OldKeyEvent keyEvent) + public override bool OnKeyDown (KeyEventArgs keyEvent) { if (base.OnKeyDown (keyEvent)) { return true; @@ -373,7 +373,7 @@ public override bool OnKeyDown (OldKeyEvent keyEvent) } /// - public override bool OnKeyUp (OldKeyEvent keyEvent) + public override bool OnKeyUp (KeyEventArgs keyEvent) { if (base.OnKeyUp (keyEvent)) { return true; @@ -393,12 +393,12 @@ public override bool OnKeyUp (OldKeyEvent keyEvent) } /// - public override bool ProcessKey (OldKeyEvent keyEvent) + public override bool ProcessKey (KeyEventArgs keyEvent) { if (base.ProcessKey (keyEvent)) return true; - var result = InvokeKeybindings (new OldKeyEvent (ShortcutHelper.GetModifiersKey (keyEvent), + var result = InvokeKeybindings (new (ShortcutHelper.GetModifiersKey (keyEvent), new KeyModifiers () { Alt = keyEvent.IsAlt, Ctrl = keyEvent.IsCtrl, Shift = keyEvent.IsShift })); if (result != null) return (bool)result; @@ -479,7 +479,7 @@ private void QuitToplevel () } /// - public override bool ProcessColdKey (OldKeyEvent keyEvent) + public override bool ProcessColdKey (KeyEventArgs keyEvent) { if (base.ProcessColdKey (keyEvent)) { return true; diff --git a/Terminal.Gui/Views/TreeView/TreeView.cs b/Terminal.Gui/Views/TreeView/TreeView.cs index 41ca22c43c..a6edb90d17 100644 --- a/Terminal.Gui/Views/TreeView/TreeView.cs +++ b/Terminal.Gui/Views/TreeView/TreeView.cs @@ -621,7 +621,7 @@ private IEnumerable> AddToLineMap (Branch currentBranch, bool paren public CollectionNavigator KeystrokeNavigator { get; private set; } = new CollectionNavigator (); /// - public override bool ProcessKey (OldKeyEvent keyEvent) + public override bool ProcessKey (KeyEventArgs keyEvent) { if (!Enabled) { return false; diff --git a/Terminal.Gui/Views/Wizard/Wizard.cs b/Terminal.Gui/Views/Wizard/Wizard.cs index ef0cdb1249..93e43c89ab 100644 --- a/Terminal.Gui/Views/Wizard/Wizard.cs +++ b/Terminal.Gui/Views/Wizard/Wizard.cs @@ -147,13 +147,13 @@ private void NextfinishBtn_Clicked (object sender, EventArgs e) /// /// is derived from and Dialog causes Esc to call - /// , closing the Dialog. Wizard overrides + /// , closing the Dialog. Wizard overrides /// to instead fire the event when Wizard is being used as a non-modal (see . - /// See for more. + /// See for more. /// /// /// - public override bool ProcessKey (OldKeyEvent kb) + public override bool ProcessKey (KeyEventArgs kb) { if (!Modal) { switch (kb.Key) { diff --git a/UICatalog/KeyBindingsDialog.cs b/UICatalog/KeyBindingsDialog.cs index 538320f383..c4d65783ed 100644 --- a/UICatalog/KeyBindingsDialog.cs +++ b/UICatalog/KeyBindingsDialog.cs @@ -181,7 +181,7 @@ private void RemapKey (object sender, EventArgs e) // prompt user to hit a key var dlg = new Dialog () { Title = "Enter Key" }; dlg.KeyPressed += (s, k) => { - key = k.KeyEvent.Key; + key = k.Key; Application.RequestStop (); }; Application.Run (dlg); diff --git a/UICatalog/Scenarios/ASCIICustomButton.cs b/UICatalog/Scenarios/ASCIICustomButton.cs index 3089fd7952..9935bbd95c 100644 --- a/UICatalog/Scenarios/ASCIICustomButton.cs +++ b/UICatalog/Scenarios/ASCIICustomButton.cs @@ -233,7 +233,7 @@ public ScrollViewTestWindow () private void Button_KeyPress (object sender, KeyEventArgs obj) { - switch (obj.KeyEvent.Key) { + switch (obj.Key) { case Key.End: scrollView.ContentOffset = new Point (scrollView.ContentOffset.X, -(scrollView.ContentSize.Height - scrollView.Frame.Height diff --git a/UICatalog/Scenarios/BackgroundWorkerCollection.cs b/UICatalog/Scenarios/BackgroundWorkerCollection.cs index 22434aaedf..7eb9dca533 100644 --- a/UICatalog/Scenarios/BackgroundWorkerCollection.cs +++ b/UICatalog/Scenarios/BackgroundWorkerCollection.cs @@ -339,7 +339,7 @@ public StagingUIController () Add (close); KeyPressed += (s, e) => { - if (e.KeyEvent.Key == Key.Esc) { + if (e.Key == Key.Esc) { OnReportClosed (this, EventArgs.Empty); } }; diff --git a/UICatalog/Scenarios/ContextMenus.cs b/UICatalog/Scenarios/ContextMenus.cs index c39cb248c6..2e0eaad8f3 100644 --- a/UICatalog/Scenarios/ContextMenus.cs +++ b/UICatalog/Scenarios/ContextMenus.cs @@ -59,7 +59,7 @@ public override void Setup () Point mousePos = default; Win.KeyPressed += (s, e) => { - if (e.KeyEvent.Key == (Key.Space | Key.CtrlMask)) { + if (e.Key == (Key.Space | Key.CtrlMask)) { ShowContextMenu (mousePos.X, mousePos.Y); e.Handled = true; } diff --git a/UICatalog/Scenarios/CsvEditor.cs b/UICatalog/Scenarios/CsvEditor.cs index 3ecc907677..7c6b1deee1 100644 --- a/UICatalog/Scenarios/CsvEditor.cs +++ b/UICatalog/Scenarios/CsvEditor.cs @@ -467,7 +467,7 @@ private void SetupScrollBar () private void TableViewKeyPress (object sender, KeyEventArgs e) { - if (e.KeyEvent.Key == Key.DeleteChar) { + if (e.Key == Key.DeleteChar) { if (tableView.FullRowSelect) { // Delete button deletes all rows when in full row mode diff --git a/UICatalog/Scenarios/DynamicMenuBar.cs b/UICatalog/Scenarios/DynamicMenuBar.cs index 00f87a6a12..bb38a2d12c 100644 --- a/UICatalog/Scenarios/DynamicMenuBar.cs +++ b/UICatalog/Scenarios/DynamicMenuBar.cs @@ -723,17 +723,17 @@ public DynamicMenuBarDetails (string title) : base (title) ReadOnly = true }; _txtShortcut.KeyDown += (s, e) => { - if (!ProcessKey (e.KeyEvent)) { + if (!ProcessKey (e)) { return; } - var k = ShortcutHelper.GetModifiersKey (e.KeyEvent); + var k = ShortcutHelper.GetModifiersKey (e); if (CheckShortcut (k, true)) { e.Handled = true; } }; - bool ProcessKey (OldKeyEvent ev) + bool ProcessKey (KeyEventArgs ev) { switch (ev.Key) { case Key.CursorUp: @@ -766,7 +766,7 @@ bool CheckShortcut (Key k, bool pre) } _txtShortcut.KeyUp += (s, e) => { - var k = ShortcutHelper.GetModifiersKey (e.KeyEvent); + var k = ShortcutHelper.GetModifiersKey (e); if (CheckShortcut (k, false)) { e.Handled = true; } diff --git a/UICatalog/Scenarios/DynamicStatusBar.cs b/UICatalog/Scenarios/DynamicStatusBar.cs index 2bb87d2798..3109e7c312 100644 --- a/UICatalog/Scenarios/DynamicStatusBar.cs +++ b/UICatalog/Scenarios/DynamicStatusBar.cs @@ -396,17 +396,17 @@ public DynamicStatusBarDetails (string title) : base (title) ReadOnly = true }; _txtShortcut.KeyDown += (s, e) => { - if (!ProcessKey (e.KeyEvent)) { + if (!ProcessKey (e)) { return; } - var k = ShortcutHelper.GetModifiersKey (e.KeyEvent); + var k = ShortcutHelper.GetModifiersKey (e); if (CheckShortcut (k, true)) { e.Handled = true; } }; - bool ProcessKey (OldKeyEvent ev) + bool ProcessKey (KeyEventArgs ev) { switch (ev.Key) { case Key.CursorUp: @@ -440,7 +440,7 @@ bool CheckShortcut (Key k, bool pre) } _txtShortcut.KeyUp += (s, e) => { - var k = ShortcutHelper.GetModifiersKey (e.KeyEvent); + var k = ShortcutHelper.GetModifiersKey (e); if (CheckShortcut (k, false)) { e.Handled = true; } diff --git a/UICatalog/Scenarios/Editor.cs b/UICatalog/Scenarios/Editor.cs index 45c6f704fd..6b945f8bbc 100644 --- a/UICatalog/Scenarios/Editor.cs +++ b/UICatalog/Scenarios/Editor.cs @@ -177,11 +177,11 @@ public override void Init () }; Win.KeyPressed += (s, e) => { - var keys = ShortcutHelper.GetModifiersKey (e.KeyEvent); - if (_winDialog != null && (e.KeyEvent.Key == Key.Esc - || e.KeyEvent.Key == Application.QuitKey)) { + var keys = ShortcutHelper.GetModifiersKey (e); + if (_winDialog != null && (e.Key == Key.Esc + || e.Key == Application.QuitKey)) { DisposeWinDialog (); - } else if (e.KeyEvent.Key == Application.QuitKey) { + } else if (e.Key == Application.QuitKey) { Quit (); e.Handled = true; } else if (_winDialog != null && keys == (Key.Tab | Key.CtrlMask)) { diff --git a/UICatalog/Scenarios/InteractiveTree.cs b/UICatalog/Scenarios/InteractiveTree.cs index 2c164e2781..6b2ba38812 100644 --- a/UICatalog/Scenarios/InteractiveTree.cs +++ b/UICatalog/Scenarios/InteractiveTree.cs @@ -46,7 +46,7 @@ public override void Setup () private void TreeView_KeyPress (object sender, KeyEventArgs obj) { - if (obj.KeyEvent.Key == Key.DeleteChar) { + if (obj.Key == Key.DeleteChar) { var toDelete = treeView.SelectedObject; diff --git a/UICatalog/Scenarios/Keys.cs b/UICatalog/Scenarios/Keys.cs index cd66eadd5b..2c31446cdc 100644 --- a/UICatalog/Scenarios/Keys.cs +++ b/UICatalog/Scenarios/Keys.cs @@ -12,19 +12,19 @@ class TestWindow : Window { public List _processHotKeyList = new List (); public List _processColdKeyList = new List (); - public override bool ProcessKey (OldKeyEvent keyEvent) + public override bool ProcessKey (KeyEventArgs keyEvent) { _processKeyList.Add (keyEvent.ToString ()); return base.ProcessKey (keyEvent); } - public override bool ProcessHotKey (OldKeyEvent keyEvent) + public override bool ProcessHotKey (KeyEventArgs keyEvent) { _processHotKeyList.Add (keyEvent.ToString ()); return base.ProcessHotKey (keyEvent); } - public override bool ProcessColdKey (OldKeyEvent keyEvent) + public override bool ProcessColdKey (KeyEventArgs keyEvent) { _processColdKeyList.Add (keyEvent.ToString ()); @@ -79,7 +79,7 @@ public override void Setup () }; Win.Add (labelKeypress); - Win.KeyPressed += (s, e) => labelKeypress.Text = e.KeyEvent.ToString (); + Win.KeyPressed += (s, e) => labelKeypress.Text = e.ToString (); // Key stroke log: var keyLogLabel = new Label ("Key event log:") { @@ -87,7 +87,7 @@ public override void Setup () Y = Pos.Top (editLabel) + 4, }; Win.Add (keyLogLabel); - var fakeKeyPress = new OldKeyEvent (Key.CtrlMask | Key.A, new KeyModifiers () { + var fakeKeyPress = new KeyEventArgs (Key.CtrlMask | Key.A, new KeyModifiers () { Alt = true, Ctrl = true, Shift = true @@ -163,7 +163,7 @@ public override void Setup () void KeyDownPressUp (KeyEventArgs args, string updown) { // BUGBUG: KeyEvent.ToString is badly broken - var msg = $"Key{updown,-5}: {args.KeyEvent}"; + var msg = $"Key{updown,-5}: {args}"; keyEventlist.Add (msg); keyEventListView.MoveDown (); processKeyListView.MoveDown (); diff --git a/UICatalog/Scenarios/LineDrawing.cs b/UICatalog/Scenarios/LineDrawing.cs index f147582465..5ef5d1f7be 100644 --- a/UICatalog/Scenarios/LineDrawing.cs +++ b/UICatalog/Scenarios/LineDrawing.cs @@ -32,7 +32,7 @@ public override void Setup () Win.Add (canvas); Win.Add (tools); - Win.KeyPressed += (s,e) => { e.Handled = canvas.ProcessKey (e.KeyEvent); }; + Win.KeyPressed += (s,e) => { e.Handled = canvas.ProcessKey (e); }; } class ToolsView : Window { @@ -107,7 +107,7 @@ public DrawingArea () Stack undoHistory = new (); - public override bool ProcessKey (OldKeyEvent e) + public override bool ProcessKey (KeyEventArgs e) { if (e.Key == (Key.Z | Key.CtrlMask)) { var pop = _currentLayer.RemoveLastLine (); diff --git a/UICatalog/Scenarios/ListColumns.cs b/UICatalog/Scenarios/ListColumns.cs index 7074f98664..bb5484d07f 100644 --- a/UICatalog/Scenarios/ListColumns.cs +++ b/UICatalog/Scenarios/ListColumns.cs @@ -155,7 +155,7 @@ private void SetupScrollBar () private void TableViewKeyPress (object sender, KeyEventArgs e) { - if (e.KeyEvent.Key == Key.DeleteChar) { + if (e.Key == Key.DeleteChar) { // set all selected cells to null foreach (var pt in listColView.GetAllSelectedCells ()) { diff --git a/UICatalog/Scenarios/SendKeys.cs b/UICatalog/Scenarios/SendKeys.cs index dd9eef8ddd..965fb30c80 100644 --- a/UICatalog/Scenarios/SendKeys.cs +++ b/UICatalog/Scenarios/SendKeys.cs @@ -58,16 +58,16 @@ public override void Setup () var IsCtrl = false; txtResult.KeyPressed += (s, e) => { - rKeys += (char)e.KeyEvent.Key; - if (!IsShift && e.KeyEvent.IsShift) { + rKeys += (char)e.Key; + if (!IsShift && e.IsShift) { rControlKeys += " Shift "; IsShift = true; } - if (!IsAlt && e.KeyEvent.IsAlt) { + if (!IsAlt && e.IsAlt) { rControlKeys += " Alt "; IsAlt = true; } - if (!IsCtrl && e.KeyEvent.IsCtrl) { + if (!IsCtrl && e.IsCtrl) { rControlKeys += " Ctrl "; IsCtrl = true; } @@ -117,7 +117,7 @@ void ProcessInput () button.Clicked += (s,e) => ProcessInput (); Win.KeyPressed += (s, e) => { - if (e.KeyEvent.Key == Key.Enter) { + if (e.Key == Key.Enter) { ProcessInput (); e.Handled = true; } diff --git a/UICatalog/Scenarios/SingleBackgroundWorker.cs b/UICatalog/Scenarios/SingleBackgroundWorker.cs index 80b3693e65..d979f34b4a 100644 --- a/UICatalog/Scenarios/SingleBackgroundWorker.cs +++ b/UICatalog/Scenarios/SingleBackgroundWorker.cs @@ -136,7 +136,7 @@ public StagingUIController (DateTime? start, List list) top.KeyPressed += (s,e) => { // Prevents Ctrl+Q from closing this. // Only Ctrl+C is allowed. - if (e.KeyEvent.Key == Application.QuitKey) { + if (e.Key == Application.QuitKey) { e.Handled = true; } }; diff --git a/UICatalog/Scenarios/Snake.cs b/UICatalog/Scenarios/Snake.cs index 1161fa0617..1c9d786c7e 100644 --- a/UICatalog/Scenarios/Snake.cs +++ b/UICatalog/Scenarios/Snake.cs @@ -124,7 +124,7 @@ public override void OnDrawContent (Rect contentArea) AddRune (State.Apple.X, State.Apple.Y, _appleRune); Driver.SetAttribute (white); } - public override bool OnKeyDown (OldKeyEvent keyEvent) + public override bool OnKeyDown (KeyEventArgs keyEvent) { if (keyEvent.Key == Key.CursorUp) { State.PlannedDirection = Direction.Up; diff --git a/UICatalog/Scenarios/TableEditor.cs b/UICatalog/Scenarios/TableEditor.cs index 0cd14568c7..4de2a7ce41 100644 --- a/UICatalog/Scenarios/TableEditor.cs +++ b/UICatalog/Scenarios/TableEditor.cs @@ -392,7 +392,7 @@ private void TableViewKeyPress (object sender, KeyEventArgs e) return; } - if (e.KeyEvent.Key == Key.DeleteChar) { + if (e.Key == Key.DeleteChar) { if (tableView.FullRowSelect) { // Delete button deletes all rows when in full row mode diff --git a/UICatalog/Scenarios/TreeViewFileSystem.cs b/UICatalog/Scenarios/TreeViewFileSystem.cs index 94f0245e46..a9517ca915 100644 --- a/UICatalog/Scenarios/TreeViewFileSystem.cs +++ b/UICatalog/Scenarios/TreeViewFileSystem.cs @@ -160,7 +160,7 @@ private void TreeViewFiles_DrawLine (object sender, DrawTreeViewLineEventArgs { - //System.Diagnostics.Debug.WriteLine ($"Output - KeyDown: {e.KeyEvent.Key}"); + //System.Diagnostics.Debug.WriteLine ($"Output - KeyDown: {e.Key}"); e.Handled = true; - if (e.KeyEvent.Key == Key.Unknown) { + if (e.Key == Key.Unknown) { _wasUnknown = true; } }; @@ -99,9 +99,9 @@ public override void Setup () tvOutput.KeyPressed += (s, e) => { //System.Diagnostics.Debug.WriteLine ($"Output - KeyPress - _keyboardStrokes: {_keyboardStrokes.Count}"); if (_outputStarted && _keyboardStrokes.Count > 0) { - var ev = ShortcutHelper.GetModifiersKey (e.KeyEvent); + var ev = ShortcutHelper.GetModifiersKey (e); //System.Diagnostics.Debug.WriteLine ($"Output - KeyPress: {ev}"); - if (!tvOutput.ProcessKey (e.KeyEvent)) { + if (!tvOutput.ProcessKey (e)) { Application.Invoke (() => { MessageBox.Query ("Keys", $"'{ShortcutHelper.GetShortcutTag (ev)}' pressed!", "Ok"); }); @@ -115,9 +115,9 @@ public override void Setup () Win.Add (tvOutput); tvInput.KeyDown += (s, e) => { - //System.Diagnostics.Debug.WriteLine ($"Input - KeyDown: {e.KeyEvent.Key}"); + //System.Diagnostics.Debug.WriteLine ($"Input - KeyDown: {e.Key}"); e.Handled = true; - if (e.KeyEvent.Key == Key.Unknown) { + if (e.Key == Key.Unknown) { _wasUnknown = true; } }; @@ -125,18 +125,18 @@ public override void Setup () KeyEventArgs unknownChar = null; tvInput.KeyPressed += (s, e) => { - if (e.KeyEvent.Key == (Key.Q | Key.CtrlMask)) { + if (e.Key == (Key.Q | Key.CtrlMask)) { Application.RequestStop (); return; } - if (e.KeyEvent.Key == Key.Unknown) { + if (e.Key == Key.Unknown) { _wasUnknown = true; e.Handled = true; return; } if (_wasUnknown && _keyboardStrokes.Count == 1) { _wasUnknown = false; - } else if (_wasUnknown && char.IsLetter ((char)e.KeyEvent.Key)) { + } else if (_wasUnknown && char.IsLetter ((char)e.Key)) { _wasUnknown = false; } else if (!_wasUnknown && _keyboardStrokes.Count > 0) { e.Handled = true; @@ -147,15 +147,15 @@ public override void Setup () } else { _keyboardStrokes.Insert (0, 0); } - var ev = ShortcutHelper.GetModifiersKey (e.KeyEvent); + var ev = ShortcutHelper.GetModifiersKey (e); //System.Diagnostics.Debug.WriteLine ($"Input - KeyPress: {ev}"); //System.Diagnostics.Debug.WriteLine ($"Input - KeyPress - _keyboardStrokes: {_keyboardStrokes.Count}"); }; tvInput.KeyUp += (s, e) => { - //System.Diagnostics.Debug.WriteLine ($"Input - KeyUp: {e.KeyEvent.Key}"); - //var ke = e.KeyEvent; - var ke = ShortcutHelper.GetModifiersKey (e.KeyEvent); + //System.Diagnostics.Debug.WriteLine ($"Input - KeyUp: {e.Key}"); + //var ke = e; + var ke = ShortcutHelper.GetModifiersKey (e); if (_wasUnknown && (int)ke - (int)(ke & (Key.AltMask | Key.CtrlMask | Key.ShiftMask)) != 0) { unknownChar = e; } @@ -234,7 +234,7 @@ void Win_LayoutComplete (object sender, LayoutEventArgs obj) private void AddKeyboardStrokes (KeyEventArgs e) { - var ke = e.KeyEvent; + var ke = e; var km = new KeyModifiers (); if (ke.IsShift) { km.Shift = true; diff --git a/UICatalog/UICatalog.cs b/UICatalog/UICatalog.cs index a84111df5b..3d8bfe0d04 100644 --- a/UICatalog/UICatalog.cs +++ b/UICatalog/UICatalog.cs @@ -373,8 +373,8 @@ public UICatalogTopLevel () // 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 (CollectionNavigator.IsCompatibleKey (a.KeyEvent)) { - var newItem = _scenarioCollectionNav?.GetNextMatchingItem (ScenarioList.SelectedRow, (char)a.KeyEvent.KeyValue); + if (CollectionNavigator.IsCompatibleKey (a)) { + var newItem = _scenarioCollectionNav?.GetNextMatchingItem (ScenarioList.SelectedRow, (char)a.KeyValue); if (newItem is int v && newItem != -1) { ScenarioList.SelectedRow = v; ScenarioList.EnsureSelectedCellIsVisible (); @@ -770,7 +770,7 @@ public void ConfigChanged () void KeyDownHandler (object? sender, KeyEventArgs? a) { - if (a!.KeyEvent.IsCapslock) { + if (a!.IsCapslock) { Capslock.Title = "Caps: On"; StatusBar.SetNeedsDisplay (); } else { @@ -778,7 +778,7 @@ void KeyDownHandler (object? sender, KeyEventArgs? a) StatusBar.SetNeedsDisplay (); } - if (a!.KeyEvent.IsNumlock) { + if (a!.IsNumlock) { Numlock.Title = "Num: On"; StatusBar.SetNeedsDisplay (); } else { @@ -786,7 +786,7 @@ void KeyDownHandler (object? sender, KeyEventArgs? a) StatusBar.SetNeedsDisplay (); } - if (a!.KeyEvent.IsScrolllock) { + if (a!.IsScrolllock) { Scrolllock.Title = "Scroll: On"; StatusBar.SetNeedsDisplay (); } else { diff --git a/UnitTests/Application/ApplicationTests.cs b/UnitTests/Application/ApplicationTests.cs index 7b020db525..7160a5c87f 100644 --- a/UnitTests/Application/ApplicationTests.cs +++ b/UnitTests/Application/ApplicationTests.cs @@ -581,8 +581,8 @@ public void KeyUp_Event () int keyUps = 0; var output = string.Empty; Application.Top.KeyUp += (object sender, KeyEventArgs args) => { - if (args.KeyEvent.Key != (Key.CtrlMask | Key.Q)) { - output += (char)args.KeyEvent.KeyValue; + if (args.Key != (Key.CtrlMask | Key.Q)) { + output += (char)args.KeyValue; } keyUps++; }; @@ -629,55 +629,55 @@ public void AlternateForwardKey_AlternateBackwardKey_Tests () Application.Iteration += (s, a) => { Assert.True (v1.HasFocus); // Using default keys. - top.ProcessKey (new OldKeyEvent (Key.CtrlMask | Key.Tab, + top.ProcessKey (new (Key.CtrlMask | Key.Tab, new KeyModifiers () { Ctrl = true })); Assert.True (v2.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.CtrlMask | Key.Tab, + top.ProcessKey (new (Key.CtrlMask | Key.Tab, new KeyModifiers () { Ctrl = true })); Assert.True (v3.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.CtrlMask | Key.Tab, + top.ProcessKey (new (Key.CtrlMask | Key.Tab, new KeyModifiers () { Ctrl = true })); Assert.True (v4.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.CtrlMask | Key.Tab, + top.ProcessKey (new (Key.CtrlMask | Key.Tab, new KeyModifiers () { Ctrl = true })); Assert.True (v1.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, + top.ProcessKey (new (Key.ShiftMask | Key.CtrlMask | Key.Tab, new KeyModifiers () { Shift = true, Ctrl = true })); Assert.True (v4.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, + top.ProcessKey (new (Key.ShiftMask | Key.CtrlMask | Key.Tab, new KeyModifiers () { Shift = true, Ctrl = true })); Assert.True (v3.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, + top.ProcessKey (new (Key.ShiftMask | Key.CtrlMask | Key.Tab, new KeyModifiers () { Shift = true, Ctrl = true })); Assert.True (v2.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.ShiftMask | Key.CtrlMask | Key.Tab, + top.ProcessKey (new (Key.ShiftMask | Key.CtrlMask | Key.Tab, new KeyModifiers () { Shift = true, Ctrl = true })); Assert.True (v1.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.CtrlMask | Key.PageDown, + top.ProcessKey (new (Key.CtrlMask | Key.PageDown, new KeyModifiers () { Ctrl = true })); Assert.True (v2.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.CtrlMask | Key.PageDown, + top.ProcessKey (new (Key.CtrlMask | Key.PageDown, new KeyModifiers () { Ctrl = true })); Assert.True (v3.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.CtrlMask | Key.PageDown, + top.ProcessKey (new (Key.CtrlMask | Key.PageDown, new KeyModifiers () { Ctrl = true })); Assert.True (v4.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.CtrlMask | Key.PageDown, + top.ProcessKey (new (Key.CtrlMask | Key.PageDown, new KeyModifiers () { Ctrl = true })); Assert.True (v1.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.CtrlMask | Key.PageUp, + top.ProcessKey (new (Key.CtrlMask | Key.PageUp, new KeyModifiers () { Ctrl = true })); Assert.True (v4.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.CtrlMask | Key.PageUp, + top.ProcessKey (new (Key.CtrlMask | Key.PageUp, new KeyModifiers () { Ctrl = true })); Assert.True (v3.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.CtrlMask | Key.PageUp, + top.ProcessKey (new (Key.CtrlMask | Key.PageUp, new KeyModifiers () { Ctrl = true })); Assert.True (v2.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.CtrlMask | Key.PageUp, + top.ProcessKey (new (Key.CtrlMask | Key.PageUp, new KeyModifiers () { Ctrl = true })); Assert.True (v1.HasFocus); @@ -685,22 +685,22 @@ public void AlternateForwardKey_AlternateBackwardKey_Tests () Application.AlternateForwardKey = Key.F7; Application.AlternateBackwardKey = Key.F6; - top.ProcessKey (new OldKeyEvent (Key.F7, new KeyModifiers ())); + top.ProcessKey (new (Key.F7, new KeyModifiers ())); Assert.True (v2.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.F7, new KeyModifiers ())); + top.ProcessKey (new (Key.F7, new KeyModifiers ())); Assert.True (v3.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.F7, new KeyModifiers ())); + top.ProcessKey (new (Key.F7, new KeyModifiers ())); Assert.True (v4.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.F7, new KeyModifiers ())); + top.ProcessKey (new (Key.F7, new KeyModifiers ())); Assert.True (v1.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.F6, new KeyModifiers ())); + top.ProcessKey (new (Key.F6, new KeyModifiers ())); Assert.True (v4.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.F6, new KeyModifiers ())); + top.ProcessKey (new (Key.F6, new KeyModifiers ())); Assert.True (v3.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.F6, new KeyModifiers ())); + top.ProcessKey (new (Key.F6, new KeyModifiers ())); Assert.True (v2.HasFocus); - top.ProcessKey (new OldKeyEvent (Key.F6, new KeyModifiers ())); + top.ProcessKey (new (Key.F6, new KeyModifiers ())); Assert.True (v1.HasFocus); Application.RequestStop (); @@ -773,14 +773,14 @@ public void EnsuresTopOnFront_CanFocus_True_By_Keyboard_And_Mouse () Assert.False (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - top.ProcessKey (new OldKeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); + top.ProcessKey (new (Key.CtrlMask | Key.Tab, new KeyModifiers ())); Assert.True (win.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); Assert.True (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - top.ProcessKey (new OldKeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); + top.ProcessKey (new (Key.CtrlMask | Key.Tab, new KeyModifiers ())); Assert.True (win.CanFocus); Assert.True (win.HasFocus); Assert.True (win2.CanFocus); @@ -825,14 +825,14 @@ public void EnsuresTopOnFront_CanFocus_False_By_Keyboard_And_Mouse () Assert.True (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - top.ProcessKey (new OldKeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); + top.ProcessKey (new (Key.CtrlMask | Key.Tab, new KeyModifiers ())); Assert.True (win2.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); Assert.True (win2.HasFocus); Assert.Equal ("win2", ((Window)top.Subviews [top.Subviews.Count - 1]).Title); - top.ProcessKey (new OldKeyEvent (Key.CtrlMask | Key.Tab, new KeyModifiers ())); + top.ProcessKey (new (Key.CtrlMask | Key.Tab, new KeyModifiers ())); Assert.False (win.CanFocus); Assert.False (win.HasFocus); Assert.True (win2.CanFocus); diff --git a/UnitTests/Application/MainLoopTests.cs b/UnitTests/Application/MainLoopTests.cs index a32f458f21..4e239ab3a9 100644 --- a/UnitTests/Application/MainLoopTests.cs +++ b/UnitTests/Application/MainLoopTests.cs @@ -688,7 +688,7 @@ public void Mainloop_Invoke_Or_AddIdle_Can_Be_Used_For_Events_Or_Actions (Action if (iterations == 0) { Assert.Null (btn); Assert.Equal (zero, total); - Assert.True (btnLaunch.ProcessKey (new OldKeyEvent (Key.Enter, null))); + Assert.True (btnLaunch.ProcessKey (new (Key.Enter, null))); if (btn == null) { Assert.Null (btn); Assert.Equal (zero, total); @@ -699,7 +699,7 @@ public void Mainloop_Invoke_Or_AddIdle_Can_Be_Used_For_Events_Or_Actions (Action } else if (iterations == 1) { Assert.Equal (clickMe, btn.Text); Assert.Equal (zero, total); - Assert.True (btn.ProcessKey (new OldKeyEvent (Key.Enter, null))); + Assert.True (btn.ProcessKey (new (Key.Enter, null))); Assert.Equal (cancel, btn.Text); Assert.Equal (one, total); } else if (taskCompleted) { diff --git a/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs b/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs index 63b0e8499e..5af91d6c1b 100644 --- a/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs +++ b/UnitTests/ConsoleDrivers/ConsoleDriverTests.cs @@ -121,8 +121,8 @@ public void FakeDriver_MockKeyPresses (Type driverType) var idx = 0; view.KeyPressed += (s, e) => { - Assert.Equal (text [idx], (char)e.KeyEvent.Key); - rText += (char)e.KeyEvent.Key; + Assert.Equal (text [idx], (char)e.Key); + rText += (char)e.Key; Assert.Equal (rText, text.Substring (0, idx + 1)); e.Handled = true; idx++; @@ -175,7 +175,7 @@ public void FakeDriver_MockKeyPresses (Type driverType) // Key key = Key.Unknown; // Application.Top.KeyPress += (e) => { - // key = e.KeyEvent.Key; + // key = e.Key; // output.WriteLine ($" Application.Top.KeyPress: {key}"); // e.Handled = true; @@ -258,7 +258,7 @@ public void TerminalResized_Simulation (Type driverType) // var pos = TestHelpers.AssertDriverContentsWithFrameAre (expected, output); // Assert.Equal (new Rect (0, 0, 20, 8), pos); -// Assert.True (dlg.ProcessKey (new OldKeyEvent (Key.Tab, new KeyModifiers ()))); +// Assert.True (dlg.ProcessKey (new (Key.Tab, new KeyModifiers ()))); // dlg.Draw (); // expected = @" diff --git a/UnitTests/ConsoleDrivers/KeyTests.cs b/UnitTests/ConsoleDrivers/KeyTests.cs index b7ad45b28c..54d0964665 100644 --- a/UnitTests/ConsoleDrivers/KeyTests.cs +++ b/UnitTests/ConsoleDrivers/KeyTests.cs @@ -209,7 +209,7 @@ public void TestVKPacket (uint unicodeCharacter, bool shift, bool alt, bool cont var top = Application.Top; top.KeyPressed += (s, e) => { - var after = ShortcutHelper.GetModifiersKey (e.KeyEvent); + var after = ShortcutHelper.GetModifiersKey (e); Assert.Equal (expectedRemapping, after); e.Handled = true; Application.RequestStop (); diff --git a/UnitTests/Dialogs/DialogTests.cs b/UnitTests/Dialogs/DialogTests.cs index c62d4cff1c..823c5b10aa 100644 --- a/UnitTests/Dialogs/DialogTests.cs +++ b/UnitTests/Dialogs/DialogTests.cs @@ -799,7 +799,7 @@ public void Dialog_Opened_From_Another_Dialog () Application.Iteration += (s, a) => { iterations++; if (iterations == 0) { - Assert.True (btn1.ProcessKey (new OldKeyEvent (Key.Enter, new KeyModifiers ()))); + Assert.True (btn1.ProcessKey (new (Key.Enter, new KeyModifiers ()))); } else if (iterations == 1) { expected = @$" ┌──────────────────────────────────────────────────────────────────┐ @@ -825,7 +825,7 @@ public void Dialog_Opened_From_Another_Dialog () └──────────────────────────────────────────────────────────────────┘"; TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.True (btn2.ProcessKey (new OldKeyEvent (Key.Enter, new KeyModifiers ()))); + Assert.True (btn2.ProcessKey (new (Key.Enter, new KeyModifiers ()))); } else if (iterations == 2) { TestHelpers.AssertDriverContentsWithFrameAre (@$" ┌──────────────────────────────────────────────────────────────────┐ @@ -850,11 +850,11 @@ public void Dialog_Opened_From_Another_Dialog () │ {CM.Glyphs.LeftBracket} Show Sub {CM.Glyphs.RightBracket} {CM.Glyphs.LeftBracket} Close {CM.Glyphs.RightBracket} │ └──────────────────────────────────────────────────────────────────┘", output); - Assert.True (Application.Current.ProcessKey (new OldKeyEvent (Key.Enter, new KeyModifiers ()))); + Assert.True (Application.Current.ProcessKey (new (Key.Enter, new KeyModifiers ()))); } else if (iterations == 3) { TestHelpers.AssertDriverContentsWithFrameAre (expected, output); - Assert.True (btn3.ProcessKey (new OldKeyEvent (Key.Enter, new KeyModifiers ()))); + Assert.True (btn3.ProcessKey (new (Key.Enter, new KeyModifiers ()))); } else if (iterations == 4) { TestHelpers.AssertDriverContentsWithFrameAre ("", output); diff --git a/UnitTests/Input/ResponderTests.cs b/UnitTests/Input/ResponderTests.cs index 2904a28794..736bce02af 100644 --- a/UnitTests/Input/ResponderTests.cs +++ b/UnitTests/Input/ResponderTests.cs @@ -23,11 +23,11 @@ public void New_Methods_Return_False () { var r = new Responder (); - Assert.False (r.ProcessKey (new OldKeyEvent () { Key = Key.Unknown })); - Assert.False (r.ProcessHotKey (new OldKeyEvent () { Key = Key.Unknown })); - Assert.False (r.ProcessColdKey (new OldKeyEvent () { Key = Key.Unknown })); - Assert.False (r.OnKeyDown (new OldKeyEvent () { Key = Key.Unknown })); - Assert.False (r.OnKeyUp (new OldKeyEvent () { Key = Key.Unknown })); + Assert.False (r.ProcessKey (new KeyEventArgs () { Key = Key.Unknown })); + Assert.False (r.ProcessHotKey (new KeyEventArgs () { Key = Key.Unknown })); + Assert.False (r.ProcessColdKey (new KeyEventArgs () { Key = Key.Unknown })); + Assert.False (r.OnKeyDown (new KeyEventArgs () { Key = Key.Unknown })); + Assert.False (r.OnKeyUp (new KeyEventArgs () { Key = Key.Unknown })); Assert.False (r.MouseEvent (new MouseEvent () { Flags = MouseFlags.AllEvents })); Assert.False (r.OnMouseEnter (new MouseEvent () { Flags = MouseFlags.AllEvents })); Assert.False (r.OnMouseLeave (new MouseEvent () { Flags = MouseFlags.AllEvents })); @@ -64,7 +64,7 @@ public DerivedView () { } - public override bool OnKeyDown (OldKeyEvent keyEvent) + public override bool OnKeyDown (KeyEventArgs keyEvent) { return true; } diff --git a/UnitTests/Text/AutocompleteTests.cs b/UnitTests/Text/AutocompleteTests.cs index e9ae3598d6..901690d680 100644 --- a/UnitTests/Text/AutocompleteTests.cs +++ b/UnitTests/Text/AutocompleteTests.cs @@ -92,7 +92,7 @@ public void KeyBindings_Command () Assert.Equal ("feature", g.AllSuggestions [^1]); Assert.Equal (0, tv.Autocomplete.SelectedIdx); Assert.Empty (tv.Autocomplete.Suggestions); - Assert.True (tv.ProcessKey (new OldKeyEvent (Key.F, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new (Key.F, new KeyModifiers ()))); top.Draw (); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); @@ -101,7 +101,7 @@ public void KeyBindings_Command () Assert.Equal ("feature", tv.Autocomplete.Suggestions [^1].Replacement); Assert.Equal (0, tv.Autocomplete.SelectedIdx); Assert.Equal ("Fortunately", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); - Assert.True (tv.ProcessKey (new OldKeyEvent (Key.CursorDown, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new (Key.CursorDown, new KeyModifiers ()))); top.Draw (); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); @@ -110,7 +110,7 @@ public void KeyBindings_Command () Assert.Equal ("feature", tv.Autocomplete.Suggestions [^1].Replacement); Assert.Equal (1, tv.Autocomplete.SelectedIdx); Assert.Equal ("feature", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); - Assert.True (tv.ProcessKey (new OldKeyEvent (Key.CursorDown, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new (Key.CursorDown, new KeyModifiers ()))); top.Draw (); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); @@ -119,7 +119,7 @@ public void KeyBindings_Command () Assert.Equal ("feature", tv.Autocomplete.Suggestions [^1].Replacement); Assert.Equal (0, tv.Autocomplete.SelectedIdx); Assert.Equal ("Fortunately", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); - Assert.True (tv.ProcessKey (new OldKeyEvent (Key.CursorUp, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new (Key.CursorUp, new KeyModifiers ()))); top.Draw (); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); @@ -128,7 +128,7 @@ public void KeyBindings_Command () Assert.Equal ("feature", tv.Autocomplete.Suggestions [^1].Replacement); Assert.Equal (1, tv.Autocomplete.SelectedIdx); Assert.Equal ("feature", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); - Assert.True (tv.ProcessKey (new OldKeyEvent (Key.CursorUp, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new (Key.CursorUp, new KeyModifiers ()))); top.Draw (); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); @@ -139,19 +139,19 @@ public void KeyBindings_Command () Assert.Equal ("Fortunately", tv.Autocomplete.Suggestions [tv.Autocomplete.SelectedIdx].Replacement); Assert.True (tv.Autocomplete.Visible); top.Draw (); - Assert.True (tv.ProcessKey (new OldKeyEvent (tv.Autocomplete.CloseKey, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new (tv.Autocomplete.CloseKey, new KeyModifiers ()))); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); Assert.Empty (tv.Autocomplete.Suggestions); Assert.Equal (3, g.AllSuggestions.Count); Assert.False (tv.Autocomplete.Visible); tv.PositionCursor (); - Assert.True (tv.ProcessKey (new OldKeyEvent (tv.Autocomplete.Reopen, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new (tv.Autocomplete.Reopen, new KeyModifiers ()))); Assert.Equal ($"F Fortunately super feature.", tv.Text); Assert.Equal (new Point (1, 0), tv.CursorPosition); Assert.Equal (2, tv.Autocomplete.Suggestions.Count); Assert.Equal (3, g.AllSuggestions.Count); - Assert.True (tv.ProcessKey (new OldKeyEvent (tv.Autocomplete.SelectionKey, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new (tv.Autocomplete.SelectionKey, new KeyModifiers ()))); tv.PositionCursor (); Assert.Equal ($"Fortunately Fortunately super feature.", tv.Text); Assert.Equal (new Point (11, 0), tv.CursorPosition); @@ -178,7 +178,7 @@ public void CursorLeft_CursorRight_Mouse_Button_Pressed_Does_Not_Show_Popup () Application.Begin (top); for (int i = 0; i < 7; i++) { - Assert.True (tv.ProcessKey (new OldKeyEvent (Key.CursorRight, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new (Key.CursorRight, new KeyModifiers ()))); Application.Refresh (); if (i < 4 || i > 5) { TestHelpers.AssertDriverContentsWithFrameAre (@" @@ -202,51 +202,51 @@ This a long line and against TextView. and against ", output); - Assert.True (tv.ProcessKey (new OldKeyEvent (Key.g, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new (Key.g, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This ag long line and against TextView. against ", output); - Assert.True (tv.ProcessKey (new OldKeyEvent (Key.CursorLeft, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new (Key.CursorLeft, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This ag long line and against TextView. against ", output); - Assert.True (tv.ProcessKey (new OldKeyEvent (Key.CursorLeft, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new (Key.CursorLeft, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This ag long line and against TextView. against ", output); - Assert.True (tv.ProcessKey (new OldKeyEvent (Key.CursorLeft, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new (Key.CursorLeft, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This ag long line and against TextView.", output); for (int i = 0; i < 3; i++) { - Assert.True (tv.ProcessKey (new OldKeyEvent (Key.CursorRight, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new (Key.CursorRight, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This ag long line and against TextView. against ", output); } - Assert.True (tv.ProcessKey (new OldKeyEvent (Key.Backspace, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new (Key.Backspace, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This a long line and against TextView. and against ", output); - Assert.True (tv.ProcessKey (new OldKeyEvent (Key.n, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new (Key.n, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This an long line and against TextView. and ", output); - Assert.True (tv.ProcessKey (new OldKeyEvent (Key.CursorRight, new KeyModifiers ()))); + Assert.True (tv.ProcessKey (new (Key.CursorRight, new KeyModifiers ()))); Application.Refresh (); TestHelpers.AssertDriverContentsWithFrameAre (@" This an long line and against TextView.", output); diff --git a/UnitTests/Text/CollectionNavigatorTests.cs b/UnitTests/Text/CollectionNavigatorTests.cs index 83f00724a2..6240a0c56a 100644 --- a/UnitTests/Text/CollectionNavigatorTests.cs +++ b/UnitTests/Text/CollectionNavigatorTests.cs @@ -382,7 +382,7 @@ public void IsCompatibleKey_Does_Not_Allow_Alt_And_Ctrl_Keys () { // test all Keys foreach (Key key in Enum.GetValues (typeof (Key))) { - var ke = new OldKeyEvent (key, new KeyModifiers () { + var ke = new KeyEventArgs (key, new KeyModifiers () { Alt = key == Key.AltMask, Ctrl = key == Key.CtrlMask, Shift = key == Key.ShiftMask @@ -395,7 +395,7 @@ public void IsCompatibleKey_Does_Not_Allow_Alt_And_Ctrl_Keys () } // test Capslock, Numlock and Scrolllock - Assert.True (CollectionNavigator.IsCompatibleKey (new OldKeyEvent (Key.Null, new KeyModifiers () { + Assert.True (CollectionNavigator.IsCompatibleKey (new (Key.Null, new KeyModifiers () { Alt = false, Ctrl = false, Shift = false, diff --git a/UnitTests/UICatalog/ScenarioTests.cs b/UnitTests/UICatalog/ScenarioTests.cs index 69e79e9bd5..40de0a8df5 100644 --- a/UnitTests/UICatalog/ScenarioTests.cs +++ b/UnitTests/UICatalog/ScenarioTests.cs @@ -70,11 +70,11 @@ public void Run_All_Scenarios () // The only key we care about is the QuitKey Application.Top.KeyPressed += (object sender, KeyEventArgs args) => { - output.WriteLine ($" Keypress: {args.KeyEvent.Key}"); + output.WriteLine ($" Keypress: {args.Key}"); // BUGBUG: (#2474) For some reason ReadKey is not returning the QuitKey for some Scenarios // by adding this Space it seems to work. // See #2474 for why this is commented out - Assert.Equal (Application.QuitKey, args.KeyEvent.Key); + Assert.Equal (Application.QuitKey, args.Key); }; uint abortTime = 500; @@ -155,7 +155,7 @@ public void Run_Generic () Application.Top.KeyPressed += (object sender, KeyEventArgs args) => { // See #2474 for why this is commented out - Assert.Equal (Key.CtrlMask | Key.Q, args.KeyEvent.Key); + Assert.Equal (Key.CtrlMask | Key.Q, args.Key); }; generic.Init (); diff --git a/UnitTests/View/KeyboardTests.cs b/UnitTests/View/KeyboardTests.cs index 70010300a1..f9388ceb87 100644 --- a/UnitTests/View/KeyboardTests.cs +++ b/UnitTests/View/KeyboardTests.cs @@ -28,7 +28,7 @@ public void KeyPress_Handled_To_True_Prevents_Changes () text.KeyPressed += (s, e) => { e.Handled = true; Assert.True (e.Handled); - Assert.Equal (Key.N, e.KeyEvent.Key); + Assert.Equal (Key.N, e.Key); }; top.Add (text); @@ -55,21 +55,21 @@ public void KeyDown_And_KeyUp_Events_Must_Called_Before_OnKeyDown_And_OnKeyUp () var view = new DerivedView (); view.KeyDown += (s, e) => { - Assert.Equal (Key.a, e.KeyEvent.Key); + Assert.Equal (Key.a, e.Key); Assert.False (keyDown); Assert.False (view.IsKeyDown); e.Handled = true; keyDown = true; }; view.KeyPressed += (s, e) => { - Assert.Equal (Key.a, e.KeyEvent.Key); + Assert.Equal (Key.a, e.Key); Assert.False (keyPress); Assert.False (view.IsKeyPress); e.Handled = true; keyPress = true; }; view.KeyUp += (s, e) => { - Assert.Equal (Key.a, e.KeyEvent.Key); + Assert.Equal (Key.a, e.Key); Assert.False (keyUp); Assert.False (view.IsKeyUp); e.Handled = true; @@ -106,19 +106,19 @@ public DerivedView () public bool IsKeyUp { get; set; } public override string Text { get; set; } - public override bool OnKeyDown (OldKeyEvent keyEvent) + public override bool OnKeyDown (KeyEventArgs keyEvent) { IsKeyDown = true; return true; } - public override bool ProcessKey (OldKeyEvent keyEvent) + public override bool ProcessKey (KeyEventArgs keyEvent) { IsKeyPress = true; return true; } - public override bool OnKeyUp (OldKeyEvent keyEvent) + public override bool OnKeyUp (KeyEventArgs keyEvent) { IsKeyUp = true; return true; @@ -137,10 +137,10 @@ public void KeyDown_And_KeyUp_Events_With_Only_Key_Modifiers (bool shift, bool a var view = new DerivedView (); view.KeyDown += (s, e) => { - Assert.Equal (-1, e.KeyEvent.KeyValue); - Assert.Equal (shift, e.KeyEvent.IsShift); - Assert.Equal (alt, e.KeyEvent.IsAlt); - Assert.Equal (control, e.KeyEvent.IsCtrl); + Assert.Equal (-1, e.KeyValue); + Assert.Equal (shift, e.IsShift); + Assert.Equal (alt, e.IsAlt); + Assert.Equal (control, e.IsCtrl); Assert.False (keyDown); Assert.False (view.IsKeyDown); keyDown = true; @@ -149,10 +149,10 @@ public void KeyDown_And_KeyUp_Events_With_Only_Key_Modifiers (bool shift, bool a keyPress = true; }; view.KeyUp += (s, e) => { - Assert.Equal (-1, e.KeyEvent.KeyValue); - Assert.Equal (shift, e.KeyEvent.IsShift); - Assert.Equal (alt, e.KeyEvent.IsAlt); - Assert.Equal (control, e.KeyEvent.IsCtrl); + Assert.Equal (-1, e.KeyValue); + Assert.Equal (shift, e.IsShift); + Assert.Equal (alt, e.IsAlt); + Assert.Equal (control, e.IsCtrl); Assert.False (keyUp); Assert.False (view.IsKeyUp); keyUp = true; diff --git a/UnitTests/View/Layout/DimTests.cs b/UnitTests/View/Layout/DimTests.cs index 535db54769..e1cccfee1f 100644 --- a/UnitTests/View/Layout/DimTests.cs +++ b/UnitTests/View/Layout/DimTests.cs @@ -688,7 +688,7 @@ public void Dim_Add_Operator () var count = 0; field.KeyDown += (s, k) => { - if (k.KeyEvent.Key == Key.Enter) { + if (k.Key == Key.Enter) { field.Text = $"Label {count}"; var label = new Label (field.Text) { X = 0, Y = view.Bounds.Height, Width = 20 }; view.Add (label); @@ -703,7 +703,7 @@ public void Dim_Add_Operator () }; Application.Iteration += (s, a) => { - while (count < 20) field.OnKeyDown (new OldKeyEvent (Key.Enter, new KeyModifiers ())); + while (count < 20) field.OnKeyDown (new (Key.Enter, new KeyModifiers ())); Application.RequestStop (); }; @@ -1050,7 +1050,7 @@ public void Dim_Add_Operator_With_Text () var listLabels = new List